[Core/MD] improved MD+ audio track loopback transitions

This commit is contained in:
ekeeke 2021-09-28 20:26:13 +02:00
parent 9863375a5a
commit 3cf83e7557
7 changed files with 114 additions and 79 deletions

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 MiB

After

Width:  |  Height:  |  Size: 3.8 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 MiB

After

Width:  |  Height:  |  Size: 4.0 MiB

View File

@ -331,86 +331,112 @@ void megasd_rom_mapper_w(unsigned int address, unsigned int data)
*/ */
void megasd_update_cdda(unsigned int samples) void megasd_update_cdda(unsigned int samples)
{ {
/* check if fade out is still in progress */ unsigned int count;
if (megasd_hw.fadeoutSamplesCount > 0)
while (samples > 0)
{ {
/* update remaining fade out samples count */ /* attempt to read remaing needed samples by default */
megasd_hw.fadeoutSamplesCount -= samples; count = samples;
/* check end of fade out */ /* check against fade out remaining samples */
if (megasd_hw.fadeoutSamplesCount <= 0) if ((megasd_hw.fadeoutSamplesCount > 0) && (count > megasd_hw.fadeoutSamplesCount))
{ {
/* pause audio playback */ count = megasd_hw.fadeoutSamplesCount;
scd.regs[0x36>>1].byte.h = 0x01;
cdd.status = CD_PAUSE;
/* restore initial volume */
cdd.fader[0] = cdd.fader[1] = megasd_hw.fadeoutStartVolume;
} }
else
/* check against playback remaining samples */
if ((megasd_hw.playbackSamplesCount > 0) && (count > megasd_hw.playbackSamplesCount))
{ {
/* force volume for next frame */ count = megasd_hw.playbackSamplesCount;
cdd.fader[0] = cdd.fader[1] = (megasd_hw.fadeoutSamplesCount * megasd_hw.fadeoutStartVolume) / megasd_hw.fadeoutSamplesTotal;
} }
}
/* Playback in progress ? */ /* read required CD-DA samples */
if (megasd_hw.playbackSamplesCount > 0) cdd_read_audio(count);
{
/* update remaining samples count */
megasd_hw.playbackSamplesCount -= samples;
/* check end of current track */ /* adjust remaing needed samples count */
if (megasd_hw.playbackSamplesCount <= 0) samples -= count;
/* check if fade out is still in progress */
if (megasd_hw.fadeoutSamplesCount > 0)
{ {
/* check playback end track */ /* update remaining fade out samples count */
if (cdd.index < megasd_hw.playbackEndTrack) megasd_hw.fadeoutSamplesCount -= count;
/* check end of fade out */
if (megasd_hw.fadeoutSamplesCount <= 0)
{ {
/* seek start of next track */ /* pause audio playback */
cdd_seek_audio(cdd.index + 1, cdd.toc.tracks[cdd.index + 1].start); scd.regs[0x36>>1].byte.h = 0x01;
cdd.status = CD_PAUSE;
/* increment current track index */ /* restore initial volume */
cdd.index++; cdd.fader[0] = cdd.fader[1] = megasd_hw.fadeoutStartVolume;
/* check if last track is being played */
if (cdd.index == megasd_hw.playbackEndTrack)
{
/* reinitialize remaining samples count using current track start sector and playback end sectors */
megasd_hw.playbackSamplesCount = (megasd_hw.playbackEndSector - cdd.toc.tracks[cdd.index].start) * 588;
}
else
{
/* reinitialize remaining samples count using current track start and end sectors */
megasd_hw.playbackSamplesCount = (cdd.toc.tracks[cdd.index].end - cdd.toc.tracks[cdd.index].start) * 588;
}
}
/* check track loop */
else if (megasd_hw.playbackLoop)
{
/* seek back to start track loop sector */
cdd_seek_audio(megasd_hw.playbackLoopTrack, megasd_hw.playbackLoopSector);
/* update current track index */
cdd.index = megasd_hw.playbackLoopTrack;
/* check if single track or successive tracks are being played */
if (cdd.index == megasd_hw.playbackEndTrack)
{
/* reinitialize remaining samples count using playback loop and end sectors */
megasd_hw.playbackSamplesCount = (megasd_hw.playbackEndSector - megasd_hw.playbackLoopSector) * 588;
}
else
{
/* reinitialize remaining samples count using playback loop sector and track end sector */
megasd_hw.playbackSamplesCount = (cdd.toc.tracks[cdd.index].end - megasd_hw.playbackLoopSector) * 588;
}
} }
else else
{ {
/* stop audio playback */ /* force volume for next frame */
cdd.status = CD_STOP; cdd.fader[0] = cdd.fader[1] = (megasd_hw.fadeoutSamplesCount * megasd_hw.fadeoutStartVolume) / megasd_hw.fadeoutSamplesTotal;
scd.regs[0x36>>1].byte.h = 0x01; }
}
/* Playback in progress ? */
if (megasd_hw.playbackSamplesCount > 0)
{
/* update remaining samples count */
megasd_hw.playbackSamplesCount -= count;
/* check end of current track */
if (megasd_hw.playbackSamplesCount <= 0)
{
/* check playback end track */
if (cdd.index < megasd_hw.playbackEndTrack)
{
/* seek start of next track */
cdd_seek_audio(cdd.index + 1, cdd.toc.tracks[cdd.index + 1].start);
/* increment current track index */
cdd.index++;
/* check if last track is being played */
if (cdd.index == megasd_hw.playbackEndTrack)
{
/* reinitialize remaining samples count using current track start sector and playback end sectors */
megasd_hw.playbackSamplesCount = (megasd_hw.playbackEndSector - cdd.toc.tracks[cdd.index].start) * 588;
}
else
{
/* reinitialize remaining samples count using current track start and end sectors */
megasd_hw.playbackSamplesCount = (cdd.toc.tracks[cdd.index].end - cdd.toc.tracks[cdd.index].start) * 588;
}
}
/* check track loop */
else if (megasd_hw.playbackLoop)
{
/* seek back to start track loop sector */
cdd_seek_audio(megasd_hw.playbackLoopTrack, megasd_hw.playbackLoopSector);
/* update current track index */
cdd.index = megasd_hw.playbackLoopTrack;
/* check if single track or successive tracks are being played */
if (cdd.index == megasd_hw.playbackEndTrack)
{
/* reinitialize remaining samples count using playback loop and end sectors */
megasd_hw.playbackSamplesCount = (megasd_hw.playbackEndSector - megasd_hw.playbackLoopSector) * 588;
}
else
{
/* reinitialize remaining samples count using playback loop sector and track end sector */
megasd_hw.playbackSamplesCount = (cdd.toc.tracks[cdd.index].end - megasd_hw.playbackLoopSector) * 588;
}
}
else
{
/* stop audio playback */
cdd.status = CD_STOP;
scd.regs[0x36>>1].byte.h = 0x01;
}
} }
} }
} }

View File

@ -903,12 +903,12 @@ int cdd_load(char *filename, char *header)
if (cdd.toc.tracks[cdd.toc.last].type) if (cdd.toc.tracks[cdd.toc.last].type)
{ {
/* DATA track length */ /* DATA track length */
cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + ((cdStreamTell(cdd.toc.tracks[cdd.toc.last].fd) + cdd.sectorSize - 1) / cdd.sectorSize); cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + (cdStreamTell(cdd.toc.tracks[cdd.toc.last].fd) / cdd.sectorSize);
} }
else else
{ {
/* AUDIO track length */ /* AUDIO track length */
cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + ((cdStreamTell(cdd.toc.tracks[cdd.toc.last].fd) + 2351) / 2352); cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + (cdStreamTell(cdd.toc.tracks[cdd.toc.last].fd) / 2352);
} }
cdStreamSeek(cdd.toc.tracks[cdd.toc.last].fd, 0, SEEK_SET); cdStreamSeek(cdd.toc.tracks[cdd.toc.last].fd, 0, SEEK_SET);
} }
@ -1443,9 +1443,6 @@ void cdd_read_audio(unsigned int samples)
int prev_l = cdd.audio[0]; int prev_l = cdd.audio[0];
int prev_r = cdd.audio[1]; int prev_r = cdd.audio[1];
/* get number of internal clocks (CD-DA samples) needed */
samples = blip_clocks_needed(snd.blips[2], samples);
/* audio track playing ? */ /* audio track playing ? */
if (!scd.regs[0x36>>1].byte.h && cdd.toc.tracks[cdd.index].fd) if (!scd.regs[0x36>>1].byte.h && cdd.toc.tracks[cdd.index].fd)
{ {
@ -1646,12 +1643,6 @@ void cdd_read_audio(unsigned int samples)
/* save last audio output for next frame */ /* save last audio output for next frame */
cdd.audio[0] = prev_l; cdd.audio[0] = prev_l;
cdd.audio[1] = prev_r; cdd.audio[1] = prev_r;
/* check CD-DA track end (Mega SD add-on specific)*/
if (cart.special & HW_MEGASD)
{
megasd_update_cdda(samples);
}
} }
else else
{ {
@ -1670,6 +1661,23 @@ void cdd_read_audio(unsigned int samples)
blip_end_frame(snd.blips[2], samples); blip_end_frame(snd.blips[2], samples);
} }
void cdd_update_audio(unsigned int samples)
{
/* get number of internal clocks (CD-DA samples) needed */
samples = blip_clocks_needed(snd.blips[2], samples);
if (cart.special & HW_MEGASD)
{
/* MegaSD add-on specific CD-DA processing */
megasd_update_cdda(samples);
}
else
{
/* read needed CD-DA samples */
cdd_read_audio(samples);
}
}
static void cdd_read_subcode(void) static void cdd_read_subcode(void)
{ {
uint8 subc[96]; uint8 subc[96];

View File

@ -141,6 +141,7 @@ extern void cdd_unload(void);
extern void cdd_read_data(uint8 *dst, uint8 *subheader); extern void cdd_read_data(uint8 *dst, uint8 *subheader);
extern void cdd_seek_audio(int index, int lba); extern void cdd_seek_audio(int index, int lba);
extern void cdd_read_audio(unsigned int samples); extern void cdd_read_audio(unsigned int samples);
extern void cdd_update_audio(unsigned int samples);
extern void cdd_update(void); extern void cdd_update(void);
extern void cdd_process(void); extern void cdd_process(void);

View File

@ -201,8 +201,8 @@ int audio_update(int16 *buffer)
/* sync PCM chip with other sound chips */ /* sync PCM chip with other sound chips */
pcm_update(size); pcm_update(size);
/* read CDDA samples */ /* read CD-DA samples */
cdd_read_audio(size); cdd_update_audio(size);
#ifdef ALIGN_SND #ifdef ALIGN_SND
/* return an aligned number of samples if required */ /* return an aligned number of samples if required */