static int control(stream_t *stream, int cmd, void *arg) { cdda_priv *p = stream->priv; switch (cmd) { case STREAM_CTRL_GET_NUM_TITLES: { *(unsigned int *)arg = p->cd->tracks; return STREAM_OK; } case STREAM_CTRL_GET_NUM_CHAPTERS: { int start_track = get_track_by_sector(p, p->start_sector); int end_track = get_track_by_sector(p, p->end_sector); if (start_track == -1 || end_track == -1) return STREAM_ERROR; *(unsigned int *)arg = end_track + 1 - start_track; return STREAM_OK; } case STREAM_CTRL_GET_CHAPTER_TIME: { int track = *(double *)arg; int start_track = get_track_by_sector(p, p->start_sector); int end_track = get_track_by_sector(p, p->end_sector); track += start_track + 1; if (track > end_track) return STREAM_ERROR; int64_t sector = p->cd->disc_toc[track].dwStartSector; int64_t pos = sector * (CDIO_CD_FRAMESIZE_RAW + 1) - 1; // Assume standard audio CD: 44.1khz, 2 channels, s16 samples *(double *)arg = pos / (44100.0 * 2 * 2); return STREAM_OK; } } return STREAM_UNSUPPORTED; }
static int control(stream_t *stream, int cmd, void *arg) { cdda_priv* p = stream->priv; switch(cmd) { case STREAM_CTRL_GET_NUM_CHAPTERS: { int start_track = get_track_by_sector(p, p->start_sector); int end_track = get_track_by_sector(p, p->end_sector); *(unsigned int *)arg = end_track + 1 - start_track; return STREAM_OK; } case STREAM_CTRL_SEEK_TO_CHAPTER: { int r; unsigned int track = *(unsigned int *)arg; int start_track = get_track_by_sector(p, p->start_sector); int seek_sector; track += start_track; if (track >= p->cd->tracks) { stream->eof = 1; return STREAM_ERROR; } seek_sector = track <= 0 ? p->start_sector : p->cd->disc_toc[track].dwStartSector; r = seek(stream, seek_sector * CD_FRAMESIZE_RAW); if (r) return STREAM_OK; break; } case STREAM_CTRL_GET_CURRENT_CHAPTER: { int start_track = get_track_by_sector(p, p->start_sector); int cur_track = get_track_by_sector(p, p->sector); *(unsigned int *)arg = cur_track - start_track; return STREAM_OK; } } return STREAM_UNSUPPORTED; }