diff --git a/source/audio.cpp b/source/audio.cpp index 1ad94b5..f17396b 100644 --- a/source/audio.cpp +++ b/source/audio.cpp @@ -39,43 +39,51 @@ extern int ConfigRequested; static u8 soundbuffer[BUFFERCOUNT][AUDIOBUFFER] __attribute__ ((__aligned__ (32))); static int playab = 0; static int nextab = 0; -int available = 0; +static int unplayed = 0; -static inline void updateAvailable(int diff) { - available += diff; +static inline void updateUnplayed(int diff) { + unplayed += diff; - if(available < 0) { - available = 0; + if(unplayed < 0) { + unplayed = 0; } - else if(available > BUFFERCOUNT-1) { - available = BUFFERCOUNT-1; + else if(unplayed > BUFFERCOUNT-1) { + unplayed = BUFFERCOUNT-1; } } static void DMACallback () { if (!ScreenshotRequested && !ConfigRequested) { + updateUnplayed(-1); AUDIO_InitDMA ((u32) soundbuffer[playab], AUDIOBUFFER); - updateAvailable(-1); playab = (playab + 1) % BUFFERCOUNT; } } static void S9xAudioCallback (void *data) { - //S9xUpdateDynamicRate(); // TODO: what arguments should be passed here? + double rate = 1.0; + + if(unplayed > 8) { + rate = 1.005; + } + else if(unplayed < 4) { + rate = 0.995; + } + + S9xUpdateDynamicRate(rate); S9xFinalizeSamples(); - int availableSamples = S9xGetSampleCount(); if (ScreenshotRequested || ConfigRequested) { AUDIO_StopDMA(); } - else if(availableSamples >= SAMPLES_TO_PROCESS) { - nextab = (nextab + 1) % BUFFERCOUNT; - updateAvailable(1); + else if(S9xGetSampleCount() >= SAMPLES_TO_PROCESS) { S9xMixSamples (soundbuffer[nextab], SAMPLES_TO_PROCESS); DCFlushRange (soundbuffer[nextab], AUDIOBUFFER); - + updateUnplayed(1); + nextab = (nextab + 1) % BUFFERCOUNT; + if(playab == -1) { - if(available > 2) { + if(unplayed > 2) { playab = 0; AUDIO_StartDMA(); } @@ -150,7 +158,7 @@ void ShutdownAudio() void AudioStart () { - available = 0; + unplayed = 0; nextab = 0; playab = -1; } diff --git a/source/snes9x/apu/apu.cpp b/source/snes9x/apu/apu.cpp index 2317e66..a1d759f 100644 --- a/source/snes9x/apu/apu.cpp +++ b/source/snes9x/apu/apu.cpp @@ -465,12 +465,12 @@ void S9xSetSamplesAvailableCallback (apu_callback callback, void *data) spc::extra_data = data; } -void S9xUpdateDynamicRate (int avail, int buffer_size) +void S9xUpdateDynamicRate (double rate) { - spc::dynamic_rate_multiplier = 1.0 + (Settings.DynamicRateLimit * (buffer_size - 2 * avail)) / - (double)(1000 * buffer_size); - - UpdatePlaybackRate(); + if(spc::dynamic_rate_multiplier != rate) { + spc::dynamic_rate_multiplier = rate; + UpdatePlaybackRate(); + } } void UpdatePlaybackRate (void) diff --git a/source/snes9x/apu/apu.h b/source/snes9x/apu/apu.h index 6c02fab..51c3c71 100644 --- a/source/snes9x/apu/apu.h +++ b/source/snes9x/apu/apu.h @@ -214,7 +214,7 @@ void S9xFinalizeSamples (void); void S9xClearSamples (void); bool8 S9xMixSamples (uint8 *, int); void S9xSetSamplesAvailableCallback (apu_callback, void *); -void S9xUpdateDynamicRate (int, int); +void S9xUpdateDynamicRate (double rate); extern SNES_SPC *spc_core;