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

Side by Side Diff: webrtc/modules/audio_processing/intelligibility/intelligibility_utils.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: 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) 2014 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2014 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
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 running_mean_sq_(new complex<float>[freqs]()), 89 running_mean_sq_(new complex<float>[freqs]()),
90 sub_running_mean_(new complex<float>[freqs]()), 90 sub_running_mean_(new complex<float>[freqs]()),
91 sub_running_mean_sq_(new complex<float>[freqs]()), 91 sub_running_mean_sq_(new complex<float>[freqs]()),
92 variance_(new float[freqs]()), 92 variance_(new float[freqs]()),
93 conj_sum_(new float[freqs]()), 93 conj_sum_(new float[freqs]()),
94 freqs_(freqs), 94 freqs_(freqs),
95 window_size_(window_size), 95 window_size_(window_size),
96 decay_(decay), 96 decay_(decay),
97 history_cursor_(0), 97 history_cursor_(0),
98 count_(0), 98 count_(0),
99 array_mean_(0.0f) { 99 array_mean_(0.0f),
100 buffer_full_(false) {
100 history_.reset(new rtc::scoped_ptr<complex<float>[]>[freqs_]()); 101 history_.reset(new rtc::scoped_ptr<complex<float>[]>[freqs_]());
101 for (int i = 0; i < freqs_; ++i) { 102 for (int i = 0; i < freqs_; ++i) {
102 history_[i].reset(new complex<float>[window_size_]()); 103 history_[i].reset(new complex<float>[window_size_]());
103 } 104 }
104 subhistory_.reset(new rtc::scoped_ptr<complex<float>[]>[freqs_]()); 105 subhistory_.reset(new rtc::scoped_ptr<complex<float>[]>[freqs_]());
105 for (int i = 0; i < freqs_; ++i) { 106 for (int i = 0; i < freqs_; ++i) {
106 subhistory_[i].reset(new complex<float>[window_size_]()); 107 subhistory_[i].reset(new complex<float>[window_size_]());
107 } 108 }
108 subhistory_sq_.reset(new rtc::scoped_ptr<complex<float>[]>[freqs_]()); 109 subhistory_sq_.reset(new rtc::scoped_ptr<complex<float>[]>[freqs_]());
109 for (int i = 0; i < freqs_; ++i) { 110 for (int i = 0; i < freqs_; ++i) {
110 subhistory_sq_[i].reset(new complex<float>[window_size_]()); 111 subhistory_sq_[i].reset(new complex<float>[window_size_]());
111 } 112 }
112 switch (type) { 113 switch (type) {
113 case kStepInfinite: 114 case kStepInfinite:
114 step_func_ = &VarianceArray::InfiniteStep; 115 step_func_ = &VarianceArray::InfiniteStep;
115 break; 116 break;
116 case kStepDecaying: 117 case kStepDecaying:
117 step_func_ = &VarianceArray::DecayStep; 118 step_func_ = &VarianceArray::DecayStep;
118 break; 119 break;
119 case kStepWindowed: 120 case kStepWindowed:
120 step_func_ = &VarianceArray::WindowedStep; 121 step_func_ = &VarianceArray::WindowedStep;
121 break; 122 break;
122 case kStepBlocked: 123 case kStepBlocked:
123 step_func_ = &VarianceArray::BlockedStep; 124 step_func_ = &VarianceArray::BlockedStep;
124 break; 125 break;
126 case kStepBlockBasedMovingAverage:
127 step_func_ = &VarianceArray::BlockBasedMovingAverage;
128 break;
125 } 129 }
126 } 130 }
127 131
128 // Compute the variance with Welford's algorithm, adding some fudge to 132 // Compute the variance with Welford's algorithm, adding some fudge to
129 // the input in case of all-zeroes. 133 // the input in case of all-zeroes.
130 void VarianceArray::InfiniteStep(const complex<float>* data, bool skip_fudge) { 134 void VarianceArray::InfiniteStep(const complex<float>* data, bool skip_fudge) {
131 array_mean_ = 0.0f; 135 array_mean_ = 0.0f;
132 ++count_; 136 ++count_;
133 for (int i = 0; i < freqs_; ++i) { 137 for (int i = 0; i < freqs_; ++i) {
134 complex<float> sample = data[i]; 138 complex<float> sample = data[i];
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 history_cursor_ = (history_cursor_ + 1) % window_size_; 220 history_cursor_ = (history_cursor_ + 1) % window_size_;
217 ++count_; 221 ++count_;
218 } 222 }
219 223
220 // Variance with a window of blocks. Within each block, the variances are 224 // Variance with a window of blocks. Within each block, the variances are
221 // recomputed from scratch at every stp, using |Var(X) = E(X^2) - E^2(X)|. 225 // recomputed from scratch at every stp, using |Var(X) = E(X^2) - E^2(X)|.
222 // Once a block is filled with kWindowBlockSize samples, it is added to the 226 // Once a block is filled with kWindowBlockSize samples, it is added to the
223 // history window and a new block is started. The variances for the window 227 // history window and a new block is started. The variances for the window
224 // are recomputed from scratch at each of these transitions. 228 // are recomputed from scratch at each of these transitions.
225 void VarianceArray::BlockedStep(const complex<float>* data, bool /*dummy*/) { 229 void VarianceArray::BlockedStep(const complex<float>* data, bool /*dummy*/) {
226 int blocks = min(window_size_, history_cursor_); 230 int blocks = min(window_size_, history_cursor_ + 1);
227 for (int i = 0; i < freqs_; ++i) { 231 for (int i = 0; i < freqs_; ++i) {
228 AddToMean(data[i], count_ + 1, &sub_running_mean_[i]); 232 AddToMean(data[i], count_ + 1, &sub_running_mean_[i]);
229 AddToMean(data[i] * std::conj(data[i]), count_ + 1, 233 AddToMean(data[i] * std::conj(data[i]), count_ + 1,
230 &sub_running_mean_sq_[i]); 234 &sub_running_mean_sq_[i]);
231 subhistory_[i][history_cursor_ % window_size_] = sub_running_mean_[i]; 235 subhistory_[i][history_cursor_ % window_size_] = sub_running_mean_[i];
232 subhistory_sq_[i][history_cursor_ % window_size_] = sub_running_mean_sq_[i]; 236 subhistory_sq_[i][history_cursor_ % window_size_] = sub_running_mean_sq_[i];
233 237
234 variance_[i] = 238 variance_[i] =
235 (NewMean(running_mean_sq_[i], sub_running_mean_sq_[i], blocks) - 239 (NewMean(running_mean_sq_[i], sub_running_mean_sq_[i], blocks) -
236 NewMean(running_mean_[i], sub_running_mean_[i], blocks) * 240 NewMean(running_mean_[i], sub_running_mean_[i], blocks) *
237 std::conj(NewMean(running_mean_[i], sub_running_mean_[i], blocks))) 241 std::conj(NewMean(running_mean_[i], sub_running_mean_[i], blocks)))
238 .real(); 242 .real();
239 if (count_ == kWindowBlockSize - 1) { 243 if (count_ == kWindowBlockSize - 1) {
240 sub_running_mean_[i] = complex<float>(0.0f, 0.0f); 244 sub_running_mean_[i] = complex<float>(0.0f, 0.0f);
241 sub_running_mean_sq_[i] = complex<float>(0.0f, 0.0f); 245 sub_running_mean_sq_[i] = complex<float>(0.0f, 0.0f);
242 running_mean_[i] = complex<float>(0.0f, 0.0f); 246 running_mean_[i] = complex<float>(0.0f, 0.0f);
243 running_mean_sq_[i] = complex<float>(0.0f, 0.0f); 247 running_mean_sq_[i] = complex<float>(0.0f, 0.0f);
244 for (int j = 0; j < min(window_size_, history_cursor_); ++j) { 248 for (int j = 0; j < min(window_size_, history_cursor_); ++j) {
245 AddToMean(subhistory_[i][j], j, &running_mean_[i]); 249 AddToMean(subhistory_[i][j], j + 1, &running_mean_[i]);
246 AddToMean(subhistory_sq_[i][j], j, &running_mean_sq_[i]); 250 AddToMean(subhistory_sq_[i][j], j + 1, &running_mean_sq_[i]);
247 } 251 }
248 ++history_cursor_; 252 ++history_cursor_;
249 } 253 }
250 } 254 }
251 ++count_; 255 ++count_;
252 if (count_ == kWindowBlockSize) { 256 if (count_ == kWindowBlockSize) {
253 count_ = 0; 257 count_ = 0;
254 } 258 }
255 } 259 }
256 260
261 // Recomputes variances from scratch each window based on previous window.
262 void VarianceArray::BlockBasedMovingAverage(
turaj 2015/06/26 00:32:58 There is a concern, which is not proven, that keep
ekm 2015/06/26 19:07:09 Interesting. This is just do to floating point err
turaj 2015/06/29 17:33:35 Something like that, but I'm not sure.
263 const std::complex<float>* data, bool /*dummy*/) {
264 for (int i = 0; i < freqs_; ++i) {
265 sub_running_mean_[i] += data[i];
266 sub_running_mean_sq_[i] += data[i] * std::conj(data[i]);
267 }
268 ++count_;
269
270 // TODO(ekmeyerson) make kWindowBlockSize nonconstant to allow
271 // experimentation with different block size,window size pairs.
272 if (count_ >= kWindowBlockSize) {
273 count_ = 0;
274
275 for (int i = 0; i < freqs_; ++i) {
276 running_mean_[i] -= subhistory_[i][history_cursor_];
277 running_mean_sq_[i] -= subhistory_sq_[i][history_cursor_];
278
279 float scale = 1.f / kWindowBlockSize;
280 subhistory_[i][history_cursor_] = sub_running_mean_[i] * scale;
281 subhistory_sq_[i][history_cursor_] = sub_running_mean_sq_[i] * scale;
282
283 sub_running_mean_[i] = std::complex<float>(0.0f, 0.0f);
284 sub_running_mean_sq_[i] = std::complex<float>(0.0f, 0.0f);
285
286 running_mean_[i] += subhistory_[i][history_cursor_];
287 running_mean_sq_[i] += subhistory_sq_[i][history_cursor_];
288
289 scale = 1.f / (buffer_full_ ? window_size_ : history_cursor_ + 1);
290 variance_[i] = std::real(running_mean_sq_[i] * scale - running_mean_[i] *
291 scale * std::conj(running_mean_[i]) * scale);
292 }
293
294 ++history_cursor_;
295 if (history_cursor_ >= window_size_) {
296 buffer_full_ = true;
297 history_cursor_ = 0;
298 }
299 }
300 }
301
257 void VarianceArray::Clear() { 302 void VarianceArray::Clear() {
258 memset(running_mean_.get(), 0, sizeof(*running_mean_.get()) * freqs_); 303 memset(running_mean_.get(), 0, sizeof(*running_mean_.get()) * freqs_);
259 memset(running_mean_sq_.get(), 0, sizeof(*running_mean_sq_.get()) * freqs_); 304 memset(running_mean_sq_.get(), 0, sizeof(*running_mean_sq_.get()) * freqs_);
260 memset(variance_.get(), 0, sizeof(*variance_.get()) * freqs_); 305 memset(variance_.get(), 0, sizeof(*variance_.get()) * freqs_);
261 memset(conj_sum_.get(), 0, sizeof(*conj_sum_.get()) * freqs_); 306 memset(conj_sum_.get(), 0, sizeof(*conj_sum_.get()) * freqs_);
262 history_cursor_ = 0; 307 history_cursor_ = 0;
263 count_ = 0; 308 count_ = 0;
264 array_mean_ = 0.0f; 309 array_mean_ = 0.0f;
265 } 310 }
266 311
(...skipping 24 matching lines...) Expand all
291 factor = 1.0f; 336 factor = 1.0f;
292 } 337 }
293 out_block[i] = factor * in_block[i]; 338 out_block[i] = factor * in_block[i];
294 current_[i] = UpdateFactor(target_[i], current_[i], change_limit_); 339 current_[i] = UpdateFactor(target_[i], current_[i], change_limit_);
295 } 340 }
296 } 341 }
297 342
298 } // namespace intelligibility 343 } // namespace intelligibility
299 344
300 } // namespace webrtc 345 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698