diff --git a/Source/Core/AudioCommon/AlsaSoundStream.cpp b/Source/Core/AudioCommon/AlsaSoundStream.cpp index ae888564b3..3a1f460133 100644 --- a/Source/Core/AudioCommon/AlsaSoundStream.cpp +++ b/Source/Core/AudioCommon/AlsaSoundStream.cpp @@ -2,6 +2,8 @@ // Licensed under GPLv2+ // Refer to the license.txt file included. +#include + #include "AudioCommon/AlsaSoundStream.h" #include "Common/CommonTypes.h" #include "Common/Thread.h" @@ -39,6 +41,10 @@ bool AlsaSound::Start() void AlsaSound::Stop() { m_thread_status.store(ALSAThreadStatus::STOPPING); + + //Give the opportunity to the audio thread + //to realize we are stopping the emulation + cv.notify_one(); thread.join(); } @@ -53,8 +59,11 @@ void AlsaSound::SoundLoop() Common::SetCurrentThreadName("Audio thread - alsa"); while (m_thread_status.load() == ALSAThreadStatus::RUNNING) { + std::unique_lock lock(cv_m); + cv.wait(lock, [this]{return !m_muted || m_thread_status.load() != ALSAThreadStatus::RUNNING;}); + m_mixer->Mix(reinterpret_cast(mix_buffer), frames_to_deliver); - int rc = m_muted ? 1337 : snd_pcm_writei(handle, mix_buffer, frames_to_deliver); + int rc = snd_pcm_writei(handle, mix_buffer, frames_to_deliver); if (rc == -EPIPE) { // Underrun @@ -69,6 +78,24 @@ void AlsaSound::SoundLoop() m_thread_status.store(ALSAThreadStatus::STOPPED); } + +void AlsaSound::Clear(bool muted) +{ + m_muted = muted; + if (m_muted) + { + std::lock_guard lock(cv_m); + snd_pcm_drop(handle); + } + else + { + std::unique_lock lock(cv_m); + snd_pcm_prepare(handle); + lock.unlock(); + cv.notify_one(); + } +} + bool AlsaSound::AlsaInit() { unsigned int sample_rate = m_mixer->GetSampleRate(); diff --git a/Source/Core/AudioCommon/AlsaSoundStream.h b/Source/Core/AudioCommon/AlsaSoundStream.h index 186e4871bb..3654f4b8a5 100644 --- a/Source/Core/AudioCommon/AlsaSoundStream.h +++ b/Source/Core/AudioCommon/AlsaSoundStream.h @@ -5,6 +5,8 @@ #pragma once #include +#include +#include #include #if defined(HAVE_ALSA) && HAVE_ALSA @@ -25,6 +27,7 @@ public: void SoundLoop() override; void Stop() override; void Update() override; + void Clear(bool) override; static bool isValid() { @@ -45,6 +48,8 @@ private: u8 *mix_buffer; std::thread thread; std::atomic m_thread_status; + std::condition_variable cv; + std::mutex cv_m; snd_pcm_t *handle; int frames_to_deliver;