Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(20)

Side by Side Diff: webrtc/modules/audio_processing/aec3/suppression_filter_unittest.cc

Issue 2678423005: Finalization of the first version of EchoCanceller 3 (Closed)
Patch Set: Fixed compilation error Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright (c) 2017 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 "webrtc/modules/audio_processing/aec3/suppression_filter.h"
12
13 #include <math.h>
14 #include <algorithm>
15 #include <numeric>
16
17 #include "webrtc/test/gtest.h"
18
19 namespace webrtc {
20 namespace {
21
22 constexpr float kPi = 3.141592f;
23
24 void ProduceSinusoid(int sample_rate_hz,
25 float sinusoidal_frequency_hz,
26 size_t* sample_counter,
27 rtc::ArrayView<float> x) {
28 // Produce a sinusoid of the specified frequency.
29 for (size_t k = *sample_counter, j = 0; k < (*sample_counter + kBlockSize);
30 ++k, ++j) {
31 x[j] =
32 32767.f * sin(2.f * kPi * sinusoidal_frequency_hz * k / sample_rate_hz);
33 }
34 *sample_counter = *sample_counter + kBlockSize;
35 }
36
37 } // namespace
38
39 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
40
41 // Verifies the check for null suppressor output.
42 TEST(SuppressionFilter, NullOutput) {
43 FftData cn;
44 FftData cn_high_bands;
45 std::array<float, kFftLengthBy2Plus1> gain;
46
47 EXPECT_DEATH(
48 SuppressionFilter(16000).ApplyGain(cn, cn_high_bands, gain, nullptr), "");
49 }
50
51 // Verifies the check for allowed sample rate.
52 TEST(SuppressionFilter, ProperSampleRate) {
53 EXPECT_DEATH(SuppressionFilter(16001), "");
54 }
55
56 #endif
57
58 // Verifies that no comfort noise is added when the gain is 1.
59 TEST(SuppressionFilter, ComfortNoiseInUnityGain) {
60 SuppressionFilter filter(48000);
61 FftData cn;
62 FftData cn_high_bands;
63 std::array<float, kFftLengthBy2Plus1> gain;
64
65 gain.fill(1.f);
66 cn.re.fill(1.f);
67 cn.im.fill(1.f);
68 cn_high_bands.re.fill(1.f);
69 cn_high_bands.im.fill(1.f);
70
71 std::vector<std::vector<float>> e(3, std::vector<float>(kBlockSize, 0.f));
72 std::vector<std::vector<float>> e_ref = e;
73 filter.ApplyGain(cn, cn_high_bands, gain, &e);
74
75 for (size_t k = 0; k < e.size(); ++k) {
76 EXPECT_EQ(e_ref[k], e[k]);
77 }
78 }
79
80 // Verifies that the suppressor is able to suppress a signal.
81 TEST(SuppressionFilter, SignalSuppression) {
82 SuppressionFilter filter(48000);
83 FftData cn;
84 FftData cn_high_bands;
85 std::array<float, kFftLengthBy2Plus1> gain;
86 std::vector<std::vector<float>> e(3, std::vector<float>(kBlockSize, 0.f));
87
88 gain.fill(1.f);
89 std::for_each(gain.begin() + 10, gain.end(), [](float& a) { a = 0.f; });
90
91 cn.re.fill(0.f);
92 cn.im.fill(0.f);
93 cn_high_bands.re.fill(0.f);
94 cn_high_bands.im.fill(0.f);
95
96 size_t sample_counter = 0;
97
98 float e0_input = 0.f;
99 float e0_output = 0.f;
100 for (size_t k = 0; k < 100; ++k) {
101 ProduceSinusoid(16000, 16000 * 40 / kFftLengthBy2 / 2, &sample_counter,
102 e[0]);
103 e0_input =
104 std::inner_product(e[0].begin(), e[0].end(), e[0].begin(), e0_input);
105 filter.ApplyGain(cn, cn_high_bands, gain, &e);
106 e0_output =
107 std::inner_product(e[0].begin(), e[0].end(), e[0].begin(), e0_output);
108 }
109
110 EXPECT_LT(e0_output, e0_input / 1000.f);
111 }
112
113 // Verifies that the suppressor is able to pass through a desired signal while
114 // applying suppressing for some frequencies.
115 TEST(SuppressionFilter, SignalTransparency) {
116 SuppressionFilter filter(48000);
117 FftData cn;
118 FftData cn_high_bands;
119 std::array<float, kFftLengthBy2Plus1> gain;
120 std::vector<std::vector<float>> e(3, std::vector<float>(kBlockSize, 0.f));
121
122 gain.fill(1.f);
123 std::for_each(gain.begin() + 30, gain.end(), [](float& a) { a = 0.f; });
124
125 cn.re.fill(0.f);
126 cn.im.fill(0.f);
127 cn_high_bands.re.fill(0.f);
128 cn_high_bands.im.fill(0.f);
129
130 size_t sample_counter = 0;
131
132 float e0_input = 0.f;
133 float e0_output = 0.f;
134 for (size_t k = 0; k < 100; ++k) {
135 ProduceSinusoid(16000, 16000 * 10 / kFftLengthBy2 / 2, &sample_counter,
136 e[0]);
137 e0_input =
138 std::inner_product(e[0].begin(), e[0].end(), e[0].begin(), e0_input);
139 filter.ApplyGain(cn, cn_high_bands, gain, &e);
140 e0_output =
141 std::inner_product(e[0].begin(), e[0].end(), e[0].begin(), e0_output);
142 }
143
144 EXPECT_LT(0.9f * e0_input, e0_output);
145 }
146
147 // Verifies that the suppressor delay.
148 TEST(SuppressionFilter, Delay) {
149 SuppressionFilter filter(48000);
150 FftData cn;
151 FftData cn_high_bands;
152 std::array<float, kFftLengthBy2Plus1> gain;
153 std::vector<std::vector<float>> e(3, std::vector<float>(kBlockSize, 0.f));
154
155 gain.fill(1.f);
156
157 cn.re.fill(0.f);
158 cn.im.fill(0.f);
159 cn_high_bands.re.fill(0.f);
160 cn_high_bands.im.fill(0.f);
161
162 for (size_t k = 0; k < 100; ++k) {
163 for (size_t j = 0; j < 3; ++j) {
164 for (size_t i = 0; i < kBlockSize; ++i) {
165 e[j][i] = k * kBlockSize + i;
166 }
167 }
168
169 filter.ApplyGain(cn, cn_high_bands, gain, &e);
170 if (k > 2) {
171 for (size_t j = 0; j < 2; ++j) {
172 for (size_t i = 0; i < kBlockSize; ++i) {
173 EXPECT_NEAR(k * kBlockSize + i - kBlockSize, e[j][i], 0.01);
174 }
175 }
176 }
177 }
178 }
179
180 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698