diff options
author | Chris Robinson <[email protected]> | 2022-06-14 03:24:23 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2022-06-14 03:24:23 -0700 |
commit | 9bf630c9d616fce921900a277fb576c5bb496495 (patch) | |
tree | 94013969be051db8108d5991a244be2fa5668819 | |
parent | 11d148502d8131fdada39b4421dbfe4cf4899dd9 (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).
-rw-r--r-- | alc/backends/wasapi.cpp | 28 |
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 { |