From 39b17ca6405a7e01592f7e098ea34c65cb4fba38 Mon Sep 17 00:00:00 2001 From: pierre Date: Fri, 7 May 2010 23:14:40 +0000 Subject: [PATCH] Linux: Fix horrible latency when the alsa pulseaudio plugin is involved, see issue #2651 The fix is asking alsa for a prefered "hardware" buffer size, so alsa does not fall back to pulseaudios offering of ~1 minute. Additionally, alsa busy waits when pulseaudio is used, sw:avail_min is set and hw:buffer_size is small. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5439 8ced0084-cf51-0410-be5f-012b33b47a6e --- .../Core/AudioCommon/Src/AlsaSoundStream.cpp | 34 +++++++++++++++---- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/Source/Core/AudioCommon/Src/AlsaSoundStream.cpp b/Source/Core/AudioCommon/Src/AlsaSoundStream.cpp index 60224ba3db..760082e1aa 100644 --- a/Source/Core/AudioCommon/Src/AlsaSoundStream.cpp +++ b/Source/Core/AudioCommon/Src/AlsaSoundStream.cpp @@ -88,6 +88,8 @@ bool AlsaSound::AlsaInit() int dir; snd_pcm_sw_params_t *swparams; snd_pcm_hw_params_t *hwparams; + snd_pcm_uframes_t buffer_size; + unsigned int periods; err = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0); if (err < 0) @@ -132,6 +134,31 @@ bool AlsaSound::AlsaInit() ERROR_LOG(AUDIO, "Channels count not available: %s\n", snd_strerror(err)); return false; } + + periods = 2; + err = snd_pcm_hw_params_set_periods_min(handle, hwparams, &periods, &dir); + if (err < 0) + { + ERROR_LOG(AUDIO, "Cannot set Minimum periods: %s\n", snd_strerror(err)); + return false; + } + + buffer_size = BUFFER_SIZE; + err = snd_pcm_hw_params_set_buffer_size_min(handle, hwparams, &buffer_size); + if (err < 0) + { + ERROR_LOG(AUDIO, "Cannot set minimum buffer size: %s\n", snd_strerror(err)); + return false; + } + + buffer_size = BUFFER_SIZE*2; + err = snd_pcm_hw_params_set_buffer_size_near(handle, hwparams, &buffer_size); + if (err < 0) + { + ERROR_LOG(AUDIO, "Cannot set buffer size: %s\n", snd_strerror(err)); + return false; + } + NOTICE_LOG(AUDIO, "ALSA gave us %d \"hardware\" buffers of %d samples.\n", periods, buffer_size); err = snd_pcm_hw_params(handle, hwparams); if (err < 0) @@ -149,13 +176,6 @@ bool AlsaSound::AlsaInit() return false; } - err = snd_pcm_sw_params_set_avail_min(handle, swparams, BUFFER_SIZE); - if (err < 0) - { - ERROR_LOG(AUDIO, "cannot set avail min: %s\n", snd_strerror(err)); - return false; - } - err = snd_pcm_sw_params_set_start_threshold(handle, swparams, 0U); if (err < 0) {