aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRainer Hochecker <fernetmenta@online.de>2014-01-15 03:59:52 -0800
committerRainer Hochecker <fernetmenta@online.de>2014-01-15 03:59:52 -0800
commitcfd44af689eb91e762ea8ac409661744b6c7b5c4 (patch)
tree640f50eaf74a6bbdbf090b051ca657e3c1af5333
parent89d728d87c8c41a5934b95b8baa4a6c863aa26fd (diff)
parent1db31fb50d56fdf41f538755f2d1100ecff42ee2 (diff)
Merge pull request #4023 from FernetMenta/aefixes
ActiveAE decides whether to open a fallback sink
-rw-r--r--xbmc/cores/AudioEngine/AESinkFactory.cpp160
-rw-r--r--xbmc/cores/AudioEngine/AESinkFactory.h3
-rw-r--r--xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp23
3 files changed, 118 insertions, 68 deletions
diff --git a/xbmc/cores/AudioEngine/AESinkFactory.cpp b/xbmc/cores/AudioEngine/AESinkFactory.cpp
index 8427cdf442..66ae5035b2 100644
--- a/xbmc/cores/AudioEngine/AESinkFactory.cpp
+++ b/xbmc/cores/AudioEngine/AESinkFactory.cpp
@@ -61,7 +61,7 @@ void CAESinkFactory::ParseDevice(std::string &device, std::string &driver)
#elif defined(TARGET_ANDROID)
driver == "AUDIOTRACK" ||
#elif defined(TARGET_RASPBERRY_PI)
- driver == "Pi" ||
+ driver == "PI" ||
#elif defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
#if defined(HAS_ALSA)
driver == "ALSA" ||
@@ -71,7 +71,8 @@ void CAESinkFactory::ParseDevice(std::string &device, std::string &driver)
#endif
driver == "OSS" ||
#endif
- driver == "PROFILER")
+ driver == "PROFILER" ||
+ driver == "NULL")
device = device.substr(pos + 1, device.length() - pos - 1);
else
driver.clear();
@@ -80,104 +81,127 @@ void CAESinkFactory::ParseDevice(std::string &device, std::string &driver)
driver.clear();
}
-#define TRY_SINK(SINK) \
-{ \
- tmpFormat = desiredFormat; \
- tmpDevice = device; \
- sink = new CAESink ##SINK(); \
- if (sink->Initialize(tmpFormat, tmpDevice)) \
- { \
- desiredFormat = tmpFormat; \
- device = tmpDevice; \
- return sink; \
- } \
- sink->Deinitialize(); \
- delete sink; \
- sink = NULL; \
-}
-
-IAESink *CAESinkFactory::Create(std::string &device, AEAudioFormat &desiredFormat, bool rawPassthrough)
+IAESink *CAESinkFactory::TrySink(std::string &driver, std::string &device, AEAudioFormat &format)
{
- // extract the driver from the device string if it exists
- std::string driver;
- ParseDevice(device, driver);
-
- AEAudioFormat tmpFormat;
- IAESink *sink;
- std::string tmpDevice;
-
- if (driver == "PROFILER")
- TRY_SINK(Profiler);
+ IAESink *sink = NULL;
+ if (driver == "NULL")
+ sink = new CAESinkNULL();
#if defined(TARGET_WINDOWS)
- if (driver == "WASAPI")
- TRY_SINK(WASAPI)
- else
- TRY_SINK(DirectSound) // always fall back to DirectSound
-
+ else if (driver == "WASAPI")
+ sink = new CAESinkWASAPI();
+ else if (driver == "DIRECTSOUND")
+ sink = new CAESinkDirectSound();
#elif defined(TARGET_ANDROID)
- if (driver.empty() || driver == "AUDIOTRACK")
- TRY_SINK(AUDIOTRACK)
-
+ sink = new CAESinkAUDIOTRACK();
#elif defined(TARGET_RASPBERRY_PI)
- if (driver.empty() || driver == "Pi")
- TRY_SINK(Pi)
-
+ sink = new CAESinkPi();
#elif defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
#if defined(HAS_PULSEAUDIO)
- if (driver.empty() || driver == "PULSE")
- TRY_SINK(PULSE)
+ else if (driver == "PULSE")
+ sink = new CAESinkPULSE();
#endif
-
#if defined(HAS_ALSA)
- if (driver.empty() || driver == "ALSA")
- TRY_SINK(ALSA)
+ else if (driver == "ALSA")
+ sink = new CAESinkALSA();
#endif
-
- if (driver.empty() || driver == "OSS")
- TRY_SINK(OSS)
+ else if (driver == "OSS")
+ sink = new CAESinkOSS();
#endif
- // complete failure.
- TRY_SINK(NULL);
+ if (!sink)
+ return NULL;
- // should never get here
- ASSERT(false);
+ if (sink->Initialize(format, device))
+ {
+ return sink;
+ }
+ sink->Deinitialize();
+ delete sink;
return NULL;
}
-#define ENUMERATE_SINK(SINK, force) { \
- AESinkInfo info; \
- info.m_sinkName = #SINK; \
- CAESink ##SINK::EnumerateDevicesEx(info.m_deviceInfoList, force); \
- if(!info.m_deviceInfoList.empty()) \
- list.push_back(info); \
+IAESink *CAESinkFactory::Create(std::string &device, AEAudioFormat &desiredFormat, bool rawPassthrough)
+{
+ // extract the driver from the device string if it exists
+ std::string driver;
+ ParseDevice(device, driver);
+
+ AEAudioFormat tmpFormat = desiredFormat;
+ IAESink *sink;
+ std::string tmpDevice = device;
+
+ sink = TrySink(driver, tmpDevice, tmpFormat);
+ if (sink)
+ {
+ desiredFormat = tmpFormat;
+ return sink;
+ }
+
+ return NULL;
}
void CAESinkFactory::EnumerateEx(AESinkInfoList &list, bool force)
{
+ AESinkInfo info;
#if defined(TARGET_WINDOWS)
- ENUMERATE_SINK(DirectSound, force);
- ENUMERATE_SINK(WASAPI, force);
+
+ info.m_deviceInfoList.clear();
+ info.m_sinkName = "DirectSound";
+ CAESinkDirectSound::EnumerateDevicesEx(info.m_deviceInfoList, force);
+ if(!info.m_deviceInfoList.empty())
+ list.push_back(info);
+
+ info.m_deviceInfoList.clear();
+ info.m_sinkName = "WASAPI";
+ CAESinkWASAPI::EnumerateDevicesEx(info.m_deviceInfoList, force);
+ if(!info.m_deviceInfoList.empty())
+ list.push_back(info);
+
#elif defined(TARGET_ANDROID)
- ENUMERATE_SINK(AUDIOTRACK, force);
+
+ info.m_deviceInfoList.clear();
+ info.m_sinkName = "AUDIOTRACK";
+ CAESinkAUDIOTRACK::EnumerateDevicesEx(info.m_deviceInfoList, force);
+ if(!info.m_deviceInfoList.empty())
+ list.push_back(info);
+
#elif defined(TARGET_RASPBERRY_PI)
- ENUMERATE_SINK(Pi, force);
+
+ info.m_deviceInfoList.clear();
+ info.m_sinkName = "PI";
+ CAESinkPi::EnumerateDevicesEx(info.m_deviceInfoList, force);
+ if(!info.m_deviceInfoList.empty())
+ list.push_back(info);
+
#elif defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
- #if defined(HAS_PULSEAUDIO)
- ENUMERATE_SINK(PULSE, force);
- #endif
- if (!list.empty()) {
+ #if defined(HAS_PULSEAUDIO)
+ info.m_deviceInfoList.clear();
+ info.m_sinkName = "PULSE";
+ CAESinkPULSE::EnumerateDevicesEx(info.m_deviceInfoList, force);
+ if(!info.m_deviceInfoList.empty())
+ {
+ list.push_back(info);
return;
}
+ #endif
#if defined(HAS_ALSA)
- ENUMERATE_SINK(ALSA, force);
+ info.m_deviceInfoList.clear();
+ info.m_sinkName = "ALSA";
+ CAESinkALSA::EnumerateDevicesEx(info.m_deviceInfoList, force);
+ if(!info.m_deviceInfoList.empty())
+ list.push_back(info);
#endif
- ENUMERATE_SINK(OSS, force);
+ info.m_deviceInfoList.clear();
+ info.m_sinkName = "OSS";
+ CAESinkOSS::EnumerateDevicesEx(info.m_deviceInfoList, force);
+ if(!info.m_deviceInfoList.empty())
+ list.push_back(info);
+
#endif
}
diff --git a/xbmc/cores/AudioEngine/AESinkFactory.h b/xbmc/cores/AudioEngine/AESinkFactory.h
index 8f1b224dd4..a87e58e0d6 100644
--- a/xbmc/cores/AudioEngine/AESinkFactory.h
+++ b/xbmc/cores/AudioEngine/AESinkFactory.h
@@ -41,5 +41,8 @@ public:
static void ParseDevice(std::string &device, std::string &driver);
static IAESink *Create(std::string &device, AEAudioFormat &desiredFormat, bool rawPassthrough);
static void EnumerateEx(AESinkInfoList &list, bool force = false); /* The force flag can be used to indicate the rescan devices */
+
+protected:
+ static IAESink *TrySink(std::string &driver, std::string &device, AEAudioFormat &format);
};
diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp
index d921846ce9..55e2ca99bc 100644
--- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp
+++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp
@@ -657,6 +657,29 @@ void CActiveAESink::OpenSink()
CLog::Log(LOGDEBUG, "CActiveAESink::OpenSink - trying to open device %s", device.c_str());
m_sink = CAESinkFactory::Create(device, m_sinkFormat, passthrough);
+ // try first device in out list
+ if (!m_sink && !m_sinkInfoList.empty())
+ {
+ driver = m_sinkInfoList.front().m_sinkName;
+ device = m_sinkInfoList.front().m_deviceInfoList.front().m_deviceName;
+ GetDeviceFriendlyName(device);
+ if (!driver.empty())
+ device = driver + ":" + device;
+ m_sinkFormat = m_requestedFormat;
+ CLog::Log(LOGDEBUG, "CActiveAESink::OpenSink - trying to open device %s", device.c_str());
+ m_sink = CAESinkFactory::Create(device, m_sinkFormat, passthrough);
+ }
+
+ // open NULL sink
+ // TODO: should not be required by ActiveAE
+ if (!m_sink)
+ {
+ device = "NULL:NULL";
+ m_sinkFormat = m_requestedFormat;
+ CLog::Log(LOGDEBUG, "CActiveAESink::OpenSink - open NULL sink");
+ m_sink = CAESinkFactory::Create(device, m_sinkFormat, passthrough);
+ }
+
if (!m_sink)
{
CLog::Log(LOGERROR, "CActiveAESink::OpenSink - no sink was returned");