/* * Re-Open the device if it is open. */ int wmcd_reopen( struct wm_drive *d ) { int status; do { wm_lib_message(WM_MSG_LEVEL_DEBUG|WM_MSG_CLASS, "wmcd_reopen\n"); status = gen_close( d ); wm_susleep( 1000 ); wm_lib_message(WM_MSG_LEVEL_DEBUG|WM_MSG_CLASS, "calling wmcd_open()\n"); status = wmcd_open( d ); /* open it as usual */ wm_susleep( 1000 ); } while ( status != 0 ); return status; } /* wmcd_reopen() */
/* * Eject the current CD, if there is one. */ int gen_eject(struct wm_drive *d) { int stat; stat = wm_scsi2_eject(d); wm_susleep(1000); return (stat); } /* gen_eject() */
int gen_close( struct wm_drive *d ) { int ret = 0; if(d->fd != -1) { wm_lib_message(WM_MSG_LEVEL_DEBUG|WM_MSG_CLASS, "closing the device.\n"); ret = CD_Close(d->fd); d->fd = -1; wm_susleep(3000000); } return ret; }
static void *cdda_fct_read(void* arg) { struct wm_drive *d = (struct wm_drive *)arg; int i, j, wakeup; long result; while (d->blocks) { while(d->command != WM_CDM_PLAYING) { d->status = d->command; wm_susleep(1000); } i = 0; (void) pthread_mutex_lock(&blks_mutex[i]); wakeup = 1; while(d->command == WM_CDM_PLAYING) { result = gen_cdda_read(d, &blks[i]); if (result <= 0 && blks[i].status != WM_CDM_TRACK_DONE) { ERRORLOG("cdda: wmcdda_read failed, stop playing\n"); d->command = WM_CDM_STOPPED; break; } else { if (output) fwrite(blks[i].buf, blks[i].buflen, 1, output); } j = get_next_block(i); (void) pthread_mutex_lock(&blks_mutex[j]); if(wakeup) { wakeup = 0; pthread_cond_signal(&wakeup_audio); } (void) pthread_mutex_unlock(&blks_mutex[i]); /* audio can start here */ i = j; } (void) pthread_mutex_unlock(&blks_mutex[i]); } return 0; }
int wm_cdda_destroy(struct wm_drive *d) { if (d->cddax) { wm_scsi_set_speed(d, -1); d->command = WM_CDM_STOPPED; oops->wmaudio_stop(); wm_susleep(2000); gen_cdda_close(d); oops->wmaudio_close(); d->numblocks = 0; d->blocks = NULL; wait(NULL); d->cddax = NULL; } return 0; }
static int cdda_play(struct wm_drive *d, int start, int end) { if (d->cddax) { d->command = WM_CDM_STOPPED; oops->wmaudio_stop(); /* wait before reader, stops */ while(d->status != d->command) wm_susleep(1000); d->current_position = start; d->ending_position = end; d->track = -1; d->index = 0; d->frame = start; d->status = d->command = WM_CDM_PLAYING; return 0; } return -1; }
/* * Try to initialize the CDDA slave. Returns 0 on success. */ int wm_cdda_init(struct wm_drive *d) { int ret = 0; if (d->cddax) { wm_cdda_destroy(d); wm_susleep(1000); d->blocks = 0; wm_susleep(1000); } memset(blks, 0, sizeof(blks)); d->blocks = blks; d->frames_at_once = COUNT_CDDA_FRAMES_PER_BLOCK; d->numblocks = COUNT_CDDA_BLOCKS; d->status = WM_CDM_UNKNOWN; if ((ret = gen_cdda_init(d))) return ret; if ((ret = gen_cdda_open(d))) return ret; wm_scsi_set_speed(d, 4); oops = setup_soundsystem(d->soundsystem, d->sounddevice, d->ctldevice); if (!oops) { ERRORLOG("cdda: setup_soundsystem failed\n"); gen_cdda_close(d); return -1; } if(pthread_create(&thread_read, NULL, cdda_fct_read, d)) { ERRORLOG("error by create pthread"); oops->wmaudio_close(); gen_cdda_close(d); return -1; } if(pthread_create(&thread_play, NULL, cdda_fct_play, d)) { ERRORLOG("error by create pthread"); oops->wmaudio_close(); gen_cdda_close(d); return -1; } d->proto.get_drive_status = cdda_status; d->proto.pause = cdda_pause; d->proto.resume = NULL; d->proto.stop = cdda_stop; d->proto.play = cdda_play; d->proto.set_volume = cdda_set_volume; d->proto.get_volume = cdda_get_volume; d->proto.scale_volume = NULL; d->proto.unscale_volume = NULL; d->cddax = (void *)1; return 0; }