diff options
Diffstat (limited to 'core/ambidefs.cpp')
-rw-r--r-- | core/ambidefs.cpp | 143 |
1 files changed, 140 insertions, 3 deletions
diff --git a/core/ambidefs.cpp b/core/ambidefs.cpp index 4aae12b6..6fecd515 100644 --- a/core/ambidefs.cpp +++ b/core/ambidefs.cpp @@ -3,11 +3,15 @@ #include "ambidefs.h" +#include "alnumbers.h" + namespace { using AmbiChannelFloatArray = std::array<float,MaxAmbiChannels>; +constexpr auto inv_sqrt2f = static_cast<float>(1.0/al::numbers::sqrt2); + constexpr std::array<std::array<float,4>,8> FirstOrderDecoder{{ {{ 1.250000000e-01f, 1.250000000e-01f, 1.250000000e-01f, 1.250000000e-01f, }}, @@ -19,7 +23,6 @@ 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, }}, }}; - constexpr std::array<AmbiChannelFloatArray,8> FirstOrderEncoder{{ CalcAmbiCoeffs( 0.57735026919f, 0.57735026919f, 0.57735026919f), CalcAmbiCoeffs( 0.57735026919f, 0.57735026919f, -0.57735026919f), @@ -58,6 +61,43 @@ auto CalcFirstOrderUp() } +constexpr std::array<std::array<float,4>,4> FirstOrder2DDecoder{{ + {{ 2.500000000e-01f, 2.041241452e-01f, 0.0f, 2.041241452e-01f, }}, + {{ 2.500000000e-01f, 2.041241452e-01f, 0.0f, -2.041241452e-01f, }}, + {{ 2.500000000e-01f, -2.041241452e-01f, 0.0f, 2.041241452e-01f, }}, + {{ 2.500000000e-01f, -2.041241452e-01f, 0.0f, -2.041241452e-01f, }}, +}}; +constexpr std::array<AmbiChannelFloatArray,4> FirstOrder2DEncoder{{ + CalcAmbiCoeffs( inv_sqrt2f, 0.0f, inv_sqrt2f), + CalcAmbiCoeffs( inv_sqrt2f, 0.0f, -inv_sqrt2f), + CalcAmbiCoeffs(-inv_sqrt2f, 0.0f, inv_sqrt2f), + CalcAmbiCoeffs(-inv_sqrt2f, 0.0f, -inv_sqrt2f), +}}; +static_assert(FirstOrder2DDecoder.size() == FirstOrder2DEncoder.size(), "First-order 2D mismatch"); + +/* This calculates a 2D first-order "upsampler" matrix. Same as the first-order + * matrix, just using a more optimized speaker array for horizontal-only + * content. + */ +auto CalcFirstOrder2DUp() +{ + std::array<AmbiChannelFloatArray,4> res{}; + + for(size_t i{0};i < FirstOrder2DDecoder[0].size();++i) + { + for(size_t j{0};j < FirstOrder2DEncoder[0].size();++j) + { + double sum{0.0}; + for(size_t k{0};k < FirstOrder2DDecoder.size();++k) + sum += double{FirstOrder2DDecoder[k][i]} * FirstOrder2DEncoder[k][j]; + res[i][j] = static_cast<float>(sum); + } + } + + return res; +} + + constexpr std::array<std::array<float,9>,14> SecondOrderDecoder{{ {{ 7.142857143e-02f, 0.000000000e+00f, 0.000000000e+00f, 1.237179148e-01f, 0.000000000e+00f, 0.000000000e+00f, -7.453559925e-02f, 0.000000000e+00f, 1.290994449e-01f, }}, {{ 7.142857143e-02f, 0.000000000e+00f, 0.000000000e+00f, -1.237179148e-01f, 0.000000000e+00f, 0.000000000e+00f, -7.453559925e-02f, 0.000000000e+00f, 1.290994449e-01f, }}, @@ -74,7 +114,6 @@ constexpr std::array<std::array<float,9>,14> SecondOrderDecoder{{ {{ 7.142857143e-02f, -7.142857143e-02f, -7.142857143e-02f, 7.142857143e-02f, -9.682458366e-02f, 9.682458366e-02f, 0.000000000e+00f, -9.682458366e-02f, 0.000000000e+00f, }}, {{ 7.142857143e-02f, -7.142857143e-02f, -7.142857143e-02f, -7.142857143e-02f, 9.682458366e-02f, 9.682458366e-02f, 0.000000000e+00f, 9.682458366e-02f, 0.000000000e+00f, }}, }}; - constexpr std::array<AmbiChannelFloatArray,14> SecondOrderEncoder{{ CalcAmbiCoeffs( 0.00000000000f, 0.00000000000f, 1.00000000000f), CalcAmbiCoeffs( 0.00000000000f, 0.00000000000f, -1.00000000000f), @@ -116,6 +155,48 @@ auto CalcSecondOrderUp() } +constexpr std::array<std::array<float,9>,6> SecondOrder2DDecoder{{ + {{ 1.666666667e-01f, -9.622504486e-02f, 0.0f, 1.666666667e-01f, -1.490711985e-01f, 0.0f, 0.0f, 0.0f, 8.606629658e-02f, }}, + {{ 1.666666667e-01f, -1.924500897e-01f, 0.0f, 0.000000000e+00f, 0.000000000e+00f, 0.0f, 0.0f, 0.0f, -1.721325932e-01f, }}, + {{ 1.666666667e-01f, -9.622504486e-02f, 0.0f, -1.666666667e-01f, 1.490711985e-01f, 0.0f, 0.0f, 0.0f, 8.606629658e-02f, }}, + {{ 1.666666667e-01f, 9.622504486e-02f, 0.0f, -1.666666667e-01f, -1.490711985e-01f, 0.0f, 0.0f, 0.0f, 8.606629658e-02f, }}, + {{ 1.666666667e-01f, 1.924500897e-01f, 0.0f, 0.000000000e+00f, 0.000000000e+00f, 0.0f, 0.0f, 0.0f, -1.721325932e-01f, }}, + {{ 1.666666667e-01f, 9.622504486e-02f, 0.0f, 1.666666667e-01f, 1.490711985e-01f, 0.0f, 0.0f, 0.0f, 8.606629658e-02f, }}, +}}; +constexpr std::array<AmbiChannelFloatArray,6> SecondOrder2DEncoder{{ + CalcAmbiCoeffs(-0.50000000000f, 0.00000000000f, 0.86602540379f), + CalcAmbiCoeffs(-1.00000000000f, 0.00000000000f, 0.00000000000f), + CalcAmbiCoeffs(-0.50000000000f, 0.00000000000f, -0.86602540379f), + CalcAmbiCoeffs( 0.50000000000f, 0.00000000000f, -0.86602540379f), + CalcAmbiCoeffs( 1.00000000000f, 0.00000000000f, 0.00000000000f), + CalcAmbiCoeffs( 0.50000000000f, 0.00000000000f, 0.86602540379f), +}}; +static_assert(SecondOrder2DDecoder.size() == SecondOrder2DEncoder.size(), + "Second-order 2D mismatch"); + +/* This calculates a 2D second-order "upsampler" matrix. Same as the second- + * order matrix, just using a more optimized speaker array for horizontal-only + * content. + */ +auto CalcSecondOrder2DUp() +{ + std::array<AmbiChannelFloatArray,9> res{}; + + for(size_t i{0};i < SecondOrder2DDecoder[0].size();++i) + { + for(size_t j{0};j < SecondOrder2DEncoder[0].size();++j) + { + double sum{0.0}; + for(size_t k{0};k < SecondOrder2DDecoder.size();++k) + sum += double{SecondOrder2DDecoder[k][i]} * SecondOrder2DEncoder[k][j]; + res[i][j] = static_cast<float>(sum); + } + } + + return res; +} + + constexpr std::array<std::array<float,16>,20> ThirdOrderDecoder{{ {{ 5.000000000e-02f, 3.090169944e-02f, 8.090169944e-02f, 0.000000000e+00f, 0.000000000e+00f, 6.454972244e-02f, 9.045084972e-02f, 0.000000000e+00f, -1.232790000e-02f, -1.256118221e-01f, 0.000000000e+00f, 1.126112056e-01f, 7.944389175e-02f, 0.000000000e+00f, 2.421151497e-02f, 0.000000000e+00f, }}, {{ 5.000000000e-02f, -3.090169944e-02f, 8.090169944e-02f, 0.000000000e+00f, 0.000000000e+00f, -6.454972244e-02f, 9.045084972e-02f, 0.000000000e+00f, -1.232790000e-02f, 1.256118221e-01f, 0.000000000e+00f, -1.126112056e-01f, 7.944389175e-02f, 0.000000000e+00f, 2.421151497e-02f, 0.000000000e+00f, }}, @@ -138,7 +219,6 @@ constexpr std::array<std::array<float,16>,20> ThirdOrderDecoder{{ {{ 5.000000000e-02f, -5.000000000e-02f, -5.000000000e-02f, 5.000000000e-02f, -6.454972244e-02f, 6.454972244e-02f, 0.000000000e+00f, -6.454972244e-02f, 0.000000000e+00f, -1.016220987e-01f, 6.338656910e-02f, 1.092600649e-02f, 7.364853795e-02f, 1.011266756e-01f, 7.086833869e-02f, -1.482646439e-02f, }}, {{ 5.000000000e-02f, -5.000000000e-02f, -5.000000000e-02f, -5.000000000e-02f, 6.454972244e-02f, 6.454972244e-02f, 0.000000000e+00f, 6.454972244e-02f, 0.000000000e+00f, -1.016220987e-01f, -6.338656910e-02f, 1.092600649e-02f, 7.364853795e-02f, -1.011266756e-01f, 7.086833869e-02f, 1.482646439e-02f, }}, }}; - constexpr std::array<AmbiChannelFloatArray,20> ThirdOrderEncoder{{ CalcAmbiCoeffs( 0.35682208976f, 0.93417235897f, 0.00000000000f), CalcAmbiCoeffs(-0.35682208976f, 0.93417235897f, 0.00000000000f), @@ -185,18 +265,75 @@ auto CalcThirdOrderUp() return res; } + +constexpr std::array<std::array<float,16>,8> ThirdOrder2DDecoder{{ + {{ 1.250000000e-01f, -5.523559567e-02f, 0.0f, 1.333505242e-01f, -9.128709292e-02f, 0.0f, 0.0f, 0.0f, 9.128709292e-02f, -1.104247249e-01f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 4.573941867e-02f, }}, + {{ 1.250000000e-01f, -1.333505242e-01f, 0.0f, 5.523559567e-02f, -9.128709292e-02f, 0.0f, 0.0f, 0.0f, -9.128709292e-02f, 4.573941867e-02f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.104247249e-01f, }}, + {{ 1.250000000e-01f, -1.333505242e-01f, 0.0f, -5.523559567e-02f, 9.128709292e-02f, 0.0f, 0.0f, 0.0f, -9.128709292e-02f, 4.573941867e-02f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.104247249e-01f, }}, + {{ 1.250000000e-01f, -5.523559567e-02f, 0.0f, -1.333505242e-01f, 9.128709292e-02f, 0.0f, 0.0f, 0.0f, 9.128709292e-02f, -1.104247249e-01f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -4.573941867e-02f, }}, + {{ 1.250000000e-01f, 5.523559567e-02f, 0.0f, -1.333505242e-01f, -9.128709292e-02f, 0.0f, 0.0f, 0.0f, 9.128709292e-02f, 1.104247249e-01f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -4.573941867e-02f, }}, + {{ 1.250000000e-01f, 1.333505242e-01f, 0.0f, -5.523559567e-02f, -9.128709292e-02f, 0.0f, 0.0f, 0.0f, -9.128709292e-02f, -4.573941867e-02f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.104247249e-01f, }}, + {{ 1.250000000e-01f, 1.333505242e-01f, 0.0f, 5.523559567e-02f, 9.128709292e-02f, 0.0f, 0.0f, 0.0f, -9.128709292e-02f, -4.573941867e-02f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.104247249e-01f, }}, + {{ 1.250000000e-01f, 5.523559567e-02f, 0.0f, 1.333505242e-01f, 9.128709292e-02f, 0.0f, 0.0f, 0.0f, 9.128709292e-02f, 1.104247249e-01f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 4.573941867e-02f, }}, +}}; +constexpr std::array<AmbiChannelFloatArray,8> ThirdOrder2DEncoder{{ + CalcAmbiCoeffs(-0.38268343237f, 0.00000000000f, 0.92387953251f), + CalcAmbiCoeffs(-0.92387953251f, 0.00000000000f, 0.38268343237f), + CalcAmbiCoeffs(-0.92387953251f, 0.00000000000f, -0.38268343237f), + CalcAmbiCoeffs(-0.38268343237f, 0.00000000000f, -0.92387953251f), + CalcAmbiCoeffs( 0.38268343237f, 0.00000000000f, -0.92387953251f), + CalcAmbiCoeffs( 0.92387953251f, 0.00000000000f, -0.38268343237f), + CalcAmbiCoeffs( 0.92387953251f, 0.00000000000f, 0.38268343237f), + CalcAmbiCoeffs( 0.38268343237f, 0.00000000000f, 0.92387953251f), +}}; +static_assert(ThirdOrder2DDecoder.size() == ThirdOrder2DEncoder.size(), "Third-order 2D mismatch"); + +/* This calculates a 2D third-order "upsampler" matrix. Same as the third-order + * matrix, just using a more optimized speaker array for horizontal-only + * content. + */ +auto CalcThirdOrder2DUp() +{ + std::array<AmbiChannelFloatArray,16> res{}; + + for(size_t i{0};i < ThirdOrder2DDecoder[0].size();++i) + { + for(size_t j{0};j < ThirdOrder2DEncoder[0].size();++j) + { + double sum{0.0}; + for(size_t k{0};k < ThirdOrder2DDecoder.size();++k) + sum += double{ThirdOrder2DDecoder[k][i]} * ThirdOrder2DEncoder[k][j]; + res[i][j] = static_cast<float>(sum); + } + } + + return res; +} + } // namespace const std::array<AmbiChannelFloatArray,4> AmbiScale::FirstOrderUp{CalcFirstOrderUp()}; +const std::array<AmbiChannelFloatArray,4> AmbiScale::FirstOrder2DUp{CalcFirstOrder2DUp()}; const std::array<AmbiChannelFloatArray,9> AmbiScale::SecondOrderUp{CalcSecondOrderUp()}; +const std::array<AmbiChannelFloatArray,9> AmbiScale::SecondOrder2DUp{CalcSecondOrder2DUp()}; const std::array<AmbiChannelFloatArray,16> AmbiScale::ThirdOrderUp{CalcThirdOrderUp()}; +const std::array<AmbiChannelFloatArray,16> AmbiScale::ThirdOrder2DUp{CalcThirdOrder2DUp()}; const std::array<float,MaxAmbiOrder+1> AmbiScale::DecoderHFScale10{{ 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.972026594e+00f, 1.527525232e+00f, 7.888106377e-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 +}}; |