[Pkg-wmaker-commits] [wmcdplay] 46/79: wmcdplay: Port to FreeBSD.

Doug Torrance dtorrance-guest at moszumanska.debian.org
Thu Aug 20 11:04:33 UTC 2015


This is an automated email from the git hooks/post-receive script.

dtorrance-guest pushed a commit to branch master
in repository wmcdplay.

commit 92f3b01d9f1b4a23ccf442a1738da48cc2da69a9
Author: Doug Torrance <dtorrance at monmouthcollege.edu>
Date:   Thu Dec 18 12:30:45 2014 -0600

    wmcdplay: Port to FreeBSD.
    
    As is, wmcdplay does not build on FreeBSD systems. Although it has since been
    deleted, a port of wmcdplay for FreeBSD was available. It consisted primarily
    of a patch to cdctl.h [1].  Include this patch when building for FreeBSD.
    
    Based on the Debian patch [2].
    
    [1] https://svnweb.freebsd.org/ports/head/audio/wmcdplay/files/ patch-aa?revision=56594&view=co&pathrev=56594
    [2] http://sources.debian.net/src/wmcdplay/1.0beta1-13/debian/patches/kfreebsd_port.patch/
---
 cdctl_freebsd.h | 459 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 wmcdplay.cc     |   4 +
 2 files changed, 463 insertions(+)

