diff options
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.cc | 146 |
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 |