diff --git a/SConstruct b/SConstruct index 2e7d83376b..3cdb263f48 100644 --- a/SConstruct +++ b/SConstruct @@ -256,6 +256,9 @@ if env['openal']: env['HAVE_ALSA'] = conf.CheckPKG('alsa') +env['HAVE_PULSEAUDIO'] = 0 +#env['HAVE_PULSEAUDIO'] = conf.CheckPKG('libpulse') + # OpenCL env['HAVE_OPENCL'] = 0 if env['opencl']: diff --git a/Source/Core/AudioCommon/Src/AudioCommon.cpp b/Source/Core/AudioCommon/Src/AudioCommon.cpp index 079077305c..1bea5458ff 100644 --- a/Source/Core/AudioCommon/Src/AudioCommon.cpp +++ b/Source/Core/AudioCommon/Src/AudioCommon.cpp @@ -23,6 +23,7 @@ #include "NullSoundStream.h" #include "CoreAudioSoundStream.h" #include "OpenALStream.h" +#include "PulseAudioStream.h" namespace AudioCommon { @@ -43,6 +44,8 @@ namespace AudioCommon soundStream = new OpenALStream(mixer); if (backend == BACKEND_ALSA && AlsaSound::isValid()) soundStream = new AlsaSound(mixer); + if (backend == BACKEND_PULSEAUDIO && PulseAudio::isValid()) + soundStream = new PulseAudio(mixer); if (backend == BACKEND_NULL && NullSound::isValid()) soundStream = new NullSound(mixer); @@ -101,6 +104,8 @@ namespace AudioCommon backends.push_back(BACKEND_OPENAL); if (AlsaSound::isValid()) backends.push_back(BACKEND_ALSA); + if (PulseAudio::isValid()) + backends.push_back(BACKEND_PULSEAUDIO); if (NullSound::isValid()) backends.push_back(BACKEND_NULL); diff --git a/Source/Core/AudioCommon/Src/AudioCommonConfig.h b/Source/Core/AudioCommon/Src/AudioCommonConfig.h index 1d4ad4a0e1..c18e5ce48d 100644 --- a/Source/Core/AudioCommon/Src/AudioCommonConfig.h +++ b/Source/Core/AudioCommon/Src/AudioCommonConfig.h @@ -27,6 +27,7 @@ #define BACKEND_AOSOUND "AOSound" #define BACKEND_OPENAL "OpenAL" #define BACKEND_ALSA "ALSA" +#define BACKEND_PULSEAUDIO "Pulse" #define BACKEND_NULL "NullSound" struct AudioCommonConfig diff --git a/Source/Core/AudioCommon/Src/PulseAudioStream.cpp b/Source/Core/AudioCommon/Src/PulseAudioStream.cpp new file mode 100644 index 0000000000..96d0157dca --- /dev/null +++ b/Source/Core/AudioCommon/Src/PulseAudioStream.cpp @@ -0,0 +1,88 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "Common.h" +#include "Thread.h" + +#include "PulseAudioStream.h" + +#define BUFFER_SIZE 4096 +#define BUFFER_SIZE_BYTES (BUFFER_SIZE*2*2) + +PulseAudio::PulseAudio(CMixer *mixer) : SoundStream(mixer), thread_data(0), handle(NULL) +{ + mix_buffer = new u8[BUFFER_SIZE_BYTES]; +} + +PulseAudio::~PulseAudio() +{ + delete [] mix_buffer; +} + +static void *ThreadTrampoline(void *args) +{ + reinterpret_cast(args)->SoundLoop(); + return NULL; +} + +bool PulseAudio::Start() +{ + thread = new Common::Thread(&ThreadTrampoline, this); + thread_data = 0; + return true; +} + +void PulseAudio::Stop() +{ + thread_data = 1; + delete thread; + thread = NULL; +} + +void PulseAudio::Update() +{ + // don't need to do anything here. +} + +// Called on audio thread. +void PulseAudio::SoundLoop() +{ + PulseInit(); + while (!thread_data) + { + int frames_to_deliver = 512; + m_mixer->Mix(reinterpret_cast(mix_buffer), frames_to_deliver); + } + PulseShutdown(); + thread_data = 2; +} + +bool PulseAudio::PulseInit() +{ + NOTICE_LOG(AUDIO, "Pulse successfully initialized.\n"); + return true; +} + +void PulseAudio::PulseShutdown() +{ + if (handle != NULL) + { + + handle = NULL; + } +} + diff --git a/Source/Core/AudioCommon/Src/PulseAudioStream.h b/Source/Core/AudioCommon/Src/PulseAudioStream.h new file mode 100644 index 0000000000..31cb85bb87 --- /dev/null +++ b/Source/Core/AudioCommon/Src/PulseAudioStream.h @@ -0,0 +1,71 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef _PULSE_AUDIO_STREAM_H +#define _PULSE_AUDIO_STREAM_H + +#if defined(HAVE_PULSE) && HAVE_PULSE +#include +#include +#include +#endif + +#include "Common.h" +#include "SoundStream.h" + +#include "Thread.h" + +class PulseAudio : public SoundStream +{ +#if defined(HAVE_PULSE) && HAVE_PULSE +public: + PulseAudio(CMixer *mixer); + virtual ~PulseAudio(); + + virtual bool Start(); + virtual void SoundLoop(); + virtual void Stop(); + + static bool isValid() { + return true; + } + virtual bool usesMixer() const { + return true; + } + + virtual void Update(); + +private: + bool PulseInit(); + void PulseShutdown(); + + u8 *mix_buffer; + Common::Thread *thread; + // 0 = continue + // 1 = shutdown + // 2 = done shutting down. + volatile int thread_data; + + snd_pcm_t *handle; +#else +public: + PulseAudio(CMixer *mixer) : SoundStream(mixer) {} +#endif +}; + +#endif + diff --git a/Source/Core/AudioCommon/Src/SConscript b/Source/Core/AudioCommon/Src/SConscript index 4adfaaf973..82f141e495 100644 --- a/Source/Core/AudioCommon/Src/SConscript +++ b/Source/Core/AudioCommon/Src/SConscript @@ -23,6 +23,9 @@ if acenv['HAVE_AO']: if acenv['HAVE_ALSA']: files += [ 'AlsaSoundStream.cpp' ] +if acenv['HAVE_PULSEAUDIO']: + files += [ 'PulseAudioStream.cpp' ] + if sys.platform == 'darwin': files += [ 'CoreAudioSoundStream.cpp' ] acenv['FRAMEWORKS'] = [ 'CoreAudio' ]