From 2b7c446363b695e1a506b92a0c5a3cf82361f6b2 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Wed, 23 Jun 2021 03:22:54 -0700 Subject: [PATCH] Support built-in 3D ambisonic decoders --- alc/panning.cpp | 44 ++++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/alc/panning.cpp b/alc/panning.cpp index daf1b9ea..b158caff 100644 --- a/alc/panning.cpp +++ b/alc/panning.cpp @@ -314,7 +314,7 @@ inline auto& GetAmbiLayout(DevAmbiLayout layouttype) noexcept } -using ChannelCoeffs = std::array; +using ChannelCoeffs = std::array; enum DecoderMode : bool { SingleBand = false, DualBand = true @@ -325,7 +325,8 @@ struct DecoderConfig; template struct DecoderConfig { - uint mOrder; + uint8_t mOrder; + bool mIs3D; std::array mChannels; std::array mOrderGain; std::array mCoeffs; @@ -333,7 +334,8 @@ struct DecoderConfig { template struct DecoderConfig { - uint mOrder; + uint8_t mOrder; + bool mIs3D; std::array mChannels; std::array mOrderGain; std::array mCoeffs; @@ -343,7 +345,8 @@ struct DecoderConfig { template<> struct DecoderConfig { - uint mOrder; + uint8_t mOrder; + bool mIs3D; al::span mChannels; al::span mOrderGain; al::span mCoeffs; @@ -354,6 +357,7 @@ struct DecoderConfig { DecoderConfig& operator=(const DecoderConfig &rhs) noexcept { mOrder = rhs.mOrder; + mIs3D = rhs.mIs3D; mChannels = rhs.mChannels; mOrderGain = rhs.mOrderGain; mCoeffs = rhs.mCoeffs; @@ -366,6 +370,7 @@ struct DecoderConfig { DecoderConfig& operator=(const DecoderConfig &rhs) noexcept { mOrder = rhs.mOrder; + mIs3D = rhs.mIs3D; mChannels = rhs.mChannels; mOrderGain = rhs.mOrderGain; mCoeffs = rhs.mCoeffs; @@ -377,12 +382,12 @@ struct DecoderConfig { using DecoderView = DecoderConfig; constexpr DecoderConfig MonoConfig{ - 0, {{FrontCenter}}, + 0, false, {{FrontCenter}}, {{1.0f}}, {{ {{1.0f}} }} }; constexpr DecoderConfig StereoConfig{ - 1, {{FrontLeft, FrontRight}}, + 1, false, {{FrontLeft, FrontRight}}, {{1.0f, 1.0f}}, {{ {{5.00000000e-1f, 2.88675135e-1f, 5.52305643e-2f}}, @@ -390,7 +395,7 @@ constexpr DecoderConfig StereoConfig{ }} }; constexpr DecoderConfig QuadConfig{ - 2, {{BackLeft, FrontLeft, FrontRight, BackRight}}, + 2, false, {{BackLeft, FrontLeft, FrontRight, BackRight}}, /*HF*/{{1.15470054e+0f, 1.00000000e+0f, 5.77350269e-1f}}, {{ {{2.50000000e-1f, 2.04124145e-1f, -2.04124145e-1f, -1.29099445e-1f, 0.00000000e+0f}}, @@ -407,7 +412,7 @@ constexpr DecoderConfig QuadConfig{ }} }; constexpr DecoderConfig X51Config{ - 2, {{SideLeft, FrontLeft, FrontRight, SideRight}}, + 2, false, {{SideLeft, FrontLeft, FrontRight, SideRight}}, {{1.0f, 1.0f, 1.0f}}, {{ {{3.33000782e-1f, 1.89084803e-1f, -2.00042375e-1f, -2.12307769e-2f, -1.14579885e-2f}}, @@ -417,7 +422,7 @@ constexpr DecoderConfig X51Config{ }} }; constexpr DecoderConfig X51RearConfig{ - 2, {{BackLeft, FrontLeft, FrontRight, BackRight}}, + 2, false, {{BackLeft, FrontLeft, FrontRight, BackRight}}, {{1.0f, 1.0f, 1.0f}}, {{ {{3.33000782e-1f, 1.89084803e-1f, -2.00042375e-1f, -2.12307769e-2f, -1.14579885e-2f}}, @@ -427,7 +432,7 @@ constexpr DecoderConfig X51RearConfig{ }} }; constexpr DecoderConfig X61Config{ - 2, {{SideLeft, FrontLeft, FrontRight, SideRight, BackCenter}}, + 2, false, {{SideLeft, FrontLeft, FrontRight, SideRight, BackCenter}}, {{1.0f, 1.0f, 1.0f}}, {{ {{2.04460341e-1f, 2.17177926e-1f, -4.39996780e-2f, -2.60790269e-2f, -6.87239792e-2f}}, @@ -438,7 +443,7 @@ constexpr DecoderConfig X61Config{ }} }; constexpr DecoderConfig X71Config{ - 3, {{BackLeft, SideLeft, FrontLeft, FrontRight, SideRight, BackRight}}, + 3, false, {{BackLeft, SideLeft, FrontLeft, FrontRight, SideRight, BackRight}}, /*HF*/{{1.22474487e+0f, 1.13151672e+0f, 8.66025404e-1f, 4.68689571e-1f}}, {{ {{1.66666667e-1f, 9.62250449e-2f, -1.66666667e-1f, -1.49071198e-1f, 8.60662966e-2f, 7.96819073e-2f, 0.00000000e+0f}}, @@ -522,7 +527,8 @@ void InitPanning(ALCdevice *device, const bool hqdec=false, const bool stablize= for(uint o{0};o < decoder.mOrder+1;++o) { const float order_gain{decoder.mOrderGain[o]}; - const size_t order_max{Ambi2DChannelsFromOrder(o)}; + const size_t order_max{decoder.mIs3D ? AmbiChannelsFromOrder(o) : + Ambi2DChannelsFromOrder(o)}; for(;ambichan < order_max;++ambichan) coeffs[ambichan] = decoder.mCoeffs[i][ambichan] * order_gain; } @@ -535,7 +541,8 @@ void InitPanning(ALCdevice *device, const bool hqdec=false, const bool stablize= for(uint o{0};o < decoder.mOrder+1;++o) { const float order_gain{decoder.mOrderGainLF[o]}; - const size_t order_max{Ambi2DChannelsFromOrder(o)}; + const size_t order_max{decoder.mIs3D ? AmbiChannelsFromOrder(o) : + Ambi2DChannelsFromOrder(o)}; for(;ambichan < order_max;++ambichan) coeffs[ambichan] = decoder.mCoeffsLF[i][ambichan] * order_gain; } @@ -544,10 +551,11 @@ void InitPanning(ALCdevice *device, const bool hqdec=false, const bool stablize= /* For non-DevFmtAmbi3D, set the ambisonic order. */ device->mAmbiOrder = decoder.mOrder; - /* Built-in speaker decoders are always 2D. */ - const size_t ambicount{Ambi2DChannelsFromOrder(decoder.mOrder)}; - std::transform(AmbiIndex::FromACN2D().begin(), AmbiIndex::FromACN2D().begin()+ambicount, - std::begin(device->Dry.AmbiMap), + const size_t ambicount{decoder.mIs3D ? AmbiChannelsFromOrder(decoder.mOrder) : + Ambi2DChannelsFromOrder(decoder.mOrder)}; + const al::span acnmap{decoder.mIs3D ? AmbiIndex::FromACN().data() : + AmbiIndex::FromACN2D().data(), ambicount}; + std::transform(acnmap.begin(), acnmap.end(), std::begin(device->Dry.AmbiMap), [](const uint8_t &index) noexcept { return BFChannelConfig{1.0f, index}; }); AllocChannels(device, ambicount, device->channelsFromFmt()); @@ -580,7 +588,7 @@ void InitPanning(ALCdevice *device, const bool hqdec=false, const bool stablize= !dual_band ? "single" : "dual", (decoder.mOrder > 2) ? "third" : (decoder.mOrder > 1) ? "second" : "first", - ""); + decoder.mIs3D ? " periphonic" : ""); device->AmbiDecoder = BFormatDec::Create(ambicount, chancoeffs, chancoeffslf, std::move(stablizer)); }