diff --git a/cdctl_freebsd.h b/cdctl_freebsd.h
new file mode 100644
index 0000000..b237609
--- /dev/null
+++ b/cdctl_freebsd.h
@@ -0,0 +1,459 @@
+// cdctl.h - CDCtl class provides easy control of cd audio functions
+// 05/09/98  Release 1.0 Beta1
+// Copyright (C) 1998  Sam Hawker <shawkie at geocities.com>
+// This software comes with ABSOLUTELY NO WARRANTY
+// This software is free software, and you are welcome to redistribute it
+// under certain conditions
+// See the README file for a more complete notice.
+
+// Although cdctl.h is an integral part of wmcdplay, it may also be distributed seperately.
+
+// Change this define to alter the size of forward and backward skips (in frames)
+// Yes, I know this should really be a method of CDCtl
+#define _CDCTL_SKIP_SIZE 1125
+
+// Try defining some of these. They may improve performance or reliability
+// (or just plain make it work)
+// #define _CDCTL_STOP_BEFORE_PLAY
+// #define _CDCTL_START_BEFORE_PLAY
+// #define _CDCTL_SOFT_STOP
+
+// Define this if it stops after each track
+#define _CDCTL_SENSITIVE_EOT
+// If it still stops for a while between tracks, increase this (0-75 is a sensible range)
+#define _CDCTL_SENSITIVITY 0
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/cdio.h>
+#include <arpa/inet.h>
+#define CD_MSF_OFFSET	150
+
+// CD status values
+#define ssData     0
+#define ssStopped  1
+#define ssPlaying  2
+#define ssPaused   3
+#define ssNoCD     4
+#define ssTrayOpen 5
+
+// Audio command values
+#define acStop   0
+#define acPlay   1
+#define acPause  2
+#define acResume 3
+#define acPrev   4
+#define acNext   5
+#define acRewd   6
+#define acFFwd   7
+#define acEject  8
+#define acClose  9
+
+// Track selection values (what to do when I've played the requested track)
+// Note:      Track selection is not perfect - so use tsNone if you want to avoid trouble.
+//            Basically, if we receive a CDROM_AUDIO_COMPLETED status, then we have to decide what to do.
+//            If we think the last play command was ours (Next/Prev/FFwd/Rewd don't count), then we do something,
+//            depending on the current track selection mode.
+// Failures:  Sometimes we may think we sent the last play command when we did not (if we didn't see play stop in
+//            in between).
+//            If another application is polling the status, it may receive the CDROM_AUDIO_COMPLETED we are looking
+//            for, and we will not, so will think play was stopped manually.
+//            Similarly, we may read the CDROM_AUDIO_COMPLETED status when we don't want it, such that the other
+//            application never sees it.
+// Verdict:   Linux audio cdrom handling is broken.
+// Update:    New define _CDCTL_SENSITIVE_EOT may help in cases where CDROM_AUDIO_COMPLETED is not being returned
+//            correctly. It may, however, interfere with other running cd players.
+
+// Update:    I think this works like a dream now. Even with many cd players sharing a cdrom. Let me know if not!!
+
+#define tsNone      0    // Just stop
+#define tsRepeat    1    // Play it again
+#define tsNext      2    // Play next track (stop at end of CD)
+#define tsRepeatCD  3    // Play next track (start from first track if end is reached)
+#define tsRandom    4    // Play a track at random
+
+class CDCtl
+{
+public:
+   CDCtl(char *dname){
+      device=(char *)malloc(sizeof(char)*(strlen(dname)+1));
+      strcpy(device,dname);
+      srand(getpid());
+      tracksel=tsRandom;
+      tskOurPlay=false;
+
+      if(cdfdopen=(cdfd=open(device,O_RDONLY | O_NONBLOCK))!=-1){
+         status_state=ssNoCD;
+         status_track=0;
+         status_pos=0;
+         cd_trklist=NULL;
+         doStatus();
+         readVolume();
+      }
+   }
+   ~CDCtl(){
+      if(cdfdopen){
+         close(cdfd);
+         if(device!=NULL)
+            free(device);
+         if(cd_trklist!=NULL)
+            free(cd_trklist);
+      }
+   }
+   bool openOK(){
+      return cdfdopen;
+   }
+   void doAudioCommand(int cmd){
+      if(cdfdopen){
+         int newtrk=status_track;
+	 switch(cmd){
+	  case acStop:
+
+             #ifdef _CDCTL_SOFT_STOP
+             ioctl(cdfd,CDIOCSTART);
+             #endif
+             #ifndef _CDCTL_SOFT_STOP
+             ioctl(cdfd,CDIOCSTOP);
+             #endif
+             tskOurPlay=false;
+
+          break;
+	  case acPlay:
+             status_state=ssPlaying;
+             select(status_track);
+             tskOurPlay=true;
+          break;
+          case acPause:
+             ioctl(cdfd,CDIOCPAUSE);
+          break;
+	  case acResume:
+             ioctl(cdfd,CDIOCRESUME);
+          break;
+	  case acPrev:
+             newtrk--;
+             if(newtrk<0)
+                newtrk=cd_tracks-1;
+             select(newtrk);
+          break;
+ 	  case acNext:
+             newtrk++;
+             if(newtrk>cd_tracks-1)
+                newtrk=0;
+             select(newtrk);
+          break;
+	  case acRewd:
+	     if(status_pos>cd_trklist[status_track].track_start+_CDCTL_SKIP_SIZE){
+                status_pos-=_CDCTL_SKIP_SIZE;
+                play();
+             }
+          break;
+          case acFFwd:
+	    if(status_pos<cd_trklist[status_track].track_start+cd_trklist[status_track].track_len-_CDCTL_SKIP_SIZE){
+               status_pos+=_CDCTL_SKIP_SIZE;
+               play();
+            }
+          break;
+	  case acEject:
+             if(ioctl(cdfd,CDIOCEJECT))
+                status_state=ssNoCD;
+             else
+                status_state=ssTrayOpen;
+          break;
+	  case acClose:
+             ioctl(cdfd,CDIOCCLOSE);
+             status_state=ssNoCD;
+          break;
+         }
+         doStatus();
+      }
+   }
+   void doStatus(){
+      if(cdfdopen){
+         struct ioc_read_subchannel sc;
+         struct cd_sub_channel_info csci;
+         sc.address_format=CD_MSF_FORMAT;
+         sc.track = 0;
+         sc.data=&csci;
+         sc.data_len=sizeof(csci);
+         sc.data_format=CD_CURRENT_POSITION;
+         if(ioctl(cdfd, CDIOCREADSUBCHANNEL, &sc)){
+            if(status_state!=ssNoCD)
+               status_state=ssTrayOpen;
+	    status_track=0;
+            status_pos=0;
+            tskOurPlay=false;
+         }
+         else{
+            if(status_state==ssNoCD || status_state==ssTrayOpen)
+	       readTOC();
+            int start,now,stop;
+            switch(csci.header.audio_status){
+             case CD_AS_PLAY_IN_PROGRESS:
+                if(status_state==ssStopped)
+                   tskOurPlay=false;
+                status_state=ssPlaying;
+             break;
+             case CD_AS_PLAY_PAUSED:
+                if(status_state==ssStopped)
+                   tskOurPlay=false;
+                status_state=ssPaused;
+             break;
+             case CD_AS_PLAY_COMPLETED:
+	        if(tskOurPlay){
+                   status_state=ssPlaying;
+	           selecttrack();
+	           doStatus();
+	           return;
+	        }
+	        else
+	           status_state=ssStopped;
+	     break;
+             default:
+
+                #ifdef _CDCTL_SENSITIVE_EOT
+                if(tskOurPlay){
+                   start = cd_trklist[status_track].track_start;
+                   stop = start + cd_trklist[status_track].track_len - _CDCTL_SENSITIVITY;
+                   now = ((csci.what.position.absaddr.msf.minute) * 60 + csci.what.position.absaddr.msf.second) * 75 + csci.what.position.absaddr.msf.frame - CD_MSF_OFFSET;
+	           if(now>0 && (now<start || now>=stop)){
+                      status_state=ssPlaying;
+                      selecttrack();
+                      doStatus();
+                      return;
+                   }
+                   else
+                      status_state=ssStopped;
+	        }
+                else
+                #endif
+
+                   status_state=ssStopped;
+            }
+            trackinfo(&csci);
+            if(cd_trklist[status_track].track_data)
+               status_state=ssData;
+         }
+      }
+   }
+   void setVolume(int l, int r){
+      if(cdfdopen){
+         struct ioc_vol vol;
+         vol.vol[0]=l;
+         vol.vol[1]=r;
+         vol.vol[2]=0;
+         vol.vol[3]=0;
+         ioctl(cdfd,CDIOCSETVOL,&vol);
+         readVolume();
+      }
+   }
+   void readVolume(){
+      if(cdfdopen){
+         struct ioc_vol vol;
+         ioctl(cdfd,CDIOCGETVOL,&vol);
+         status_volumel=vol.vol[0];
+         status_volumer=vol.vol[1];
+      }
+   }
+   int getVolumeL(){
+      return status_volumel;
+   }
+   int getVolumeR(){
+      return status_volumer;
+   }
+   void setTrackSelection(int ts){
+      tracksel=ts;
+   }
+   int getTrackSelection(){
+      return tracksel;
+   }
+   char *getDevName(){
+      return device;
+   }
+   int getCDTracks(){
+      return cd_tracks;
+   }
+   int getCDLen(){
+      return cd_len;
+   }
+   int getTrackStart(int trk){
+      return cd_trklist[trk-1].track_start;
+   }
+   int getTrackLen(int trk){
+      return cd_trklist[trk-1].track_len;
+   }
+   bool getTrackData(int trk){
+      return cd_trklist[trk-1].track_data;
+   }
+   int getStatusState(){
+      return status_state;
+   }
+   int getStatusTrack(){
+      return status_track+1;
+   }
+   int getStatusPosAbs(){
+      return status_pos-cd_trklist[0].track_start;
+   }
+   int getStatusPosRel(){
+      return status_pos-cd_trklist[status_track].track_start;
+   }
+private:
+   void readTOC(){
+      if(cd_trklist!=NULL)
+         free(cd_trklist);
+      struct ioc_toc_header hdr;
+      ioctl(cdfd, CDIOREADTOCHEADER, &hdr);
+      cd_tracks=hdr.ending_track;
+      cd_trklist=(struct CDTrack *)malloc(cd_tracks*sizeof(struct CDTrack));
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+	struct ioc_read_toc_entry te;
+      
+	te.data_len = (cd_tracks + 1) * sizeof(struct cd_toc_entry);
+	te.data = (struct cd_toc_entry *)malloc(te.data_len);
+	te.address_format = CD_LBA_FORMAT;
+	te.starting_track = 0;
+	ioctl(cdfd, CDIOREADTOCENTRYS, &te);
+	for(int i = 0; i < cd_tracks; i++) {
+		cd_trklist[i].track_data = te.data[i].control & 4 ? true : false;
+		cd_trklist[i].track_start = ntohl(te.data[i].addr.lba);
+		cd_trklist[i].track_len = ntohl(te.data[i + 1].addr.lba)
+			- cd_trklist[i].track_start;
+	}
+	cd_len = ntohl(te.data[cd_tracks].addr.lba);
+	free(te.data);
+#else
+      struct cdrom_tocentry te;
+      int prev_addr=0;
+      
+      for(int i=0;i<=cd_tracks;i++){
+         if(i==cd_tracks)
+            te.cdte_track=CDROM_LEADOUT;
+         else
+            te.cdte_track=i+1;
+         te.cdte_format=CDROM_MSF;    // I think it is ok to read this as LBA, but for a quiet life...
+         ioctl(cdfd, CDROMREADTOCENTRY, &te);
+         int this_addr=((te.cdte_addr.msf.minute * 60) + te.cdte_addr.msf.second) * 75 + te.cdte_addr.msf.frame - CD_MSF_OFFSET;
+         if(i>0)
+	    cd_trklist[i-1].track_len = this_addr - prev_addr - 1;
+         prev_addr=this_addr;
+         if(i<cd_tracks){
+            cd_trklist[i].track_data = te.cdte_ctrl & CDROM_DATA_TRACK ? true : false;
+	    cd_trklist[i].track_start = this_addr;
+         }
+         else
+            cd_len = this_addr;
+      }
+#endif
+   }
+   void trackinfo(struct cd_sub_channel_info *subchnl){
+      int currenttrack = status_track;
+
+      if(status_state==ssPlaying || status_state==ssPaused){
+         status_pos=((subchnl->what.position.absaddr.msf.minute) * 60 + subchnl->what.position.absaddr.msf.second) * 75 + subchnl->what.position.absaddr.msf.frame - CD_MSF_OFFSET;
+         for(status_track=0;status_track<cd_tracks;status_track++){
+            if(status_pos<cd_trklist[status_track].track_start+cd_trklist[status_track].track_len) {
+               if (status_track != currenttrack) {
+                  status_track = currenttrack;
+               }
+               break;
+            }
+         }
+      }
+   }
+   void play(){
+      struct ioc_play_msf pmsf;
+      int abs0=status_pos + CD_MSF_OFFSET;
+      int abs1=cd_trklist[status_track].track_start + cd_trklist[status_track].track_len - 1 + CD_MSF_OFFSET;
+      pmsf.start_m=abs0/(75*60);
+      pmsf.end_m=abs1/(75*60);
+      pmsf.start_s=(abs0%(75*60))/75;
+      pmsf.end_s=(abs1%(75*60))/75;
+      pmsf.start_f=abs0%75;
+      pmsf.end_f=abs1%75;
+
+      #ifdef _CDCTL_STOP_BEFORE_PLAY
+      ioctl(cdfd,CDIOCSTOP);
+      #endif
+      #ifdef _CDCTL_START_BEFORE_PLAY
+      ioctl(cdfd,CDIOCSTART);
+      #endif
+
+      ioctl(cdfd,CDIOCPLAYMSF,&pmsf);
+   }
+   void select(int trk){
+      status_track=trk;
+      status_pos=cd_trklist[status_track].track_start;
+      if(status_state==ssPlaying){
+         if(cd_trklist[status_track].track_data){
+
+             #ifdef _CDCTL_HARD_STOP
+             ioctl(cdfd,CDIOCSTOP);
+             #endif
+             #ifndef _CDCTL_HARD_STOP
+             ioctl(cdfd,CDIOCSTART);
+             #endif
+             tskOurPlay=false;
+
+         }
+         else
+            play();
+      }
+   }
+   void selecttrack(){
+      int newtrk=status_track;
+      do{
+         switch(tracksel){
+          case tsNone:
+             tskOurPlay=false;
+             return;
+          break;
+          case tsRepeat:
+             // do nothing
+          break;
+          case tsNext:
+             newtrk++;
+             if(newtrk>=cd_tracks){
+                tskOurPlay=false;
+                return;
+             }
+          break;
+          case tsRepeatCD:
+             newtrk++;
+             if(newtrk>=cd_tracks)
+                newtrk=0;
+          break;
+          case tsRandom:
+             newtrk+=(int)((cd_tracks-1)*(float)rand()/RAND_MAX+1);
+             if(newtrk>=cd_tracks)
+                newtrk-=cd_tracks;
+          break;
+         }
+      }  while(cd_trklist[newtrk].track_data);
+      select(newtrk);
+      play();
+   }
+   int cdfd;
+   int cdfdopen;
+   char *device;
+   int tracksel;
+   bool tskOurPlay;
+
+   struct CDTrack{
+      int track_start;
+      int track_len;
+      bool track_data;
+   };
+
+   int cd_tracks;
+   int cd_len;
+   struct CDTrack *cd_trklist;
+   int status_state;
+   int status_track;
+   int status_pos;
+   int status_volumel;
+   int status_volumer;
+};
diff --git a/wmcdplay.cc b/wmcdplay.cc
index 3ca2f0b..c60ef48 100644
--- a/wmcdplay.cc
+++ b/wmcdplay.cc
@@ -35,7 +35,11 @@
 #include <unistd.h>
 
 // Includes - custom
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#include "cdctl_freebsd.h"
+#else
 #include "cdctl.h"
+#endif
 
 // X-Windows includes - standard
 #include <X11/X.h>

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-wmaker/wmcdplay.git



More information about the Pkg-wmaker-commits mailing list