Get SoundSync working and don't overflow dsp buffer.

This commit is contained in:
Brandon Wright 2019-02-06 15:00:45 -06:00
parent 9994023f09
commit 2701e7219c
2 changed files with 27 additions and 18 deletions

View File

@ -22,8 +22,12 @@ static const int APU_DENOMINATOR_NTSC = 328125;
static const int APU_NUMERATOR_PAL = 34176; static const int APU_NUMERATOR_PAL = 34176;
static const int APU_DENOMINATOR_PAL = 709379; static const int APU_DENOMINATOR_PAL = 709379;
// Max number of sample frames we'll ever generate before call to port API // Max number of sample frames we'll ever generate before call to port API and
static const int MAX_SAMPLE_FRAMES = (32040 + 59) / 60; // moving the samples to the resampler.
// This is 535 sample frames, which corresponds to 1 video frame + some leeway
// for use with SoundSync.
static const int MAX_SAMPLE_FRAMES = 600;
static const int SAMPLE_FRAMES_LIMIT = 550;
namespace SNES namespace SNES
{ {
@ -125,17 +129,27 @@ int S9xGetSampleCount(void)
void S9xFinalizeSamples(void) void S9xFinalizeSamples(void)
{ {
bool drop_msu1_samples = true;
if (!Settings.Mute) if (!Settings.Mute)
{ {
drop_msu1_samples = false;
if (!spc::resampler->push((short *)spc::dsp_buffer, if (!spc::resampler->push((short *)spc::dsp_buffer,
SNES::dsp.spc_dsp.sample_count())) SNES::dsp.spc_dsp.sample_count()))
{ {
// Don't drop samples if SoundSync is enabled. The port will wait
// and call S9xSyncSound again to catch up.
// If the sample count is over a frame, it indicates the port
// didn't implement SoundSync correctly.
if (Settings.SoundSync && !Settings.TurboMode && !Settings.Mute &&
SNES::dsp.spc_dsp.sample_count() < SAMPLE_FRAMES_LIMIT)
{
spc::sound_in_sync = false;
return;
}
spc::resampler->clear(); spc::resampler->clear();
drop_msu1_samples = true; spc::resampler->push((short *)spc::dsp_buffer,
SNES::dsp.spc_dsp.sample_count());
if (Settings.MSU1)
msu::resampler->clear();
} }
} }
@ -147,19 +161,15 @@ void S9xFinalizeSamples(void)
// generate the same number of msu1 samples as dsp samples were generated // generate the same number of msu1 samples as dsp samples were generated
S9xMSU1SetOutput((int16 *)msu::mixing_buffer, msu::buffer_size); S9xMSU1SetOutput((int16 *)msu::mixing_buffer, msu::buffer_size);
S9xMSU1Generate(SNES::dsp.spc_dsp.sample_count()); S9xMSU1Generate(SNES::dsp.spc_dsp.sample_count());
if (drop_msu1_samples)
msu::resampler->clear(); if (!msu::resampler->push((short *)msu::mixing_buffer, S9xMSU1Samples()))
else if (!msu::resampler->push((short *)msu::mixing_buffer, S9xMSU1Samples()))
{ {
// should not occur, msu buffer is larger and we drop msu samples if spc buffer overruns // should not occur, msu buffer is larger and we drop msu samples if spc buffer overruns
assert(0); assert(0);
} }
} }
if (!Settings.SoundSync || Settings.TurboMode || Settings.Mute || spc::resampler->space_filled() <= 8) spc::sound_in_sync = true;
spc::sound_in_sync = TRUE;
else
spc::sound_in_sync = FALSE;
reset_dsp_output(); reset_dsp_output();
} }

View File

@ -504,15 +504,14 @@ static void S9xThrottle ()
if (Settings.SkipFrames == THROTTLE_SOUND_SYNC && if (Settings.SkipFrames == THROTTLE_SOUND_SYNC &&
!Settings.DynamicRateControl) !Settings.DynamicRateControl)
{ {
while (!S9xSyncSound ()) while (!S9xSyncSound())
{ {
usleep (100); usleep (100);
/* If we can't sync sound within a half-second, we're probably deadlocked */ /* If we can't sync sound within a half-second, we're probably deadlocked */
if (g_get_monotonic_time () - now > 500000) if (g_get_monotonic_time() - now > 500000)
{ {
S9xClearSamples (); S9xClearSamples();
break;
} }
} }