OLD | NEW |
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 15 matching lines...) Expand all Loading... |
26 #include "webrtc/base/checks.h" | 26 #include "webrtc/base/checks.h" |
27 #include "webrtc/common_audio/vad/include/webrtc_vad.h" | 27 #include "webrtc/common_audio/vad/include/webrtc_vad.h" |
28 #include "webrtc/common_audio/window_generator.h" | 28 #include "webrtc/common_audio/window_generator.h" |
29 | 29 |
30 using std::complex; | 30 using std::complex; |
31 using std::max; | 31 using std::max; |
32 using std::min; | 32 using std::min; |
33 | 33 |
34 namespace webrtc { | 34 namespace webrtc { |
35 | 35 |
36 const int IntelligibilityEnhancer::kErbResolution = 2; | |
37 const int IntelligibilityEnhancer::kWindowSizeMs = 2; | 36 const int IntelligibilityEnhancer::kWindowSizeMs = 2; |
38 const int IntelligibilityEnhancer::kChunkSizeMs = 10; // Size provided by APM. | 37 const int IntelligibilityEnhancer::kChunkSizeMs = 10; // Size provided by APM. |
39 const int IntelligibilityEnhancer::kAnalyzeRate = 800; | 38 const int IntelligibilityEnhancer::kAnalyzeRate = 800; |
40 const int IntelligibilityEnhancer::kVarianceRate = 2; | 39 const int IntelligibilityEnhancer::kVarianceRate = 2; |
41 const float IntelligibilityEnhancer::kClipFreq = 200.0f; | 40 const float IntelligibilityEnhancer::kClipFreq = 200.0f; |
42 const float IntelligibilityEnhancer::kConfigRho = 0.02f; | 41 const float IntelligibilityEnhancer::kConfigRho = 0.02f; |
43 const float IntelligibilityEnhancer::kKbdAlpha = 1.5f; | 42 const float IntelligibilityEnhancer::kKbdAlpha = 1.5f; |
44 | 43 |
45 // To disable gain update smoothing, set gain limit to be VERY high. | 44 // To disable gain update smoothing, set gain limit to be VERY high. |
46 // TODO(ekmeyerson): Add option to disable gain smoothing altogether | 45 // TODO(ekmeyerson): Add option to disable gain smoothing altogether |
47 // to avoid the extra computation. | 46 // to avoid the extra computation. |
48 const float IntelligibilityEnhancer::kGainChangeLimit = 0.0125f; | 47 const float IntelligibilityEnhancer::kGainChangeLimit = 0.0125f; |
49 | 48 |
50 using VarianceType = intelligibility::VarianceArray::StepType; | 49 using VarianceType = intelligibility::VarianceArray::StepType; |
51 | 50 |
52 IntelligibilityEnhancer::TransformCallback::TransformCallback( | 51 IntelligibilityEnhancer::TransformCallback::TransformCallback( |
53 IntelligibilityEnhancer* parent, | 52 IntelligibilityEnhancer* parent, |
54 IntelligibilityEnhancer::AudioSource source) | 53 IntelligibilityEnhancer::AudioSource source) |
55 : parent_(parent), source_(source) { | 54 : parent_(parent), source_(source) { |
56 } | 55 } |
57 | 56 |
58 void IntelligibilityEnhancer::TransformCallback::ProcessAudioBlock( | 57 void IntelligibilityEnhancer::TransformCallback::ProcessAudioBlock( |
59 const complex<float>* const* in_block, | 58 const complex<float>* const* in_block, |
60 int in_channels, | 59 int in_channels, |
61 int frames, | 60 size_t frames, |
62 int /* out_channels */, | 61 int /* out_channels */, |
63 complex<float>* const* out_block) { | 62 complex<float>* const* out_block) { |
64 DCHECK_EQ(parent_->freqs_, frames); | 63 DCHECK_EQ(parent_->freqs_, frames); |
65 for (int i = 0; i < in_channels; ++i) { | 64 for (int i = 0; i < in_channels; ++i) { |
66 parent_->DispatchAudio(source_, in_block[i], out_block[i]); | 65 parent_->DispatchAudio(source_, in_block[i], out_block[i]); |
67 } | 66 } |
68 } | 67 } |
69 | 68 |
70 IntelligibilityEnhancer::IntelligibilityEnhancer(int erb_resolution, | 69 IntelligibilityEnhancer::IntelligibilityEnhancer(size_t erb_resolution, |
71 int sample_rate_hz, | 70 int sample_rate_hz, |
72 int channels, | 71 int channels, |
73 int cv_type, | 72 int cv_type, |
74 float cv_alpha, | 73 float cv_alpha, |
75 int cv_win, | 74 size_t cv_win, |
76 int analysis_rate, | 75 int analysis_rate, |
77 int variance_rate, | 76 int variance_rate, |
78 float gain_limit) | 77 float gain_limit) |
79 : freqs_(RealFourier::ComplexLength( | 78 : freqs_(RealFourier::ComplexLength( |
80 RealFourier::FftOrder(sample_rate_hz * kWindowSizeMs / 1000))), | 79 RealFourier::FftOrder(sample_rate_hz * kWindowSizeMs / 1000))), |
81 window_size_(1 << RealFourier::FftOrder(freqs_)), | 80 window_size_(static_cast<size_t>(1 << RealFourier::FftOrder(freqs_))), |
82 chunk_length_(sample_rate_hz * kChunkSizeMs / 1000), | 81 chunk_length_(static_cast<size_t>(sample_rate_hz * kChunkSizeMs / 1000)), |
83 bank_size_(GetBankSize(sample_rate_hz, erb_resolution)), | 82 bank_size_(GetBankSize(sample_rate_hz, erb_resolution)), |
84 sample_rate_hz_(sample_rate_hz), | 83 sample_rate_hz_(sample_rate_hz), |
85 erb_resolution_(erb_resolution), | 84 erb_resolution_(erb_resolution), |
86 channels_(channels), | 85 channels_(channels), |
87 analysis_rate_(analysis_rate), | 86 analysis_rate_(analysis_rate), |
88 variance_rate_(variance_rate), | 87 variance_rate_(variance_rate), |
89 clear_variance_(freqs_, | 88 clear_variance_(freqs_, |
90 static_cast<VarianceType>(cv_type), | 89 static_cast<VarianceType>(cv_type), |
91 cv_win, | 90 cv_win, |
92 cv_alpha), | 91 cv_alpha), |
(...skipping 27 matching lines...) Expand all Loading... |
120 temp_out_buffer_ = static_cast<float**>( | 119 temp_out_buffer_ = static_cast<float**>( |
121 malloc(sizeof(*temp_out_buffer_) * channels_ + | 120 malloc(sizeof(*temp_out_buffer_) * channels_ + |
122 sizeof(**temp_out_buffer_) * chunk_length_ * channels_)); | 121 sizeof(**temp_out_buffer_) * chunk_length_ * channels_)); |
123 for (int i = 0; i < channels_; ++i) { | 122 for (int i = 0; i < channels_; ++i) { |
124 temp_out_buffer_[i] = | 123 temp_out_buffer_[i] = |
125 reinterpret_cast<float*>(temp_out_buffer_ + channels_) + | 124 reinterpret_cast<float*>(temp_out_buffer_ + channels_) + |
126 chunk_length_ * i; | 125 chunk_length_ * i; |
127 } | 126 } |
128 | 127 |
129 // Assumes all rho equal. | 128 // Assumes all rho equal. |
130 for (int i = 0; i < bank_size_; ++i) { | 129 for (size_t i = 0; i < bank_size_; ++i) { |
131 rho_[i] = kConfigRho * kConfigRho; | 130 rho_[i] = kConfigRho * kConfigRho; |
132 } | 131 } |
133 | 132 |
134 float freqs_khz = kClipFreq / 1000.0f; | 133 float freqs_khz = kClipFreq / 1000.0f; |
135 int erb_index = static_cast<int>(ceilf( | 134 size_t erb_index = static_cast<size_t>(ceilf( |
136 11.17f * logf((freqs_khz + 0.312f) / (freqs_khz + 14.6575f)) + 43.0f)); | 135 11.17f * logf((freqs_khz + 0.312f) / (freqs_khz + 14.6575f)) + 43.0f)); |
137 start_freq_ = max(1, erb_index * kErbResolution); | 136 start_freq_ = std::max(static_cast<size_t>(1), erb_index * erb_resolution); |
138 | 137 |
139 WindowGenerator::KaiserBesselDerived(kKbdAlpha, window_size_, | 138 WindowGenerator::KaiserBesselDerived(kKbdAlpha, window_size_, |
140 kbd_window_.get()); | 139 kbd_window_.get()); |
141 render_mangler_.reset(new LappedTransform( | 140 render_mangler_.reset(new LappedTransform( |
142 channels_, channels_, chunk_length_, kbd_window_.get(), window_size_, | 141 channels_, channels_, chunk_length_, kbd_window_.get(), window_size_, |
143 window_size_ / 2, &render_callback_)); | 142 window_size_ / 2, &render_callback_)); |
144 capture_mangler_.reset(new LappedTransform( | 143 capture_mangler_.reset(new LappedTransform( |
145 channels_, channels_, chunk_length_, kbd_window_.get(), window_size_, | 144 channels_, channels_, chunk_length_, kbd_window_.get(), window_size_, |
146 window_size_ / 2, &capture_callback_)); | 145 window_size_ / 2, &capture_callback_)); |
147 } | 146 } |
148 | 147 |
149 IntelligibilityEnhancer::~IntelligibilityEnhancer() { | 148 IntelligibilityEnhancer::~IntelligibilityEnhancer() { |
150 WebRtcVad_Free(vad_low_); | 149 WebRtcVad_Free(vad_low_); |
151 WebRtcVad_Free(vad_high_); | 150 WebRtcVad_Free(vad_high_); |
152 free(filter_bank_); | 151 free(filter_bank_); |
153 } | 152 } |
154 | 153 |
155 void IntelligibilityEnhancer::ProcessRenderAudio(float* const* audio) { | 154 void IntelligibilityEnhancer::ProcessRenderAudio(float* const* audio) { |
156 for (int i = 0; i < chunk_length_; ++i) { | 155 for (size_t i = 0; i < chunk_length_; ++i) { |
157 vad_tmp_buffer_[i] = (int16_t)audio[0][i]; | 156 vad_tmp_buffer_[i] = (int16_t)audio[0][i]; |
158 } | 157 } |
159 has_voice_low_ = WebRtcVad_Process(vad_low_, sample_rate_hz_, | 158 has_voice_low_ = WebRtcVad_Process(vad_low_, sample_rate_hz_, |
160 vad_tmp_buffer_.get(), chunk_length_) == 1; | 159 vad_tmp_buffer_.get(), chunk_length_) == 1; |
161 | 160 |
162 // Process and enhance chunk of |audio| | 161 // Process and enhance chunk of |audio| |
163 render_mangler_->ProcessChunk(audio, temp_out_buffer_); | 162 render_mangler_->ProcessChunk(audio, temp_out_buffer_); |
164 | 163 |
165 for (int i = 0; i < channels_; ++i) { | 164 for (int i = 0; i < channels_; ++i) { |
166 memcpy(audio[i], temp_out_buffer_[i], | 165 memcpy(audio[i], temp_out_buffer_[i], |
167 chunk_length_ * sizeof(**temp_out_buffer_)); | 166 chunk_length_ * sizeof(**temp_out_buffer_)); |
168 } | 167 } |
169 } | 168 } |
170 | 169 |
171 void IntelligibilityEnhancer::ProcessCaptureAudio(float* const* audio) { | 170 void IntelligibilityEnhancer::ProcessCaptureAudio(float* const* audio) { |
172 for (int i = 0; i < chunk_length_; ++i) { | 171 for (size_t i = 0; i < chunk_length_; ++i) { |
173 vad_tmp_buffer_[i] = (int16_t)audio[0][i]; | 172 vad_tmp_buffer_[i] = (int16_t)audio[0][i]; |
174 } | 173 } |
175 // TODO(bercic): The VAD was always detecting voice in the noise stream, | 174 // TODO(bercic): The VAD was always detecting voice in the noise stream, |
176 // no matter what the aggressiveness, so it was temporarily disabled here. | 175 // no matter what the aggressiveness, so it was temporarily disabled here. |
177 | 176 |
178 #if 0 | 177 #if 0 |
179 if (WebRtcVad_Process(vad_high_, sample_rate_hz_, vad_tmp_buffer_.get(), | 178 if (WebRtcVad_Process(vad_high_, sample_rate_hz_, vad_tmp_buffer_.get(), |
180 chunk_length_) == 1) { | 179 chunk_length_) == 1) { |
181 printf("capture HAS speech\n"); | 180 printf("capture HAS speech\n"); |
182 return; | 181 return; |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
263 lambda_bot = lambda; | 262 lambda_bot = lambda; |
264 } else { | 263 } else { |
265 lambda_top = lambda; | 264 lambda_top = lambda; |
266 } | 265 } |
267 power_ratio = fabs(power / power_target); | 266 power_ratio = fabs(power / power_target); |
268 ++iters; | 267 ++iters; |
269 } | 268 } |
270 | 269 |
271 // (ERB gain) = filterbank' * (freq gain) | 270 // (ERB gain) = filterbank' * (freq gain) |
272 float* gains = gain_applier_.target(); | 271 float* gains = gain_applier_.target(); |
273 for (int i = 0; i < freqs_; ++i) { | 272 for (size_t i = 0; i < freqs_; ++i) { |
274 gains[i] = 0.0f; | 273 gains[i] = 0.0f; |
275 for (int j = 0; j < bank_size_; ++j) { | 274 for (size_t j = 0; j < bank_size_; ++j) { |
276 gains[i] = fmaf(filter_bank_[j][i], gains_eq_[j], gains[i]); | 275 gains[i] = fmaf(filter_bank_[j][i], gains_eq_[j], gains[i]); |
277 } | 276 } |
278 } | 277 } |
279 } | 278 } |
280 | 279 |
281 void IntelligibilityEnhancer::ProcessNoiseBlock(const complex<float>* in_block, | 280 void IntelligibilityEnhancer::ProcessNoiseBlock(const complex<float>* in_block, |
282 complex<float>* /*out_block*/) { | 281 complex<float>* /*out_block*/) { |
283 noise_variance_.Step(in_block); | 282 noise_variance_.Step(in_block); |
284 } | 283 } |
285 | 284 |
286 int IntelligibilityEnhancer::GetBankSize(int sample_rate, int erb_resolution) { | 285 size_t IntelligibilityEnhancer::GetBankSize(int sample_rate, |
| 286 size_t erb_resolution) { |
287 float freq_limit = sample_rate / 2000.0f; | 287 float freq_limit = sample_rate / 2000.0f; |
288 int erb_scale = ceilf( | 288 size_t erb_scale = static_cast<size_t>(ceilf( |
289 11.17f * logf((freq_limit + 0.312f) / (freq_limit + 14.6575f)) + 43.0f); | 289 11.17f * logf((freq_limit + 0.312f) / (freq_limit + 14.6575f)) + 43.0f)); |
290 return erb_scale * erb_resolution; | 290 return erb_scale * erb_resolution; |
291 } | 291 } |
292 | 292 |
293 void IntelligibilityEnhancer::CreateErbBank() { | 293 void IntelligibilityEnhancer::CreateErbBank() { |
294 int lf = 1, rf = 4; | 294 size_t lf = 1, rf = 4; |
295 | 295 |
296 for (int i = 0; i < bank_size_; ++i) { | 296 for (size_t i = 0; i < bank_size_; ++i) { |
297 float abs_temp = fabsf((i + 1.0f) / static_cast<float>(erb_resolution_)); | 297 float abs_temp = fabsf((i + 1.0f) / static_cast<float>(erb_resolution_)); |
298 center_freqs_[i] = 676170.4f / (47.06538f - expf(0.08950404f * abs_temp)); | 298 center_freqs_[i] = 676170.4f / (47.06538f - expf(0.08950404f * abs_temp)); |
299 center_freqs_[i] -= 14678.49f; | 299 center_freqs_[i] -= 14678.49f; |
300 } | 300 } |
301 float last_center_freq = center_freqs_[bank_size_ - 1]; | 301 float last_center_freq = center_freqs_[bank_size_ - 1]; |
302 for (int i = 0; i < bank_size_; ++i) { | 302 for (size_t i = 0; i < bank_size_; ++i) { |
303 center_freqs_[i] *= 0.5f * sample_rate_hz_ / last_center_freq; | 303 center_freqs_[i] *= 0.5f * sample_rate_hz_ / last_center_freq; |
304 } | 304 } |
305 | 305 |
306 filter_bank_ = static_cast<float**>( | 306 filter_bank_ = static_cast<float**>( |
307 malloc(sizeof(*filter_bank_) * bank_size_ + | 307 malloc(sizeof(*filter_bank_) * bank_size_ + |
308 sizeof(**filter_bank_) * freqs_ * bank_size_)); | 308 sizeof(**filter_bank_) * freqs_ * bank_size_)); |
309 for (int i = 0; i < bank_size_; ++i) { | 309 for (size_t i = 0; i < bank_size_; ++i) { |
310 filter_bank_[i] = | 310 filter_bank_[i] = |
311 reinterpret_cast<float*>(filter_bank_ + bank_size_) + freqs_ * i; | 311 reinterpret_cast<float*>(filter_bank_ + bank_size_) + freqs_ * i; |
312 } | 312 } |
313 | 313 |
314 for (int i = 1; i <= bank_size_; ++i) { | 314 for (size_t i = 1; i <= bank_size_; ++i) { |
315 int lll, ll, rr, rrr; | 315 size_t lll, ll, rr, rrr; |
316 lll = round(center_freqs_[max(1, i - lf) - 1] * freqs_ / | 316 static const size_t one = 1; |
317 (0.5f * sample_rate_hz_)); | 317 lll = static_cast<size_t>(round( |
318 ll = | 318 center_freqs_[max(one, i - lf) - 1] * freqs_ / |
319 round(center_freqs_[max(1, i) - 1] * freqs_ / (0.5f * sample_rate_hz_)); | 319 (0.5f * sample_rate_hz_))); |
320 lll = min(freqs_, max(lll, 1)) - 1; | 320 ll = static_cast<size_t>(round( |
321 ll = min(freqs_, max(ll, 1)) - 1; | 321 center_freqs_[max(one, i) - 1] * freqs_ / (0.5f * sample_rate_hz_))); |
| 322 lll = min(freqs_, max(lll, one)) - 1; |
| 323 ll = min(freqs_, max(ll, one)) - 1; |
322 | 324 |
323 rrr = round(center_freqs_[min(bank_size_, i + rf) - 1] * freqs_ / | 325 rrr = static_cast<size_t>(round( |
324 (0.5f * sample_rate_hz_)); | 326 center_freqs_[min(bank_size_, i + rf) - 1] * freqs_ / |
325 rr = round(center_freqs_[min(bank_size_, i + 1) - 1] * freqs_ / | 327 (0.5f * sample_rate_hz_))); |
326 (0.5f * sample_rate_hz_)); | 328 rr = static_cast<size_t>(round( |
327 rrr = min(freqs_, max(rrr, 1)) - 1; | 329 center_freqs_[min(bank_size_, i + 1) - 1] * freqs_ / |
328 rr = min(freqs_, max(rr, 1)) - 1; | 330 (0.5f * sample_rate_hz_))); |
| 331 rrr = min(freqs_, max(rrr, one)) - 1; |
| 332 rr = min(freqs_, max(rr, one)) - 1; |
329 | 333 |
330 float step, element; | 334 float step, element; |
331 | 335 |
332 step = 1.0f / (ll - lll); | 336 step = 1.0f / (ll - lll); |
333 element = 0.0f; | 337 element = 0.0f; |
334 for (int j = lll; j <= ll; ++j) { | 338 for (size_t j = lll; j <= ll; ++j) { |
335 filter_bank_[i - 1][j] = element; | 339 filter_bank_[i - 1][j] = element; |
336 element += step; | 340 element += step; |
337 } | 341 } |
338 step = 1.0f / (rrr - rr); | 342 step = 1.0f / (rrr - rr); |
339 element = 1.0f; | 343 element = 1.0f; |
340 for (int j = rr; j <= rrr; ++j) { | 344 for (size_t j = rr; j <= rrr; ++j) { |
341 filter_bank_[i - 1][j] = element; | 345 filter_bank_[i - 1][j] = element; |
342 element -= step; | 346 element -= step; |
343 } | 347 } |
344 for (int j = ll; j <= rr; ++j) { | 348 for (size_t j = ll; j <= rr; ++j) { |
345 filter_bank_[i - 1][j] = 1.0f; | 349 filter_bank_[i - 1][j] = 1.0f; |
346 } | 350 } |
347 } | 351 } |
348 | 352 |
349 float sum; | 353 float sum; |
350 for (int i = 0; i < freqs_; ++i) { | 354 for (size_t i = 0; i < freqs_; ++i) { |
351 sum = 0.0f; | 355 sum = 0.0f; |
352 for (int j = 0; j < bank_size_; ++j) { | 356 for (size_t j = 0; j < bank_size_; ++j) { |
353 sum += filter_bank_[j][i]; | 357 sum += filter_bank_[j][i]; |
354 } | 358 } |
355 for (int j = 0; j < bank_size_; ++j) { | 359 for (size_t j = 0; j < bank_size_; ++j) { |
356 filter_bank_[j][i] /= sum; | 360 filter_bank_[j][i] /= sum; |
357 } | 361 } |
358 } | 362 } |
359 } | 363 } |
360 | 364 |
361 void IntelligibilityEnhancer::SolveForGainsGivenLambda(float lambda, | 365 void IntelligibilityEnhancer::SolveForGainsGivenLambda(float lambda, |
362 int start_freq, | 366 size_t start_freq, |
363 float* sols) { | 367 float* sols) { |
364 bool quadratic = (kConfigRho < 1.0f); | 368 bool quadratic = (kConfigRho < 1.0f); |
365 const float* var_x0 = filtered_clear_var_.get(); | 369 const float* var_x0 = filtered_clear_var_.get(); |
366 const float* var_n0 = filtered_noise_var_.get(); | 370 const float* var_n0 = filtered_noise_var_.get(); |
367 | 371 |
368 for (int n = 0; n < start_freq; ++n) { | 372 for (size_t n = 0; n < start_freq; ++n) { |
369 sols[n] = 1.0f; | 373 sols[n] = 1.0f; |
370 } | 374 } |
371 | 375 |
372 // Analytic solution for optimal gains. See paper for derivation. | 376 // Analytic solution for optimal gains. See paper for derivation. |
373 for (int n = start_freq - 1; n < bank_size_; ++n) { | 377 for (size_t n = start_freq - 1; n < bank_size_; ++n) { |
374 float alpha0, beta0, gamma0; | 378 float alpha0, beta0, gamma0; |
375 gamma0 = 0.5f * rho_[n] * var_x0[n] * var_n0[n] + | 379 gamma0 = 0.5f * rho_[n] * var_x0[n] * var_n0[n] + |
376 lambda * var_x0[n] * var_n0[n] * var_n0[n]; | 380 lambda * var_x0[n] * var_n0[n] * var_n0[n]; |
377 beta0 = lambda * var_x0[n] * (2 - rho_[n]) * var_x0[n] * var_n0[n]; | 381 beta0 = lambda * var_x0[n] * (2 - rho_[n]) * var_x0[n] * var_n0[n]; |
378 if (quadratic) { | 382 if (quadratic) { |
379 alpha0 = lambda * var_x0[n] * (1 - rho_[n]) * var_x0[n] * var_x0[n]; | 383 alpha0 = lambda * var_x0[n] * (1 - rho_[n]) * var_x0[n] * var_x0[n]; |
380 sols[n] = | 384 sols[n] = |
381 (-beta0 - sqrtf(beta0 * beta0 - 4 * alpha0 * gamma0)) / (2 * alpha0); | 385 (-beta0 - sqrtf(beta0 * beta0 - 4 * alpha0 * gamma0)) / (2 * alpha0); |
382 } else { | 386 } else { |
383 sols[n] = -gamma0 / beta0; | 387 sols[n] = -gamma0 / beta0; |
384 } | 388 } |
385 sols[n] = fmax(0, sols[n]); | 389 sols[n] = fmax(0, sols[n]); |
386 } | 390 } |
387 } | 391 } |
388 | 392 |
389 void IntelligibilityEnhancer::FilterVariance(const float* var, float* result) { | 393 void IntelligibilityEnhancer::FilterVariance(const float* var, float* result) { |
390 for (int i = 0; i < bank_size_; ++i) { | 394 for (size_t i = 0; i < bank_size_; ++i) { |
391 result[i] = DotProduct(filter_bank_[i], var, freqs_); | 395 result[i] = DotProduct(filter_bank_[i], var, freqs_); |
392 } | 396 } |
393 } | 397 } |
394 | 398 |
395 float IntelligibilityEnhancer::DotProduct(const float* a, | 399 float IntelligibilityEnhancer::DotProduct(const float* a, |
396 const float* b, | 400 const float* b, |
397 int length) { | 401 size_t length) { |
398 float ret = 0.0f; | 402 float ret = 0.0f; |
399 | 403 |
400 for (int i = 0; i < length; ++i) { | 404 for (size_t i = 0; i < length; ++i) { |
401 ret = fmaf(a[i], b[i], ret); | 405 ret = fmaf(a[i], b[i], ret); |
402 } | 406 } |
403 return ret; | 407 return ret; |
404 } | 408 } |
405 | 409 |
406 } // namespace webrtc | 410 } // namespace webrtc |
OLD | NEW |