summaryrefslogtreecommitdiff
path: root/Source/Core/AudioCommon/PulseAudioStream.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/AudioCommon/PulseAudioStream.cpp')
-rw-r--r--Source/Core/AudioCommon/PulseAudioStream.cpp99
1 files changed, 99 insertions, 0 deletions
diff --git a/Source/Core/AudioCommon/PulseAudioStream.cpp b/Source/Core/AudioCommon/PulseAudioStream.cpp
new file mode 100644
index 0000000000..13307a8fe0
--- /dev/null
+++ b/Source/Core/AudioCommon/PulseAudioStream.cpp
@@ -0,0 +1,99 @@
+// Copyright 2013 Dolphin Emulator Project
+// Licensed under GPLv2
+// Refer to the license.txt file included.
+
+#include <functional>
+
+#include "Common.h"
+#include "Thread.h"
+
+#include "PulseAudioStream.h"
+
+namespace
+{
+const size_t BUFFER_SAMPLES = 512;
+const size_t CHANNEL_COUNT = 2;
+const size_t BUFFER_SIZE = BUFFER_SAMPLES * CHANNEL_COUNT;
+}
+
+PulseAudio::PulseAudio(CMixer *mixer)
+ : SoundStream(mixer)
+ , mix_buffer(BUFFER_SIZE)
+ , thread()
+ , run_thread()
+ , pa()
+{}
+
+bool PulseAudio::Start()
+{
+ run_thread = true;
+ thread = std::thread(std::mem_fun(&PulseAudio::SoundLoop), this);
+ return true;
+}
+
+void PulseAudio::Stop()
+{
+ run_thread = false;
+ thread.join();
+}
+
+void PulseAudio::Update()
+{
+ // don't need to do anything here.
+}
+
+// Called on audio thread.
+void PulseAudio::SoundLoop()
+{
+ Common::SetCurrentThreadName("Audio thread - pulse");
+
+ if (PulseInit())
+ {
+ while (run_thread)
+ {
+ m_mixer->Mix(&mix_buffer[0], mix_buffer.size() / CHANNEL_COUNT);
+ Write(&mix_buffer[0], mix_buffer.size() * sizeof(s16));
+ }
+
+ PulseShutdown();
+ }
+}
+
+bool PulseAudio::PulseInit()
+{
+ pa_sample_spec ss = {};
+ ss.format = PA_SAMPLE_S16LE;
+ ss.channels = 2;
+ ss.rate = m_mixer->GetSampleRate();
+
+ int error;
+ pa = pa_simple_new(nullptr, "dolphin-emu", PA_STREAM_PLAYBACK,
+ nullptr, "audio", &ss, nullptr, nullptr, &error);
+
+ if (!pa)
+ {
+ ERROR_LOG(AUDIO, "PulseAudio failed to initialize: %s",
+ pa_strerror(error));
+ return false;
+ }
+ else
+ {
+ NOTICE_LOG(AUDIO, "Pulse successfully initialized.");
+ return true;
+ }
+}
+
+void PulseAudio::PulseShutdown()
+{
+ pa_simple_free(pa);
+}
+
+void PulseAudio::Write(const void *data, size_t length)
+{
+ int error;
+ if (pa_simple_write(pa, data, length, &error) < 0)
+ {
+ ERROR_LOG(AUDIO, "PulseAudio failed to write data: %s",
+ pa_strerror(error));
+ }
+}