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

Side by Side Diff: webrtc/modules/audio_processing/intelligibility/intelligibility_enhancer_unittest.cc

Issue 1207353002: Add new variance update option and unittests for intelligibility (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Addressed comments from hlundin Created 5 years, 5 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) 2015 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 //
12 // Unit tests for intelligibility enhancer.
13 //
14
15 #include <math.h>
16 #include <algorithm>
17 #include <vector>
18
19 #include "testing/gtest/include/gtest/gtest.h"
20 #include "webrtc/base/arraysize.h"
21 #include "webrtc/common_audio/signal_processing/include/signal_processing_librar y.h"
22 #include "webrtc/modules/audio_processing/intelligibility/intelligibility_enhanc er.h"
23
24 namespace {
25
26 // Generated with matlab code: normrnd(0,1000,64,1).
27 const double kGaussianSamples[] = {
28 1689.1, 1437, -2251.1, 356.49, -850.24, -299.55, -634.25, 1624.5,
29 1241.1, 555.28, 703.42, 458.16, 683.98, 251.29, -178.5, 507.73,
30 -309.9, -394.37, -269.74, -88.13, 8.0293, 2531.8, -1223.2, -1071.8,
31 246.06, -50.611, -730.15, 326.99, 752.99, -1153.7, -407.87, -1287.9,
32 83.578, 163.8, 682.57, -1086.4, 297.49, -143.31, 1392, 306.75,
33 -537.18, -228.93, -536.22, 1439, -511.1, -1606.8, -201.24, 1143.5,
34 663.29, 164.08, 1785.4, -587.71, 259.04, -871.83, -787.92, -344.34,
35 647.62, 2054.1, 798.94, -1071.1, -205.16, -554.44, -292.94, 1180.2};
36 static_assert(arraysize(kGaussianSamples) == 64, "Samples badly initialized.");
37
hlundin-webrtc 2015/07/02 10:53:13 You have a blank line here that is not present bet
ekm 2015/07/07 21:57:02 Done.
38 // Target output for ERB create test. Generated with matlab.
39 const double kTestCenterFreqs[] = {
40 13.169, 26.965, 41.423, 56.577, 72.461, 89.113, 106.57, 124.88,
41 144.08, 164.21, 185.34, 207.5, 230.75, 255.16, 280.77, 307.66,
42 335.9, 365.56, 396.71, 429.44, 463.84, 500};
43 const double kTestFilterBank[][2] = {{0.055556, 0},
44 {0.055556, 0},
45 {0.055556, 0},
46 {0.055556, 0},
47 {0.055556, 0},
48 {0.055556, 0},
49 {0.055556, 0},
50 {0.055556, 0},
51 {0.055556, 0},
52 {0.055556, 0},
53 {0.055556, 0},
54 {0.055556, 0},
55 {0.055556, 0},
56 {0.055556, 0},
57 {0.055556, 0},
58 {0.055556, 0},
59 {0.055556, 0},
60 {0.055556, 0.2},
61 {0, 0.2},
62 {0, 0.2},
63 {0, 0.2},
64 {0, 0.2}};
65 static_assert(arraysize(kTestCenterFreqs) == arraysize(kTestFilterBank),
66 "Test filterbank badly initialized.");
67 // Target output for gain solving test. Generated with matlab.
68 const int kTestStartFreq = 12; // Lowest integral frequency for ERBs.
69 const double kTestZeroVar[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
70 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
71 static_assert(arraysize(kTestCenterFreqs) == arraysize(kTestZeroVar),
72 "Variance test data badly initialized.");
73 const double kTestNonZeroVarLambdaTop[] = {
74 1, 1, 1, 1, 1, 1, 1, 1,
75 1, 1, 1, 0, 0, 0.0351, 0.0636, 0.0863,
76 0.1037, 0.1162, 0.1236, 0.1251, 0.1189, 0.0993};
77 static_assert(arraysize(kTestCenterFreqs) ==
78 arraysize(kTestNonZeroVarLambdaTop),
79 "Variance test data badly initialized.");
80 const float kMaxTestError = 0.005f;
81
82 // Enhancer initialization parameters.
83 const int kSamples = 2000;
84 const int kErbResolution = 2;
85 const int kSampleRate = 1000;
86 const int kFragmentSize = kSampleRate / 100;
87 const int kNumChannels = 1;
88 const float kDecayRate = 0.9f;
89 const int kWindowSize = 800;
90 const int kAnalyzeRate = 800;
91 const int kVarianceRate = 2;
92 const float kGainLimit = 0.1f;
93
94 } // namespace
95
96 namespace webrtc {
97
98 using std::vector;
99 using intelligibility::VarianceArray;
100
101 void GenerateConstantData(vector<float>* data, float constant) {
Andrew MacDonald 2015/07/02 02:46:48 Replace this function with: std::fill(data.begin()
ekm 2015/07/07 21:57:02 Done.
102 for (size_t i = 0; i < data->size(); i++) {
103 (*data)[i] = constant;
104 }
105 }
106
107 void GenerateGaussianData(vector<float>* data, int* count) {
Andrew MacDonald 2015/07/02 02:46:48 Does this need to be Gaussian distributed, or will
ekm 2015/07/07 21:57:02 Done.
108 for (size_t i = 0; i < data->size(); i++) {
109 (*data)[i] = kGaussianSamples[(*count) % 64];
110 (*count)++;
111 }
112 }
113
114 class IntelligibilityEnhancerTest : public ::testing::Test {
115 protected:
116 IntelligibilityEnhancerTest()
117 : enh_(kErbResolution,
118 kSampleRate,
119 kNumChannels,
120 VarianceArray::kStepInfinite,
121 kDecayRate,
122 kWindowSize,
123 kAnalyzeRate,
124 kVarianceRate,
125 kGainLimit),
126 clear_data_(kSamples),
127 noise_data_(kSamples),
128 orig_data_(kSamples) {}
129
130 bool CheckUpdate(VarianceArray::StepType step_type) {
131 IntelligibilityEnhancer enh(kErbResolution, kSampleRate, kNumChannels,
132 step_type, kDecayRate, kWindowSize,
133 kAnalyzeRate, kVarianceRate, kGainLimit);
134 float* clear_cursor = &clear_data_[0];
135 float* noise_cursor = &noise_data_[0];
136 for (int i = 0; i < kSamples; i += kFragmentSize) {
137 enh.ProcessCaptureAudio(&noise_cursor);
138 enh.ProcessRenderAudio(&clear_cursor);
139 clear_cursor += kFragmentSize;
140 noise_cursor += kFragmentSize;
141 }
142 for (int i = 0; i < kSamples; i++) {
143 if (std::fabs(clear_data_[i] - orig_data_[i]) > kMaxTestError) {
144 return true;
145 }
146 }
147 return false;
148 }
149
150 IntelligibilityEnhancer enh_;
151 vector<float> clear_data_;
152 vector<float> noise_data_;
153 vector<float> orig_data_;
154 };
155
156 // For each class of generated data, tests that render stream is
157 // updated when it should be for each variance update method.
158 TEST_F(IntelligibilityEnhancerTest, TestRenderUpdate) {
159 vector<VarianceArray::StepType> step_types = {
160 VarianceArray::kStepInfinite,
161 VarianceArray::kStepDecaying,
162 VarianceArray::kStepWindowed,
163 VarianceArray::kStepBlocked,
164 VarianceArray::kStepBlockBasedMovingAverage};
165 GenerateConstantData(&noise_data_, 0.0f);
166 GenerateConstantData(&orig_data_, 0.0f);
167 for (auto step_type : step_types) {
168 GenerateConstantData(&clear_data_, 0.0f);
169 EXPECT_FALSE(CheckUpdate(step_type));
170 }
171 int samples_grabbed = 0;
172 GenerateGaussianData(&noise_data_, &samples_grabbed);
173 for (auto step_type : step_types) {
174 EXPECT_FALSE(CheckUpdate(step_type));
175 }
176 for (auto step_type : step_types) {
177 GenerateGaussianData(&clear_data_, &samples_grabbed);
178 orig_data_ = clear_data_;
179 EXPECT_TRUE(CheckUpdate(step_type));
180 }
181 }
182
183 // Tests ERB bank creation, comparing against matlab output.
184 TEST_F(IntelligibilityEnhancerTest, TestErbCreation) {
185 ASSERT_EQ(static_cast<int>(arraysize(kTestCenterFreqs)), enh_.bank_size_);
186 for (int i = 0; i < enh_.bank_size_; ++i) {
187 EXPECT_NEAR(enh_.center_freqs_[i], kTestCenterFreqs[i], kMaxTestError);
188 ASSERT_EQ(static_cast<int>(arraysize(kTestFilterBank[0])), enh_.freqs_);
189 for (int j = 0; j < enh_.freqs_; ++j) {
190 EXPECT_NEAR(enh_.filter_bank_[i][j], kTestFilterBank[i][j],
191 kMaxTestError);
192 }
193 }
194 }
195
196 // Tests analytic solution for optimal gains, comparing
197 // against matlab output.
198 TEST_F(IntelligibilityEnhancerTest, TestSolveForGains) {
199 ASSERT_EQ(kTestStartFreq, enh_.start_freq_);
200 vector<float> sols(enh_.bank_size_);
201 float lambda = -0.001f;
202 for (int i = 0; i < enh_.bank_size_; i++) {
203 enh_.filtered_clear_var_[i] = 0.0;
204 enh_.filtered_noise_var_[i] = 0.0;
205 enh_.rho_[i] = 0.02;
206 }
207 enh_.SolveForGainsGivenLambda(lambda, enh_.start_freq_, &sols[0]);
208 for (int i = 0; i < enh_.bank_size_; i++) {
209 EXPECT_NEAR(sols[i], kTestZeroVar[i], kMaxTestError);
210 }
211 for (int i = 0; i < enh_.bank_size_; i++) {
212 enh_.filtered_clear_var_[i] = static_cast<float>(i + 1);
213 enh_.filtered_noise_var_[i] = static_cast<float>(enh_.bank_size_ - i);
214 }
215 enh_.SolveForGainsGivenLambda(lambda, enh_.start_freq_, &sols[0]);
216 for (int i = 0; i < enh_.bank_size_; i++) {
217 EXPECT_NEAR(sols[i], kTestNonZeroVarLambdaTop[i], kMaxTestError);
218 }
219 lambda = -1.0;
220 enh_.SolveForGainsGivenLambda(lambda, enh_.start_freq_, &sols[0]);
221 for (int i = 0; i < enh_.bank_size_; i++) {
222 EXPECT_NEAR(sols[i], kTestZeroVar[i], kMaxTestError);
223 }
224 }
225
226 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698