mcd, revisit track handling in cdd

This commit is contained in:
kub 2024-04-19 20:53:52 +02:00
parent db2b6d9966
commit 4447902711

View file

@ -196,6 +196,70 @@ static void cdd_change_track(int index, int lba)
cdda_start_play(base, lba_offset, lb_len);
}
static off_t read_pos = -1;
void cdd_seek(int index, int lba)
{
int aindex = (index < 0 ? -index : 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.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
/* update current track index and LBA */
cdd.index = aindex;
cdd.lba = 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 block */
if (!is_audio(cdd.index))
{
/* DATA track */
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)
{
/* 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);
}
#endif
#if 0
else if (cdd.toc.tracks[cdd.index].fd)
{
/* PCM AUDIO track */
fseek(cdd.toc.tracks[cdd.index].fd, (lba * 2352) - cdd.toc.tracks[cdd.index].offset, SEEK_SET);
}
#else
else
{
cdd_change_track(cdd.index, lba);
}
#endif
}
int cdd_context_save(uint8 *state)
{
int bufferptr = 0;
@ -213,19 +277,8 @@ int cdd_context_save(uint8 *state)
int cdd_context_load(uint8 *state)
{
int lba;
int bufferptr = 0;
#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
load_param(&cdd.cycles, sizeof(cdd.cycles));
load_param(&cdd.latency, sizeof(cdd.latency));
load_param(&cdd.index, sizeof(cdd.index));
@ -234,45 +287,8 @@ int cdd_context_load(uint8 *state)
load_param(&cdd.volume, sizeof(cdd.volume));
load_param(&cdd.status, sizeof(cdd.status));
/* adjust current LBA within track limit */
lba = cdd.lba;
if (lba < cdd.toc.tracks[cdd.index].start)
{
lba = cdd.toc.tracks[cdd.index].start;
}
/* seek to current track position */
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);
}
}
#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);
}
#endif
#if 0
else if (cdd.toc.tracks[cdd.index].fd)
{
/* PCM AUDIO track */
fseek(cdd.toc.tracks[cdd.index].fd, (lba * 2352) - cdd.toc.tracks[cdd.index].offset, SEEK_SET);
}
#else
else
{
cdd_change_track(cdd.index, lba);
}
#endif
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++;
/* skip directly to track start position */
cdd.lba = cdd.toc.tracks[cdd.index].start;
/* AUDIO track playing ? */
if (cdd.status == CD_PLAY)
if (cdd.index >= cdd.toc.last)
{
Pico_mcd->s68k_regs[0x36+0] = 0x00;
/* no AUDIO track playing */
Pico_mcd->s68k_regs[0x36+0] = 0x01;
/* end of disc */
cdd.lba = cdd.toc.end;
cdd.status = CD_END;
}
else
{
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)
{
ogg_free(cdd.index);
}
#endif
#endif
/* previous track */
cdd.index--;
/* skip directly to track end position */
cdd.lba = cdd.toc.tracks[cdd.index].end;
if (cdd.index <= 0)
{
cdd_seek(0, 0);
}
else
{
cdd_seek(cdd.index - 1, cdd.toc.tracks[cdd.index-1].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;