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/
This commit is contained in:
		
							parent
							
								
									a16e508465
								
							
						
					
					
						commit
						4e9f4c66ab
					
				
					 2 changed files with 463 additions and 0 deletions
				
			
		
							
								
								
									
										459
									
								
								wmcdplay/cdctl_freebsd.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										459
									
								
								wmcdplay/cdctl_freebsd.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -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@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;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -35,7 +35,11 @@
 | 
				
			||||||
#include <unistd.h>
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Includes - custom
 | 
					// Includes - custom
 | 
				
			||||||
 | 
					#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
 | 
				
			||||||
 | 
					#include "cdctl_freebsd.h"
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
#include "cdctl.h"
 | 
					#include "cdctl.h"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// X-Windows includes - standard
 | 
					// X-Windows includes - standard
 | 
				
			||||||
#include <X11/X.h>
 | 
					#include <X11/X.h>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue