2013-12-06, 02:53
So it turns out that WASAPI simply refuses to initialize the 3.0/5.0/7.0 channel layouts on my system, resulting in silence whenever XBMC decides to choose one of these as destination layout. I can reproduce by forcing anything to up- or downmix to 3.0, 5.0 or 7.0 (e.g. by changing XBMC audio settings to the respective layout). The "find something that works" loop in CAESinkWASAPI::InitializeExclusive will fail because it only loops through sample rates and formats, but not through channel layouts.
I "fixed" it by force-adding a LFE channel to anything that has a FC channel and is not mono - and might therefore result in one of the nonworking layouts.
I guess the proper fix would be that XBMC does not try to use channel layouts that aren't supported by the output device, just like it does with sample formats and -rates.
Here's my quick&dirty fix for anybody who's interested (diff based on Git rev. e3a145 with pull request 3744 applied):
I "fixed" it by force-adding a LFE channel to anything that has a FC channel and is not mono - and might therefore result in one of the nonworking layouts.
I guess the proper fix would be that XBMC does not try to use channel layouts that aren't supported by the output device, just like it does with sample formats and -rates.
Here's my quick&dirty fix for anybody who's interested (diff based on Git rev. e3a145 with pull request 3744 applied):
Code:
diff --git "a/xbmc/cores/AudioEngine/Utils/AEChannelInfo.cpp" "b/xbmc/cores/AudioEngine/Utils/AEChannelInfo.cpp"
index c0963c9..7df0a00 100644
--- "a/xbmc/cores/AudioEngine/Utils/AEChannelInfo.cpp"
+++ "b/xbmc/cores/AudioEngine/Utils/AEChannelInfo.cpp"
@@ -56,6 +56,7 @@ void CAEChannelInfo::ResolveChannels(const CAEChannelInfo& rhs, bool mix)
bool srcHasRL = false;
bool srcHasRR = false;
bool srcHasBC = false;
+ bool srcHasFC = false;
bool dstHasSL = false;
bool dstHasSR = false;
@@ -85,6 +86,7 @@ void CAEChannelInfo::ResolveChannels(const CAEChannelInfo& rhs, bool mix)
case AE_CH_BL: srcHasRL = true; break;
case AE_CH_BR: srcHasRR = true; break;
case AE_CH_BC: srcHasBC = true; break;
+ case AE_CH_FC: srcHasFC = true; break;
default:
break;
}
@@ -136,6 +138,10 @@ void CAEChannelInfo::ResolveChannels(const CAEChannelInfo& rhs, bool mix)
newInfo += AE_CH_SR;
}
+ // Add LFE to 3.0/5.0/7.0 formats
+ if (srcHasFC && !newInfo.HasChannel(AE_CH_LFE))
+ newInfo += AE_CH_LFE;
+
*this = newInfo;
}