1 /* 2 I got tired of `workbone' not being able to shuffle and other things. 3 4 -- Roy Keene [021119991215] rkeene@netfueldesign.com 5 */ 6 7 #include <unistd.h> 8 #include <getopt.h> 9 #include <stdio.h> 10 #include <signal.h> 11 #include <stdlib.h> 12 #include <string.h> 13 #ifndef NO_SETPRIORITY 14 #include <sys/time.h> 15 #include <sys/resource.h> 16 #endif 17 #ifndef CDROM_DEV 18 #define CDROM_DEV "/dev/cdrom" 19 #endif 20 #include "cdrom.h" 21 /* Perhaps this is overdoing it? */ 22 #include "random.h" 23 #include "cdplay.h" 24 25 #include <linux/cdrom.h> 26 #include <fcntl.h> 27 #include <sys/types.h> 28 #include <sys/stat.h> 29 #include <sys/ioctl.h> 30 31 32 extern char *optarg; 33 extern int optind, optopt, opterr; 34 int cdrom=-1; 35 int dsp=-1; 36 37 void shutdown(void) { 38 if (cdrom!=-1) { 39 cd_stop(cdrom); 40 close(cdrom); 41 } 42 exit(0); 43 } 44 45 #ifdef MAKE_EJECT 46 int matchexec(char *path, char *cmp) { 47 int i,x,y,z; 48 x=strlen(path); 49 y=strlen(cmp); 50 if (x<y) z=x; else z=y; 51 for (i=0;i<z;i++) { 52 if (path[x-i]=='/' || path[x-i]=='\\') { return(0); } 53 if (path[x-i]!=cmp[y-i]) { return(1); } 54 } 55 return(0); 56 } 57 #endif 58 59 int printhelp(int fullhelp, char argv0[128]) { 60 printf("usage: %s [-aheslqdbSV] [-v volume] [-t track#] [-f seconds] [-r seconds]\n",argv0); 61 if (fullhelp==0) { return(0); } 62 printf(" -V\tPrints version (%s).\n",VERSION); 63 printf(" -h\tThis help screen.\n"); 64 printf(" -a\t*Raw play for people with broken analog cables.\n"); 65 printf(" -e\tEject the CD-ROM from the drive.\n"); 66 printf(" -s\tShuffle tracks randomly.\n"); 67 printf(" -l\tLoop tracks.\n"); 68 printf(" -S\tStop CD from playing.\n"); 69 printf(" -q\tQuiet (no tty output).\n"); 70 printf(" -d\tDisplay current Track, time, and volume.\n"); 71 printf(" -b\tStart in background\n"); 72 printf(" -vX\tSet the volume to X\n"); 73 printf(" -tX\tGoto track X.\n"); 74 printf(" -fX\t*Fast forward X seconds.\n"); 75 printf(" -rX\t*Rewind X seconds.\n"); 76 printf("%s with no arguments plays the CD all the way through in logical\n order, once.\n",argv0); 77 printf("\"*\"s indicate options that do not yet work.\n"); 78 return(0); 79 } 80 81 int main(int argc, char *argv[]) { 82 char opt, *buf; 83 char *track_buffer; 84 struct cdrom_read_audio block_read; 85 int start_track=0, num_tracks=0; 86 int loop=0, shuffle=0, play=1, track=0, quiet=0; 87 int action=CDPLAY_NOACTION, volume=0; 88 int prio=20; 89 int tracklist[128]; 90 int usedlist[128]= 91 {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 92 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 93 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 94 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 95 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 96 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 97 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 98 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}; 99 int i,x=0; 100 #ifdef DEBUG 101 printf("cdplay.c: main(argc, argv)\n"); 102 #endif 103 104 #ifdef MAKE_EJECT 105 #ifdef DEBUG 106 printf("cdplay.c: main: argv[0]=\"%s\"\n",argv[0]); 107 #endif DEBUG 108 if (!matchexec(argv[0],"eject")) { 109 signal(SIGINT, (void *)shutdown); 110 signal(SIGHUP, (void *)shutdown); 111 cdrom=open_cdrom(CDROM_DEV); 112 if (cdrom<0) { 113 printf("Unable to open %s\n",CDROM_DEV); 114 return(-1); 115 } 116 cd_eject(cdrom); 117 close(cdrom); 118 return(0); 119 } 120 #endif MAKE_EJECT 121 122 while ((opt=getopt(argc,argv,"adbhVeSqslt:f:r:v:"))!=-1) { 123 switch(opt) { 124 case 'b': 125 if (fork()!=0) return(0); 126 close(STDIN_FILENO); 127 close(STDOUT_FILENO); 128 close(STDERR_FILENO); 129 chdir("/tmp"); 130 case 'q': 131 quiet=1; 132 break; 133 case 'v': 134 action=CDPLAY_SETVOL; 135 volume=atoi(optarg); 136 break; 137 case 'V': 138 printf("cdplay version %s.\n", VERSION); 139 return(0); 140 case 'S': 141 play=0; 142 break; 143 case 'e': 144 action=CDPLAY_EJECT; 145 break; 146 case 's': 147 shuffle=1; 148 break; 149 case 'l': 150 loop=1; 151 break; 152 case 't': 153 i=0; 154 track_buffer=strtok(optarg,","); 155 while (1) { 156 if (track_buffer==NULL) break; 157 tracklist[i]=atoi(track_buffer); 158 i++; 159 track_buffer=strtok(NULL, ","); 160 } 161 start_track=0; 162 num_tracks=i; 163 if (num_tracks==1) { track=atoi(optarg); } else { track=-1; } 164 break; 165 case 'd': 166 action=CDPLAY_DISPLAY; 167 break; 168 case 'a': 169 prio=-20; 170 action=CDPLAY_RAWPLAY; 171 break; 172 case 'h': 173 printhelp(1, argv[0]); 174 return(0); 175 default: 176 printhelp(0, argv[0]); 177 return(-1); 178 } 179 } 180 #ifndef NO_SETPRIORITY 181 setpriority(PRIO_PROCESS, 0, prio); 182 #endif 183 signal(SIGINT, (void *)shutdown); 184 signal(SIGHUP, (void *)shutdown); 185 signal(SIGTERM, (void *)shutdown); 186 cdrom=open_cdrom(CDROM_DEV); 187 if (cdrom<0) { 188 printf("Unable to open %s\n",CDROM_DEV); 189 return(-1); 190 } 191 #ifdef DEBUG 192 printf("cdplay.c: main: action=%i\n",action); 193 #endif 194 switch(action) { 195 case CDPLAY_DISPLAY: 196 if (cd_isplaying(cdrom)) 197 printf("Current track is\t%i\nVolume is \t%i\n",cd_currenttrack(cdrom),cd_getvolume(cdrom)); 198 else 199 printf("CD is stopped.\n"); 200 close(cdrom); 201 return(0); 202 case CDPLAY_EJECT: 203 cd_stop(cdrom); 204 cd_eject(cdrom); 205 close(cdrom); 206 return(0); 207 case CDPLAY_SETVOL: 208 cd_setvolume(cdrom, volume); 209 if (cd_isplaying(cdrom)) return(0); 210 break; 211 case CDPLAY_RAWPLAY: 212 #ifndef NFRAMES 213 #define NFRAMES 1 214 #endif 215 buf=malloc(2352*NFRAMES); 216 ioctl(cdrom, CDROMSTART); 217 block_read.addr.lba=1; 218 block_read.addr_format=CDROM_LBA; 219 block_read.nframes=NFRAMES; 220 block_read.buf=buf; 221 dsp=open("/dev/dsp",O_WRONLY); 222 while (1) { 223 block_read.addr.lba++; 224 ioctl(cdrom, CDROMREADAUDIO, &block_read); 225 write(dsp, buf, 2352*NFRAMES); 226 } 227 break; 228 } 229 #ifdef DEBUG 230 printf("cdplay.c: main: num_tracks=%i\n",num_tracks=cd_num_tracks(cdrom, 0)); 231 printf("cdplay.c: main: start_track=%i\n",start_track=cd_num_tracks(cdrom,1)); 232 #else 233 if (track!=-1) { 234 num_tracks=cd_num_tracks(cdrom, 0); 235 start_track=cd_num_tracks(cdrom,1); 236 } 237 #endif 238 if (argc==1) { 239 cd_play(cdrom,start_track); 240 close(cdrom); 241 return(0); 242 } 243 244 245 if (play==0) { cd_stop(cdrom); close(cdrom); return(0); } 246 247 if (track>0) { 248 if (track<start_track || track>=(start_track+num_tracks)) { 249 printf("No such track (%i)!\n",track); 250 return(-1); 251 } 252 if (loop==0) { 253 cd_playtrack(cdrom, track); 254 close(cdrom); 255 return(0); 256 } else { 257 while(1) { 258 CDPLAY_LOOP_PLAY(cdrom, track); 259 while (cd_currenttrack(cdrom)==track) 260 usleep(CDPLAY_CHECK_DELAY); 261 } 262 } 263 } 264 265 if (track!=-1) { 266 for (i=start_track;i<(start_track+num_tracks);i++) { 267 tracklist[i]=i; 268 } 269 } 270 271 272 x=1; 273 while(loop+x>0) { 274 275 if (shuffle==1) { 276 for (i=start_track;i<(start_track+num_tracks);i++) { 277 track=0; 278 while(track==0) { 279 x=(generate_random_number(num_tracks-1)+1); 280 if (usedlist[x]==-1) { 281 tracklist[i]=x; 282 usedlist[x]=0; 283 track=1; 284 } 285 } 286 } 287 } 288 for (i=start_track;i<(start_track+num_tracks);i++) { 289 if (!quiet) printf("Playing track %i \n",tracklist[i]); 290 CDPLAY_LOOP_PLAY(cdrom, tracklist[i]); 291 while (cd_currenttrack(cdrom)==tracklist[i]) 292 usleep(CDPLAY_CHECK_DELAY); 293 if (!quiet) { 294 printf("\033[1A"); 295 fflush(stdout); 296 } 297 if (shuffle==1) usedlist[i]=-1; 298 } 299 x=0; 300 } 301 close(cdrom); 302 return(0); 303 } cdplay.c is the source code containing main(). |