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

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

Issue 1234463003: Integrate Intelligibility with APM (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Addr. comments from aluebs (incl. made ProcessReverseStream nicer) 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
1 /* 1 /*
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 // 11 //
12 // Unit tests for intelligibility enhancer. 12 // Unit tests for intelligibility enhancer.
13 // 13 //
14 14
15 #include <math.h> 15 #include <math.h>
16 #include <stdlib.h> 16 #include <stdlib.h>
17 #include <algorithm> 17 #include <algorithm>
18 #include <vector> 18 #include <vector>
19 19
20 #include "testing/gtest/include/gtest/gtest.h" 20 #include "testing/gtest/include/gtest/gtest.h"
21 #include "webrtc/base/arraysize.h" 21 #include "webrtc/base/arraysize.h"
22 #include "webrtc/base/scoped_ptr.h"
22 #include "webrtc/common_audio/signal_processing/include/signal_processing_librar y.h" 23 #include "webrtc/common_audio/signal_processing/include/signal_processing_librar y.h"
23 #include "webrtc/modules/audio_processing/intelligibility/intelligibility_enhanc er.h" 24 #include "webrtc/modules/audio_processing/intelligibility/intelligibility_enhanc er.h"
24 25
25 namespace webrtc { 26 namespace webrtc {
26 27
27 namespace { 28 namespace {
28 29
29 // Target output for ERB create test. Generated with matlab. 30 // Target output for ERB create test. Generated with matlab.
30 const float kTestCenterFreqs[] = { 31 const float kTestCenterFreqs[] = {
31 13.169f, 26.965f, 41.423f, 56.577f, 72.461f, 89.113f, 106.57f, 124.88f, 32 13.169f, 26.965f, 41.423f, 56.577f, 72.461f, 89.113f, 106.57f, 124.88f,
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 68 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f,
68 1.f, 1.f, 1.f, 0.f, 0.f, 0.0351f, 0.0636f, 0.0863f, 69 1.f, 1.f, 1.f, 0.f, 0.f, 0.0351f, 0.0636f, 0.0863f,
69 0.1037f, 0.1162f, 0.1236f, 0.1251f, 0.1189f, 0.0993f}; 70 0.1037f, 0.1162f, 0.1236f, 0.1251f, 0.1189f, 0.0993f};
70 static_assert(arraysize(kTestCenterFreqs) == 71 static_assert(arraysize(kTestCenterFreqs) ==
71 arraysize(kTestNonZeroVarLambdaTop), 72 arraysize(kTestNonZeroVarLambdaTop),
72 "Variance test data badly initialized."); 73 "Variance test data badly initialized.");
73 const float kMaxTestError = 0.005f; 74 const float kMaxTestError = 0.005f;
74 75
75 // Enhancer initialization parameters. 76 // Enhancer initialization parameters.
76 const int kSamples = 2000; 77 const int kSamples = 2000;
77 const int kErbResolution = 2;
78 const int kSampleRate = 1000; 78 const int kSampleRate = 1000;
79 const int kNumChannels = 1;
79 const int kFragmentSize = kSampleRate / 100; 80 const int kFragmentSize = kSampleRate / 100;
80 const int kNumChannels = 1; 81 const float kNoiseDetected = 0.f;
81 const float kDecayRate = 0.9f; 82 const float kSpeechDetected = 1.f;
82 const int kWindowSize = 800;
83 const int kAnalyzeRate = 800;
84 const int kVarianceRate = 2;
85 const float kGainLimit = 0.1f;
86 83
87 } // namespace 84 } // namespace
88 85
89 using std::vector; 86 using std::vector;
90 using intelligibility::VarianceArray; 87 using intelligibility::VarianceArray;
91 88
92 class IntelligibilityEnhancerTest : public ::testing::Test { 89 class IntelligibilityEnhancerTest : public ::testing::Test {
93 protected: 90 protected:
94 IntelligibilityEnhancerTest() 91 IntelligibilityEnhancerTest()
95 : enh_(kErbResolution, 92 : clear_data_(kSamples), noise_data_(kSamples), orig_data_(kSamples) {
96 kSampleRate, 93 config_.sample_rate_hz = kSampleRate;
97 kNumChannels, 94 enh_.reset(new IntelligibilityEnhancer(config_));
98 VarianceArray::kStepInfinite, 95 }
99 kDecayRate,
100 kWindowSize,
101 kAnalyzeRate,
102 kVarianceRate,
103 kGainLimit),
104 clear_data_(kSamples),
105 noise_data_(kSamples),
106 orig_data_(kSamples) {}
107 96
108 bool CheckUpdate(VarianceArray::StepType step_type) { 97 bool CheckUpdate(VarianceArray::StepType step_type) {
109 IntelligibilityEnhancer enh(kErbResolution, kSampleRate, kNumChannels, 98 config_.sample_rate_hz = kSampleRate;
110 step_type, kDecayRate, kWindowSize, 99 config_.var_type = step_type;
111 kAnalyzeRate, kVarianceRate, kGainLimit); 100 enh_.reset(new IntelligibilityEnhancer(config_));
112 float* clear_cursor = &clear_data_[0]; 101 float* clear_cursor = &clear_data_[0];
113 float* noise_cursor = &noise_data_[0]; 102 float* noise_cursor = &noise_data_[0];
114 for (int i = 0; i < kSamples; i += kFragmentSize) { 103 for (int i = 0; i < kSamples; i += kFragmentSize) {
115 enh.ProcessCaptureAudio(&noise_cursor); 104 enh_->AnalyzeCaptureAudio(&noise_cursor, kSampleRate, kNumChannels,
116 enh.ProcessRenderAudio(&clear_cursor); 105 kNoiseDetected);
106 enh_->ProcessRenderAudio(&clear_cursor, kSampleRate, kNumChannels,
107 kSpeechDetected);
117 clear_cursor += kFragmentSize; 108 clear_cursor += kFragmentSize;
118 noise_cursor += kFragmentSize; 109 noise_cursor += kFragmentSize;
119 } 110 }
120 for (int i = 0; i < kSamples; i++) { 111 for (int i = 0; i < kSamples; i++) {
121 if (std::fabs(clear_data_[i] - orig_data_[i]) > kMaxTestError) { 112 if (std::fabs(clear_data_[i] - orig_data_[i]) > kMaxTestError) {
122 return true; 113 return true;
123 } 114 }
124 } 115 }
125 return false; 116 return false;
126 } 117 }
127 118
128 IntelligibilityEnhancer enh_; 119 IntelligibilityEnhancer::Config config_;
120 rtc::scoped_ptr<IntelligibilityEnhancer> enh_;
129 vector<float> clear_data_; 121 vector<float> clear_data_;
130 vector<float> noise_data_; 122 vector<float> noise_data_;
131 vector<float> orig_data_; 123 vector<float> orig_data_;
132 }; 124 };
133 125
134 // For each class of generated data, tests that render stream is 126 // For each class of generated data, tests that render stream is
135 // updated when it should be for each variance update method. 127 // updated when it should be for each variance update method.
136 TEST_F(IntelligibilityEnhancerTest, TestRenderUpdate) { 128 TEST_F(IntelligibilityEnhancerTest, TestRenderUpdate) {
137 vector<VarianceArray::StepType> step_types; 129 vector<VarianceArray::StepType> step_types;
138 step_types.push_back(VarianceArray::kStepInfinite); 130 step_types.push_back(VarianceArray::kStepInfinite);
(...skipping 15 matching lines...) Expand all
154 } 146 }
155 for (auto step_type : step_types) { 147 for (auto step_type : step_types) {
156 std::generate(clear_data_.begin(), clear_data_.end(), float_rand); 148 std::generate(clear_data_.begin(), clear_data_.end(), float_rand);
157 orig_data_ = clear_data_; 149 orig_data_ = clear_data_;
158 EXPECT_TRUE(CheckUpdate(step_type)); 150 EXPECT_TRUE(CheckUpdate(step_type));
159 } 151 }
160 } 152 }
161 153
162 // Tests ERB bank creation, comparing against matlab output. 154 // Tests ERB bank creation, comparing against matlab output.
163 TEST_F(IntelligibilityEnhancerTest, TestErbCreation) { 155 TEST_F(IntelligibilityEnhancerTest, TestErbCreation) {
164 ASSERT_EQ(static_cast<int>(arraysize(kTestCenterFreqs)), enh_.bank_size_); 156 ASSERT_EQ(static_cast<int>(arraysize(kTestCenterFreqs)), enh_->bank_size_);
165 for (int i = 0; i < enh_.bank_size_; ++i) { 157 for (int i = 0; i < enh_->bank_size_; ++i) {
166 EXPECT_NEAR(kTestCenterFreqs[i], enh_.center_freqs_[i], kMaxTestError); 158 EXPECT_NEAR(kTestCenterFreqs[i], enh_->center_freqs_[i], kMaxTestError);
167 ASSERT_EQ(static_cast<int>(arraysize(kTestFilterBank[0])), enh_.freqs_); 159 ASSERT_EQ(static_cast<int>(arraysize(kTestFilterBank[0])), enh_->freqs_);
168 for (int j = 0; j < enh_.freqs_; ++j) { 160 for (int j = 0; j < enh_->freqs_; ++j) {
169 EXPECT_NEAR(kTestFilterBank[i][j], enh_.filter_bank_[i][j], 161 EXPECT_NEAR(kTestFilterBank[i][j], enh_->filter_bank_[i][j],
170 kMaxTestError); 162 kMaxTestError);
171 } 163 }
172 } 164 }
173 } 165 }
174 166
175 // Tests analytic solution for optimal gains, comparing 167 // Tests analytic solution for optimal gains, comparing
176 // against matlab output. 168 // against matlab output.
177 TEST_F(IntelligibilityEnhancerTest, TestSolveForGains) { 169 TEST_F(IntelligibilityEnhancerTest, TestSolveForGains) {
178 ASSERT_EQ(kTestStartFreq, enh_.start_freq_); 170 ASSERT_EQ(kTestStartFreq, enh_->start_freq_);
179 vector<float> sols(enh_.bank_size_); 171 vector<float> sols(enh_->bank_size_);
180 float lambda = -0.001f; 172 float lambda = -0.001f;
181 for (int i = 0; i < enh_.bank_size_; i++) { 173 for (int i = 0; i < enh_->bank_size_; i++) {
182 enh_.filtered_clear_var_[i] = 0.0f; 174 enh_->filtered_clear_var_[i] = 0.0f;
183 enh_.filtered_noise_var_[i] = 0.0f; 175 enh_->filtered_noise_var_[i] = 0.0f;
184 enh_.rho_[i] = 0.02f; 176 enh_->rho_[i] = 0.02f;
185 } 177 }
186 enh_.SolveForGainsGivenLambda(lambda, enh_.start_freq_, &sols[0]); 178 enh_->SolveForGainsGivenLambda(lambda, enh_->start_freq_, &sols[0]);
187 for (int i = 0; i < enh_.bank_size_; i++) { 179 for (int i = 0; i < enh_->bank_size_; i++) {
188 EXPECT_NEAR(kTestZeroVar[i], sols[i], kMaxTestError); 180 EXPECT_NEAR(kTestZeroVar[i], sols[i], kMaxTestError);
189 } 181 }
190 for (int i = 0; i < enh_.bank_size_; i++) { 182 for (int i = 0; i < enh_->bank_size_; i++) {
191 enh_.filtered_clear_var_[i] = static_cast<float>(i + 1); 183 enh_->filtered_clear_var_[i] = static_cast<float>(i + 1);
192 enh_.filtered_noise_var_[i] = static_cast<float>(enh_.bank_size_ - i); 184 enh_->filtered_noise_var_[i] = static_cast<float>(enh_->bank_size_ - i);
193 } 185 }
194 enh_.SolveForGainsGivenLambda(lambda, enh_.start_freq_, &sols[0]); 186 enh_->SolveForGainsGivenLambda(lambda, enh_->start_freq_, &sols[0]);
195 for (int i = 0; i < enh_.bank_size_; i++) { 187 for (int i = 0; i < enh_->bank_size_; i++) {
196 EXPECT_NEAR(kTestNonZeroVarLambdaTop[i], sols[i], kMaxTestError); 188 EXPECT_NEAR(kTestNonZeroVarLambdaTop[i], sols[i], kMaxTestError);
197 } 189 }
198 lambda = -1.0; 190 lambda = -1.0;
199 enh_.SolveForGainsGivenLambda(lambda, enh_.start_freq_, &sols[0]); 191 enh_->SolveForGainsGivenLambda(lambda, enh_->start_freq_, &sols[0]);
200 for (int i = 0; i < enh_.bank_size_; i++) { 192 for (int i = 0; i < enh_->bank_size_; i++) {
201 EXPECT_NEAR(kTestZeroVar[i], sols[i], kMaxTestError); 193 EXPECT_NEAR(kTestZeroVar[i], sols[i], kMaxTestError);
202 } 194 }
203 } 195 }
204 196
205 } // namespace webrtc 197 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698