2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
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.
11 #include "webrtc/modules/audio_processing/utility/delay_estimator_wrapper.h"
17 #include "webrtc/modules/audio_processing/utility/delay_estimator.h"
18 #include "webrtc/modules/audio_processing/utility/delay_estimator_internal.h"
19 #include "webrtc/system_wrappers/interface/compile_assert_c.h"
21 // Only bit |kBandFirst| through bit |kBandLast| are processed and
22 // |kBandFirst| - |kBandLast| must be < 32.
23 enum { kBandFirst = 12 };
24 enum { kBandLast = 43 };
26 static __inline uint32_t SetBit(uint32_t in, int pos) {
27 uint32_t mask = (1 << pos);
28 uint32_t out = (in | mask);
33 // Calculates the mean recursively. Same version as WebRtc_MeanEstimatorFix(),
37 // - new_value : New additional value.
38 // - scale : Scale for smoothing (should be less than 1.0).
41 // - mean_value : Pointer to the mean value for updating.
43 static void MeanEstimatorFloat(float new_value,
47 *mean_value += (new_value - *mean_value) * scale;
50 // Computes the binary spectrum by comparing the input |spectrum| with a
51 // |threshold_spectrum|. Float and fixed point versions.
54 // - spectrum : Spectrum of which the binary spectrum should be
56 // - threshold_spectrum : Threshold spectrum with which the input
57 // spectrum is compared.
59 // - out : Binary spectrum.
61 static uint32_t BinarySpectrumFix(const uint16_t* spectrum,
62 SpectrumType* threshold_spectrum,
64 int* threshold_initialized) {
68 assert(q_domain < 16);
70 if (!(*threshold_initialized)) {
71 // Set the |threshold_spectrum| to half the input |spectrum| as starting
72 // value. This speeds up the convergence.
73 for (i = kBandFirst; i <= kBandLast; i++) {
74 if (spectrum[i] > 0) {
75 // Convert input spectrum from Q(|q_domain|) to Q15.
76 int32_t spectrum_q15 = ((int32_t) spectrum[i]) << (15 - q_domain);
77 threshold_spectrum[i].int32_ = (spectrum_q15 >> 1);
78 *threshold_initialized = 1;
82 for (i = kBandFirst; i <= kBandLast; i++) {
83 // Convert input spectrum from Q(|q_domain|) to Q15.
84 int32_t spectrum_q15 = ((int32_t) spectrum[i]) << (15 - q_domain);
85 // Update the |threshold_spectrum|.
86 WebRtc_MeanEstimatorFix(spectrum_q15, 6, &(threshold_spectrum[i].int32_));
87 // Convert |spectrum| at current frequency bin to a binary value.
88 if (spectrum_q15 > threshold_spectrum[i].int32_) {
89 out = SetBit(out, i - kBandFirst);
96 static uint32_t BinarySpectrumFloat(const float* spectrum,
97 SpectrumType* threshold_spectrum,
98 int* threshold_initialized) {
101 const float kScale = 1 / 64.0;
103 if (!(*threshold_initialized)) {
104 // Set the |threshold_spectrum| to half the input |spectrum| as starting
105 // value. This speeds up the convergence.
106 for (i = kBandFirst; i <= kBandLast; i++) {
107 if (spectrum[i] > 0.0f) {
108 threshold_spectrum[i].float_ = (spectrum[i] / 2);
109 *threshold_initialized = 1;
114 for (i = kBandFirst; i <= kBandLast; i++) {
115 // Update the |threshold_spectrum|.
116 MeanEstimatorFloat(spectrum[i], kScale, &(threshold_spectrum[i].float_));
117 // Convert |spectrum| at current frequency bin to a binary value.
118 if (spectrum[i] > threshold_spectrum[i].float_) {
119 out = SetBit(out, i - kBandFirst);
126 void WebRtc_FreeDelayEstimatorFarend(void* handle) {
127 DelayEstimatorFarend* self = (DelayEstimatorFarend*) handle;
129 if (handle == NULL) {
133 free(self->mean_far_spectrum);
134 self->mean_far_spectrum = NULL;
136 WebRtc_FreeBinaryDelayEstimatorFarend(self->binary_farend);
137 self->binary_farend = NULL;
142 void* WebRtc_CreateDelayEstimatorFarend(int spectrum_size, int history_size) {
143 DelayEstimatorFarend* self = NULL;
145 // Check if the sub band used in the delay estimation is small enough to fit
146 // the binary spectra in a uint32_t.
147 COMPILE_ASSERT(kBandLast - kBandFirst < 32);
149 if (spectrum_size >= kBandLast) {
150 self = malloc(sizeof(DelayEstimatorFarend));
156 // Allocate memory for the binary far-end spectrum handling.
157 self->binary_farend = WebRtc_CreateBinaryDelayEstimatorFarend(history_size);
158 memory_fail |= (self->binary_farend == NULL);
160 // Allocate memory for spectrum buffers.
161 self->mean_far_spectrum = malloc(spectrum_size * sizeof(SpectrumType));
162 memory_fail |= (self->mean_far_spectrum == NULL);
164 self->spectrum_size = spectrum_size;
167 WebRtc_FreeDelayEstimatorFarend(self);
175 int WebRtc_InitDelayEstimatorFarend(void* handle) {
176 DelayEstimatorFarend* self = (DelayEstimatorFarend*) handle;
182 // Initialize far-end part of binary delay estimator.
183 WebRtc_InitBinaryDelayEstimatorFarend(self->binary_farend);
185 // Set averaged far and near end spectra to zero.
186 memset(self->mean_far_spectrum, 0,
187 sizeof(SpectrumType) * self->spectrum_size);
188 // Reset initialization indicators.
189 self->far_spectrum_initialized = 0;
194 void WebRtc_SoftResetDelayEstimatorFarend(void* handle, int delay_shift) {
195 DelayEstimatorFarend* self = (DelayEstimatorFarend*) handle;
196 assert(self != NULL);
197 WebRtc_SoftResetBinaryDelayEstimatorFarend(self->binary_farend, delay_shift);
200 int WebRtc_AddFarSpectrumFix(void* handle,
201 const uint16_t* far_spectrum,
204 DelayEstimatorFarend* self = (DelayEstimatorFarend*) handle;
205 uint32_t binary_spectrum = 0;
210 if (far_spectrum == NULL) {
211 // Empty far end spectrum.
214 if (spectrum_size != self->spectrum_size) {
215 // Data sizes don't match.
219 // If |far_q| is larger than 15 we cannot guarantee no wrap around.
223 // Get binary spectrum.
224 binary_spectrum = BinarySpectrumFix(far_spectrum, self->mean_far_spectrum,
225 far_q, &(self->far_spectrum_initialized));
226 WebRtc_AddBinaryFarSpectrum(self->binary_farend, binary_spectrum);
231 int WebRtc_AddFarSpectrumFloat(void* handle,
232 const float* far_spectrum,
234 DelayEstimatorFarend* self = (DelayEstimatorFarend*) handle;
235 uint32_t binary_spectrum = 0;
240 if (far_spectrum == NULL) {
241 // Empty far end spectrum.
244 if (spectrum_size != self->spectrum_size) {
245 // Data sizes don't match.
249 // Get binary spectrum.
250 binary_spectrum = BinarySpectrumFloat(far_spectrum, self->mean_far_spectrum,
251 &(self->far_spectrum_initialized));
252 WebRtc_AddBinaryFarSpectrum(self->binary_farend, binary_spectrum);
257 void WebRtc_FreeDelayEstimator(void* handle) {
258 DelayEstimator* self = (DelayEstimator*) handle;
260 if (handle == NULL) {
264 free(self->mean_near_spectrum);
265 self->mean_near_spectrum = NULL;
267 WebRtc_FreeBinaryDelayEstimator(self->binary_handle);
268 self->binary_handle = NULL;
273 void* WebRtc_CreateDelayEstimator(void* farend_handle, int max_lookahead) {
274 DelayEstimator* self = NULL;
275 DelayEstimatorFarend* farend = (DelayEstimatorFarend*) farend_handle;
277 if (farend_handle != NULL) {
278 self = malloc(sizeof(DelayEstimator));
284 // Allocate memory for the farend spectrum handling.
285 self->binary_handle =
286 WebRtc_CreateBinaryDelayEstimator(farend->binary_farend, max_lookahead);
287 memory_fail |= (self->binary_handle == NULL);
289 // Allocate memory for spectrum buffers.
290 self->mean_near_spectrum = malloc(farend->spectrum_size *
291 sizeof(SpectrumType));
292 memory_fail |= (self->mean_near_spectrum == NULL);
294 self->spectrum_size = farend->spectrum_size;
297 WebRtc_FreeDelayEstimator(self);
305 int WebRtc_InitDelayEstimator(void* handle) {
306 DelayEstimator* self = (DelayEstimator*) handle;
312 // Initialize binary delay estimator.
313 WebRtc_InitBinaryDelayEstimator(self->binary_handle);
315 // Set averaged far and near end spectra to zero.
316 memset(self->mean_near_spectrum, 0,
317 sizeof(SpectrumType) * self->spectrum_size);
318 // Reset initialization indicators.
319 self->near_spectrum_initialized = 0;
324 int WebRtc_SoftResetDelayEstimator(void* handle, int delay_shift) {
325 DelayEstimator* self = (DelayEstimator*) handle;
326 assert(self != NULL);
327 return WebRtc_SoftResetBinaryDelayEstimator(self->binary_handle, delay_shift);
330 int WebRtc_set_history_size(void* handle, int history_size) {
331 DelayEstimator* self = handle;
333 if ((self == NULL) || (history_size <= 1)) {
336 return WebRtc_AllocateHistoryBufferMemory(self->binary_handle, history_size);
339 int WebRtc_history_size(const void* handle) {
340 const DelayEstimator* self = handle;
345 if (self->binary_handle->farend->history_size !=
346 self->binary_handle->history_size) {
347 // Non matching history sizes.
350 return self->binary_handle->history_size;
353 int WebRtc_set_lookahead(void* handle, int lookahead) {
354 DelayEstimator* self = (DelayEstimator*) handle;
355 assert(self != NULL);
356 assert(self->binary_handle != NULL);
357 if ((lookahead > self->binary_handle->near_history_size - 1) ||
361 self->binary_handle->lookahead = lookahead;
362 return self->binary_handle->lookahead;
365 int WebRtc_lookahead(void* handle) {
366 DelayEstimator* self = (DelayEstimator*) handle;
367 assert(self != NULL);
368 assert(self->binary_handle != NULL);
369 return self->binary_handle->lookahead;
372 int WebRtc_set_allowed_offset(void* handle, int allowed_offset) {
373 DelayEstimator* self = (DelayEstimator*) handle;
375 if ((self == NULL) || (allowed_offset < 0)) {
378 self->binary_handle->allowed_offset = allowed_offset;
382 int WebRtc_get_allowed_offset(const void* handle) {
383 const DelayEstimator* self = (const DelayEstimator*) handle;
388 return self->binary_handle->allowed_offset;
391 int WebRtc_enable_robust_validation(void* handle, int enable) {
392 DelayEstimator* self = (DelayEstimator*) handle;
397 if ((enable < 0) || (enable > 1)) {
400 assert(self->binary_handle != NULL);
401 self->binary_handle->robust_validation_enabled = enable;
405 int WebRtc_is_robust_validation_enabled(const void* handle) {
406 const DelayEstimator* self = (const DelayEstimator*) handle;
411 return self->binary_handle->robust_validation_enabled;
414 int WebRtc_DelayEstimatorProcessFix(void* handle,
415 const uint16_t* near_spectrum,
418 DelayEstimator* self = (DelayEstimator*) handle;
419 uint32_t binary_spectrum = 0;
424 if (near_spectrum == NULL) {
425 // Empty near end spectrum.
428 if (spectrum_size != self->spectrum_size) {
429 // Data sizes don't match.
433 // If |near_q| is larger than 15 we cannot guarantee no wrap around.
437 // Get binary spectra.
438 binary_spectrum = BinarySpectrumFix(near_spectrum,
439 self->mean_near_spectrum,
441 &(self->near_spectrum_initialized));
443 return WebRtc_ProcessBinarySpectrum(self->binary_handle, binary_spectrum);
446 int WebRtc_DelayEstimatorProcessFloat(void* handle,
447 const float* near_spectrum,
449 DelayEstimator* self = (DelayEstimator*) handle;
450 uint32_t binary_spectrum = 0;
455 if (near_spectrum == NULL) {
456 // Empty near end spectrum.
459 if (spectrum_size != self->spectrum_size) {
460 // Data sizes don't match.
464 // Get binary spectrum.
465 binary_spectrum = BinarySpectrumFloat(near_spectrum, self->mean_near_spectrum,
466 &(self->near_spectrum_initialized));
468 return WebRtc_ProcessBinarySpectrum(self->binary_handle, binary_spectrum);
471 int WebRtc_last_delay(void* handle) {
472 DelayEstimator* self = (DelayEstimator*) handle;
478 return WebRtc_binary_last_delay(self->binary_handle);
481 float WebRtc_last_delay_quality(void* handle) {
482 DelayEstimator* self = (DelayEstimator*) handle;
483 assert(self != NULL);
484 return WebRtc_binary_last_delay_quality(self->binary_handle);