Merge pull request #6134 from ligfx/soundstreamlifecycle

SoundStream: change Start/Stop lifecycle to Init/SetRunning/destruct
This commit is contained in:
Markus Wick 2018-01-02 09:58:36 +01:00 committed by GitHub
commit cb168b1843
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 113 additions and 115 deletions

View File

@ -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()

View File

@ -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:

View File

@ -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();
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 +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;

View File

@ -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,
&params, 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, &params, std::max(BUFFER_SAMPLES, minimum_latency),
DataCallback, StateCallback, this) == CUBEB_OK;
}
void CubebStream::Stop()
bool CubebStream::SetRunning(bool running)
{
if (cubeb_stream_stop(m_stream) != CUBEB_OK)
{
ERROR_LOG(AUDIO, "Error stopping cubeb stream");
}
if (running)
return cubeb_stream_start(m_stream) == CUBEB_OK;
else
return cubeb_stream_stop(m_stream) == CUBEB_OK;
}
CubebStream::~CubebStream()
{
SetRunning(false);
cubeb_stream_destroy(m_stream);
m_ctx.reset();
}

View File

@ -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:

View File

@ -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()
{
}

View File

@ -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; }

View File

@ -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)

View File

@ -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();

View File

@ -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)
{

View File

@ -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;

View File

@ -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()
{

View File

@ -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);

View File

@ -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; }
};

View File

@ -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()

View File

@ -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(); }

View File

@ -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()

View File

@ -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(); }