libretro / gpsp

gpSP for libretro.
GNU General Public License v2.0
52 stars 52 forks source link

Send audio samples to frontend with correct pacing #165

Closed jdgleaver closed 2 years ago

jdgleaver commented 2 years ago

At present, the core is susceptible to crackling audio, particularly when using low frontend audio latency settings.

This is because the core is handling audio output suboptimally. At the set audio sample rate, the frontend expects between 1097 and 1098 audio samples per frame - but the core is sending samples in multiples of 256. This means that the audio output becomes 'desynchronised' with retro_run() - sometimes 1024 samples will get sent to the frontend for the current frame, sometimes 1280 as the core either falls behind or overcompensates. As a result, when the frontend tries to synchronise on audio, jitter can occur - and if the frontend audio buffer is small (when using low latency values), it can sometimes run dry or reach capacity, causing crackling.

This PR modifies audio handling such that the correct expected number of samples is sent to the frontend in proper synchronisation with retro_run(). This greatly improves audio quality, even on the notoriously crackly Mother 3.

To demonstrate the effect of this PR, here are a couple of figures measured from the core on a Linux desktop with an audio latency setting of 64 ms, averaged over 5k frames:

Time spent close to audio buffer underrun: