diff options
author | Rainer Hochecker <fernetmenta@online.de> | 2014-01-15 03:59:52 -0800 |
---|---|---|
committer | Rainer Hochecker <fernetmenta@online.de> | 2014-01-15 03:59:52 -0800 |
commit | cfd44af689eb91e762ea8ac409661744b6c7b5c4 (patch) | |
tree | 640f50eaf74a6bbdbf090b051ca657e3c1af5333 | |
parent | 89d728d87c8c41a5934b95b8baa4a6c863aa26fd (diff) | |
parent | 1db31fb50d56fdf41f538755f2d1100ecff42ee2 (diff) |
Merge pull request #4023 from FernetMenta/aefixes
ActiveAE decides whether to open a fallback sink
-rw-r--r-- | xbmc/cores/AudioEngine/AESinkFactory.cpp | 160 | ||||
-rw-r--r-- | xbmc/cores/AudioEngine/AESinkFactory.h | 3 | ||||
-rw-r--r-- | xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp | 23 |
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"); |