1 /*
2 * Copyright (C) 1990 Regents of the University of California.
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and
5 * its documentation for any purpose is hereby granted without fee,
6 * provided that the above copyright notice appear in all copies and that
7 * both that copyright notice and this permission notice appear in
8 * supporting documentation, and that the name of the University of
9 * California not be used in advertising or publicity pertaining to
10 * distribution of the software without specific, written prior
11 * permission. the University of California makes no representations
12 * about the suitability of this software for any purpose. It is provided
13 * "as is" without express or implied warranty.
14 */
15
16 static int c;
17
18 # if defined(sgi)
19 # include <stdio.h>
20
21 # include <sys/file.h>
22 # include <sys/types.h>
23 # include <sys/param.h>
24 # include <sys/stat.h>
25
26 # include <mntent.h>
27 # include <string.h>
28 # include <signal.h>
29
30 # include <sys/buf.h>
31
32 # include <sys/time.h>
33
34 /* We need shared memory for the counter display if using scsi_audio */
35 #include <sys/ipc.h>
36 #include <sys/shm.h>
37 int shmid;
38 key_t shmkey;
39
40
41 # include "debug.h"
42 # include "cdrom_sgi.h"
43
44 extern char *device;
45 # if defined(notdef)
46 extern void cdrom_print_toc();
47 # endif /* defined(notdef) */
48
49 void cdrom_audio_close();
50 void cdrom_callback();
51 void cdrom_kill_child();
52 int cdrom_child_setup();
53 void cdrom_child_pause();
54 void cdrom_child_died();
55 void cdrom_child_quit();
56
57 #define INIT_READ 200 /* Maximum number we can play */
58 #define ONE_SECOND 75 /* One second of data */
59
60 cdrom_info cdi;
61 struct _cdrom_shmem *cdrom_shmem;
62 char info_filename[256];
63 FILE *disc_info = NULL;
64
65 CDPLAYER *cdrom_fd = NULL;
66 ALport audio_fd = NULL;
67 long audio_param[6];
68 CDFRAME *cd_audio_buff = NULL;
69 CDPARSER *cd_parser = NULL;
70 int cdrom_audio_opened = 0;
71
get_stored_info()72 get_stored_info()
73 {
74 int i,n;
75 char line[100];
76 char *title;
77
78 if ( cdi.maxtrack == 0) {
79 return(0);
80 }
81 for (i = 0, n = 0; i < cdi.maxtrack; i++)
82 n = n + ((i+1) * cdi.times[i]);
83 n = n / cdi.maxtrack;
84
85 disc_title = NULL;
86 if (cdInfoDir != NULL)
87 sprintf(info_filename, "%s/cd.%d", cdInfoDir, n);
88 else
89 sprintf(info_filename, "cd.%d", n);
90
91 if ((disc_info = fopen(info_filename, "r")) != NULL)
92 {
93 fgets(line, 100, disc_info);
94 title = strchr(line, ':');
95 if (title != NULL)
96 {
97 *(strchr(title, '\n')) = '\0';
98 disc_title = strdup(title + 1);
99 }
100 fgets(line, 100, disc_info);
101 sscanf(line, "Program: %s", program_str);
102 }
103 if (disc_title == NULL) {
104 disc_title = NOTITLESTR;
105 }
106 }
107
108 int
cdrom_open()109 cdrom_open() {
110 int n;
111 CDSTATUS cdrom_stat;
112 extern void update_title();
113
114 if (cdrom_fd != NULL) {
115 return(cdi.curtrack);
116 }
117
118 if (device != NULL) {
119 fprintf(stderr,"Device: %s\n",device);
120 if ((cdrom_fd = CDopen(device, "r")) == NULL) {
121 fprintf(stderr, "open cdrom: %s",device);
122 perror("CDopen");
123 return(-1);
124 }
125 } else {
126 if ((cdrom_fd = CDopen(0, "r")) == NULL) {
127 fprintf(stderr, "open cdrom: ");
128 perror("CDopen");
129 return(-1);
130 }
131 }
132
133 if (cdrom_get_times() == -1) {
134 cdrom_close();
135 return(-1);
136 }
137
138 if ((n = cdrom_get_curtrack()) == -1)
139 return(-1);
140
141 get_stored_info();
142
143 update_title();
144
145 if (! CDgetstatus(cdrom_fd, (CDSTATUS *) &cdrom_stat)) {
146 fprintf(stderr, "CDgetstatus(cdrom_stat): ");
147 perror("CDgetstatus");
148 return(-1);
149 }
150 if ((cdrom_stat.state == CD_PLAYING) ||
151 (cdrom_stat.state == CD_PAUSED)) {
152 cdi.scsi_audio = 0;
153 } else {
154 cdi.scsi_audio = cdrom_audio_avail();
155 }
156
157 if (cdi.scsi_audio) {
158 if (cd_audio_buff == (CDFRAME *) NULL) {
159 if ((cd_audio_buff =
160 (CDFRAME *) malloc(INIT_READ * CDDA_BLOCKSIZE)) == NULL) {
161 fprintf(stderr,"cdrom_open: cannot allocate cd digital data buffer!\n");
162 perror("cdrom_open");
163 cdi.scsi_audio = 0;
164 }
165 }
166 if (cd_parser == NULL) {
167 if ((cd_parser = CDcreateparser()) == NULL) {
168 fprintf(stderr,"cdrom_open: CDcreateparser failed!\n");
169 perror("cdrom_open");
170 cdi.scsi_audio = 0;
171 }
172 CDresetparser(cd_parser);
173 CDsetcallback(cd_parser, cd_audio, cdrom_callback, 0);
174 CDsetcallback(cd_parser, cd_pnum, cdrom_callback, 0);
175 CDsetcallback(cd_parser, cd_atime, cdrom_callback, 0);
176 CDsetcallback(cd_parser, cd_catalog, cdrom_callback, 0);
177 }
178 #if 0
179 /* Get the catalog number, if one exists */
180 CDseektrack(cdrom_fd,1);
181 cdrom_shmem->cdrom_audio_cdi.state = CD_PLAYING;
182 cdrom_play_frames(1);
183 #endif
184 }
185
186 if (cdi.state & CDROM_STATE_PLAY)
187 cdi.curtrack = n;
188
189 if (cdi.state & CDROM_STATE_SHUFFLE)
190 shuffle_setup();
191
192 return(cdi.curtrack);
193 }
194
195 void
cdrom_close()196 cdrom_close() {
197 if (cdrom_fd == NULL)
198 return;
199
200 if (cdi.scsi_audio) {
201 cdrom_kill_child();
202 cdrom_audio_close();
203 }
204 if (cdi.times != NULL) {
205 free((char *) cdi.times);
206 free((char *) cdi.addrs);
207 cdi.times = NULL;
208 cdi.addrs = NULL;
209 }
210
211 (void) CDclose(cdrom_fd);
212 cdrom_fd = NULL;
213 }
214
215 int
cdrom_audio_open()216 cdrom_audio_open() {
217 ALconfig aconfig;
218
219 aconfig = ALnewconfig();
220
221 /* Attempt to create the largest buffer we can */
222 ALsetqueuesize (aconfig, SAMPLES_PER_FRAME * INIT_READ);
223
224 /* Make sure we are 16bit stereo */
225 ALsetwidth(aconfig, AL_SAMPLE_16);
226 ALsetchannels(aconfig, AL_STEREO);
227
228 if ((audio_fd = ALopenport("XCplayer", "w", aconfig)) == NULL) {
229 ALfreeconfig(aconfig);
230 return(-1); /* No error, just return -1 */
231 }
232
233 ALfreeconfig(aconfig);
234
235 audio_param[0] = AL_OUTPUT_RATE;
236 audio_param[1] = AL_RATE_44100;
237 ALsetparams(AL_DEFAULT_DEVICE, audio_param, 2);
238
239 shmkey = IPC_PRIVATE;
240 if ((shmid = shmget(shmkey, sizeof(struct _cdrom_shmem),
241 (SHM_R | SHM_W | IPC_CREAT | IPC_EXCL) )) < 0) {
242 perror("shmget");
243 return(-1);
244 }
245 cdrom_shmem = shmat(shmid, NULL, SHM_RND);
246 }
247
248 void
cdrom_audio_close()249 cdrom_audio_close() {
250 if (audio_fd == NULL)
251 return;
252
253 (void) ALcloseport(audio_fd);
254 shmdt(cdrom_shmem);
255 shmctl(shmid,IPC_RMID);
256 audio_fd = NULL;
257 cdrom_audio_opened = 0;
258 }
259
260 void
cdrom_callback(arg,type,data)261 cdrom_callback(arg, type, data)
262 int arg;
263 CDDATATYPES type;
264 void *data;
265 {
266 struct cdtimecode *timecode_info;
267 CDPROGNUM *pnum_info;
268 char * catalog_num;
269 int otime, time;
270 int i;
271
272 switch (type) {
273 case cd_audio:
274 ALwritesamps(audio_fd, data, SAMPLES_PER_FRAME);
275 break;
276 case cd_pnum:
277 pnum_info = data;
278
279 if (pnum_info->value <=
280 cdrom_shmem->cdrom_audio_cdi.end_track) {
281 cdrom_shmem->cdrom_audio_cdi.curtrack = pnum_info->value;
282 } else {
283 cdrom_shmem->cdrom_audio_cdi.curtrack = 0;
284 cdrom_shmem->cdrom_audio_cdi.state = CD_READY;
285 }
286 break;
287 case cd_atime:
288 timecode_info = data;
289
290 otime = (cdrom_shmem->cdrom_audio_msf.minute * 60) +
291 cdrom_shmem->cdrom_audio_msf.second;
292 time = (((timecode_info->mhi * 10) +
293 timecode_info->mlo) * 60) +
294 (timecode_info->shi * 10) +
295 timecode_info->slo;
296
297 if ((otime > (time + 2)) || (otime < time - 2)) {
298 if (CDseek(cdrom_fd,
299 cdrom_shmem->cdrom_audio_msf.minute,
300 cdrom_shmem->cdrom_audio_msf.second,
301 cdrom_shmem->cdrom_audio_msf.frame) < 0) {
302 perror("CDseek");
303 }
304 cdrom_shmem->cdrom_audio_cdi.state = CD_ABORT;
305 return;
306 }
307
308 cdrom_shmem->cdrom_audio_msf.minute =
309 (timecode_info->mhi * 10) + timecode_info->mlo;
310 cdrom_shmem->cdrom_audio_msf.second =
311 (timecode_info->shi * 10) + timecode_info->slo;
312 cdrom_shmem->cdrom_audio_msf.frame =
313 (timecode_info->fhi * 10) + timecode_info->flo;
314
315 break;
316 case cd_catalog:
317 catalog_num = data;
318 #if 0
319 fprintf(stderr,"Catalog #: ");
320 for (i=0; i<13; i++) {
321 fprintf(stderr,"%d",*(catalog_num+i));
322 }
323 fprintf(stderr,"\n");
324 #endif
325 default:
326 return;
327 }
328 }
329
330 int
cdrom_start()331 cdrom_start() {
332 return(0);
333 }
334
335 int
cdrom_stop()336 cdrom_stop() {
337 if (cdi.scsi_audio && cdrom_audio_opened) {
338 cdrom_kill_child();
339 cdrom_shmem->cdrom_audio_cdi.curtrack = cdi.curtrack;
340 cdrom_shmem->cdrom_audio_cdi.state = CD_READY;
341 }
342 if (! CDstop(cdrom_fd)) {
343 perror("CDstop");
344 return(-1);
345 }
346
347 return(0);
348 }
349
350 int
cdrom_eject()351 cdrom_eject() {
352 if (cdi.scsi_audio && cdrom_audio_opened) {
353 cdrom_kill_child();
354 cdrom_shmem->cdrom_audio_cdi.state = CD_NODISC;
355 }
356 if (! CDeject(cdrom_fd)) {
357 perror("ioctl(cdromeject)");
358 return(-1);
359 }
360 cdrom_close();
361
362 return(0);
363 }
364
365 int
cdrom_pause()366 cdrom_pause() {
367 int track;
368
369 if (cdi.scsi_audio && cdrom_audio_opened) {
370 cdrom_shmem->cdrom_audio_cdi.state = CD_PAUSED;
371 return(0);
372 }
373 if (! cdrom_paused(&track)) {
374 if (! CDtogglepause(cdrom_fd)) {
375 perror("CDtogglepause");
376 return(-1);
377 }
378 }
379
380 return(0);
381 }
382
383 int
cdrom_resume()384 cdrom_resume() {
385 int track;
386
387 if (cdi.scsi_audio && cdrom_audio_opened) {
388 cdrom_shmem->cdrom_audio_cdi.state = CD_PLAYING;
389 return(0);
390 }
391 if (! cdrom_playing(&track)) {
392 if (! CDtogglepause(cdrom_fd)) {
393 perror("CDtogglepause");
394 return(-1);
395 }
396 }
397
398 return(0);
399 }
400
401 int
cdrom_toggle_audio()402 cdrom_toggle_audio()
403 {
404 if (cdi.scsi_audio) {
405 cdrom_kill_child();
406 cdi.scsi_audio = 0;
407 return;
408 }
409 cdi.scsi_audio = 1;
410 }
411
412 int
cdrom_volume(left_vol,right_vol)413 cdrom_volume(left_vol, right_vol)
414 int left_vol;
415 int right_vol;
416 {
417 CDVOLUME cd_vol;
418
419 if (cdi.scsi_audio) {
420 audio_param[0] = AL_LEFT_SPEAKER_GAIN;
421 audio_param[1] = left_vol;
422 audio_param[2] = AL_RIGHT_SPEAKER_GAIN;
423 audio_param[3] = right_vol;
424
425 ALsetparams (AL_DEFAULT_DEVICE, audio_param, 4);
426 } else {
427 #if 0
428 /* I would love to use this, but it isn't documented */
429 cd_vol.chan0 = (unsigned char)left_vol;
430 cd_vol.chan1 = (unsigned char)right_vol;
431 CDsetvolume(cdrom_fd, &cd_vol);
432 #endif
433 return(-1);
434 }
435
436 return(0);
437 }
438
439 int
cdrom_get_volume()440 cdrom_get_volume()
441 {
442 int vol;
443 CDVOLUME cd_vol;
444
445 audio_param[0] = AL_LEFT_SPEAKER_GAIN;
446 audio_param[2] = AL_RIGHT_SPEAKER_GAIN;
447 if (cdi.scsi_audio) {
448 ALgetparams (AL_DEFAULT_DEVICE, audio_param, 4);
449
450 /* Return the average of left and right channels */
451 vol=(audio_param[1] + audio_param[3]) / 2;
452 } else {
453 #if 0
454 /* I would love to use this, but it isn't documented */
455 CDgetvolume(cdrom_fd, &cd_vol);
456 fprintf(stderr,"%d %d %d %d\n",cd_vol.chan0,cd_vol.chan1,
457 cd_vol.chan2,cd_vol.chan3);
458 vol=(cd_vol.chan0 + cd_vol.chan1) / 2;
459 #endif
460 vol = -1;
461 }
462
463 return(vol);
464 }
465
466 int
cdrom_get_times()467 cdrom_get_times() {
468 CDSTATUS tochdr;
469 extern unsigned short *ushort_malloc();
470 extern struct msf *msf_malloc();
471 unsigned long trk, trk_total, otime;
472 struct msf msf;
473
474 if (cdrom_read_tochdr(&tochdr) == -1) {
475 cdi.mintrack = 0;
476 cdi.maxtrack = 0;
477 return(-1);
478 #if 0
479 return(0);
480 #endif
481 }
482
483 cdi.mintrack = tochdr.first;
484 cdi.maxtrack = tochdr.last;
485
486 if (cdi.times != NULL)
487 {
488 free((char *) cdi.times);
489 free((char *) cdi.addrs);
490 cdi.times = NULL;
491 cdi.addrs = NULL;
492 }
493
494 cdi.times = ushort_malloc(cdi.maxtrack - cdi.mintrack + 1);
495 cdi.addrs = msf_malloc(cdi.maxtrack - cdi.mintrack + 2);
496
497 otime = 0;
498
499 for (trk = cdi.mintrack; trk <= cdi.maxtrack; trk++) {
500 if (cdrom_get_msf(trk, &msf, &trk_total) == -1)
501 return(-1);
502
503 /* record start address for each track (track 1 starts at 0)*/
504 cdi.addrs[trk - cdi.mintrack] = msf;
505
506 trk_total -= otime;
507
508 /* use start time of next track as length of previous */
509 if (otime != 0)
510 {
511 cdi.times[trk - cdi.mintrack - 1] = trk_total;
512 }
513
514 otime += trk_total;
515
516 }
517
518 /* find start of leadout to get length of last track */
519 if (cdrom_get_msf(CDROM_LEADOUT, &msf, &trk_total) == -1)
520 return(-1);
521
522 /* recode leadout start address */
523 cdi.addrs[trk - cdi.mintrack] = msf;
524 trk_total -= otime;
525 otime += trk_total;
526
527 cdi.times[trk - cdi.mintrack - 1] = trk_total;
528
529 return(0);
530 }
531
532 # if defined(notdef)
533 static void
cdrom_print_toc()534 cdrom_print_toc() {
535 unsigned long trk, trk_total;
536
537 for (trk = cdi.mintrack; trk <= cdi.maxtrack; trk++) {
538 trk_total = cdi.times[trk - cdi.mintrack];
539 debug_printf(1, "%02u:%02u\n", trk_total/60, trk_total%60);
540 }
541 }
542 # endif /* defined(notdef) */
543
544 int
cdrom_get_curtrack()545 cdrom_get_curtrack() {
546 CDSTATUS cdrom_stat;
547
548 if (cdi.scsi_audio && cdrom_audio_opened &&
549 ((cdrom_shmem->cdrom_audio_cdi.state == CD_PLAYING) ||
550 (cdrom_shmem->cdrom_audio_cdi.state == CD_PAUSED))) {
551 if (((cdrom_shmem->cdrom_audio_msf.minute * 60) +
552 cdrom_shmem->cdrom_audio_msf.second) >
553 ((cdi.addrs[cdrom_shmem->cdrom_audio_cdi.curtrack].minute * 60) +
554 cdi.addrs[cdrom_shmem->cdrom_audio_cdi.curtrack].second)) {
555 cdrom_shmem->cdrom_audio_cdi.curtrack++;
556 }
557 if (((cdrom_shmem->cdrom_audio_msf.minute * 60) +
558 cdrom_shmem->cdrom_audio_msf.second) <
559 ((cdi.addrs[cdrom_shmem->cdrom_audio_cdi.curtrack-1].minute * 60) +
560 cdi.addrs[cdrom_shmem->cdrom_audio_cdi.curtrack-1].second)) {
561 cdrom_shmem->cdrom_audio_cdi.curtrack--;
562 }
563 return(cdrom_shmem->cdrom_audio_cdi.curtrack);
564 }
565 if (! CDgetstatus(cdrom_fd, (CDSTATUS *) &cdrom_stat)) {
566 fprintf(stderr, "CDgetstatus(cdrom_stat): ");
567 perror("CDgetstatus");
568 return(-1);
569 }
570
571 switch (cdrom_stat.state) {
572 case CD_ERROR:
573 return(-1);
574
575 case CD_NODISC:
576 debug_printf(1, "cdrom_get_curtrack: no disc\n");
577 return(0);
578
579 /* playing track cdrom_stat.track */
580 case CD_PLAYING:
581 return((int) cdrom_stat.track);
582
583 /* paused on track cdrom_stat.track */
584 case CD_PAUSED:
585 return((int) cdrom_stat.track);
586
587 /* punt */
588 case CD_READY:
589 return(0);
590
591 /* punt */
592 case CD_STILL:
593 return(0);
594
595 #if 0
596 case CD_NOSTATUS:
597 debug_printf(1, "cdrom_get_curtrack: no status\n");
598 return(0);
599 #endif
600 }
601
602 /* bad value in cdrom_stat */
603 return(-1);
604 }
605
606 int
cdrom_get_msf(track,msf,length)607 cdrom_get_msf(track, msf, length)
608 unsigned long track;
609 struct msf *msf;
610 unsigned long *length;
611 {
612 struct cdrom_tocentry tocentry;
613
614 if (cdrom_read_tocentry(track, &tocentry) == -1)
615 return(-1);
616
617 msf->minute = tocentry.cdte_addr.msf.minute;
618 msf->second = tocentry.cdte_addr.msf.second;
619 msf->frame = tocentry.cdte_addr.msf.frame;
620
621 *length = ((int) tocentry.cdte_addr.msf.minute * 60) +
622 (int) tocentry.cdte_addr.msf.second;
623
624 return(0);
625 }
626
627 int
cdrom_get_curmsf(msf)628 cdrom_get_curmsf(msf)
629 struct msf *msf;
630 {
631 int num_frames;
632 CDSTATUS cdrom_stat;
633
634 if (cdi.scsi_audio && cdrom_audio_opened) {
635 msf->minute = cdrom_shmem->cdrom_audio_msf.minute;
636 msf->second = cdrom_shmem->cdrom_audio_msf.second;
637 msf->frame = cdrom_shmem->cdrom_audio_msf.frame;
638 if (msf->minute < 0) {
639 msf->minute = 0;
640 msf->second = 0;
641 msf->frame = 0;
642 }
643 return(0);
644 }
645 if (! CDgetstatus(cdrom_fd, (CDSTATUS *) &cdrom_stat)) {
646 fprintf(stderr, "CDgetstatus(cdrom_stat): ");
647 perror("CDgetstatus");
648 return(-1);
649 }
650 msf->minute = cdrom_stat.abs_min;
651 msf->second = cdrom_stat.abs_sec;
652 msf->frame = cdrom_stat.abs_frame;
653
654 return (0);
655 }
656
657 int
cdrom_play_track(start_track,end_track)658 cdrom_play_track(start_track, end_track)
659 unsigned char start_track;
660 unsigned char end_track;
661 {
662 int track;
663 struct msf msf;
664
665 track = start_track;
666
667 if ( cdi.scsi_audio && cdrom_audio_opened ) {
668 cdrom_shmem->cdrom_audio_cdi.start_track = start_track;
669 cdrom_shmem->cdrom_audio_cdi.end_track = end_track;
670
671 cdrom_shmem->cdrom_audio_cdi.state = CD_ABORT;
672 if (CDseektrack(cdrom_fd, track) < 0) {
673 perror("CDseektrack");
674 return(-1);
675 }
676 msf = cdi.addrs[track - cdi.mintrack];
677 cdrom_shmem->cdrom_audio_msf.minute = msf.minute;
678 cdrom_shmem->cdrom_audio_msf.second = msf.second;
679 cdrom_shmem->cdrom_audio_msf.frame = msf.frame;
680 cdi.curtrack = track;
681 cdrom_shmem->cdrom_audio_cdi.curtrack = track;
682 cdrom_shmem->cdrom_audio_cdi.state = CD_PLAYING;
683 if (cdrom_shmem->cdrom_audio_cdi.child_pid != 0) {
684 return(0);
685 }
686 signal(SIGCLD, cdrom_child_died);
687 if ((cdrom_shmem->cdrom_audio_cdi.child_pid = fork()) == 0) {
688 cdrom_child_setup();
689 while (1) {
690 cdrom_play_frames(ONE_SECOND);
691 }
692 }
693 } else {
694 if (! CDplaytrack(cdrom_fd, track, 1)) {
695 perror("CDplaytrack");
696 return(-1);
697 }
698 }
699
700 return(0);
701 }
702
703 int
cdrom_play_msf(start_msf,end_msf)704 cdrom_play_msf(start_msf, end_msf)
705 struct msf *start_msf;
706 struct msf *end_msf;
707 {
708 int num_frames;
709 int i;
710
711 /* Fix negative seconds */
712 if (start_msf->second < 0) {
713 start_msf->second += 60;
714 start_msf->minute--;
715 }
716
717 if ( cdi.scsi_audio && cdrom_audio_opened ) {
718 cdrom_shmem->cdrom_audio_msf.minute = start_msf->minute;
719 cdrom_shmem->cdrom_audio_msf.second = start_msf->second;
720 cdrom_shmem->cdrom_audio_msf.frame = start_msf->frame;
721 if (CDseek(cdrom_fd, start_msf->minute,
722 start_msf->second,
723 start_msf->frame) < 0) {
724 perror("CDseek");
725 return(-1);
726 }
727 cdrom_shmem->cdrom_audio_cdi.state = CD_PLAYING;
728 cdrom_shmem->cdrom_audio_cdi.curtrack = cdi.curtrack;
729 if (cdrom_shmem->cdrom_audio_cdi.child_pid != 0) {
730 return(0);
731 }
732 signal(SIGCLD, cdrom_child_died);
733 if ((cdrom_shmem->cdrom_audio_cdi.child_pid = fork()) == 0) {
734 cdrom_child_setup();
735 while (1) {
736 cdrom_play_frames(ONE_SECOND);
737 }
738 }
739
740 } else {
741 if (! CDplayabs(cdrom_fd, start_msf->minute,
742 start_msf->second,
743 start_msf->frame, 1)) {
744 perror("CDplayabs");
745 return(-1);
746 }
747
748 return(0);
749 }
750 }
751
752 int
cdrom_read_tocentry(track,tocentry)753 cdrom_read_tocentry(track, tocentry)
754 unsigned int track;
755 struct cdrom_tocentry *tocentry;
756 {
757 CDSTATUS cdrom_stat;
758 CDTRACKINFO cdrom_track;
759
760 tocentry->cdte_track = track;
761 tocentry->cdte_format = CDROM_MSF;
762
763 if (cdrom_status() == CD_NODISC) {
764 tocentry->cdte_addr.msf.minute = 0;
765 tocentry->cdte_addr.msf.second = 0;
766 tocentry->cdte_addr.msf.frame = 0;
767 return(0);
768 }
769
770 if (track == CDROM_LEADOUT) {
771 if (! CDgetstatus(cdrom_fd, (CDSTATUS *) &cdrom_stat)) {
772 fprintf(stderr, "CDgetstatus(cdrom_read_tocentry): ");
773 perror("CDgetstatus");
774 return(-1);
775 }
776 tocentry->cdte_addr.msf.minute = cdrom_stat.total_min;
777 tocentry->cdte_addr.msf.second = cdrom_stat.total_sec;
778 tocentry->cdte_addr.msf.frame = cdrom_stat.total_frame;
779 } else {
780 if (! CDgettrackinfo(cdrom_fd, track,
781 (CDTRACKINFO *) &cdrom_track)) {
782 fprintf(stderr, "CDgettrackinfo(cdrom_read_tocentry): ");
783 perror("CDgetstatus");
784 return(-1);
785 }
786 tocentry->cdte_addr.msf.minute = cdrom_track.start_min;
787 tocentry->cdte_addr.msf.second = cdrom_track.start_sec;
788 tocentry->cdte_addr.msf.frame = cdrom_track.start_frame;
789 }
790 return(0);
791 }
792
793 int
cdrom_read_tochdr(tochdr)794 cdrom_read_tochdr(tochdr)
795 CDSTATUS *tochdr;
796 {
797 if (cdrom_status() == CD_NODISC)
798 return(-1);
799
800 if (! CDgetstatus(cdrom_fd, tochdr)) {
801 fprintf(stderr, "CDgetstatus(cdrom_read_tochdr): ");
802 perror("CDgetstatus");
803 return(-1);
804 }
805
806 return(0);
807 }
808
809 int
cdrom_status()810 cdrom_status() {
811 CDSTATUS cdrom_stat;
812
813 if (cdrom_fd == NULL) {
814 return(-1);
815 }
816
817 if (cdi.scsi_audio && cdrom_audio_opened &&
818 (cdrom_shmem->cdrom_audio_cdi.child_pid != 0)) {
819 return(cdrom_shmem->cdrom_audio_cdi.state);
820 }
821 if (! CDgetstatus(cdrom_fd, (CDSTATUS *) &cdrom_stat)) {
822 fprintf(stderr, "CDgetstatus(cdrom_stat): ");
823 perror("CDgetstatus");
824 return(-1);
825 }
826
827 switch (cdrom_stat.state) {
828 case CD_ERROR:
829 return(CD_ERROR);
830 case CD_NODISC:
831 return(CD_NODISC);
832 case CD_READY:
833 return(CD_READY);
834 case CD_PLAYING:
835 return(CD_PLAYING);
836 case CD_PAUSED:
837 return(CD_PAUSED);
838 case CD_STILL:
839 return(CD_STILL);
840 }
841
842 return(-1);
843 }
844
845 int
cdrom_playing(track)846 cdrom_playing(track)
847 int *track;
848 {
849 CDSTATUS cdrom_stat;
850
851 if (cdi.scsi_audio && cdrom_audio_opened &&
852 ((cdrom_shmem->cdrom_audio_cdi.state == CD_PLAYING) ||
853 (cdrom_shmem->cdrom_audio_cdi.state == CD_PAUSED))) {
854 return(cdrom_shmem->cdrom_audio_cdi.state);
855 }
856
857 if (! CDgetstatus(cdrom_fd, (CDSTATUS *) &cdrom_stat)) {
858 fprintf(stderr, "CDgetstatus(cdrom_playing): ");
859 perror("CDstatus");
860 return(-1);
861 }
862
863 *track = cdrom_stat.track;
864 if (cdrom_stat.state == CD_PLAYING) {
865 return(1);
866 }
867
868 return(0);
869 }
870
871 int
cdrom_paused(track)872 cdrom_paused(track)
873 int *track;
874 {
875 CDSTATUS cdrom_stat;
876
877 if (cdi.scsi_audio && cdrom_audio_opened &&
878 ((cdrom_shmem->cdrom_audio_cdi.state == CD_PLAYING) ||
879 (cdrom_shmem->cdrom_audio_cdi.state == CD_PAUSED))) {
880 return(cdrom_shmem->cdrom_audio_cdi.state);
881 }
882
883 if (! CDgetstatus(cdrom_fd, (CDSTATUS *) &cdrom_stat)) {
884 fprintf(stderr, "CDgetstatus(cdrom_paused): ");
885 perror("CDgetstatus");
886 return(-1);
887 }
888
889 *track = cdrom_stat.track;
890 if (cdrom_status() == CD_PAUSED) {
891 return(1);
892 }
893
894 return(0);
895 }
896
897 # if defined(notused)
898 int
mounted(name)899 mounted(name)
900 char *name;
901 {
902 char buf[MAXPATHLEN], *cp;
903 struct stat st;
904 dev_t bdevno;
905 FILE *fp;
906 struct mntent *mnt;
907
908 /*
909 * Get the block device corresponding to the raw device opened,
910 * and find its device number.
911 */
912 if (stat(name, &st) != 0) {
913 (void) fprintf(stderr, "stat: ");
914 perror(name);
915 return(UNMOUNTED);
916 }
917
918 /*
919 * If this is a raw device, we have to build the block device name.
920 */
921 if ((st.st_mode & S_IFMT) == S_IFCHR) {
922 if ((cp = strchr(name, 'r')) != NULL)
923 cp++;
924
925 (void) sprintf(buf, "/dev/%s", cp);
926 if (stat(buf, &st) != 0) {
927 (void) fprintf(stderr, "stat: ");
928 perror(buf);
929 return(UNMOUNTED);
930 }
931 }
932
933 if ((st.st_mode & S_IFMT) != S_IFBLK)
934 return(UNMOUNTED);
935
936 bdevno = st.st_rdev & (dev_t)(~0x07); /* Mask out partition. */
937
938 /*
939 * Now go through the mtab, looking at all hsfs filesystems.
940 * Compare the device mounted with our bdevno.
941 */
942 if ((fp = setmntent(MOUNTED, "r")) == NULL) {
943 (void) fprintf(stderr, "couldn't open %s\n", MOUNTED);
944 return(UNMOUNTED);
945 }
946
947 while ((mnt = getmntent(fp)) != NULL) {
948 /* avoid obvious excess stat(2)'s */
949 if (strcmp(mnt->mnt_type, "hsfs") != 0)
950 continue;
951
952 if (stat(mnt->mnt_fsname, &st) != 0)
953 continue;
954
955 if (((st.st_mode & S_IFMT) == S_IFBLK) &&
956 ((st.st_rdev & (dev_t)(~0x07)) == bdevno)) {
957 (void) endmntent(fp);
958 return(STILL_MOUNTED);
959 }
960 }
961
962 (void) endmntent(fp);
963
964 return(UNMOUNTED);
965 }
966 # endif /* defined(notused) */
967
968 int
cdrom_play_frames(number)969 cdrom_play_frames(number)
970 int number;
971 {
972 int frames_to_read = number;
973 int num_frames;
974 int frame_ctr;
975 struct msf msf;
976 CDSTATUS cdrom_stat;
977
978 if (cdrom_audio_opened &&
979 cdrom_shmem->cdrom_audio_cdi.state != CD_PLAYING) {
980 sleep(1);
981 return(-1);
982 }
983
984 if (frames_to_read > INIT_READ) {
985 frames_to_read = INIT_READ;
986 }
987 if ((num_frames =
988 CDreadda(cdrom_fd, &cd_audio_buff[0], frames_to_read)) == -1) {
989 perror("CDreadda");
990 return(-1);
991 }
992 if (num_frames == 0) {
993 msf = cdi.addrs[cdi.maxtrack];
994 if ((cdrom_shmem->cdrom_audio_msf.minute >= (msf.minute-1)) &&
995 (cdrom_shmem->cdrom_audio_msf.second >= (msf.second-1)) ) {
996 cdrom_shmem->cdrom_audio_cdi.curtrack = 0;
997 cdrom_shmem->cdrom_audio_cdi.state = CD_READY;
998 }
999 return(0);
1000 }
1001 for (frame_ctr=0;
1002 frame_ctr<num_frames &&
1003 cdrom_shmem->cdrom_audio_cdi.state == CD_PLAYING;
1004 frame_ctr++) {
1005 CDparseframe(cd_parser, &cd_audio_buff[frame_ctr]);
1006 }
1007 if (cdrom_shmem->cdrom_audio_cdi.state == CD_ABORT) {
1008 cdrom_shmem->cdrom_audio_cdi.state = CD_PLAYING;
1009 }
1010 return(num_frames);
1011 }
1012
1013 int
cdrom_child_setup()1014 cdrom_child_setup() {
1015 cdrom_shmem = shmat(shmid, NULL, SHM_RND);
1016 cdrom_shmem->cdrom_audio_cdi.state = CD_PLAYING;
1017 signal(SIGHUP,cdrom_child_quit);
1018 }
1019
1020 void
cdrom_child_died()1021 cdrom_child_died() {
1022 cdrom_stop();
1023 wait(NULL);
1024 cdrom_shmem->cdrom_audio_cdi.child_pid = 0;
1025 cdrom_shmem->cdrom_audio_cdi.state = CD_READY;
1026 cdrom_shmem->cdrom_audio_cdi.curtrack = 0;
1027 cdi.curtrack = 0;
1028 cdrom_shmem->cdrom_audio_msf.minute = 0;
1029 cdrom_shmem->cdrom_audio_msf.second = 0;
1030 cdrom_shmem->cdrom_audio_msf.frame = 0;
1031 signal(SIGCLD,cdrom_child_died);
1032 }
1033
1034 void
cdrom_child_quit()1035 cdrom_child_quit() {
1036 shmdt(cdrom_shmem);
1037 exit(1);
1038 }
1039
1040 void
cdrom_kill_child()1041 cdrom_kill_child()
1042 {
1043 if (!(cdrom_audio_opened && cdrom_shmem->cdrom_audio_cdi.child_pid)) {
1044 return;
1045 }
1046 kill(cdrom_shmem->cdrom_audio_cdi.child_pid, SIGHUP);
1047 wait(NULL);
1048 cdrom_shmem->cdrom_audio_cdi.state = CD_READY;
1049 cdrom_shmem->cdrom_audio_cdi.child_pid = 0;
1050 }
1051
1052 int
cdrom_audio_avail()1053 cdrom_audio_avail() {
1054 CDSTATUS cdrom_stat;
1055
1056 if (cdrom_audio_opened && (! audio_button_state())) {
1057 return(0);
1058 }
1059 cdrom_audio_opened = 1;
1060
1061 if (! CDgetstatus(cdrom_fd, (CDSTATUS *) &cdrom_stat)) {
1062 fprintf(stderr, "CDgetstatus(cdrom_stat): ");
1063 perror("CDgetstatus");
1064 return(-1);
1065 }
1066
1067 if ( cdrom_stat.scsi_audio && (cdrom_audio_open() >= 0) ) {
1068 return(1);
1069 } else {
1070 return(0);
1071 }
1072 }
1073
1074 unsigned short *
ushort_malloc(n)1075 ushort_malloc(n)
1076 int n;
1077 {
1078 extern char *calloc();
1079 unsigned short *ptr;
1080
1081 ptr = (unsigned short *) calloc(n, sizeof(unsigned short));
1082 if (ptr == NULL) {
1083 perror("calloc");
1084 exit(1);
1085 }
1086
1087 return(ptr);
1088 }
1089
1090 struct msf *
msf_malloc(n)1091 msf_malloc(n)
1092 int n;
1093 {
1094 extern char *calloc();
1095 struct msf *ptr;
1096
1097 ptr = (struct msf *) calloc(n, sizeof(struct msf));
1098 if (ptr == NULL) {
1099 perror("calloc");
1100 exit(1);
1101 }
1102
1103 return(ptr);
1104 }
1105
1106 int
cdrom_disp_cdi()1107 cdrom_disp_cdi() {
1108 int trk;
1109
1110 fprintf(stderr,"CDI structure:\n");
1111 fprintf(stderr,"\tcurtrack: %d\n",cdi.curtrack);
1112 fprintf(stderr,"\tmin: %d max: %d total: %d\n",
1113 cdi.mintrack, cdi.maxtrack, cdi.ntracks);
1114 fprintf(stderr,"\tdur: %d state: %2x\n",cdi.duration, cdi.state);
1115 fprintf(stderr,"\tcurrand: %d lastprog: %d\n",
1116 cdi.currand, cdi.lastprog);
1117 fprintf(stderr,"\n\tTracklist:\n");
1118 if (cdi.maxtrack != cdi.mintrack) {
1119 for (trk=cdi.mintrack; trk<=cdi.maxtrack; trk++) {
1120 fprintf(stderr,"\t%3d: %d %02d:%02d %d\n",trk,cdi.times[trk],
1121 cdi.addrs[trk].minute,cdi.addrs[trk].second,
1122 cdi.addrs[trk].frame);
1123 }
1124 }
1125
1126 if (cdi.scsi_audio) {
1127 fprintf(stderr,"AUDIO_CDI structure:\n");
1128 fprintf(stderr,"\tcurtrack: %d\n",cdrom_shmem->cdrom_audio_cdi.curtrack);
1129 fprintf(stderr,"\tdur: %d state: %d\n",cdrom_shmem->cdrom_audio_cdi.duration, cdrom_shmem->cdrom_audio_cdi.state);
1130 }
1131 }
1132
1133 # endif /* defined(sgi) */
1134