[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)
{
/* check if fade out is still in progress */
if (megasd_hw.fadeoutSamplesCount > 0)
unsigned int count;
while (samples > 0)
{
/* update remaining fade out samples count */
megasd_hw.fadeoutSamplesCount -= samples;
/* attempt to read remaing needed samples by default */
count = samples;
/* check end of fade out */
if (megasd_hw.fadeoutSamplesCount <= 0)
/* check against fade out remaining samples */
if ((megasd_hw.fadeoutSamplesCount > 0) && (count > megasd_hw.fadeoutSamplesCount))
{
/* pause audio playback */
scd.regs[0x36>>1].byte.h = 0x01;
cdd.status = CD_PAUSE;
/* restore initial volume */
cdd.fader[0] = cdd.fader[1] = megasd_hw.fadeoutStartVolume;
count = megasd_hw.fadeoutSamplesCount;
}
else
/* check against playback remaining samples */
if ((megasd_hw.playbackSamplesCount > 0) && (count > megasd_hw.playbackSamplesCount))
{
/* force volume for next frame */
cdd.fader[0] = cdd.fader[1] = (megasd_hw.fadeoutSamplesCount * megasd_hw.fadeoutStartVolume) / megasd_hw.fadeoutSamplesTotal;
count = megasd_hw.playbackSamplesCount;
}
}
/* Playback in progress ? */
if (megasd_hw.playbackSamplesCount > 0)
{
/* update remaining samples count */
megasd_hw.playbackSamplesCount -= samples;
/* read required CD-DA samples */
cdd_read_audio(count);
/* check end of current track */
if (megasd_hw.playbackSamplesCount <= 0)
/* adjust remaing needed samples count */
samples -= count;
/* check if fade out is still in progress */
if (megasd_hw.fadeoutSamplesCount > 0)
{
/* check playback end track */
if (cdd.index < megasd_hw.playbackEndTrack)
/* update remaining fade out samples count */
megasd_hw.fadeoutSamplesCount -= count;
/* check end of fade out */
if (megasd_hw.fadeoutSamplesCount <= 0)
{
/* seek start of next track */
cdd_seek_audio(cdd.index + 1, cdd.toc.tracks[cdd.index + 1].start);
/* pause audio playback */
scd.regs[0x36>>1].byte.h = 0x01;
cdd.status = CD_PAUSE;
/* 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;
}
/* restore initial volume */
cdd.fader[0] = cdd.fader[1] = megasd_hw.fadeoutStartVolume;
}
else
{
/* stop audio playback */
cdd.status = CD_STOP;
scd.regs[0x36>>1].byte.h = 0x01;
/* force volume for next frame */
cdd.fader[0] = cdd.fader[1] = (megasd_hw.fadeoutSamplesCount * megasd_hw.fadeoutStartVolume) / megasd_hw.fadeoutSamplesTotal;
}
}
/* 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)
{
/* 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
{
/* 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);
}
@ -1443,9 +1443,6 @@ void cdd_read_audio(unsigned int samples)
int prev_l = cdd.audio[0];
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 ? */
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 */
cdd.audio[0] = prev_l;
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
{
@ -1670,6 +1661,23 @@ void cdd_read_audio(unsigned int 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)
{
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_seek_audio(int index, int lba);
extern void cdd_read_audio(unsigned int samples);
extern void cdd_update_audio(unsigned int samples);
extern void cdd_update(void);
extern void cdd_process(void);

View File

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