Skip to content
Permalink
Browse files
Merge pull request #6134 from ligfx/soundstreamlifecycle
SoundStream: change Start/Stop lifecycle to Init/SetRunning/destruct
  • Loading branch information
degasus committed Jan 2, 2018
2 parents 26a9957 + a988a8a commit cb168b1
Show file tree
Hide file tree
Showing 18 changed files with 111 additions and 113 deletions.
@@ -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();
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;
@@ -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;
}
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;
}

if (cubeb_stream_start(m_stream) != CUBEB_OK)
{
ERROR_LOG(AUDIO, "Error starting cubeb stream");
return false;
}
return true;
bool CubebStream::SetRunning(bool running)
{
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,19 +8,20 @@ void NullSound::SoundLoop()
{
}

bool NullSound::Start()
bool NullSound::Init()
{
return true;
}

void NullSound::SetVolume(int volume)
bool NullSound::SetRunning(bool running)
{
return true;
}

void NullSound::Update()
void NullSound::SetVolume(int volume)
{
}

void NullSound::Stop()
void NullSound::Update()
{
}
@@ -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 @@ class SoundStream
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; }
};

0 comments on commit cb168b1

Please sign in to comment.