diff options
author | Chris Robinson <[email protected]> | 2020-06-15 18:50:59 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2020-06-15 20:21:54 -0700 |
commit | bd0144065a343c936b6a12be6e546e114575217b (patch) | |
tree | 391a13f7bf6d71e228c30da12e75af8432a787da /alc/backends/base.cpp | |
parent | c142b49981b57bdd50f20b6e916ead92ca9f044d (diff) |
Set channel labels from WFX channel masks
Diffstat (limited to 'alc/backends/base.cpp')
-rw-r--r-- | alc/backends/base.cpp | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/alc/backends/base.cpp b/alc/backends/base.cpp index 45a1c25d..5c53e3b8 100644 --- a/alc/backends/base.cpp +++ b/alc/backends/base.cpp @@ -6,12 +6,20 @@ #include <atomic> #include <thread> +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#include <mmreg.h> +#endif + #include "AL/al.h" #include "alcmain.h" #include "alexcpt.h" #include "alnumeric.h" +#include "aloptional.h" #include "atomic.h" +#include "logging.h" bool BackendBase::reset() @@ -140,3 +148,50 @@ void BackendBase::setDefaultChannelOrder() break; } } + +#ifdef _WIN32 +void BackendBase::setChannelOrderFromWFXMask(ALuint chanmask) +{ + auto get_channel = [](const DWORD chanbit) noexcept -> al::optional<Channel> + { + switch(chanbit) + { + case SPEAKER_FRONT_LEFT: return al::make_optional(FrontLeft); + case SPEAKER_FRONT_RIGHT: return al::make_optional(FrontRight); + case SPEAKER_FRONT_CENTER: return al::make_optional(FrontCenter); + case SPEAKER_LOW_FREQUENCY: return al::make_optional(LFE); + case SPEAKER_BACK_LEFT: return al::make_optional(BackLeft); + case SPEAKER_BACK_RIGHT: return al::make_optional(BackRight); + case SPEAKER_FRONT_LEFT_OF_CENTER: break; + case SPEAKER_FRONT_RIGHT_OF_CENTER: break; + case SPEAKER_BACK_CENTER: return al::make_optional(BackCenter); + case SPEAKER_SIDE_LEFT: return al::make_optional(SideLeft); + case SPEAKER_SIDE_RIGHT: return al::make_optional(SideRight); + case SPEAKER_TOP_CENTER: return al::make_optional(TopCenter); + case SPEAKER_TOP_FRONT_LEFT: return al::make_optional(TopFrontLeft); + case SPEAKER_TOP_FRONT_CENTER: return al::make_optional(TopFrontCenter); + case SPEAKER_TOP_FRONT_RIGHT: return al::make_optional(TopFrontRight); + case SPEAKER_TOP_BACK_LEFT: return al::make_optional(TopBackLeft); + case SPEAKER_TOP_BACK_CENTER: return al::make_optional(TopBackCenter); + case SPEAKER_TOP_BACK_RIGHT: return al::make_optional(TopBackRight); + } + WARN("Unhandled WFX channel bit 0x%lx\n", chanbit); + return al::nullopt; + }; + + const ALuint numchans{mDevice->channelsFromFmt()}; + ALuint idx{0}; + while(chanmask) + { + const int bit{CTZ32(chanmask)}; + const ALuint mask{1u << bit}; + chanmask &= ~mask; + + if(auto label = get_channel(mask)) + { + mDevice->RealOut.ChannelIndex[*label] = idx; + if(++idx == numchans) break; + } + } +} +#endif |