aboutsummaryrefslogtreecommitdiffstats
path: root/alc/backends
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2022-06-14 03:24:23 -0700
committerChris Robinson <[email protected]>2022-06-14 03:24:23 -0700
commit9bf630c9d616fce921900a277fb576c5bb496495 (patch)
tree94013969be051db8108d5991a244be2fa5668819 /alc/backends
parent11d148502d8131fdada39b4421dbfe4cf4899dd9 (diff)
Handle a blank channel mask from WASAPI
Without a channel mask, the channels are treated as "raw" or unknown. Auto- detection will only go up to stereo (assuming the first two channels are front- left and front-right), while explicit requests will work as long as there are enough channels (the user is responsible for ensuring a correct setup).
Diffstat (limited to 'alc/backends')
-rw-r--r--alc/backends/wasapi.cpp28
1 files changed, 18 insertions, 10 deletions
diff --git a/alc/backends/wasapi.cpp b/alc/backends/wasapi.cpp
index ab24a85e..dd928299 100644
--- a/alc/backends/wasapi.cpp
+++ b/alc/backends/wasapi.cpp
@@ -882,6 +882,10 @@ HRESULT WasapiPlayback::resetProxy()
mDevice->Frequency = OutputType.Format.nSamplesPerSec;
if(!mDevice->Flags.test(ChannelsRequest))
{
+ /* If not requesting a channel configuration, auto-select given what
+ * fits the mask's lsb (to ensure no gaps in the output channels). If
+ * there's no mask, we can only assume mono or stereo.
+ */
const uint32_t chancount{OutputType.Format.nChannels};
const DWORD chanmask{OutputType.dwChannelMask};
if(chancount >= 8 && (chanmask&X71Mask) == X7DOT1)
@@ -897,9 +901,9 @@ HRESULT WasapiPlayback::resetProxy()
}
else if(chancount >= 4 && (chanmask&QuadMask) == QUAD)
mDevice->FmtChans = DevFmtQuad;
- else if(chancount >= 2 && (chanmask&StereoMask) == STEREO)
+ else if(chancount >= 2 && ((chanmask&StereoMask) == STEREO || !chanmask))
mDevice->FmtChans = DevFmtStereo;
- else if(chancount >= 1 && (chanmask&MonoMask) == MONO)
+ else if(chancount >= 1 && ((chanmask&MonoMask) == MONO || !chanmask))
mDevice->FmtChans = DevFmtMono;
else
ERR("Unhandled channel config: %d -- 0x%08lx\n", chancount, chanmask);
@@ -1015,27 +1019,31 @@ HRESULT WasapiPlayback::resetProxy()
bool chansok{false};
if(mDevice->Flags.test(ChannelsRequest))
{
+ /* When requesting a channel configuration, make sure it fits the
+ * mask's lsb (to ensure no gaps in the output channels). If
+ * there's no mask, assume the request fits with enough channels.
+ */
switch(mDevice->FmtChans)
{
case DevFmtMono:
- chansok = (chancount >= 1 && (chanmask&MonoMask) == MONO);
+ chansok = (chancount >= 1 && ((chanmask&MonoMask) == MONO || !chanmask));
break;
case DevFmtStereo:
- chansok = (chancount >= 2 && (chanmask&StereoMask) == STEREO);
+ chansok = (chancount >= 2 && ((chanmask&StereoMask) == STEREO || !chanmask));
break;
case DevFmtQuad:
- chansok = (chancount >= 4 && (chanmask&QuadMask) == QUAD);
+ chansok = (chancount >= 4 && ((chanmask&QuadMask) == QUAD || !chanmask));
break;
case DevFmtX51:
chansok = (chancount >= 6 && ((chanmask&X51Mask) == X5DOT1
- || (chanmask&X51RearMask) == X5DOT1REAR));
+ || (chanmask&X51RearMask) == X5DOT1REAR || !chanmask));
break;
case DevFmtX61:
- chansok = (chancount >= 7 && (chanmask&X61Mask) == X6DOT1);
+ chansok = (chancount >= 7 && ((chanmask&X61Mask) == X6DOT1 || !chanmask));
break;
case DevFmtX71:
case DevFmtX3D71:
- chansok = (chancount >= 8 && (chanmask&X71Mask) == X7DOT1);
+ chansok = (chancount >= 8 && ((chanmask&X71Mask) == X7DOT1 || !chanmask));
break;
case DevFmtAmbi3D:
break;
@@ -1052,9 +1060,9 @@ HRESULT WasapiPlayback::resetProxy()
mDevice->FmtChans = DevFmtX51;
else if(chancount >= 4 && (chanmask&QuadMask) == QUAD)
mDevice->FmtChans = DevFmtQuad;
- else if(chancount >= 2 && (chanmask&StereoMask) == STEREO)
+ else if(chancount >= 2 && ((chanmask&StereoMask) == STEREO || !chanmask))
mDevice->FmtChans = DevFmtStereo;
- else if(chancount >= 1 && (chanmask&MonoMask) == MONO)
+ else if(chancount >= 1 && ((chanmask&MonoMask) == MONO || !chanmask))
mDevice->FmtChans = DevFmtMono;
else
{