From 340a22be6befeb308745bea871396da94b873245 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Mon, 2 Oct 2023 18:51:16 -0700 Subject: [PATCH] Improve ambisonic rotator coefficient accuracy --- alc/alu.cpp | 55 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 38 insertions(+), 17 deletions(-) diff --git a/alc/alu.cpp b/alc/alu.cpp index 6eb4691edf..1585b8f291 100644 --- a/alc/alu.cpp +++ b/alc/alu.cpp @@ -627,17 +627,38 @@ struct RotatorCoeffs { { for(int m{-l};m <= l;++m) { - // compute u,v,w terms of Eq.8.1 (Table I) - const bool d{m == 0}; // the delta function d_m0 - const float denom{static_cast((std::abs(n) == l) ? - (2*l) * (2*l - 1) : (l*l - n*n))}; - - const int abs_m{std::abs(m)}; - coeffs->u = std::sqrt(static_cast(l*l - m*m)/denom); - coeffs->v = std::sqrt(static_cast(l+abs_m-1) * - static_cast(l+abs_m) / denom) * (1.0f+d) * (1.0f - 2.0f*d) * 0.5f; - coeffs->w = std::sqrt(static_cast(l-abs_m-1) * - static_cast(l-abs_m) / denom) * (1.0f-d) * -0.5f; + /* compute u,v,w terms of Eq.8.1 (Table I) + * + * const bool d{m == 0}; // the delta function d_m0 + * const double denom{(std::abs(n) == l) ? + * (2*l) * (2*l - 1) : (l*l - n*n)}; + * + * const int abs_m{std::abs(m)}; + * coeffs->u = std::sqrt((l*l - m*m) / denom); + * coeffs->v = std::sqrt((l+abs_m-1) * (l+abs_m) / denom) * + * (1.0+d) * (1.0 - 2.0*d) * 0.5; + * coeffs->w = std::sqrt((l-abs_m-1) * (l-abs_m) / denom) * + * (1.0-d) * -0.5; + */ + + const double denom{static_cast((std::abs(n) == l) ? + (2*l) * (2*l - 1) : (l*l - n*n))}; + + if(m == 0) + { + coeffs->u = static_cast(std::sqrt(l * l / denom)); + coeffs->v = static_cast(std::sqrt((l-1) * l / denom) * -1.0); + coeffs->w = 0.0f; + } + else + { + const int abs_m{std::abs(m)}; + coeffs->u = static_cast(std::sqrt((l*l - m*m) / denom)); + coeffs->v = static_cast(std::sqrt((l+abs_m-1) * (l+abs_m) / denom) * + 0.5); + coeffs->w = static_cast(std::sqrt((l-abs_m-1) * (l-abs_m) / denom) * + -0.5); + } ++coeffs; } } @@ -721,12 +742,12 @@ void AmbiRotator(AmbiRotateMatrix &matrix, const int order) float r{0.0f}; // computes Eq.8.1 - const float u{coeffs->u}; - if(u != 0.0f) r += u * U(l, m, n, last_band, matrix); - const float v{coeffs->v}; - if(v != 0.0f) r += v * V(l, m, n, last_band, matrix); - const float w{coeffs->w}; - if(w != 0.0f) r += w * W(l, m, n, last_band, matrix); + if(const float u{coeffs->u}; u != 0.0f) + r += u * U(l, m, n, last_band, matrix); + if(const float v{coeffs->v}; v != 0.0f) + r += v * V(l, m, n, last_band, matrix); + if(const float w{coeffs->w}; w != 0.0f) + r += w * W(l, m, n, last_band, matrix); matrix[y][x] = r; ++coeffs;