From d0e75bb438b400b3e24979b1775b8e019fc99bff Mon Sep 17 00:00:00 2001 From: MerryMage Date: Sat, 22 Apr 2017 09:46:39 +0100 Subject: [PATCH 1/7] DPL2Decoder: Remove unnecessary pointer arguments of DesignFIR --- Source/Core/AudioCommon/DPL2Decoder.cpp | 26 ++++++++++++------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/Source/Core/AudioCommon/DPL2Decoder.cpp b/Source/Core/AudioCommon/DPL2Decoder.cpp index fa483249e6..8b2f0e53b2 100644 --- a/Source/Core/AudioCommon/DPL2Decoder.cpp +++ b/Source/Core/AudioCommon/DPL2Decoder.cpp @@ -105,9 +105,7 @@ static void Hamming(int n, float* w) *w++ = float(0.54 - 0.46 * cos(k * (float)i)); } -/****************************************************************************** -* FIR filter design -******************************************************************************/ +// FIR filter design /* Design FIR filter using the Window method @@ -122,10 +120,10 @@ opt beta constant used only when designing using kaiser windows returns 0 if OK, -1 if fail */ -static float* DesignFIR(unsigned int* n, float* fc, float opt) +static float* DesignFIR(unsigned int n, float fc, float opt) { - unsigned int o = *n & 1; // Indicator for odd filter length - unsigned int end = ((*n + 1) >> 1) - o; // Loop end + unsigned int o = n & 1; // Indicator for odd filter length + unsigned int end = ((n + 1) >> 1) - o; // Loop end float k1 = 2 * float(M_PI); // 2*pi*fc1 float k2 = 0.5f * (float)(1 - o); // Constant used if the filter has even length @@ -134,17 +132,17 @@ static float* DesignFIR(unsigned int* n, float* fc, float opt) float fc1; // Cutoff frequencies // Sanity check - if (*n == 0) + if (n == 0) return nullptr; - fc[0] = MathUtil::Clamp(fc[0], 0.001f, 1.0f); + fc = MathUtil::Clamp(fc, 0.001f, 1.0f); - float* w = (float*)calloc(sizeof(float), *n); + float* w = (float*)calloc(sizeof(float), n); // Get window coefficients - Hamming(*n, w); + Hamming(n, w); - fc1 = *fc; + fc1 = fc; // Cutoff frequency must be < 0.5 where 0.5 <=> Fs/2 fc1 = ((fc1 <= 1.0) && (fc1 > 0.0)) ? fc1 / 2 : 0.25f; k1 *= fc1; @@ -165,13 +163,13 @@ static float* DesignFIR(unsigned int* n, float* fc, float opt) for (u32 i = 0; i < end; i++) { t1 = (float)(i + 1) - k2; - w[end - i - 1] = w[*n - end + i] = float(w[end - i - 1] * sin(k1 * t1) / (M_PI * t1)); // Sinc + w[end - i - 1] = w[n - end + i] = float(w[end - i - 1] * sin(k1 * t1) / (M_PI * t1)); // Sinc g += 2 * w[end - i - 1]; // Total gain in filter } // Normalize gain g = 1 / g; - for (u32 i = 0; i < *n; i++) + for (u32 i = 0; i < n; i++) w[i] *= g; return w; @@ -209,7 +207,7 @@ static float* CalculateCoefficients125HzLowpass(int rate) { len125 = 256; float f = 125.0f / (rate / 2); - float* coeffs = DesignFIR(&len125, &f, 0); + float* coeffs = DesignFIR(len125, f, 0); static const float M3_01DB = 0.7071067812f; for (unsigned int i = 0; i < len125; i++) { From 24027c1d4adc230121fea67d201265eca9e109a1 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Sat, 22 Apr 2017 09:47:10 +0100 Subject: [PATCH 2/7] DPL2Decoder: Reduce scope of variable in DesignFIR --- Source/Core/AudioCommon/DPL2Decoder.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Source/Core/AudioCommon/DPL2Decoder.cpp b/Source/Core/AudioCommon/DPL2Decoder.cpp index 8b2f0e53b2..a6b301fc5a 100644 --- a/Source/Core/AudioCommon/DPL2Decoder.cpp +++ b/Source/Core/AudioCommon/DPL2Decoder.cpp @@ -128,7 +128,6 @@ static float* DesignFIR(unsigned int n, float fc, float opt) float k1 = 2 * float(M_PI); // 2*pi*fc1 float k2 = 0.5f * (float)(1 - o); // Constant used if the filter has even length float g = 0.0f; // Gain - float t1; // Temporary variables float fc1; // Cutoff frequencies // Sanity check @@ -162,9 +161,10 @@ static float* DesignFIR(unsigned int n, float fc, float opt) // Create filter for (u32 i = 0; i < end; i++) { - t1 = (float)(i + 1) - k2; - w[end - i - 1] = w[n - end + i] = float(w[end - i - 1] * sin(k1 * t1) / (M_PI * t1)); // Sinc - g += 2 * w[end - i - 1]; // Total gain in filter + float t1 = static_cast(i + 1) - k2; + w[end - i - 1] = w[n - end + i] = + static_cast(w[end - i - 1] * sin(k1 * t1) / (M_PI * t1)); // Sinc + g += 2 * w[end - i - 1]; // Total gain in filter } // Normalize gain From 751351fd20443d855f4d7d50754ec0d1001f6a97 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Sat, 22 Apr 2017 09:49:46 +0100 Subject: [PATCH 3/7] DPL2Decoder: Simplify cut-off frequency logic in DesignFIR --- Source/Core/AudioCommon/DPL2Decoder.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Source/Core/AudioCommon/DPL2Decoder.cpp b/Source/Core/AudioCommon/DPL2Decoder.cpp index a6b301fc5a..6c8be523bf 100644 --- a/Source/Core/AudioCommon/DPL2Decoder.cpp +++ b/Source/Core/AudioCommon/DPL2Decoder.cpp @@ -134,16 +134,13 @@ static float* DesignFIR(unsigned int n, float fc, float opt) if (n == 0) return nullptr; - fc = MathUtil::Clamp(fc, 0.001f, 1.0f); - float* w = (float*)calloc(sizeof(float), n); // Get window coefficients Hamming(n, w); - fc1 = fc; // Cutoff frequency must be < 0.5 where 0.5 <=> Fs/2 - fc1 = ((fc1 <= 1.0) && (fc1 > 0.0)) ? fc1 / 2 : 0.25f; + fc1 = MathUtil::Clamp(fc, 0.001f, 1.0f) / 2; k1 *= fc1; // Low pass filter From 71dc81041865e9849ac491ab577a01b5bc82f3d4 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Sat, 22 Apr 2017 09:51:26 +0100 Subject: [PATCH 4/7] DPL2Decoder: Make constant variables const in DesignFIR --- Source/Core/AudioCommon/DPL2Decoder.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/Source/Core/AudioCommon/DPL2Decoder.cpp b/Source/Core/AudioCommon/DPL2Decoder.cpp index 6c8be523bf..9ac95a26d1 100644 --- a/Source/Core/AudioCommon/DPL2Decoder.cpp +++ b/Source/Core/AudioCommon/DPL2Decoder.cpp @@ -122,13 +122,15 @@ returns 0 if OK, -1 if fail */ static float* DesignFIR(unsigned int n, float fc, float opt) { - unsigned int o = n & 1; // Indicator for odd filter length - unsigned int end = ((n + 1) >> 1) - o; // Loop end + const unsigned int o = n & 1; // Indicator for odd filter length + const unsigned int end = ((n + 1) >> 1) - o; // Loop end - float k1 = 2 * float(M_PI); // 2*pi*fc1 - float k2 = 0.5f * (float)(1 - o); // Constant used if the filter has even length - float g = 0.0f; // Gain - float fc1; // Cutoff frequencies + // Cutoff frequency must be < 0.5 where 0.5 <=> Fs/2 + const float fc1 = MathUtil::Clamp(fc, 0.001f, 1.0f) / 2; + + const float k1 = 2 * static_cast(M_PI) * fc1; // Cutoff frequency in rad/s + const float k2 = 0.5f * static_cast(1 - o); // Time offset if filter has even length + float g = 0.0f; // Gain // Sanity check if (n == 0) @@ -139,10 +141,6 @@ static float* DesignFIR(unsigned int n, float fc, float opt) // Get window coefficients Hamming(n, w); - // Cutoff frequency must be < 0.5 where 0.5 <=> Fs/2 - fc1 = MathUtil::Clamp(fc, 0.001f, 1.0f) / 2; - k1 *= fc1; - // Low pass filter // If the filter length is odd, there is one point which is exactly From 42a1f7939d00e38e8a9c29f593b792d06126f41e Mon Sep 17 00:00:00 2001 From: MerryMage Date: Sat, 22 Apr 2017 10:01:26 +0100 Subject: [PATCH 5/7] DPL2Decoder: Prefer std::vector to calloc-ed array --- Source/Core/AudioCommon/DPL2Decoder.cpp | 59 +++++++++++-------------- 1 file changed, 27 insertions(+), 32 deletions(-) diff --git a/Source/Core/AudioCommon/DPL2Decoder.cpp b/Source/Core/AudioCommon/DPL2Decoder.cpp index 9ac95a26d1..6ec8d55144 100644 --- a/Source/Core/AudioCommon/DPL2Decoder.cpp +++ b/Source/Core/AudioCommon/DPL2Decoder.cpp @@ -10,8 +10,8 @@ #include #include #include +#include #include -#include #include #include "AudioCommon/DPL2Decoder.h" @@ -35,11 +35,11 @@ static float adapt_l_gain, adapt_r_gain, adapt_lpr_gain, adapt_lmr_gain; static std::vector lf, rf, lr, rr, cf, cr; static float LFE_buf[256]; static unsigned int lfe_pos; -static float* filter_coefs_lfe; +static std::vector filter_coefs_lfe; static unsigned int len125; -template -static _ftype_t DotProduct(int count, const T* buf, const _ftype_t* coefficients) +template +static float DotProduct(int count, const T* buf, const std::vector& coeffs, int offset) { int i; float sum0 = 0.0f, sum1 = 0.0f, sum2 = 0.0f, sum3 = 0.0f; @@ -47,21 +47,21 @@ static _ftype_t DotProduct(int count, const T* buf, const _ftype_t* coefficients // Unrolled loop for (i = 0; (i + 3) < count; i += 4) { - sum0 += buf[i + 0] * coefficients[i + 0]; - sum1 += buf[i + 1] * coefficients[i + 1]; - sum2 += buf[i + 2] * coefficients[i + 2]; - sum3 += buf[i + 3] * coefficients[i + 3]; + sum0 += buf[i + 0] * coeffs[offset + i + 0]; + sum1 += buf[i + 1] * coeffs[offset + i + 1]; + sum2 += buf[i + 2] * coeffs[offset + i + 2]; + sum3 += buf[i + 3] * coeffs[offset + i + 3]; } // Epilogue of unrolled loop for (; i < count; i++) - sum0 += buf[i] * coefficients[i]; + sum0 += buf[i] * coeffs[offset + i]; return sum0 + sum1 + sum2 + sum3; } template -static T FIRFilter(const T* buf, int pos, int len, int count, const float* coefficients) +static T FIRFilter(const T* buf, int pos, int len, int count, const std::vector& coeffs) { int count1, count2; @@ -81,9 +81,8 @@ static T FIRFilter(const T* buf, int pos, int len, int count, const float* coeff // high part of window const T* ptr = &buf[pos]; - float r1 = DotProduct(count1, ptr, coefficients); - coefficients += count1; - float r2 = DotProduct(count2, buf, coefficients); + float r1 = DotProduct(count1, ptr, coeffs, 0); + float r2 = DotProduct(count2, buf, coeffs, count1); return T(r1 + r2); } @@ -94,15 +93,19 @@ static T FIRFilter(const T* buf, int pos, int len, int count, const float* coeff // N-1 // // n window length -// w buffer for the window parameters +// returns buffer with the window parameters */ -static void Hamming(int n, float* w) +static std::vector Hamming(int n) { + std::vector w(n); + float k = float(2 * M_PI / ((float)(n - 1))); // 2*pi/(N-1) // Calculate window coefficients for (int i = 0; i < n; i++) - *w++ = float(0.54 - 0.46 * cos(k * (float)i)); + w[i] = float(0.54 - 0.46 * cos(k * (float)i)); + + return w; } // FIR filter design @@ -110,7 +113,6 @@ static void Hamming(int n, float* w) /* Design FIR filter using the Window method n filter length must be odd for HP and BS filters -w buffer for the filter taps (must be n long) fc cutoff frequencies (1 for LP and HP, 2 for BP and BS) 0 < fc < 1 where 1 <=> Fs/2 flags window and filter type as defined in filter.h @@ -118,9 +120,9 @@ variables are ored together: i.e. LP|HAMMING will give a low pass filter designed using a hamming window opt beta constant used only when designing using kaiser windows -returns 0 if OK, -1 if fail +returns buffer for the filter taps (will be n long) */ -static float* DesignFIR(unsigned int n, float fc, float opt) +static std::vector DesignFIR(unsigned int n, float fc, float opt) { const unsigned int o = n & 1; // Indicator for odd filter length const unsigned int end = ((n + 1) >> 1) - o; // Loop end @@ -134,12 +136,10 @@ static float* DesignFIR(unsigned int n, float fc, float opt) // Sanity check if (n == 0) - return nullptr; - - float* w = (float*)calloc(sizeof(float), n); + return {}; // Get window coefficients - Hamming(n, w); + std::vector w = Hamming(n); // Low pass filter @@ -190,19 +190,14 @@ static void Done() { OnSeek(); - if (filter_coefs_lfe) - { - free(filter_coefs_lfe); - } - - filter_coefs_lfe = nullptr; + filter_coefs_lfe.clear(); } -static float* CalculateCoefficients125HzLowpass(int rate) +static std::vector CalculateCoefficients125HzLowpass(int rate) { len125 = 256; float f = 125.0f / (rate / 2); - float* coeffs = DesignFIR(len125, f, 0); + std::vector coeffs = DesignFIR(len125, f, 0); static const float M3_01DB = 0.7071067812f; for (unsigned int i = 0; i < len125; i++) { @@ -380,5 +375,5 @@ void DPL2Reset() { olddelay = -1; oldfreq = 0; - filter_coefs_lfe = nullptr; + filter_coefs_lfe.clear(); } From 4f884d0b2fd2dbbc11caa45477017885b90f32a9 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Sat, 22 Apr 2017 21:23:19 +0100 Subject: [PATCH 6/7] DPL2Decoder: Simplify DotProduct --- Source/Core/AudioCommon/DPL2Decoder.cpp | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/Source/Core/AudioCommon/DPL2Decoder.cpp b/Source/Core/AudioCommon/DPL2Decoder.cpp index 6ec8d55144..29fc60b719 100644 --- a/Source/Core/AudioCommon/DPL2Decoder.cpp +++ b/Source/Core/AudioCommon/DPL2Decoder.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include "AudioCommon/DPL2Decoder.h" @@ -41,23 +42,7 @@ static unsigned int len125; template static float DotProduct(int count, const T* buf, const std::vector& coeffs, int offset) { - int i; - float sum0 = 0.0f, sum1 = 0.0f, sum2 = 0.0f, sum3 = 0.0f; - - // Unrolled loop - for (i = 0; (i + 3) < count; i += 4) - { - sum0 += buf[i + 0] * coeffs[offset + i + 0]; - sum1 += buf[i + 1] * coeffs[offset + i + 1]; - sum2 += buf[i + 2] * coeffs[offset + i + 2]; - sum3 += buf[i + 3] * coeffs[offset + i + 3]; - } - - // Epilogue of unrolled loop - for (; i < count; i++) - sum0 += buf[i] * coeffs[offset + i]; - - return sum0 + sum1 + sum2 + sum3; + return std::inner_product(buf, buf + count, coeffs.begin() + offset, T(0)); } template From c9f50fd4ed95ae74c790f10c0ac5ffc334d7caec Mon Sep 17 00:00:00 2001 From: MerryMage Date: Sat, 22 Apr 2017 21:24:47 +0100 Subject: [PATCH 7/7] DPL2Decoder: Prefer static_cast to C-style casts --- Source/Core/AudioCommon/DPL2Decoder.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Source/Core/AudioCommon/DPL2Decoder.cpp b/Source/Core/AudioCommon/DPL2Decoder.cpp index 29fc60b719..c48026003a 100644 --- a/Source/Core/AudioCommon/DPL2Decoder.cpp +++ b/Source/Core/AudioCommon/DPL2Decoder.cpp @@ -84,11 +84,11 @@ static std::vector Hamming(int n) { std::vector w(n); - float k = float(2 * M_PI / ((float)(n - 1))); // 2*pi/(N-1) + float k = static_cast(2.0 * M_PI / (n - 1)); // Calculate window coefficients for (int i = 0; i < n; i++) - w[i] = float(0.54 - 0.46 * cos(k * (float)i)); + w[i] = static_cast(0.54 - 0.46 * cos(k * i)); return w; } @@ -238,10 +238,10 @@ static void MatrixDecode(const float* in, const int k, const int il, const int i /* Matrix */ l_agc = in[il] * PassiveLock(*_adapt_l_gain); r_agc = in[ir] * PassiveLock(*_adapt_r_gain); - _cf[k] = (l_agc + r_agc) * (float)M_SQRT1_2; + _cf[k] = (l_agc + r_agc) * static_cast(M_SQRT1_2); if (decode_rear) { - _lr[kr] = _rr[kr] = (l_agc - r_agc) * (float)M_SQRT1_2; + _lr[kr] = _rr[kr] = (l_agc - r_agc) * static_cast(M_SQRT1_2); // Stereo rear channel is steered with the same AGC steering as // the decoding matrix. Note this requires a fast updating AGC // at the order of 20 ms (which is the case here). @@ -250,8 +250,8 @@ static void MatrixDecode(const float* in, const int k, const int il, const int i } /*** AXIS NO. 2: (Lt + Rt, Lt - Rt) -> (L, R) ***/ - lpr = (in[il] + in[ir]) * (float)M_SQRT1_2; - lmr = (in[il] - in[ir]) * (float)M_SQRT1_2; + lpr = (in[il] + in[ir]) * static_cast(M_SQRT1_2); + lmr = (in[il] - in[ir]) * static_cast(M_SQRT1_2); /* AGC adaption */ d_gain = fabs(lmr_unlim_gain - *_adapt_lmr_gain); f = d_gain * (1.0f / MATAGCTRIG); @@ -261,8 +261,8 @@ static void MatrixDecode(const float* in, const int k, const int il, const int i /* Matrix */ lpr_agc = lpr * PassiveLock(*_adapt_lpr_gain); lmr_agc = lmr * PassiveLock(*_adapt_lmr_gain); - _lf[k] = (lpr_agc + lmr_agc) * (float)M_SQRT1_2; - _rf[k] = (lpr_agc - lmr_agc) * (float)M_SQRT1_2; + _lf[k] = (lpr_agc + lmr_agc) * static_cast(M_SQRT1_2); + _rf[k] = (lpr_agc - lmr_agc) * static_cast(M_SQRT1_2); /*** CENTER FRONT CANCELLATION ***/ // A heuristic approach exploits that Lt + Rt gain contains the