aboutsummaryrefslogtreecommitdiffstats
path: root/alc/backends/base.cpp
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2020-06-15 18:50:59 -0700
committerChris Robinson <[email protected]>2020-06-15 20:21:54 -0700
commitbd0144065a343c936b6a12be6e546e114575217b (patch)
tree391a13f7bf6d71e228c30da12e75af8432a787da /alc/backends/base.cpp
parentc142b49981b57bdd50f20b6e916ead92ca9f044d (diff)
Set channel labels from WFX channel masks
Diffstat (limited to 'alc/backends/base.cpp')
-rw-r--r--alc/backends/base.cpp55
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