/* Set all audio channels to level. level is assumed to be in the range 0..100. */ static bool set_volume_level(CdIo_t *p_cdio, uint8_t i_level) { const unsigned int i_new_level= rounded_div(i_level*256, 100); unsigned int i; driver_return_code_t rc; for (i=0; i<=3; i++) { audio_volume.level[i] = i_new_level; } rc = cdio_audio_set_volume(p_cdio, &audio_volume); if ( DRIVER_OP_SUCCESS != rc ) { /* If we can't do a get volume, audio_volume.level is used as a second-best guess. But if this set failed restore it to an invalid value so we don't get confused and think that this was set. */ for (i=0; i<=3; i++) { audio_volume.level[i] = 0; } } else { /* Set i_vol_port so volume levels set above will get used. */ i_vol_port=0; } return rc; }
int main(int argc, char *argv[]) { int c; char *h; int i_rc = 0; int i_volume_level = -1; cd_operation_t todo = NO_OP; /* operation to do in non-interactive mode */ psz_program = strrchr(argv[0],'/'); psz_program = psz_program ? psz_program+1 : argv[0]; /* parse options */ while ( 1 ) { if (-1 == (c = getopt(argc, argv, "aCdehkpL:sSt:vx"))) break; switch (c) { case 'v': b_verbose = true; break; case 'd': debug = 1; break; case 'a': auto_mode = 1; break; case 'L': if (NULL != strchr(optarg,'-')) { i_volume_level = atoi(optarg); todo = SET_VOLUME; } break; case 't': if (NULL != (h = strchr(optarg,'-'))) { *h = 0; start_track = atoi(optarg); stop_track = atoi(h+1)+1; if (0 == start_track) start_track = 1; if (1 == stop_track) stop_track = CDIO_CDROM_LEADOUT_TRACK; } else { start_track = atoi(optarg); stop_track = start_track+1; one_track = 1; } todo = PLAY_TRACK; break; case 'p': todo = PLAY_CD; break; case 'C': todo = CLOSE_CD; break; break; case 's': todo = STOP_PLAYING; break; case 'S': todo = LIST_SUBCHANNEL; break; case 'e': todo = EJECT_CD; break; case 'h': usage(psz_program); exit(1); default: usage(psz_program); exit(1); } } if (argc > optind) { psz_device = strdup(argv[optind]); } else { char **ppsz_cdda_drives=NULL; char **ppsz_all_cd_drives = cdio_get_devices_ret(&driver_id); if (!ppsz_all_cd_drives) { fprintf(stderr, "Can't find a CD-ROM drive\n"); exit(2); } ppsz_cdda_drives = cdio_get_devices_with_cap(ppsz_all_cd_drives, CDIO_FS_AUDIO, false); if (!ppsz_cdda_drives || !ppsz_cdda_drives[0]) { fprintf(stderr, "Can't find a CD-ROM drive with a CD-DA in it\n"); exit(3); } psz_device = strdup(ppsz_cdda_drives[0]); cdio_free_device_list(ppsz_all_cd_drives); cdio_free_device_list(ppsz_cdda_drives); } if (!b_cd && todo != EJECT_CD) { cd_close(psz_device); } /* open device */ if (b_verbose) fprintf(stderr,"open %s... ", psz_device); p_cdio = cdio_open (psz_device, driver_id); if (!p_cdio) { if (b_verbose) fprintf(stderr, "error: %s\n", strerror(errno)); else fprintf(stderr, "open %s: %s\n", psz_device, strerror(errno)); exit(1); } else if (b_verbose) fprintf(stderr,"ok\n"); if (EJECT_CD == todo) { i_rc = cd_eject() ? 0 : 1; } else { read_toc(p_cdio); if (!b_cd) { cd_close(psz_device); read_toc(p_cdio); } if (b_cd) switch (todo) { case NO_OP: break; case STOP_PLAYING: i_rc = cd_stop(p_cdio) ? 0 : 1; break; case EJECT_CD: /* Should have been handled above before case statement. gcc warns if we don't include this. And with this Coverty complains when we do - we can't win, so go with gcc. */ cd_eject(); break; case PLAY_TRACK: /* play just this one track */ play_track(start_track, stop_track); break; case PLAY_CD: play_track(1,CDIO_CDROM_LEADOUT_TRACK); break; case CLOSE_CD: i_rc = cdio_close_tray(psz_device, NULL) ? 0 : 1; break; case SET_VOLUME: { cdio_audio_volume_t volume; volume.level[0] = i_volume_level; i_rc = (DRIVER_OP_SUCCESS == cdio_audio_set_volume(p_cdio, &volume)) ? 0 : 1; break; } case LIST_SUBCHANNEL: if (read_subchannel(p_cdio)) { if (sub.audio_status == CDIO_MMC_READ_SUB_ST_PAUSED || sub.audio_status == CDIO_MMC_READ_SUB_ST_PLAY) { { printf("track %2d - %02x:%02x (%02x:%02x abs) ", sub.track, sub.rel_addr.m, sub.rel_addr.s, sub.abs_addr.m, sub.abs_addr.s); } } printf("drive state: %s\n", mmc_audio_state2str(sub.audio_status)); } else { i_rc = 1; } break; } else { fprintf(stderr,"no CD in drive (%s)\n", psz_device); } } oops("bye", i_rc); return 0; /* keep compiler happy */ }