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