Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

[AE/Pulseaudio] use xbmc gui audio device for skin/menu sound playbac…

…k and stream audio playback
  • Loading branch information...
commit 521da3d2558c6b709fa3a88d6bd4664c3e6297d8 1 parent 44eda77
@s7mx1 authored
19 xbmc/cores/AudioEngine/Engines/PulseAE/PulseAE.cpp
@@ -30,6 +30,7 @@
#include <pulse/pulseaudio.h>
#include <pulse/simple.h>
#include "guilib/LocalizeStrings.h"
+#include "settings/GUISettings.h"
/* Static helpers */
static const char *ContextStateToString(pa_context_state s)
@@ -353,7 +354,7 @@ static void SinkInfo(pa_context *c, const pa_sink_info *i, int eol, void *userda
CStdString desc, sink;
desc.Format("%s (PulseAudio)", i->description);
- sink.Format("pulse:%s@default", i->name);
+ sink.Format("%s", i->name);
sinkStruct->list->push_back(AEDevice(desc, sink));
CLog::Log(LOGDEBUG, "PulseAudio: Found %s with devicestring %s", desc.c_str(), sink.c_str());
@@ -375,7 +376,7 @@ void CPulseAE::EnumerateOutputDevices(AEDeviceList &devices, bool passthrough)
sinkStruct.list = &devices;
CStdString def;
def.Format("%s (PulseAudio)",g_localizeStrings.Get(409).c_str());
- devices.push_back(AEDevice(def, "pulse:default@default"));
+ devices.push_back(AEDevice(def, "default"));
SinkInfo, &sinkStruct), m_MainLoop, "EnumerateAudioSinks");
@@ -409,4 +410,18 @@ void CPulseAE::SetMute(const bool enabled)
m_muted = enabled;
+ Return audio device name set within XBMC GUI. If passthrough is set to true
+ audio passthrough device name will be returned.
+const char* CPulseAE::GetAudioDevice(bool passthrough)
+ std::string m_outputDevice;
+ if (passthrough)
+ m_outputDevice = g_guiSettings.GetString("audiooutput.passthroughdevice");
+ else
+ m_outputDevice = g_guiSettings.GetString("audiooutput.audiodevice");
+ return m_outputDevice.c_str();
1  xbmc/cores/AudioEngine/Engines/PulseAE/PulseAE.h
@@ -69,6 +69,7 @@ class CPulseAE : public IAE
virtual void SetMute(const bool enabled);
virtual bool IsMuted() { return m_muted; }
virtual void SetSoundMode(const int mode) {}
+ static const char* GetAudioDevice(bool passthrough);
fritsch added a note

You use this as a std::string the whole time, what do you really need here, const char* or std::string?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
virtual bool SupportsRaw() { return true; }
7 xbmc/cores/AudioEngine/Engines/PulseAE/PulseAESound.cpp
@@ -22,6 +22,7 @@
#include "PulseAESound.h"
+#include "PulseAE.h"
fritsch added a note

Yeah there is no real Sink right now, so the sound has to know the engine. This should not be like this, if there would be a Sink that knows what it should play and is properly initialized...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
#include "AEFactory.h"
#include "Utils/AEUtil.h"
#include "utils/log.h"
@@ -138,7 +139,11 @@ void CPulseAESound::Play()
m_maxVolume = CAEFactory::GetEngine()->GetVolume();
pa_volume_t paVolume = CAEUtil::PercentToPulseVolume((double)(m_volume * m_maxVolume));
- m_op = pa_context_play_sample(m_context, m_pulseName.c_str(), NULL, paVolume, NULL, NULL);
+ std::string m_outputDevice = CPulseAE::GetAudioDevice(false);
fritsch added a note

m_something are class fields.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ if (m_outputDevice == "default")
+ m_op = pa_context_play_sample(m_context, m_pulseName.c_str(), NULL, paVolume, NULL, NULL);
+ else
+ m_op = pa_context_play_sample(m_context, m_pulseName.c_str(), m_outputDevice.c_str(), paVolume, NULL, NULL);
15 xbmc/cores/AudioEngine/Engines/PulseAE/PulseAEStream.cpp
@@ -22,6 +22,7 @@
#include "PulseAEStream.h"
+#include "PulseAE.h"
fritsch added a note

Same as above

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
#include "AEFactory.h"
#include "Utils/AEUtil.h"
#include "Utils/AEUtil.h"
@@ -64,6 +65,8 @@ CPulseAEStream::CPulseAEStream(pa_context *context, pa_threaded_mainloop *mainLo
m_channelLayout = channelLayout;
m_options = options;
+ bool m_passthrough = false;
m_DrainOperation = NULL;
m_slave = NULL;
@@ -156,6 +159,8 @@ CPulseAEStream::CPulseAEStream(pa_context *context, pa_threaded_mainloop *mainLo
pa_format_info_set_channels (info[0], m_SampleSpec.channels);
pa_format_info_set_sample_format(info[0], m_SampleSpec.format);
m_Stream = pa_stream_new_extended(m_Context, "audio stream", info, 1, NULL);
+ if (!info[0]->encoding == PA_ENCODING_PCM)
+ m_passthrough = true;
m_Stream = pa_stream_new(m_Context, "audio stream", &m_SampleSpec, &map);
@@ -178,7 +183,14 @@ CPulseAEStream::CPulseAEStream(pa_context *context, pa_threaded_mainloop *mainLo
- if (pa_stream_connect_playback(m_Stream, NULL, NULL, (pa_stream_flags)flags, &m_ChVolume, NULL) < 0)
+ int pa_state;
+ std::string m_outputDevice = CPulseAE::GetAudioDevice(m_passthrough);
+ if (m_outputDevice == "default")
+ pa_state = pa_stream_connect_playback(m_Stream, NULL, NULL, (pa_stream_flags)flags, &m_ChVolume, NULL);
+ else
+ pa_state = pa_stream_connect_playback(m_Stream, m_outputDevice.c_str(), NULL, (pa_stream_flags)flags, &m_ChVolume, NULL);
+ if (pa_state < 0)
CLog::Log(LOGERROR, "PulseAudio: Failed to connect stream to output");
@@ -209,6 +221,7 @@ CPulseAEStream::CPulseAEStream(pa_context *context, pa_threaded_mainloop *mainLo
m_Initialized = true;
CLog::Log(LOGINFO, "PulseAEStream::Initialized");
+ CLog::Log(LOGINFO, " Sink Output : %s", m_outputDevice.c_str());
fritsch added a note

Stream and Sound should just play, no matter they know which device is currently used. Now you make a lot of work at points where it should not be. We have the PulseAE already, that could manage this for us.

fritsch added a note

It is okay to include the stuff from above as you have to know some things about Audio Setup and so on - but device selection should be done either more up in Engine or way more down in the Sink directly. We can talk on irc if you want.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
CLog::Log(LOGINFO, " Sample Rate : %d", m_sampleRate);
CLog::Log(LOGINFO, " Sample Format : %s", CAEUtil::DataFormatToStr(m_format));
CLog::Log(LOGINFO, " Channel Count : %d", m_channelLayout.Count());

2 comments on commit 521da3d


What's your irc details?


just fritsch on freenode.

Please sign in to comment.
Something went wrong with that request. Please try again.