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