From 9bf630c9d616fce921900a277fb576c5bb496495 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 14 Jun 2022 03:24:23 -0700 Subject: 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). --- alc/backends/wasapi.cpp | 28 ++++++++++++++++++---------- 1 file 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 { -- cgit v1.2.3