From ad4a89d64b0d346553be473c1d877b34b896bfeb Mon Sep 17 00:00:00 2001 From: Michael M Date: Sat, 21 Oct 2017 12:49:34 -0700 Subject: [PATCH 1/3] CubebStream: implement SetRunning --- Source/Core/AudioCommon/CubebStream.cpp | 19 +++++++++++++++---- Source/Core/AudioCommon/CubebStream.h | 1 + 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/Source/Core/AudioCommon/CubebStream.cpp b/Source/Core/AudioCommon/CubebStream.cpp index a12f0fda4b..c2f3cc30cb 100644 --- a/Source/Core/AudioCommon/CubebStream.cpp +++ b/Source/Core/AudioCommon/CubebStream.cpp @@ -76,12 +76,23 @@ bool CubebStream::Start() return true; } +void CubebStream::SetRunning(bool running) +{ + if (running) + { + if (cubeb_stream_start(m_stream) != CUBEB_OK) + ERROR_LOG(AUDIO, "Error starting cubeb stream"); + } + else + { + if (cubeb_stream_stop(m_stream) != CUBEB_OK) + ERROR_LOG(AUDIO, "Error stopping cubeb stream"); + } +} + void CubebStream::Stop() { - if (cubeb_stream_stop(m_stream) != CUBEB_OK) - { - ERROR_LOG(AUDIO, "Error stopping cubeb stream"); - } + SetRunning(false); cubeb_stream_destroy(m_stream); m_ctx.reset(); } diff --git a/Source/Core/AudioCommon/CubebStream.h b/Source/Core/AudioCommon/CubebStream.h index eb7e915751..f558ed1b20 100644 --- a/Source/Core/AudioCommon/CubebStream.h +++ b/Source/Core/AudioCommon/CubebStream.h @@ -17,6 +17,7 @@ class CubebStream final : public SoundStream public: bool Start() override; void Stop() override; + void SetRunning(bool running) override; void SetVolume(int) override; private: From 0baddbf9a8152ab7dd3ab200e516a998a0c9433f Mon Sep 17 00:00:00 2001 From: Michael M Date: Sat, 21 Oct 2017 16:23:40 -0700 Subject: [PATCH 2/3] SoundStream: change Start/Stop to Init/SetRunning/destruct --- Source/Core/AudioCommon/AlsaSoundStream.cpp | 27 +++++++------- Source/Core/AudioCommon/AlsaSoundStream.h | 6 ++-- Source/Core/AudioCommon/AudioCommon.cpp | 37 +++++++++----------- Source/Core/AudioCommon/CubebStream.cpp | 33 +++++------------ Source/Core/AudioCommon/CubebStream.h | 6 ++-- Source/Core/AudioCommon/NullSoundStream.cpp | 11 +++--- Source/Core/AudioCommon/NullSoundStream.h | 4 +-- Source/Core/AudioCommon/OpenALStream.cpp | 7 ++-- Source/Core/AudioCommon/OpenALStream.h | 6 ++-- Source/Core/AudioCommon/OpenSLESStream.cpp | 4 +-- Source/Core/AudioCommon/OpenSLESStream.h | 5 +-- Source/Core/AudioCommon/PulseAudioStream.cpp | 9 ++--- Source/Core/AudioCommon/PulseAudioStream.h | 7 ++-- Source/Core/AudioCommon/SoundStream.h | 5 ++- Source/Core/AudioCommon/XAudio2Stream.cpp | 20 ++++++----- Source/Core/AudioCommon/XAudio2Stream.h | 8 ++--- Source/Core/AudioCommon/XAudio2_7Stream.cpp | 20 ++++++----- Source/Core/AudioCommon/XAudio2_7Stream.h | 8 ++--- 18 files changed, 102 insertions(+), 121 deletions(-) diff --git a/Source/Core/AudioCommon/AlsaSoundStream.cpp b/Source/Core/AudioCommon/AlsaSoundStream.cpp index 6345b7646b..fad5dde8b0 100644 --- a/Source/Core/AudioCommon/AlsaSoundStream.cpp +++ b/Source/Core/AudioCommon/AlsaSoundStream.cpp @@ -15,9 +15,19 @@ AlsaSound::AlsaSound() { } -bool AlsaSound::Start() +AlsaSound::~AlsaSound() { - m_thread_status.store(ALSAThreadStatus::RUNNING); + 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(); +} + +bool AlsaSound::Init() +{ + m_thread_status.store(ALSAThreadStatus::PAUSED); if (!AlsaInit()) { m_thread_status.store(ALSAThreadStatus::STOPPED); @@ -28,16 +38,6 @@ bool AlsaSound::Start() return true; } -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(); -} - void AlsaSound::Update() { // don't need to do anything here. @@ -78,10 +78,11 @@ void AlsaSound::SoundLoop() m_thread_status.store(ALSAThreadStatus::STOPPED); } -void AlsaSound::SetRunning(bool running) +bool AlsaSound::SetRunning(bool running) { m_thread_status.store(running ? ALSAThreadStatus::RUNNING : ALSAThreadStatus::PAUSED); cv.notify_one(); // Notify thread that status has changed + return true; } bool AlsaSound::AlsaInit() diff --git a/Source/Core/AudioCommon/AlsaSoundStream.h b/Source/Core/AudioCommon/AlsaSoundStream.h index dfe0faf3fb..7bb71531ef 100644 --- a/Source/Core/AudioCommon/AlsaSoundStream.h +++ b/Source/Core/AudioCommon/AlsaSoundStream.h @@ -21,12 +21,12 @@ class AlsaSound final : public SoundStream #if defined(HAVE_ALSA) && HAVE_ALSA public: AlsaSound(); + ~AlsaSound() override; - bool Start() override; + bool Init() override; void SoundLoop() override; - void Stop() override; void Update() override; - void SetRunning(bool running) override; + bool SetRunning(bool running) override; static bool isValid() { return true; } private: diff --git a/Source/Core/AudioCommon/AudioCommon.cpp b/Source/Core/AudioCommon/AudioCommon.cpp index 77da1e4c70..3e04ea8f19 100644 --- a/Source/Core/AudioCommon/AudioCommon.cpp +++ b/Source/Core/AudioCommon/AudioCommon.cpp @@ -50,23 +50,15 @@ void InitSoundStream() else if (backend == BACKEND_OPENSLES && OpenSLESStream::isValid()) g_sound_stream = std::make_unique(); - if (!g_sound_stream) + if (!g_sound_stream || !g_sound_stream->Init()) { WARN_LOG(AUDIO, "Could not initialize backend %s, using %s instead.", backend.c_str(), BACKEND_NULLSOUND); g_sound_stream = std::make_unique(); } - if (!g_sound_stream->Start()) - { - ERROR_LOG(AUDIO, "Could not start backend %s, using %s instead", backend.c_str(), - BACKEND_NULLSOUND); - - g_sound_stream = std::make_unique(); - g_sound_stream->Start(); - } - UpdateSoundStream(); + SetSoundStreamRunning(true); if (SConfig::GetInstance().m_DumpAudio && !s_audio_dump_start) StartAudioDump(); @@ -76,15 +68,11 @@ void ShutdownSoundStream() { INFO_LOG(AUDIO, "Shutting down sound stream"); - if (g_sound_stream) - { - g_sound_stream->Stop(); + if (SConfig::GetInstance().m_DumpAudio && s_audio_dump_start) + StopAudioDump(); - if (SConfig::GetInstance().m_DumpAudio && s_audio_dump_start) - StopAudioDump(); - - g_sound_stream.reset(); - } + SetSoundStreamRunning(false); + g_sound_stream.reset(); INFO_LOG(AUDIO, "Done shutting down sound stream"); } @@ -161,8 +149,15 @@ void UpdateSoundStream() void SetSoundStreamRunning(bool running) { - if (g_sound_stream) - g_sound_stream->SetRunning(running); + if (!g_sound_stream) + return; + + if (g_sound_stream->SetRunning(running)) + return; + if (running) + ERROR_LOG(AUDIO, "Error starting stream."); + else + ERROR_LOG(AUDIO, "Error stopping stream."); } void SendAIBuffer(const short* samples, unsigned int num_samples) @@ -198,6 +193,8 @@ void StartAudioDump() void StopAudioDump() { + if (!g_sound_stream) + return; g_sound_stream->GetMixer()->StopLogDTKAudio(); g_sound_stream->GetMixer()->StopLogDSPAudio(); s_audio_dump_start = false; diff --git a/Source/Core/AudioCommon/CubebStream.cpp b/Source/Core/AudioCommon/CubebStream.cpp index c2f3cc30cb..754db1d957 100644 --- a/Source/Core/AudioCommon/CubebStream.cpp +++ b/Source/Core/AudioCommon/CubebStream.cpp @@ -32,7 +32,7 @@ void CubebStream::StateCallback(cubeb_stream* stream, void* user_data, cubeb_sta { } -bool CubebStream::Start() +bool CubebStream::Init() { m_ctx = CubebUtils::GetContext(); if (!m_ctx) @@ -60,37 +60,20 @@ bool CubebStream::Start() ERROR_LOG(AUDIO, "Error getting minimum latency"); INFO_LOG(AUDIO, "Minimum latency: %i frames", minimum_latency); - if (cubeb_stream_init(m_ctx.get(), &m_stream, "Dolphin Audio Output", nullptr, nullptr, nullptr, - ¶ms, std::max(BUFFER_SAMPLES, minimum_latency), DataCallback, - StateCallback, this) != CUBEB_OK) - { - ERROR_LOG(AUDIO, "Error initializing cubeb stream"); - return false; - } - - if (cubeb_stream_start(m_stream) != CUBEB_OK) - { - ERROR_LOG(AUDIO, "Error starting cubeb stream"); - return false; - } - return true; + return cubeb_stream_init(m_ctx.get(), &m_stream, "Dolphin Audio Output", nullptr, nullptr, + nullptr, ¶ms, std::max(BUFFER_SAMPLES, minimum_latency), + DataCallback, StateCallback, this) == CUBEB_OK; } -void CubebStream::SetRunning(bool running) +bool CubebStream::SetRunning(bool running) { if (running) - { - if (cubeb_stream_start(m_stream) != CUBEB_OK) - ERROR_LOG(AUDIO, "Error starting cubeb stream"); - } + return cubeb_stream_start(m_stream) == CUBEB_OK; else - { - if (cubeb_stream_stop(m_stream) != CUBEB_OK) - ERROR_LOG(AUDIO, "Error stopping cubeb stream"); - } + return cubeb_stream_stop(m_stream) == CUBEB_OK; } -void CubebStream::Stop() +CubebStream::~CubebStream() { SetRunning(false); cubeb_stream_destroy(m_stream); diff --git a/Source/Core/AudioCommon/CubebStream.h b/Source/Core/AudioCommon/CubebStream.h index f558ed1b20..894d00ac19 100644 --- a/Source/Core/AudioCommon/CubebStream.h +++ b/Source/Core/AudioCommon/CubebStream.h @@ -15,9 +15,9 @@ class CubebStream final : public SoundStream { public: - bool Start() override; - void Stop() override; - void SetRunning(bool running) override; + ~CubebStream() override; + bool Init() override; + bool SetRunning(bool running) override; void SetVolume(int) override; private: diff --git a/Source/Core/AudioCommon/NullSoundStream.cpp b/Source/Core/AudioCommon/NullSoundStream.cpp index ce1cfc6a59..c27e407a78 100644 --- a/Source/Core/AudioCommon/NullSoundStream.cpp +++ b/Source/Core/AudioCommon/NullSoundStream.cpp @@ -8,7 +8,12 @@ void NullSound::SoundLoop() { } -bool NullSound::Start() +bool NullSound::Init() +{ + return true; +} + +bool NullSound::SetRunning(bool running) { return true; } @@ -20,7 +25,3 @@ void NullSound::SetVolume(int volume) void NullSound::Update() { } - -void NullSound::Stop() -{ -} diff --git a/Source/Core/AudioCommon/NullSoundStream.h b/Source/Core/AudioCommon/NullSoundStream.h index f9fc3b9542..4bcc0c2682 100644 --- a/Source/Core/AudioCommon/NullSoundStream.h +++ b/Source/Core/AudioCommon/NullSoundStream.h @@ -9,10 +9,10 @@ class NullSound final : public SoundStream { public: - bool Start() override; + bool Init() override; void SoundLoop() override; + bool SetRunning(bool running) override; void SetVolume(int volume) override; - void Stop() override; void Update() override; static bool isValid() { return true; } diff --git a/Source/Core/AudioCommon/OpenALStream.cpp b/Source/Core/AudioCommon/OpenALStream.cpp index ed295ff18c..cb1281a88e 100644 --- a/Source/Core/AudioCommon/OpenALStream.cpp +++ b/Source/Core/AudioCommon/OpenALStream.cpp @@ -92,7 +92,7 @@ bool OpenALStream::isValid() // // AyuanX: Spec says OpenAL1.1 is thread safe already // -bool OpenALStream::Start() +bool OpenALStream::Init() { if (!palcIsExtensionPresent(nullptr, "ALC_ENUMERATION_EXT")) { @@ -124,7 +124,7 @@ bool OpenALStream::Start() return true; } -void OpenALStream::Stop() +OpenALStream::~OpenALStream() { m_run_thread.Clear(); // kick the thread if it's waiting @@ -161,7 +161,7 @@ void OpenALStream::Update() m_sound_sync_event.Set(); } -void OpenALStream::SetRunning(bool running) +bool OpenALStream::SetRunning(bool running) { if (running) { @@ -171,6 +171,7 @@ void OpenALStream::SetRunning(bool running) { palSourceStop(m_source); } + return true; } static ALenum CheckALError(const char* desc) diff --git a/Source/Core/AudioCommon/OpenALStream.h b/Source/Core/AudioCommon/OpenALStream.h index 69c7701de1..61fbf5c092 100644 --- a/Source/Core/AudioCommon/OpenALStream.h +++ b/Source/Core/AudioCommon/OpenALStream.h @@ -55,11 +55,11 @@ class OpenALStream final : public SoundStream #ifdef _WIN32 public: OpenALStream() : m_source(0) {} - bool Start() override; + ~OpenALStream() override; + bool Init() override; void SoundLoop() override; void SetVolume(int volume) override; - void Stop() override; - void SetRunning(bool running) override; + bool SetRunning(bool running) override; void Update() override; static bool isValid(); diff --git a/Source/Core/AudioCommon/OpenSLESStream.cpp b/Source/Core/AudioCommon/OpenSLESStream.cpp index a65e4407a8..b7359418ee 100644 --- a/Source/Core/AudioCommon/OpenSLESStream.cpp +++ b/Source/Core/AudioCommon/OpenSLESStream.cpp @@ -49,7 +49,7 @@ static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void* context) _assert_msg_(AUDIO, SL_RESULT_SUCCESS == result, "Couldn't enqueue audio stream."); } -bool OpenSLESStream::Start() +bool OpenSLESStream::Init() { SLresult result; // create engine @@ -110,7 +110,7 @@ bool OpenSLESStream::Start() return true; } -void OpenSLESStream::Stop() +OpenSLESStream::~OpenSLESStream() { if (bqPlayerObject != nullptr) { diff --git a/Source/Core/AudioCommon/OpenSLESStream.h b/Source/Core/AudioCommon/OpenSLESStream.h index 0521f0e2e5..fb300d1614 100644 --- a/Source/Core/AudioCommon/OpenSLESStream.h +++ b/Source/Core/AudioCommon/OpenSLESStream.h @@ -13,8 +13,9 @@ class OpenSLESStream final : public SoundStream { #ifdef ANDROID public: - bool Start() override; - void Stop() override; + ~OpenSLESStream() override; + bool Init() override; + bool SetRunning(bool running) override { return running; } static bool isValid() { return true; } private: std::thread thread; diff --git a/Source/Core/AudioCommon/PulseAudioStream.cpp b/Source/Core/AudioCommon/PulseAudioStream.cpp index 827816d4e8..e8d5090b25 100644 --- a/Source/Core/AudioCommon/PulseAudioStream.cpp +++ b/Source/Core/AudioCommon/PulseAudioStream.cpp @@ -19,7 +19,7 @@ PulseAudio::PulseAudio() : m_thread(), m_run_thread() { } -bool PulseAudio::Start() +bool PulseAudio::Init() { m_stereo = !SConfig::GetInstance().bDPL2Decoder; m_channels = m_stereo ? 2 : 5; // will tell PA we use a Stereo or 5.0 channel setup @@ -32,17 +32,12 @@ bool PulseAudio::Start() return true; } -void PulseAudio::Stop() +PulseAudio::~PulseAudio() { m_run_thread.Clear(); m_thread.join(); } -void PulseAudio::Update() -{ - // don't need to do anything here. -} - // Called on audio thread. void PulseAudio::SoundLoop() { diff --git a/Source/Core/AudioCommon/PulseAudioStream.h b/Source/Core/AudioCommon/PulseAudioStream.h index 5821007664..3ff3043d32 100644 --- a/Source/Core/AudioCommon/PulseAudioStream.h +++ b/Source/Core/AudioCommon/PulseAudioStream.h @@ -18,11 +18,10 @@ class PulseAudio final : public SoundStream #if defined(HAVE_PULSEAUDIO) && HAVE_PULSEAUDIO public: PulseAudio(); + ~PulseAudio() override; - bool Start() override; - void Stop() override; - void Update() override; - + bool Init() override; + bool SetRunning(bool running) override { return running; } static bool isValid() { return true; } void StateCallback(pa_context* c); void WriteCallback(pa_stream* s, size_t length); diff --git a/Source/Core/AudioCommon/SoundStream.h b/Source/Core/AudioCommon/SoundStream.h index 549a89178d..b5f40dea15 100644 --- a/Source/Core/AudioCommon/SoundStream.h +++ b/Source/Core/AudioCommon/SoundStream.h @@ -19,10 +19,9 @@ public: virtual ~SoundStream() {} static bool isValid() { return false; } Mixer* GetMixer() const { return m_mixer.get(); } - virtual bool Start() { return false; } + virtual bool Init() { return false; } virtual void SetVolume(int) {} virtual void SoundLoop() {} - virtual void Stop() {} virtual void Update() {} - virtual void SetRunning(bool running) {} + virtual bool SetRunning(bool running) { return false; } }; diff --git a/Source/Core/AudioCommon/XAudio2Stream.cpp b/Source/Core/AudioCommon/XAudio2Stream.cpp index b87a0e0a06..339bb96f94 100644 --- a/Source/Core/AudioCommon/XAudio2Stream.cpp +++ b/Source/Core/AudioCommon/XAudio2Stream.cpp @@ -169,7 +169,7 @@ XAudio2::~XAudio2() CoUninitialize(); } -bool XAudio2::Start() +bool XAudio2::Init() { HRESULT hr; @@ -210,15 +210,17 @@ void XAudio2::SetVolume(int volume) m_mastering_voice->SetVolume(m_volume); } -void XAudio2::SetRunning(bool running) +bool XAudio2::SetRunning(bool running) { - if (m_voice_context) - { - if (running) - m_voice_context->Play(); - else - m_voice_context->Stop(); - } + if (!m_voice_context) + return false; + + if (running) + m_voice_context->Play(); + else + m_voice_context->Stop(); + + return true; } void XAudio2::Stop() diff --git a/Source/Core/AudioCommon/XAudio2Stream.h b/Source/Core/AudioCommon/XAudio2Stream.h index ce8e137097..b3cf623797 100644 --- a/Source/Core/AudioCommon/XAudio2Stream.h +++ b/Source/Core/AudioCommon/XAudio2Stream.h @@ -51,15 +51,15 @@ private: static void* PXAudio2Create; static bool InitLibrary(); + void Stop(); public: XAudio2(); - virtual ~XAudio2(); + ~XAudio2() override; - bool Start() override; - void Stop() override; + bool Init() override; - void SetRunning(bool running) override; + bool SetRunning(bool running) override; void SetVolume(int volume) override; static bool isValid() { return InitLibrary(); } diff --git a/Source/Core/AudioCommon/XAudio2_7Stream.cpp b/Source/Core/AudioCommon/XAudio2_7Stream.cpp index bff7c7dfa1..0e596e3255 100644 --- a/Source/Core/AudioCommon/XAudio2_7Stream.cpp +++ b/Source/Core/AudioCommon/XAudio2_7Stream.cpp @@ -157,7 +157,7 @@ XAudio2_7::~XAudio2_7() CoUninitialize(); } -bool XAudio2_7::Start() +bool XAudio2_7::Init() { HRESULT hr; @@ -198,15 +198,17 @@ void XAudio2_7::SetVolume(int volume) m_mastering_voice->SetVolume(m_volume); } -void XAudio2_7::SetRunning(bool running) +bool XAudio2_7::SetRunning(bool running) { - if (m_voice_context) - { - if (running) - m_voice_context->Play(); - else - m_voice_context->Stop(); - } + if (!m_voice_context) + return false; + + if (running) + m_voice_context->Play(); + else + m_voice_context->Stop(); + + return true; } void XAudio2_7::Stop() diff --git a/Source/Core/AudioCommon/XAudio2_7Stream.h b/Source/Core/AudioCommon/XAudio2_7Stream.h index 82270003a7..e931f22708 100644 --- a/Source/Core/AudioCommon/XAudio2_7Stream.h +++ b/Source/Core/AudioCommon/XAudio2_7Stream.h @@ -56,15 +56,15 @@ private: static HMODULE m_xaudio2_dll; static bool InitLibrary(); + void Stop(); public: XAudio2_7(); - virtual ~XAudio2_7(); + ~XAudio2_7() override; - bool Start() override; - void Stop() override; + bool Init() override; - void SetRunning(bool running) override; + bool SetRunning(bool running) override; void SetVolume(int volume) override; static bool isValid() { return InitLibrary(); } From a988a8a4587bf18d8ad8dba36653b803e3a583b4 Mon Sep 17 00:00:00 2001 From: Michael M Date: Sat, 21 Oct 2017 15:12:05 -0700 Subject: [PATCH 3/3] AudioCommon: make SetSoundStreamRunning idempotent --- Source/Core/AudioCommon/AudioCommon.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Source/Core/AudioCommon/AudioCommon.cpp b/Source/Core/AudioCommon/AudioCommon.cpp index 3e04ea8f19..ceecd4b909 100644 --- a/Source/Core/AudioCommon/AudioCommon.cpp +++ b/Source/Core/AudioCommon/AudioCommon.cpp @@ -21,6 +21,7 @@ std::unique_ptr g_sound_stream; static bool s_audio_dump_start = false; +static bool s_sound_stream_running = false; namespace AudioCommon { @@ -152,6 +153,10 @@ void SetSoundStreamRunning(bool running) if (!g_sound_stream) return; + if (s_sound_stream_running == running) + return; + s_sound_stream_running = running; + if (g_sound_stream->SetRunning(running)) return; if (running)