diff options
Diffstat (limited to 'backends/mixer')
-rw-r--r-- | backends/mixer/sdl/sdl-mixer.cpp | 46 |
1 files changed, 38 insertions, 8 deletions
diff --git a/backends/mixer/sdl/sdl-mixer.cpp b/backends/mixer/sdl/sdl-mixer.cpp index 5a31feb4dc..11a45ebcb2 100644 --- a/backends/mixer/sdl/sdl-mixer.cpp +++ b/backends/mixer/sdl/sdl-mixer.cpp @@ -125,6 +125,24 @@ void SdlMixerManager::init() { startAudio(); } +static uint32 roundDownPowerOfTwo(uint32 samples) { + // Public domain code from Sean Eron Anderson + // http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 + uint32 rounded = samples; + --rounded; + rounded |= rounded >> 1; + rounded |= rounded >> 2; + rounded |= rounded >> 4; + rounded |= rounded >> 8; + rounded |= rounded >> 16; + ++rounded; + + if (rounded != samples) + rounded >>= 1; + + return rounded; +} + SDL_AudioSpec SdlMixerManager::getAudioSpec(uint32 outputRate) { SDL_AudioSpec desired; @@ -139,19 +157,31 @@ SDL_AudioSpec SdlMixerManager::getAudioSpec(uint32 outputRate) { if (freq <= 0) freq = outputRate; - // Determine the sample buffer size. We want it to store enough data for - // at least 1/16th of a second (though at most 8192 samples). Note - // that it must be a power of two. So e.g. at 22050 Hz, we request a - // sample buffer size of 2048. - uint32 samples = 8192; - while (samples * 16 > freq * 2) - samples >>= 1; + // One SDL "sample" is a complete audio frame (i.e. all channels = 1 sample) + uint32 samples = 0; + + // Different games and host systems have different performance + // characteristics which are not easily measured, so allow advanced users to + // tweak their audio buffer size if they are experience excess latency or + // drop-outs by setting this value in their ScummVM config file directly + if (ConfMan.hasKey("audio_buffer_size", appDomain)) + samples = ConfMan.getInt("audio_buffer_size", appDomain); + + // 256 is an arbitrary minimum; 32768 is the largest power-of-two value + // representable with uint16 + if (samples < 256 || samples > 32768) + // By default, hold no more than 45ms worth of samples to avoid + // perceptable audio lag (ATSC IS-191). For reference, DOSBox (as of Sep + // 2017) uses a buffer size of 1024 samples by default for a 16-bit + // stereo 44kHz mixer, which happens to be the next lowest power of two + // below 45ms. + samples = freq / (1000.0 / 45); memset(&desired, 0, sizeof(desired)); desired.freq = freq; desired.format = AUDIO_S16SYS; desired.channels = 2; - desired.samples = (uint16)samples; + desired.samples = roundDownPowerOfTwo(samples); desired.callback = sdlCallback; desired.userdata = this; |