diff options
author | Chris Robinson <[email protected]> | 2018-12-05 15:20:52 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2018-12-05 15:20:52 -0800 |
commit | 10b39d57d53b541bd4e8fd60d166a03de0c9e28c (patch) | |
tree | 70b764d3a5542312f04e9e9f964bc1525e1105b2 /Alc/filters | |
parent | 164a86a381e4f51383c6afbfdf63dadd3ecb3785 (diff) |
Use class methods for the NFC filters
Diffstat (limited to 'Alc/filters')
-rw-r--r-- | Alc/filters/nfc.cpp | 191 | ||||
-rw-r--r-- | Alc/filters/nfc.h | 64 |
2 files changed, 127 insertions, 128 deletions
diff --git a/Alc/filters/nfc.cpp b/Alc/filters/nfc.cpp index 11a7b467..8cabfc5b 100644 --- a/Alc/filters/nfc.cpp +++ b/Alc/filters/nfc.cpp @@ -48,7 +48,9 @@ * low frequencies. */ -static const float B[4][3] = { +namespace { + +constexpr float B[4][3] = { { 0.0f }, { 1.0f }, { 3.0f, 3.0f }, @@ -56,33 +58,36 @@ static const float B[4][3] = { /*{ 4.2076f, 11.4877f, 5.7924f, 9.1401f }*/ }; -static void NfcFilterCreate1(struct NfcFilter1 *nfc, const float w0, const float w1) +NfcFilter1 NfcFilterCreate1(const float w0, const float w1) noexcept { + NfcFilter1 nfc{}; float b_00, g_0; float r; - nfc->base_gain = 1.0f; - nfc->gain = 1.0f; + nfc.base_gain = 1.0f; + nfc.gain = 1.0f; /* Calculate bass-boost coefficients. */ r = 0.5f * w0; b_00 = B[1][0] * r; g_0 = 1.0f + b_00; - nfc->gain *= g_0; - nfc->b1 = 2.0f * b_00 / g_0; + nfc.gain *= g_0; + nfc.b1 = 2.0f * b_00 / g_0; /* Calculate bass-cut coefficients. */ r = 0.5f * w1; b_00 = B[1][0] * r; g_0 = 1.0f + b_00; - nfc->base_gain /= g_0; - nfc->gain /= g_0; - nfc->a1 = 2.0f * b_00 / g_0; + nfc.base_gain /= g_0; + nfc.gain /= g_0; + nfc.a1 = 2.0f * b_00 / g_0; + + return nfc; } -static void NfcFilterAdjust1(struct NfcFilter1 *nfc, const float w0) +void NfcFilterAdjust1(NfcFilter1 *nfc, const float w0) noexcept { float b_00, g_0; float r; @@ -96,13 +101,14 @@ static void NfcFilterAdjust1(struct NfcFilter1 *nfc, const float w0) } -static void NfcFilterCreate2(struct NfcFilter2 *nfc, const float w0, const float w1) +NfcFilter2 NfcFilterCreate2(const float w0, const float w1) noexcept { + NfcFilter2 nfc{}; float b_10, b_11, g_1; float r; - nfc->base_gain = 1.0f; - nfc->gain = 1.0f; + nfc.base_gain = 1.0f; + nfc.gain = 1.0f; /* Calculate bass-boost coefficients. */ r = 0.5f * w0; @@ -110,9 +116,9 @@ static void NfcFilterCreate2(struct NfcFilter2 *nfc, const float w0, const float b_11 = B[2][1] * r * r; g_1 = 1.0f + b_10 + b_11; - nfc->gain *= g_1; - nfc->b1 = (2.0f*b_10 + 4.0f*b_11) / g_1; - nfc->b2 = 4.0f * b_11 / g_1; + nfc.gain *= g_1; + nfc.b1 = (2.0f*b_10 + 4.0f*b_11) / g_1; + nfc.b2 = 4.0f * b_11 / g_1; /* Calculate bass-cut coefficients. */ r = 0.5f * w1; @@ -120,13 +126,15 @@ static void NfcFilterCreate2(struct NfcFilter2 *nfc, const float w0, const float b_11 = B[2][1] * r * r; g_1 = 1.0f + b_10 + b_11; - nfc->base_gain /= g_1; - nfc->gain /= g_1; - nfc->a1 = (2.0f*b_10 + 4.0f*b_11) / g_1; - nfc->a2 = 4.0f * b_11 / g_1; + nfc.base_gain /= g_1; + nfc.gain /= g_1; + nfc.a1 = (2.0f*b_10 + 4.0f*b_11) / g_1; + nfc.a2 = 4.0f * b_11 / g_1; + + return nfc; } -static void NfcFilterAdjust2(struct NfcFilter2 *nfc, const float w0) +void NfcFilterAdjust2(NfcFilter2 *nfc, const float w0) noexcept { float b_10, b_11, g_1; float r; @@ -142,14 +150,15 @@ static void NfcFilterAdjust2(struct NfcFilter2 *nfc, const float w0) } -static void NfcFilterCreate3(struct NfcFilter3 *nfc, const float w0, const float w1) +NfcFilter3 NfcFilterCreate3(const float w0, const float w1) noexcept { + NfcFilter3 nfc{}; float b_10, b_11, g_1; float b_00, g_0; float r; - nfc->base_gain = 1.0f; - nfc->gain = 1.0f; + nfc.base_gain = 1.0f; + nfc.gain = 1.0f; /* Calculate bass-boost coefficients. */ r = 0.5f * w0; @@ -157,15 +166,15 @@ static void NfcFilterCreate3(struct NfcFilter3 *nfc, const float w0, const float b_11 = B[3][1] * r * r; g_1 = 1.0f + b_10 + b_11; - nfc->gain *= g_1; - nfc->b1 = (2.0f*b_10 + 4.0f*b_11) / g_1; - nfc->b2 = 4.0f * b_11 / g_1; + nfc.gain *= g_1; + nfc.b1 = (2.0f*b_10 + 4.0f*b_11) / g_1; + nfc.b2 = 4.0f * b_11 / g_1; b_00 = B[3][2] * r; g_0 = 1.0f + b_00; - nfc->gain *= g_0; - nfc->b3 = 2.0f * b_00 / g_0; + nfc.gain *= g_0; + nfc.b3 = 2.0f * b_00 / g_0; /* Calculate bass-cut coefficients. */ r = 0.5f * w1; @@ -173,20 +182,22 @@ static void NfcFilterCreate3(struct NfcFilter3 *nfc, const float w0, const float b_11 = B[3][1] * r * r; g_1 = 1.0f + b_10 + b_11; - nfc->base_gain /= g_1; - nfc->gain /= g_1; - nfc->a1 = (2.0f*b_10 + 4.0f*b_11) / g_1; - nfc->a2 = 4.0f * b_11 / g_1; + nfc.base_gain /= g_1; + nfc.gain /= g_1; + nfc.a1 = (2.0f*b_10 + 4.0f*b_11) / g_1; + nfc.a2 = 4.0f * b_11 / g_1; b_00 = B[3][2] * r; g_0 = 1.0f + b_00; - nfc->base_gain /= g_0; - nfc->gain /= g_0; - nfc->a3 = 2.0f * b_00 / g_0; + nfc.base_gain /= g_0; + nfc.gain /= g_0; + nfc.a3 = 2.0f * b_00 / g_0; + + return nfc; } -static void NfcFilterAdjust3(struct NfcFilter3 *nfc, const float w0) +void NfcFilterAdjust3(NfcFilter3 *nfc, const float w0) noexcept { float b_10, b_11, g_1; float b_00, g_0; @@ -208,100 +219,96 @@ static void NfcFilterAdjust3(struct NfcFilter3 *nfc, const float w0) nfc->b3 = 2.0f * b_00 / g_0; } +} // namespace -void NfcFilterCreate(NfcFilter *nfc, const float w0, const float w1) +void NfcFilter::init(const float w0, const float w1) noexcept { - memset(nfc, 0, sizeof(*nfc)); - NfcFilterCreate1(&nfc->first, w0, w1); - NfcFilterCreate2(&nfc->second, w0, w1); - NfcFilterCreate3(&nfc->third, w0, w1); + first = NfcFilterCreate1(w0, w1); + second = NfcFilterCreate2(w0, w1); + third = NfcFilterCreate3(w0, w1); } -void NfcFilterAdjust(NfcFilter *nfc, const float w0) +void NfcFilter::adjust(const float w0) noexcept { - NfcFilterAdjust1(&nfc->first, w0); - NfcFilterAdjust2(&nfc->second, w0); - NfcFilterAdjust3(&nfc->third, w0); + NfcFilterAdjust1(&first, w0); + NfcFilterAdjust2(&second, w0); + NfcFilterAdjust3(&third, w0); } -void NfcFilterProcess1(NfcFilter *nfc, float *RESTRICT dst, const float *RESTRICT src, const int count) +void NfcFilter::process1(float *RESTRICT dst, const float *RESTRICT src, const int count) { - const float gain = nfc->first.gain; - const float b1 = nfc->first.b1; - const float a1 = nfc->first.a1; - float z1 = nfc->first.z[0]; - ASSUME(count > 0); - auto proc_sample = [gain,b1,a1,&z1](float in) noexcept -> float + const float gain{first.gain}; + const float b1{first.b1}; + const float a1{first.a1}; + float z1{first.z[0]}; + auto proc_sample = [gain,b1,a1,&z1](const float in) noexcept -> float { - float y = in*gain - a1*z1; - float out = y + b1*z1; + const float y{in*gain - a1*z1}; + const float out{y + b1*z1}; z1 += y; return out; }; - std::transform<const float*RESTRICT>(src, src+count, dst, proc_sample); - nfc->first.z[0] = z1; + std::transform(src, src+count, dst, proc_sample); + first.z[0] = z1; } -void NfcFilterProcess2(NfcFilter *nfc, float *RESTRICT dst, const float *RESTRICT src, const int count) +void NfcFilter::process2(float *RESTRICT dst, const float *RESTRICT src, const int count) { - const float gain = nfc->second.gain; - const float b1 = nfc->second.b1; - const float b2 = nfc->second.b2; - const float a1 = nfc->second.a1; - const float a2 = nfc->second.a2; - float z1 = nfc->second.z[0]; - float z2 = nfc->second.z[1]; - ASSUME(count > 0); - auto proc_sample = [gain,b1,b2,a1,a2,&z1,&z2](float in) noexcept -> float + const float gain{second.gain}; + const float b1{second.b1}; + const float b2{second.b2}; + const float a1{second.a1}; + const float a2{second.a2}; + float z1{second.z[0]}; + float z2{second.z[1]}; + auto proc_sample = [gain,b1,b2,a1,a2,&z1,&z2](const float in) noexcept -> float { - float y = in*gain - a1*z1 - a2*z2; - float out = y + b1*z1 + b2*z2; + const float y{in*gain - a1*z1 - a2*z2}; + const float out{y + b1*z1 + b2*z2}; z2 += z1; z1 += y; return out; }; - std::transform<const float*RESTRICT>(src, src+count, dst, proc_sample); - nfc->second.z[0] = z1; - nfc->second.z[1] = z2; + std::transform(src, src+count, dst, proc_sample); + second.z[0] = z1; + second.z[1] = z2; } -void NfcFilterProcess3(NfcFilter *nfc, float *RESTRICT dst, const float *RESTRICT src, const int count) +void NfcFilter::process3(float *RESTRICT dst, const float *RESTRICT src, const int count) { - const float gain = nfc->third.gain; - const float b1 = nfc->third.b1; - const float b2 = nfc->third.b2; - const float b3 = nfc->third.b3; - const float a1 = nfc->third.a1; - const float a2 = nfc->third.a2; - const float a3 = nfc->third.a3; - float z1 = nfc->third.z[0]; - float z2 = nfc->third.z[1]; - float z3 = nfc->third.z[2]; - ASSUME(count > 0); - auto proc_sample = [gain,b1,b2,b3,a1,a2,a3,&z1,&z2,&z3](float in) noexcept -> float + const float gain{third.gain}; + const float b1{third.b1}; + const float b2{third.b2}; + const float b3{third.b3}; + const float a1{third.a1}; + const float a2{third.a2}; + const float a3{third.a3}; + float z1{third.z[0]}; + float z2{third.z[1]}; + float z3{third.z[2]}; + auto proc_sample = [gain,b1,b2,b3,a1,a2,a3,&z1,&z2,&z3](const float in) noexcept -> float { - float y = in*gain - a1*z1 - a2*z2; - float out = y + b1*z1 + b2*z2; + float y{in*gain - a1*z1 - a2*z2}; + float out{y + b1*z1 + b2*z2}; z2 += z1; z1 += y; y = out - a3*z3; out = y + b3*z3; z3 += y; - return out; }; - std::transform<const float*RESTRICT>(src, src+count, dst, proc_sample); - nfc->third.z[0] = z1; - nfc->third.z[1] = z2; - nfc->third.z[2] = z3; + std::transform(src, src+count, dst, proc_sample); + third.z[0] = z1; + third.z[1] = z2; + third.z[2] = z3; } #if 0 /* Original methods the above are derived from. */ diff --git a/Alc/filters/nfc.h b/Alc/filters/nfc.h index d59280d0..40aca36e 100644 --- a/Alc/filters/nfc.h +++ b/Alc/filters/nfc.h @@ -1,10 +1,6 @@ #ifndef FILTER_NFC_H #define FILTER_NFC_H -#ifdef __cplusplus -extern "C" { -#endif - struct NfcFilter1 { float base_gain, gain; float b1, a1; @@ -21,37 +17,33 @@ struct NfcFilter3 { float z[3]; }; -typedef struct NfcFilter { - struct NfcFilter1 first; - struct NfcFilter2 second; - struct NfcFilter3 third; -} NfcFilter; - - -/* NOTE: - * w0 = speed_of_sound / (source_distance * sample_rate); - * w1 = speed_of_sound / (control_distance * sample_rate); - * - * Generally speaking, the control distance should be approximately the average - * speaker distance, or based on the reference delay if outputing NFC-HOA. It - * must not be negative, 0, or infinite. The source distance should not be too - * small relative to the control distance. - */ - -void NfcFilterCreate(NfcFilter *nfc, const float w0, const float w1); -void NfcFilterAdjust(NfcFilter *nfc, const float w0); - -/* Near-field control filter for first-order ambisonic channels (1-3). */ -void NfcFilterProcess1(NfcFilter *nfc, float *RESTRICT dst, const float *RESTRICT src, const int count); - -/* Near-field control filter for second-order ambisonic channels (4-8). */ -void NfcFilterProcess2(NfcFilter *nfc, float *RESTRICT dst, const float *RESTRICT src, const int count); - -/* Near-field control filter for third-order ambisonic channels (9-15). */ -void NfcFilterProcess3(NfcFilter *nfc, float *RESTRICT dst, const float *RESTRICT src, const int count); - -#ifdef __cplusplus -} // extern "C" -#endif +class NfcFilter { + NfcFilter1 first; + NfcFilter2 second; + NfcFilter3 third; + +public: + /* NOTE: + * w0 = speed_of_sound / (source_distance * sample_rate); + * w1 = speed_of_sound / (control_distance * sample_rate); + * + * Generally speaking, the control distance should be approximately the + * average speaker distance, or based on the reference delay if outputing + * NFC-HOA. It must not be negative, 0, or infinite. The source distance + * should not be too small relative to the control distance. + */ + + void init(const float w0, const float w1) noexcept; + void adjust(const float w0) noexcept; + + /* Near-field control filter for first-order ambisonic channels (1-3). */ + void process1(float *RESTRICT dst, const float *RESTRICT src, const int count); + + /* Near-field control filter for second-order ambisonic channels (4-8). */ + void process2(float *RESTRICT dst, const float *RESTRICT src, const int count); + + /* Near-field control filter for third-order ambisonic channels (9-15). */ + void process3(float *RESTRICT dst, const float *RESTRICT src, const int count); +}; #endif /* FILTER_NFC_H */ |