diff options
author | Chris Robinson <[email protected]> | 2022-09-03 21:06:39 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2022-09-03 21:06:39 -0700 |
commit | f2ff2bb2f6f2f9190210b60833b4232fe5398b07 (patch) | |
tree | 4506fea997e6c6828e428bea6791df467971d118 | |
parent | d2a2a696a13645414410c89614d482c33eae4d19 (diff) |
Use the difference in HF scale for upsampling ambisonics
-rw-r--r-- | alc/effects/convolution.cpp | 2 | ||||
-rw-r--r-- | alc/effects/reverb.cpp | 2 | ||||
-rw-r--r-- | core/ambidefs.cpp | 45 | ||||
-rw-r--r-- | core/ambidefs.h | 15 | ||||
-rw-r--r-- | core/voice.cpp | 2 |
5 files changed, 32 insertions, 34 deletions
diff --git a/alc/effects/convolution.cpp b/alc/effects/convolution.cpp index 90220a50..196238fc 100644 --- a/alc/effects/convolution.cpp +++ b/alc/effects/convolution.cpp @@ -420,7 +420,7 @@ void ConvolutionState::update(const ContextBase *context, const EffectSlot *slot if(device->mAmbiOrder > mAmbiOrder) { mMix = &ConvolutionState::UpsampleMix; - const auto scales = AmbiScale::GetHFOrderScales(mAmbiOrder, true); + const auto scales = AmbiScale::GetHFOrderScales(mAmbiOrder, device->mAmbiOrder); (*mChans)[0].mHfScale = scales[0]; for(size_t i{1};i < mChans->size();++i) (*mChans)[i].mHfScale = scales[1]; diff --git a/alc/effects/reverb.cpp b/alc/effects/reverb.cpp index ea3367d0..71640a87 100644 --- a/alc/effects/reverb.cpp +++ b/alc/effects/reverb.cpp @@ -686,7 +686,7 @@ void ReverbState::deviceUpdate(const DeviceBase *device, const Buffer&) if(device->mAmbiOrder > 1) { mUpmixOutput = true; - mOrderScales = AmbiScale::GetHFOrderScales(1, true); + mOrderScales = AmbiScale::GetHFOrderScales(1, device->mAmbiOrder); } else { diff --git a/core/ambidefs.cpp b/core/ambidefs.cpp index 31ac699e..49b2d144 100644 --- a/core/ambidefs.cpp +++ b/core/ambidefs.cpp @@ -14,6 +14,22 @@ constexpr auto inv_sqrt2f = static_cast<float>(1.0/al::numbers::sqrt2); constexpr auto inv_sqrt3f = static_cast<float>(1.0/al::numbers::sqrt3); +/* These HF gains are derived from the same 32-point speaker array. The scale + * factor between orders represents the same scale factors for any (regular) + * speaker array decoder. e.g. Given a first-order source and second-order + * output, applying an HF scale of HFScales[1][0] / HFScales[2][0] to channel 0 + * will result in that channel being subsequently decoded for second-order as + * if it was a first-order decoder for that same speaker array. + */ +constexpr std::array<std::array<float,MaxAmbiOrder+1>,MaxAmbiOrder+1> HFScales{{ + {{ 4.000000000e+00f, 2.309401077e+00f, 1.192569588e+00f, 7.189495850e-01f }}, + {{ 4.000000000e+00f, 2.309401077e+00f, 1.192569588e+00f, 7.189495850e-01f }}, + {{ 2.981423970e+00f, 2.309401077e+00f, 1.192569588e+00f, 7.189495850e-01f }}, + {{ 2.359168820e+00f, 2.031565936e+00f, 1.444598386e+00f, 7.189495850e-01f }}, + /* 1.947005434e+00f, 1.764337084e+00f, 1.424707344e+00f, 9.755104127e-01f, 4.784482742e-01f */ +}}; + + constexpr std::array<std::array<float,4>,8> FirstOrderDecoder{{ {{ 1.250000000e-01f, 1.250000000e-01f, 1.250000000e-01f, 1.250000000e-01f, }}, {{ 1.250000000e-01f, 1.250000000e-01f, 1.250000000e-01f, -1.250000000e-01f, }}, @@ -367,21 +383,14 @@ const std::array<AmbiChannelFloatArray,16> AmbiScale::ThirdOrderUp{CalcThirdOrde const std::array<AmbiChannelFloatArray,16> AmbiScale::ThirdOrder2DUp{CalcThirdOrder2DUp()}; const std::array<AmbiChannelFloatArray,25> AmbiScale::FourthOrder2DUp{CalcFourthOrder2DUp()}; -const std::array<float,MaxAmbiOrder+1> AmbiScale::DecoderHFScale1O{{ - 2.000000000e+00f, 1.154700538e+00f -}}; -const std::array<float,MaxAmbiOrder+1> AmbiScale::DecoderHFScale1O2D{{ - 1.414213562e+00f, 1.000000000e+00f -}}; -const std::array<float,MaxAmbiOrder+1> AmbiScale::DecoderHFScale2O{{ - 1.825741858e+00f, 1.414213562e+00f, 7.302967433e-01f -}}; -const std::array<float,MaxAmbiOrder+1> AmbiScale::DecoderHFScale2O2D{{ - 1.414213562e+00f, 1.224744871e+00f, 7.071067812e-01f -}}; -const std::array<float,MaxAmbiOrder+1> AmbiScale::DecoderHFScale3O{{ - 1.865086714e+00f, 1.606093894e+00f, 1.142055301e+00f, 5.683795528e-01f -}}; -const std::array<float,MaxAmbiOrder+1> AmbiScale::DecoderHFScale3O2D{{ - 1.414213562e+00f, 1.306562965e+00f, 1.000000000e+00f, 5.411961001e-01f -}}; + +std::array<float,MaxAmbiOrder+1> AmbiScale::GetHFOrderScales(const uint src_order, + const uint dev_order) noexcept +{ + std::array<float,MaxAmbiOrder+1> res{}; + + for(size_t i{0};i < MaxAmbiOrder+1;++i) + res[i] = HFScales[src_order][i] / HFScales[dev_order][i]; + + return res; +} diff --git a/core/ambidefs.h b/core/ambidefs.h index 7f0f14ad..aa69b2e6 100644 --- a/core/ambidefs.h +++ b/core/ambidefs.h @@ -114,19 +114,8 @@ struct AmbiScale { } /* Retrieves per-order HF scaling factors for "upsampling" ambisonic data. */ - static std::array<float,MaxAmbiOrder+1> GetHFOrderScales(const uint order, const bool is3D) noexcept - { - if(order >= 3) return is3D ? DecoderHFScale3O : DecoderHFScale3O2D; - if(order == 2) return is3D ? DecoderHFScale2O : DecoderHFScale2O2D; - return is3D ? DecoderHFScale1O : DecoderHFScale1O2D; - } - - static const std::array<float,MaxAmbiOrder+1> DecoderHFScale1O; - static const std::array<float,MaxAmbiOrder+1> DecoderHFScale1O2D; - static const std::array<float,MaxAmbiOrder+1> DecoderHFScale2O; - static const std::array<float,MaxAmbiOrder+1> DecoderHFScale2O2D; - static const std::array<float,MaxAmbiOrder+1> DecoderHFScale3O; - static const std::array<float,MaxAmbiOrder+1> DecoderHFScale3O2D; + static std::array<float,MaxAmbiOrder+1> GetHFOrderScales(const uint src_order, + const uint dev_order) noexcept; static const std::array<std::array<float,MaxAmbiChannels>,4> FirstOrderUp; static const std::array<std::array<float,MaxAmbiChannels>,4> FirstOrder2DUp; diff --git a/core/voice.cpp b/core/voice.cpp index 5263202e..8b4cabe2 100644 --- a/core/voice.cpp +++ b/core/voice.cpp @@ -899,7 +899,7 @@ void Voice::prepare(DeviceBase *device) { const uint8_t *OrderFromChan{Is2DAmbisonic(mFmtChannels) ? AmbiIndex::OrderFrom2DChannel().data() : AmbiIndex::OrderFromChannel().data()}; - const auto scales = AmbiScale::GetHFOrderScales(mAmbiOrder, !Is2DAmbisonic(mFmtChannels)); + const auto scales = AmbiScale::GetHFOrderScales(mAmbiOrder, device->mAmbiOrder); const BandSplitter splitter{device->mXOverFreq / static_cast<float>(device->Frequency)}; for(auto &chandata : mChans) |