/* pr.c -- Play music from Raw audio sectors. * * This program plays an audio CD on a SparcStation with a Toshiba XM3401 * CDROM drive. I'm using SunOS 4.1.3. * You FIRST should have set the 3401 in raw CD-DA mode (e.g. via set_raw)! * Warning: It's a dirty (test)program. * * Usage: pr [ []] * * Author: Adrie Koolen (adrie@ica.philips.nl) */ #include #include #include #include #include #include "/usr/demo/SOUND/multimedia/ulaw2linear.h" #define AUDIO_DEV "/dev/audio" /* Define the cluster length. Don't make it too large, or SunOS will fail! */ #define NR_SECS 250 u_char scsibuf[] = { 0x28, /* READ */ 0x08, /* LUN */ 0x00, 0x00, 0x00, 0x00, 0x00, NR_SECS / 256, /* nr of blocks */ NR_SECS % 256, /* nr of blocks */ 0x00 }; u_char databuf[2352 * NR_SECS]; u_char bigbuf[NR_SECS * 107]; struct uscsi_cmd usc; char *program; int afd; /* Audio device file descriptor. */ main(argc, argv) int argc; char *argv[]; { int fd; int len; int i, p; int bnr; int w; int e; int cnt; program = argv[0]; bnr = (argc > 1) ? atoi(argv[1]) : 0; cnt = (argc > 2) ? atoi(argv[2]) / NR_SECS : 5000; if ((fd = open("/dev/rsr0", 0)) < 0) pfatal("open"); afd = open(AUDIO_DEV, O_RDWR); if (afd < 0) { fprintf(stderr, "%s: can't open /dev/audio.\n", program); exit(1); } back: usc.uscsi_cdb = (caddr_t) scsibuf; usc.uscsi_cdblen = sizeof(scsibuf); usc.uscsi_bufaddr = (caddr_t) databuf; usc.uscsi_buflen = sizeof(databuf); usc.uscsi_status = 0; usc.uscsi_flags = (USCSI_DIAGNOSE | USCSI_ISOLATE | USCSI_READ); scsibuf[3] = (bnr >> 16) & 0xFF; scsibuf[4] = (bnr >> 8) & 0xFF; scsibuf[5] = bnr & 0xFF; /* printf("bnr = %d.\n", bnr); */ if (ioctl(fd, USCSICMD, usc) < 0) pfatal("ioctl"); /* Convert the samples. Use only the left channel. */ p = e = 0; for (i = 0; i < sizeof databuf; ) { bigbuf[p++] = audio_s2u((short)(databuf[i] + 256 * databuf[i+1])); e += 44100; i += (e / 8000) * 4; e %= 8000; } w = write(afd, bigbuf, p); bnr += NR_SECS; if (cnt--) goto back; } pfatal(s) char *s; { fprintf(stderr, "%s: ", program); perror(s); fprintf(stderr, "\n"); exit(1); }