summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/resonance-audio/resonance_audio/dsp/filter_coefficient_generators_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/resonance-audio/resonance_audio/dsp/filter_coefficient_generators_test.cc')
-rw-r--r--src/3rdparty/resonance-audio/resonance_audio/dsp/filter_coefficient_generators_test.cc146
1 files changed, 146 insertions, 0 deletions
diff --git a/src/3rdparty/resonance-audio/resonance_audio/dsp/filter_coefficient_generators_test.cc b/src/3rdparty/resonance-audio/resonance_audio/dsp/filter_coefficient_generators_test.cc
new file mode 100644
index 000000000..163b6a6d2
--- /dev/null
+++ b/src/3rdparty/resonance-audio/resonance_audio/dsp/filter_coefficient_generators_test.cc
@@ -0,0 +1,146 @@
+/*
+Copyright 2018 Google Inc. All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS-IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+#include "dsp/filter_coefficient_generators.h"
+
+#include "third_party/googletest/googletest/include/gtest/gtest.h"
+
+namespace vraudio {
+
+namespace {
+
+// Allowable error between filter coefficients.
+const float kErrorf = 1e-5f;
+
+// Input into the ComputeLowPassBiquadCoefficients() function.
+const int kSampleRate = 44100;
+const float kSpecificationFrequency = 13000.0f;
+const float kAttenuation = -15.0f;
+
+const float kMonoPoleCoefficient = 0.94863985f;
+
+// These filter coefficients were calculated in MATLAB with a specified Q value
+// of 0.17775. The attenuation at the specification frequency was then
+// calculated from the MATLAB freqz() calls.
+const BiquadCoefficients kIdealCoefficients(3.70224817628938f,
+ 0.555382147099001f,
+ -1.70224817628938f,
+ 0.63884553677475f, 1.2776910735495f,
+ 0.63884553677475f);
+
+// These filter coefficients were calculated in MATLAB for a centre_frequency of
+// 8kHz and a bandwidth of 1 octave.
+const BiquadCoefficients kIdealBandpassCoefficients(1.37364799922092f, -1.0f,
+ 0.626352000779082f,
+ 0.373647999220918f, 0.0f,
+ -0.373647999220918f);
+
+const float kBandPassCenterFrequency = 8000.0f;
+const int kBandPassOctaveBandwidth = 1;
+
+// Input into the ComputeDualBandBiquadCoefficients() function.
+const int kSampleRate48 = 48000;
+const float kCrossoverFrequency = 380.0f;
+
+// Pre-computed coefficients for the phase-matched filter pair (dual-band) with
+// the cross-over frequency set at 380Hz and the sample rate 48kHz.
+const float kLowPassA[] = {1.0f, -1.9029109f, 0.90526748f};
+const float kLowPassB[] = {0.00058914319f, 0.0011782864f, 0.00058914319f};
+const float kHighPassA[] = {1.0f, -1.9029109f, 0.90526748f};
+const float kHighPassB[] = {0.95204461f, -1.9040892f, 0.95204461f};
+
+TEST(FilterCoefficientGeneratorsTest, ComputeMonoPoleLowpassCoefficientTest) {
+ float coefficient =
+ ComputeLowPassMonoPoleCoefficient(kCrossoverFrequency, kSampleRate);
+ EXPECT_NEAR(kMonoPoleCoefficient, coefficient, kErrorf);
+
+ const float twenty_hertz = 20.0f;
+ coefficient = ComputeLowPassMonoPoleCoefficient(twenty_hertz, kSampleRate);
+ EXPECT_EQ(0.0f, coefficient);
+ // New test for the case where a frequency below 20Hz is passed.
+}
+
+// Tests that the BiquadCoefficients generated by
+// ComputeBandPassBiquadCoefficients() match those known to be correct as
+// directly calculated from MATLAB.
+TEST(FilterCoefficientGeneratorsTest, ComputeBandPassBiquadCoefficientsTest) {
+ // Perform computation.
+ BiquadCoefficients biquad_filter_coefficients =
+ ComputeBandPassBiquadCoefficients(kSampleRate48, kBandPassCenterFrequency,
+ kBandPassOctaveBandwidth);
+
+ // Make sure they are all equal.
+ for (size_t i = 0; i < biquad_filter_coefficients.a.size(); ++i) {
+ EXPECT_NEAR(kIdealBandpassCoefficients.a[i],
+ biquad_filter_coefficients.a[i], kErrorf);
+ EXPECT_NEAR(kIdealBandpassCoefficients.b[i],
+ biquad_filter_coefficients.b[i], kErrorf);
+ }
+}
+
+// Tests that the BiquadCoefficients generated by
+// ComputeLowPassBiquadCoefficients() match those known to be correct as
+// directly calculated from MATLAB. This also tests the validity of the inherent
+// 4th order best fit between attenuation at a specified frequency and Q factor.
+TEST(FilterCoefficientGeneratorsTest, ComputeLowPassBiquadCoefficientsTest) {
+ // Perform computation.
+ BiquadCoefficients biquad_filter_coefficients =
+ ComputeLowPassBiquadCoefficients(kSampleRate, kSpecificationFrequency,
+ kAttenuation);
+
+ // Make sure they are all equal.
+ for (size_t i = 0; i < biquad_filter_coefficients.a.size(); ++i) {
+ EXPECT_NEAR(kIdealCoefficients.a[i], biquad_filter_coefficients.a[i],
+ kErrorf);
+ EXPECT_NEAR(kIdealCoefficients.b[i], biquad_filter_coefficients.b[i],
+ kErrorf);
+ }
+}
+
+// Tests that the BiquadCoefficients generated by
+// ComputeDualBandBiquadCoefficients() match those known to be correct as
+// directly calculated from MATLAB. These coefficients are as described in:
+// http://www.ai.sri.com/ajh/ambisonics/BLaH3.pdf.
+TEST(DualBandBiquadCoefficientsTest, ComputeDualBandBiquadCoefficientsTest) {
+ // Generate default bi-quad coefficients and constructs low- and high-pass
+ // filter coefficients.
+ const BiquadCoefficients kDefaultCoefficients;
+ BiquadCoefficients low_pass_coefficients(kDefaultCoefficients);
+ BiquadCoefficients high_pass_coefficients(kDefaultCoefficients);
+
+ // Perform computation.
+ ComputeDualBandBiquadCoefficients(kSampleRate48, kCrossoverFrequency,
+ &low_pass_coefficients,
+ &high_pass_coefficients);
+
+ // Check if arrays with a and b coefficients for both filters are of the
+ // same size.
+ ASSERT_EQ(low_pass_coefficients.a.size(), low_pass_coefficients.b.size());
+ ASSERT_EQ(high_pass_coefficients.a.size(), low_pass_coefficients.a.size());
+ ASSERT_EQ(high_pass_coefficients.b.size(), low_pass_coefficients.b.size());
+
+ // Make sure they are all equal.
+ for (size_t i = 0; i < low_pass_coefficients.a.size(); ++i) {
+ EXPECT_NEAR(low_pass_coefficients.a[i], kLowPassA[i], kErrorf);
+ EXPECT_NEAR(low_pass_coefficients.b[i], kLowPassB[i], kErrorf);
+ EXPECT_NEAR(high_pass_coefficients.a[i], kHighPassA[i], kErrorf);
+ EXPECT_NEAR(high_pass_coefficients.b[i], kHighPassB[i], kErrorf);
+ }
+}
+
+} // namespace
+
+} // namespace vraudio