1 /*
2  *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "modules/audio_processing/aec3/cascaded_biquad_filter.h"
12 
13 #include <vector>
14 
15 #include "test/gtest.h"
16 
17 namespace webrtc {
18 
19 namespace {
20 
21 // Coefficients for a second order Butterworth high-pass filter with cutoff
22 // frequency 100 Hz.
23 const CascadedBiQuadFilter::BiQuadCoefficients kHighPassFilterCoefficients = {
24     {0.97261f, -1.94523f, 0.97261f},
25     {-1.94448f, 0.94598f}};
26 
27 const CascadedBiQuadFilter::BiQuadCoefficients kTransparentCoefficients = {
28     {1.f, 0.f, 0.f},
29     {0.f, 0.f}};
30 
31 const CascadedBiQuadFilter::BiQuadCoefficients kBlockingCoefficients = {
32     {0.f, 0.f, 0.f},
33     {0.f, 0.f}};
34 
CreateInputWithIncreasingValues(size_t vector_length)35 std::vector<float> CreateInputWithIncreasingValues(size_t vector_length) {
36   std::vector<float> v(vector_length);
37   for (size_t k = 0; k < v.size(); ++k) {
38     v[k] = k;
39   }
40   return v;
41 }
42 
43 }  // namespace
44 
45 // Verifies that the filter applies an effect which removes the input signal.
46 // The test also verifies that the in-place Process API call works as intended.
TEST(CascadedBiquadFilter,BlockingConfiguration)47 TEST(CascadedBiquadFilter, BlockingConfiguration) {
48   std::vector<float> values = CreateInputWithIncreasingValues(1000);
49 
50   CascadedBiQuadFilter filter(kBlockingCoefficients, 1);
51   filter.Process(values);
52 
53   EXPECT_EQ(std::vector<float>(1000, 0.f), values);
54 }
55 
56 // Verifies that the filter is able to form a zero-mean output from a
57 // non-zeromean input signal when coefficients for a high-pass filter are
58 // applied. The test also verifies that the filter works with multiple biquads.
TEST(CascadedBiquadFilter,HighPassConfiguration)59 TEST(CascadedBiquadFilter, HighPassConfiguration) {
60   std::vector<float> values(1000);
61   for (size_t k = 0; k < values.size(); ++k) {
62     values[k] = 1.f;
63   }
64 
65   CascadedBiQuadFilter filter(kHighPassFilterCoefficients, 2);
66   filter.Process(values);
67 
68   for (size_t k = values.size() / 2; k < values.size(); ++k) {
69     EXPECT_NEAR(0.f, values[k], 1e-4);
70   }
71 }
72 
73 // Verifies that the filter is able to produce a transparent effect with no
74 // impact on the data when the proper coefficients are applied. The test also
75 // verifies that the non-in-place Process API call works as intended.
TEST(CascadedBiquadFilter,TransparentConfiguration)76 TEST(CascadedBiquadFilter, TransparentConfiguration) {
77   const std::vector<float> input = CreateInputWithIncreasingValues(1000);
78   std::vector<float> output(input.size());
79 
80   CascadedBiQuadFilter filter(kTransparentCoefficients, 1);
81   filter.Process(input, output);
82 
83   EXPECT_EQ(input, output);
84 }
85 
86 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
87 // Verifies that the check of the lengths for the input and output works for the
88 // non-in-place call.
TEST(CascadedBiquadFilter,InputSizeCheckVerification)89 TEST(CascadedBiquadFilter, InputSizeCheckVerification) {
90   const std::vector<float> input = CreateInputWithIncreasingValues(10);
91   std::vector<float> output(input.size() - 1);
92 
93   CascadedBiQuadFilter filter(kTransparentCoefficients, 1);
94   EXPECT_DEATH(filter.Process(input, output), "");
95 }
96 #endif
97 
98 }  // namespace webrtc
99