Merge pull request #6134 from ligfx/soundstreamlifecycle
SoundStream: change Start/Stop lifecycle to Init/SetRunning/destruct
This commit is contained in:
commit
cb168b1843
|
@ -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()
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
std::unique_ptr<SoundStream> g_sound_stream;
|
||||
|
||||
static bool s_audio_dump_start = false;
|
||||
static bool s_sound_stream_running = false;
|
||||
|
||||
namespace AudioCommon
|
||||
{
|
||||
|
@ -50,23 +51,15 @@ void InitSoundStream()
|
|||
else if (backend == BACKEND_OPENSLES && OpenSLESStream::isValid())
|
||||
g_sound_stream = std::make_unique<OpenSLESStream>();
|
||||
|
||||
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<NullSound>();
|
||||
}
|
||||
|
||||
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<NullSound>();
|
||||
g_sound_stream->Start();
|
||||
}
|
||||
|
||||
UpdateSoundStream();
|
||||
SetSoundStreamRunning(true);
|
||||
|
||||
if (SConfig::GetInstance().m_DumpAudio && !s_audio_dump_start)
|
||||
StartAudioDump();
|
||||
|
@ -76,15 +69,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();
|
||||
|
||||
SetSoundStreamRunning(false);
|
||||
g_sound_stream.reset();
|
||||
}
|
||||
|
||||
INFO_LOG(AUDIO, "Done shutting down sound stream");
|
||||
}
|
||||
|
@ -161,8 +150,19 @@ void UpdateSoundStream()
|
|||
|
||||
void SetSoundStreamRunning(bool running)
|
||||
{
|
||||
if (g_sound_stream)
|
||||
g_sound_stream->SetRunning(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)
|
||||
ERROR_LOG(AUDIO, "Error starting stream.");
|
||||
else
|
||||
ERROR_LOG(AUDIO, "Error stopping stream.");
|
||||
}
|
||||
|
||||
void SendAIBuffer(const short* samples, unsigned int num_samples)
|
||||
|
@ -198,6 +198,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;
|
||||
|
|
|
@ -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,28 +60,22 @@ 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;
|
||||
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;
|
||||
}
|
||||
|
||||
if (cubeb_stream_start(m_stream) != CUBEB_OK)
|
||||
bool CubebStream::SetRunning(bool running)
|
||||
{
|
||||
ERROR_LOG(AUDIO, "Error starting cubeb stream");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
if (running)
|
||||
return cubeb_stream_start(m_stream) == CUBEB_OK;
|
||||
else
|
||||
return cubeb_stream_stop(m_stream) == CUBEB_OK;
|
||||
}
|
||||
|
||||
void CubebStream::Stop()
|
||||
CubebStream::~CubebStream()
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
|
|
@ -15,8 +15,9 @@
|
|||
class CubebStream final : public SoundStream
|
||||
{
|
||||
public:
|
||||
bool Start() override;
|
||||
void Stop() override;
|
||||
~CubebStream() override;
|
||||
bool Init() override;
|
||||
bool SetRunning(bool running) override;
|
||||
void SetVolume(int) override;
|
||||
|
||||
private:
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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; }
|
||||
};
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
if (m_voice_context)
|
||||
bool XAudio2::SetRunning(bool running)
|
||||
{
|
||||
if (!m_voice_context)
|
||||
return false;
|
||||
|
||||
if (running)
|
||||
m_voice_context->Play();
|
||||
else
|
||||
m_voice_context->Stop();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void XAudio2::Stop()
|
||||
|
|
|
@ -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(); }
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
if (m_voice_context)
|
||||
bool XAudio2_7::SetRunning(bool running)
|
||||
{
|
||||
if (!m_voice_context)
|
||||
return false;
|
||||
|
||||
if (running)
|
||||
m_voice_context->Play();
|
||||
else
|
||||
m_voice_context->Stop();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void XAudio2_7::Stop()
|
||||
|
|
|
@ -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(); }
|
||||
|
|
Loading…
Reference in New Issue