From 44479027112489b8bbe4a03eb08d49ec9d57554f Mon Sep 17 00:00:00 2001 From: kub Date: Fri, 19 Apr 2024 20:53:52 +0200 Subject: [PATCH] mcd, revisit track handling in cdd --- pico/cd/cdd.c | 372 ++++++++++++++------------------------------------ 1 file changed, 102 insertions(+), 270 deletions(-) diff --git a/pico/cd/cdd.c b/pico/cd/cdd.c index 78fae75d..9715c679 100644 --- a/pico/cd/cdd.c +++ b/pico/cd/cdd.c @@ -196,67 +196,52 @@ static void cdd_change_track(int index, int lba) cdda_start_play(base, lba_offset, lb_len); } -int cdd_context_save(uint8 *state) -{ - int bufferptr = 0; - - save_param(&cdd.cycles, sizeof(cdd.cycles)); - save_param(&cdd.latency, sizeof(cdd.latency)); - save_param(&cdd.index, sizeof(cdd.index)); - save_param(&cdd.lba, sizeof(cdd.lba)); - save_param(&cdd.scanOffset, sizeof(cdd.scanOffset)); - save_param(&cdd.volume, sizeof(cdd.volume)); - save_param(&cdd.status, sizeof(cdd.status)); - - return bufferptr; -} +static off_t read_pos = -1; -int cdd_context_load(uint8 *state) +void cdd_seek(int index, int lba) { - int lba; - int bufferptr = 0; + int aindex = (index < 0 ? -index : index); #ifdef USE_LIBTREMOR #ifdef DISABLE_MANY_OGG_OPEN_FILES - /* close previous track VORBIS file structure to save memory */ - if (cdd.toc.tracks[cdd.index].vf.datasource) + /* check if track index has changed */ + if (index != cdd.index) { - ogg_free(cdd.index); + /* close previous track VORBIS file structure to save memory */ + if (cdd.index >= 0 && cdd.toc.tracks[cdd.index].vf.datasource) + { + ogg_free(cdd.index); + } + + /* open current track VORBIS file */ + if (cdd.toc.tracks[aindex].vf.seekable) + { + ov_open(cdd.toc.tracks[aindex].fd,&cdd.toc.tracks[aindex].vf,0,0); + } } #endif #endif - load_param(&cdd.cycles, sizeof(cdd.cycles)); - load_param(&cdd.latency, sizeof(cdd.latency)); - load_param(&cdd.index, sizeof(cdd.index)); - load_param(&cdd.lba, sizeof(cdd.lba)); - load_param(&cdd.scanOffset, sizeof(cdd.scanOffset)); - load_param(&cdd.volume, sizeof(cdd.volume)); - load_param(&cdd.status, sizeof(cdd.status)); + /* update current track index and LBA */ + cdd.index = aindex; + cdd.lba = lba; - /* adjust current LBA within track limit */ - lba = cdd.lba; + /* stay within track limits when seeking files */ if (lba < cdd.toc.tracks[cdd.index].start) { lba = cdd.toc.tracks[cdd.index].start; } - /* seek to current track position */ + /* seek to current block */ if (!is_audio(cdd.index)) { /* DATA track */ - if (cdd.toc.tracks[cdd.index].fd) - { - pm_seek(cdd.toc.tracks[cdd.index].fd, lba * cdd.sectorSize, SEEK_SET); - } + read_pos = lba * cdd.sectorSize; + pm_seek(cdd.toc.tracks[cdd.index].fd, read_pos, SEEK_SET); } #ifdef USE_LIBTREMOR else if (cdd.toc.tracks[cdd.index].vf.seekable) { -#ifdef DISABLE_MANY_OGG_OPEN_FILES - /* VORBIS file need to be opened first */ - ov_open(cdd.toc.tracks[cdd.index].fd,&cdd.toc.tracks[cdd.index].vf,0,0); -#endif /* VORBIS AUDIO track */ ov_pcm_seek(&cdd.toc.tracks[cdd.index].vf, (lba - cdd.toc.tracks[cdd.index].start) * 588 - cdd.toc.tracks[cdd.index].offset); } @@ -273,6 +258,37 @@ int cdd_context_load(uint8 *state) cdd_change_track(cdd.index, lba); } #endif +} + +int cdd_context_save(uint8 *state) +{ + int bufferptr = 0; + + save_param(&cdd.cycles, sizeof(cdd.cycles)); + save_param(&cdd.latency, sizeof(cdd.latency)); + save_param(&cdd.index, sizeof(cdd.index)); + save_param(&cdd.lba, sizeof(cdd.lba)); + save_param(&cdd.scanOffset, sizeof(cdd.scanOffset)); + save_param(&cdd.volume, sizeof(cdd.volume)); + save_param(&cdd.status, sizeof(cdd.status)); + + return bufferptr; +} + +int cdd_context_load(uint8 *state) +{ + int bufferptr = 0; + + load_param(&cdd.cycles, sizeof(cdd.cycles)); + load_param(&cdd.latency, sizeof(cdd.latency)); + load_param(&cdd.index, sizeof(cdd.index)); + load_param(&cdd.lba, sizeof(cdd.lba)); + load_param(&cdd.scanOffset, sizeof(cdd.scanOffset)); + load_param(&cdd.volume, sizeof(cdd.volume)); + load_param(&cdd.status, sizeof(cdd.status)); + + /* seek to current track position */ + cdd_seek(-cdd.index, cdd.lba); return bufferptr; } @@ -280,6 +296,8 @@ int cdd_context_load(uint8 *state) int cdd_context_load_old(uint8 *state) { memcpy(&cdd.lba, state + 8, sizeof(cdd.lba)); + cdd_seek(-cdd.index, cdd.lba); + return 12 * 4; } @@ -510,17 +528,29 @@ int cdd_unload(void) void cdd_read_data(uint8 *dst) { /* only read DATA track sectors */ - if (!is_audio(cdd.index) && (cdd.lba >= 0) && (cdd.lba < cdd.toc.tracks[cdd.index].end)) + if (!is_audio(cdd.index) && (cdd.lba >= cdd.toc.tracks[cdd.index].start) && + (cdd.lba < cdd.toc.tracks[cdd.index].end)) { + off_t pos; + /* BIN format ? */ if (cdd.sectorSize == 2352) { /* skip 16-byte header */ - pm_seek(cdd.toc.tracks[cdd.index].fd, cdd.lba * 2352 + 16, SEEK_SET); + pos = cdd.lba * 2352 + 16; + } + else + { + pos = cdd.lba * cdd.sectorSize; + } + + if (pos != read_pos) { + pm_seek(cdd.toc.tracks[cdd.index].fd, pos, SEEK_SET); + read_pos = pos; } /* read sector data (Mode 1 = 2048 bytes) */ - pm_read(dst, 2048, cdd.toc.tracks[cdd.index].fd); + read_pos += pm_read(dst, 2048, cdd.toc.tracks[cdd.index].fd); } } @@ -719,7 +749,7 @@ void cdd_update(void) header[3] = 0x01; /* data track sector read is controlled by CDC */ - cdd.lba += cdc_decoder_update(header); + cdc_decoder_update(header); } else { @@ -734,51 +764,19 @@ void cdd_update(void) /* audio blocks are still sent to CDC as well as CD DAC/Fader */ cdc_decoder_update(header); - - /* next audio block is automatically read */ - cdd.lba++; } + + /* next block is automatically read */ + cdd.lba++; /* check end of current track */ if (cdd.lba >= cdd.toc.tracks[cdd.index].end) { -#ifdef USE_LIBTREMOR -#ifdef DISABLE_MANY_OGG_OPEN_FILES - /* close previous track VORBIS file structure to save memory */ - if (cdd.toc.tracks[cdd.index].vf.datasource) - { - ogg_free(cdd.index); - } -#endif -#endif - /* play next track */ - cdd.index++; - /* PAUSE between tracks */ Pico_mcd->s68k_regs[0x36+0] = 0x01; /* seek to next audio track start */ -#ifdef USE_LIBTREMOR - if (cdd.toc.tracks[cdd.index].vf.seekable) - { -#ifdef DISABLE_MANY_OGG_OPEN_FILES - /* VORBIS file need to be opened first */ - ov_open(cdd.toc.tracks[cdd.index].fd,&cdd.toc.tracks[cdd.index].vf,0,0); -#endif - ov_pcm_seek(&cdd.toc.tracks[cdd.index].vf, -cdd.toc.tracks[cdd.index].offset); - } - else -#endif -#if 0 - if (cdd.toc.tracks[cdd.index].fd) - { - fseek(cdd.toc.tracks[cdd.index].fd, (cdd.toc.tracks[cdd.index].start * 2352) - cdd.toc.tracks[cdd.index].offset, SEEK_SET); - } -#else - { - cdd_change_track(cdd.index, cdd.lba); - } -#endif + cdd_seek(cdd.index + 1, cdd.lba); } } @@ -791,100 +789,45 @@ void cdd_update(void) /* check current track limits */ if (cdd.lba >= cdd.toc.tracks[cdd.index].end) { -#ifdef USE_LIBTREMOR -#ifdef DISABLE_MANY_OGG_OPEN_FILES - /* close previous track VORBIS file structure to save memory */ - if (cdd.toc.tracks[cdd.index].vf.datasource) - { - ogg_free(cdd.index); - } -#endif -#endif /* next track */ - cdd.index++; + if (cdd.index >= cdd.toc.last) + { + /* no AUDIO track playing */ + Pico_mcd->s68k_regs[0x36+0] = 0x01; - /* skip directly to track start position */ - cdd.lba = cdd.toc.tracks[cdd.index].start; - - /* AUDIO track playing ? */ - if (cdd.status == CD_PLAY) + /* end of disc */ + cdd.lba = cdd.toc.end; + cdd.status = CD_END; + } + else { - Pico_mcd->s68k_regs[0x36+0] = 0x00; + cdd_seek(cdd.index + 1, cdd.toc.tracks[cdd.index+1].start); + + /* AUDIO track playing ? */ + if (cdd.status == CD_PLAY && is_audio(cdd.index)) + { + Pico_mcd->s68k_regs[0x36+0] = 0x00; + } } } else if (cdd.lba < cdd.toc.tracks[cdd.index].start) { -#ifdef USE_LIBTREMOR -#ifdef DISABLE_MANY_OGG_OPEN_FILES - /* close previous track VORBIS file structure to save memory */ - if (cdd.toc.tracks[cdd.index].vf.datasource) + /* previous track */ + if (cdd.index <= 0) { - ogg_free(cdd.index); + cdd_seek(0, 0); + } + else + { + cdd_seek(cdd.index - 1, cdd.toc.tracks[cdd.index-1].end); } -#endif -#endif - - /* previous track */ - cdd.index--; - - /* skip directly to track end position */ - cdd.lba = cdd.toc.tracks[cdd.index].end; - } - - /* check disc limits */ - if (cdd.index < 0) - { - cdd.index = 0; - cdd.lba = 0; - } - else if (cdd.index >= cdd.toc.last) - { - /* no AUDIO track playing */ - Pico_mcd->s68k_regs[0x36+0] = 0x01; - - /* end of disc */ - cdd.index = cdd.toc.last; - cdd.lba = cdd.toc.end; - cdd.status = CD_END; - return; } - /* seek to current block */ if (!is_audio(cdd.index)) { /* no AUDIO track playing */ Pico_mcd->s68k_regs[0x36+0] = 0x01; - - /* DATA track */ - pm_seek(cdd.toc.tracks[cdd.index].fd, cdd.lba * cdd.sectorSize, SEEK_SET); } -#ifdef USE_LIBTREMOR - else if (cdd.toc.tracks[cdd.index].vf.seekable) - { -#ifdef DISABLE_MANY_OGG_OPEN_FILES - /* check if a new track is being played */ - if (!cdd.toc.tracks[cdd.index].vf.datasource) - { - /* VORBIS file need to be opened first */ - ov_open(cdd.toc.tracks[cdd.index].fd,&cdd.toc.tracks[cdd.index].vf,0,0); - } -#endif - /* VORBIS AUDIO track */ - ov_pcm_seek(&cdd.toc.tracks[cdd.index].vf, (cdd.lba - cdd.toc.tracks[cdd.index].start) * 588 - cdd.toc.tracks[cdd.index].offset); - } -#endif -#if 0 - else if (cdd.toc.tracks[cdd.index].fd) - { - /* PCM AUDIO track */ - fseek(cdd.toc.tracks[cdd.index].fd, (cdd.lba * 2352) - cdd.toc.tracks[cdd.index].offset, SEEK_SET); - } -#else - else - { - cdd_change_track(cdd.index, cdd.lba); - } -#endif } } @@ -910,7 +853,7 @@ void cdd_process(void) Pico_mcd->s68k_regs[0x38+1] == 0x00 || Pico_mcd->s68k_regs[0x38+1] == 0x01) { - int lba = cdd.lba + 150; + int lba = cdd.lba + 150 - cdd.latency; if (Pico_mcd->s68k_regs[0x38+1] == 0x01) lba = abs(cdd.lba - cdd.toc.tracks[cdd.index].start); if (Pico_mcd->s68k_regs[0x38+1] == 0x0f) @@ -1081,66 +1024,10 @@ void cdd_process(void) cdd.latency += (((cdd.lba - lba) * 120) / 270000); } - /* update current LBA */ - cdd.lba = lba; - /* get track index */ while ((cdd.toc.tracks[index].end <= lba) && (index < cdd.toc.last)) index++; -#ifdef USE_LIBTREMOR -#ifdef DISABLE_MANY_OGG_OPEN_FILES - /* check if track index has changed */ - if (index != cdd.index) - { - /* close previous track VORBIS file structure to save memory */ - if (cdd.toc.tracks[cdd.index].vf.datasource) - { - ogg_free(cdd.index); - } - - /* open current track VORBIS file */ - if (cdd.toc.tracks[index].vf.seekable) - { - ov_open(cdd.toc.tracks[index].fd,&cdd.toc.tracks[index].vf,0,0); - } - } -#endif -#endif - - /* update current track index */ - cdd.index = index; - - /* stay within track limits when seeking files */ - if (lba < cdd.toc.tracks[index].start) - { - lba = cdd.toc.tracks[index].start; - } - - /* seek to current block */ - if (!is_audio(cdd.index)) - { - /* DATA track */ - pm_seek(cdd.toc.tracks[cdd.index].fd, lba * cdd.sectorSize, SEEK_SET); - } -#ifdef USE_LIBTREMOR - else if (cdd.toc.tracks[index].vf.seekable) - { - /* VORBIS AUDIO track */ - ov_pcm_seek(&cdd.toc.tracks[index].vf, (lba - cdd.toc.tracks[index].start) * 588 - cdd.toc.tracks[index].offset); - } -#endif -#if 0 - else if (cdd.toc.tracks[index].fd) - { - /* PCM AUDIO track */ - fseek(cdd.toc.tracks[index].fd, (lba * 2352) - cdd.toc.tracks[index].offset, SEEK_SET); - } -#else - else - { - cdd_change_track(index, lba); - } -#endif + cdd_seek(index, lba); /* no audio track playing (yet) */ Pico_mcd->s68k_regs[0x36+0] = 0x01; @@ -1180,66 +1067,11 @@ void cdd_process(void) cdd.latency = ((cdd.lba - lba) * 120) / 270000; } - /* update current LBA */ - cdd.lba = lba; - /* get current track index */ while ((cdd.toc.tracks[index].end <= lba) && (index < cdd.toc.last)) index++; -#ifdef USE_LIBTREMOR -#ifdef DISABLE_MANY_OGG_OPEN_FILES - /* check if track index has changed */ - if (index != cdd.index) - { - /* close previous track VORBIS file structure to save memory */ - if (cdd.toc.tracks[cdd.index].vf.datasource) - { - ogg_free(cdd.index); - } - - /* open current track VORBIS file */ - if (cdd.toc.tracks[index].vf.seekable) - { - ov_open(cdd.toc.tracks[index].fd,&cdd.toc.tracks[index].vf,0,0); - } - } -#endif -#endif - - /* update current track index */ - cdd.index = index; - - /* stay within track limits */ - if (lba < cdd.toc.tracks[index].start) - { - lba = cdd.toc.tracks[index].start; - } - /* seek to current block */ - if (!is_audio(cdd.index)) - { - /* DATA track */ - pm_seek(cdd.toc.tracks[cdd.index].fd, lba * cdd.sectorSize, SEEK_SET); - } -#ifdef USE_LIBTREMOR - else if (cdd.toc.tracks[index].vf.seekable) - { - /* VORBIS AUDIO track */ - ov_pcm_seek(&cdd.toc.tracks[index].vf, (lba - cdd.toc.tracks[index].start) * 588 - cdd.toc.tracks[index].offset); - } -#endif -#if 0 - else if (cdd.toc.tracks[index].fd) - { - /* PCM AUDIO track */ - fseek(cdd.toc.tracks[index].fd, (lba * 2352) - cdd.toc.tracks[index].offset, SEEK_SET); - } -#else - else - { - cdd_change_track(index, lba); - } -#endif + cdd_seek(index, lba); /* no audio track playing */ Pico_mcd->s68k_regs[0x36+0] = 0x01; -- 2.39.2