#include #include #include #include #include #include #define FRAMES 1 #define SIZE CD_FRAMESIZE_RAW #define PERIOD 1024 #define COUNT 2 struct cdrom_read_audio sr; void forward(int signum) { sr.addr.lba += 3600; } void backward(int signum) { sr.addr.lba -= 3600; } void weite_err(char *s) { char *p; p = s; while (*p) ++p; write(STDERR_FILENO, s, p - s); } int main(int argc, char *argv[]) { int fdi, card = 0, device = 0; struct pcm *pcm; struct pcm_config config; char *msg, buff[SIZE * FRAMES]; struct sigaction f_action, b_action; if (argc < 2) { weite_err("Usage: "); weite_err(argv[0]); weite_err("cdrom [card=0] [device=0]\n"); goto err0; } if ((fdi = open(argv[1], O_RDONLY | O_NONBLOCK)) < 0) { weite_err("couldn't open input device "); weite_err(argv[1]); weite_err(" \n"); goto err0; } switch (ioctl(fdi, CDROM_DRIVE_STATUS, 0)) { case CDS_NO_DISC: weite_err("No disk\n"); goto err1; case CDS_DRIVE_NOT_READY: weite_err("Drive not ready\n"); goto err1; case CDS_TRAY_OPEN: weite_err("Tray open\n"); goto err1; case -1: weite_err("Error\n"); goto err1; } switch (argc) { case 4: device = *argv[3] - '0'; case 3: card = *argv[2] - '0'; } /* Prepare signals */ { f_action.sa_handler = forward; b_action.sa_handler = backward; sigaddset(&f_action.sa_mask, SIGUSR1); sigaddset(&b_action.sa_mask, SIGUSR2); sigaction(SIGUSR1, &f_action, NULL); sigaction(SIGUSR2, &b_action, NULL); } /* config pcm */ { config.channels = 2; config.rate = 44100; config.format = PCM_FORMAT_S16_LE; config.period_size = PERIOD; config.period_count = COUNT; config.start_threshold = PERIOD; config.silence_threshold = PERIOD * COUNT; config.stop_threshold = PERIOD * COUNT; } /* config sr */ { sr.buf = buff; sr.nframes = FRAMES; sr.addr_format = CDROM_LBA; } pcm = pcm_open(card, device, PCM_OUT, &config); sr.addr.lba = 0; while (ioctl(fdi, CDROMREADAUDIO, &sr) != -1) { pcm_writei(pcm, buff, SIZE * FRAMES / 4); sr.addr.lba += FRAMES; } pcm_close(pcm); close(fdi); return 0; err1: close(fdi); err0: return 1; }