1 /*
2 * Copyright (c) 2012 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 #include "modules/audio_processing/utility/delay_estimator_wrapper.h"
12
13 #include <stdlib.h>
14 #include <string.h>
15
16 #include "modules/audio_processing/utility/delay_estimator.h"
17 #include "modules/audio_processing/utility/delay_estimator_internal.h"
18 #include "rtc_base/checks.h"
19
20 namespace webrtc {
21
22 // Only bit |kBandFirst| through bit |kBandLast| are processed and
23 // |kBandFirst| - |kBandLast| must be < 32.
24 enum { kBandFirst = 12 };
25 enum { kBandLast = 43 };
26
SetBit(uint32_t in,int pos)27 static __inline uint32_t SetBit(uint32_t in, int pos) {
28 uint32_t mask = (1 << pos);
29 uint32_t out = (in | mask);
30
31 return out;
32 }
33
34 // Calculates the mean recursively. Same version as WebRtc_MeanEstimatorFix(),
35 // but for float.
36 //
37 // Inputs:
38 // - new_value : New additional value.
39 // - scale : Scale for smoothing (should be less than 1.0).
40 //
41 // Input/Output:
42 // - mean_value : Pointer to the mean value for updating.
43 //
MeanEstimatorFloat(float new_value,float scale,float * mean_value)44 static void MeanEstimatorFloat(float new_value,
45 float scale,
46 float* mean_value) {
47 RTC_DCHECK_LT(scale, 1.0f);
48 *mean_value += (new_value - *mean_value) * scale;
49 }
50
51 // Computes the binary spectrum by comparing the input |spectrum| with a
52 // |threshold_spectrum|. Float and fixed point versions.
53 //
54 // Inputs:
55 // - spectrum : Spectrum of which the binary spectrum should be
56 // calculated.
57 // - threshold_spectrum : Threshold spectrum with which the input
58 // spectrum is compared.
59 // Return:
60 // - out : Binary spectrum.
61 //
BinarySpectrumFix(const uint16_t * spectrum,SpectrumType * threshold_spectrum,int q_domain,int * threshold_initialized)62 static uint32_t BinarySpectrumFix(const uint16_t* spectrum,
63 SpectrumType* threshold_spectrum,
64 int q_domain,
65 int* threshold_initialized) {
66 int i = kBandFirst;
67 uint32_t out = 0;
68
69 RTC_DCHECK_LT(q_domain, 16);
70
71 if (!(*threshold_initialized)) {
72 // Set the |threshold_spectrum| to half the input |spectrum| as starting
73 // value. This speeds up the convergence.
74 for (i = kBandFirst; i <= kBandLast; i++) {
75 if (spectrum[i] > 0) {
76 // Convert input spectrum from Q(|q_domain|) to Q15.
77 int32_t spectrum_q15 = ((int32_t)spectrum[i]) << (15 - q_domain);
78 threshold_spectrum[i].int32_ = (spectrum_q15 >> 1);
79 *threshold_initialized = 1;
80 }
81 }
82 }
83 for (i = kBandFirst; i <= kBandLast; i++) {
84 // Convert input spectrum from Q(|q_domain|) to Q15.
85 int32_t spectrum_q15 = ((int32_t)spectrum[i]) << (15 - q_domain);
86 // Update the |threshold_spectrum|.
87 WebRtc_MeanEstimatorFix(spectrum_q15, 6, &(threshold_spectrum[i].int32_));
88 // Convert |spectrum| at current frequency bin to a binary value.
89 if (spectrum_q15 > threshold_spectrum[i].int32_) {
90 out = SetBit(out, i - kBandFirst);
91 }
92 }
93
94 return out;
95 }
96
BinarySpectrumFloat(const float * spectrum,SpectrumType * threshold_spectrum,int * threshold_initialized)97 static uint32_t BinarySpectrumFloat(const float* spectrum,
98 SpectrumType* threshold_spectrum,
99 int* threshold_initialized) {
100 int i = kBandFirst;
101 uint32_t out = 0;
102 const float kScale = 1 / 64.0;
103
104 if (!(*threshold_initialized)) {
105 // Set the |threshold_spectrum| to half the input |spectrum| as starting
106 // value. This speeds up the convergence.
107 for (i = kBandFirst; i <= kBandLast; i++) {
108 if (spectrum[i] > 0.0f) {
109 threshold_spectrum[i].float_ = (spectrum[i] / 2);
110 *threshold_initialized = 1;
111 }
112 }
113 }
114
115 for (i = kBandFirst; i <= kBandLast; i++) {
116 // Update the |threshold_spectrum|.
117 MeanEstimatorFloat(spectrum[i], kScale, &(threshold_spectrum[i].float_));
118 // Convert |spectrum| at current frequency bin to a binary value.
119 if (spectrum[i] > threshold_spectrum[i].float_) {
120 out = SetBit(out, i - kBandFirst);
121 }
122 }
123
124 return out;
125 }
126
WebRtc_FreeDelayEstimatorFarend(void * handle)127 void WebRtc_FreeDelayEstimatorFarend(void* handle) {
128 DelayEstimatorFarend* self = (DelayEstimatorFarend*)handle;
129
130 if (handle == NULL) {
131 return;
132 }
133
134 free(self->mean_far_spectrum);
135 self->mean_far_spectrum = NULL;
136
137 WebRtc_FreeBinaryDelayEstimatorFarend(self->binary_farend);
138 self->binary_farend = NULL;
139
140 free(self);
141 }
142
WebRtc_CreateDelayEstimatorFarend(int spectrum_size,int history_size)143 void* WebRtc_CreateDelayEstimatorFarend(int spectrum_size, int history_size) {
144 DelayEstimatorFarend* self = NULL;
145
146 // Check if the sub band used in the delay estimation is small enough to fit
147 // the binary spectra in a uint32_t.
148 static_assert(kBandLast - kBandFirst < 32, "");
149
150 if (spectrum_size >= kBandLast) {
151 self = static_cast<DelayEstimatorFarend*>(
152 malloc(sizeof(DelayEstimatorFarend)));
153 }
154
155 if (self != NULL) {
156 int memory_fail = 0;
157
158 // Allocate memory for the binary far-end spectrum handling.
159 self->binary_farend = WebRtc_CreateBinaryDelayEstimatorFarend(history_size);
160 memory_fail |= (self->binary_farend == NULL);
161
162 // Allocate memory for spectrum buffers.
163 self->mean_far_spectrum = static_cast<SpectrumType*>(
164 malloc(spectrum_size * sizeof(SpectrumType)));
165 memory_fail |= (self->mean_far_spectrum == NULL);
166
167 self->spectrum_size = spectrum_size;
168
169 if (memory_fail) {
170 WebRtc_FreeDelayEstimatorFarend(self);
171 self = NULL;
172 }
173 }
174
175 return self;
176 }
177
WebRtc_InitDelayEstimatorFarend(void * handle)178 int WebRtc_InitDelayEstimatorFarend(void* handle) {
179 DelayEstimatorFarend* self = (DelayEstimatorFarend*)handle;
180
181 if (self == NULL) {
182 return -1;
183 }
184
185 // Initialize far-end part of binary delay estimator.
186 WebRtc_InitBinaryDelayEstimatorFarend(self->binary_farend);
187
188 // Set averaged far and near end spectra to zero.
189 memset(self->mean_far_spectrum, 0,
190 sizeof(SpectrumType) * self->spectrum_size);
191 // Reset initialization indicators.
192 self->far_spectrum_initialized = 0;
193
194 return 0;
195 }
196
WebRtc_SoftResetDelayEstimatorFarend(void * handle,int delay_shift)197 void WebRtc_SoftResetDelayEstimatorFarend(void* handle, int delay_shift) {
198 DelayEstimatorFarend* self = (DelayEstimatorFarend*)handle;
199 RTC_DCHECK(self);
200 WebRtc_SoftResetBinaryDelayEstimatorFarend(self->binary_farend, delay_shift);
201 }
202
WebRtc_AddFarSpectrumFix(void * handle,const uint16_t * far_spectrum,int spectrum_size,int far_q)203 int WebRtc_AddFarSpectrumFix(void* handle,
204 const uint16_t* far_spectrum,
205 int spectrum_size,
206 int far_q) {
207 DelayEstimatorFarend* self = (DelayEstimatorFarend*)handle;
208 uint32_t binary_spectrum = 0;
209
210 if (self == NULL) {
211 return -1;
212 }
213 if (far_spectrum == NULL) {
214 // Empty far end spectrum.
215 return -1;
216 }
217 if (spectrum_size != self->spectrum_size) {
218 // Data sizes don't match.
219 return -1;
220 }
221 if (far_q > 15) {
222 // If |far_q| is larger than 15 we cannot guarantee no wrap around.
223 return -1;
224 }
225
226 // Get binary spectrum.
227 binary_spectrum = BinarySpectrumFix(far_spectrum, self->mean_far_spectrum,
228 far_q, &(self->far_spectrum_initialized));
229 WebRtc_AddBinaryFarSpectrum(self->binary_farend, binary_spectrum);
230
231 return 0;
232 }
233
WebRtc_AddFarSpectrumFloat(void * handle,const float * far_spectrum,int spectrum_size)234 int WebRtc_AddFarSpectrumFloat(void* handle,
235 const float* far_spectrum,
236 int spectrum_size) {
237 DelayEstimatorFarend* self = (DelayEstimatorFarend*)handle;
238 uint32_t binary_spectrum = 0;
239
240 if (self == NULL) {
241 return -1;
242 }
243 if (far_spectrum == NULL) {
244 // Empty far end spectrum.
245 return -1;
246 }
247 if (spectrum_size != self->spectrum_size) {
248 // Data sizes don't match.
249 return -1;
250 }
251
252 // Get binary spectrum.
253 binary_spectrum = BinarySpectrumFloat(far_spectrum, self->mean_far_spectrum,
254 &(self->far_spectrum_initialized));
255 WebRtc_AddBinaryFarSpectrum(self->binary_farend, binary_spectrum);
256
257 return 0;
258 }
259
WebRtc_FreeDelayEstimator(void * handle)260 void WebRtc_FreeDelayEstimator(void* handle) {
261 DelayEstimator* self = (DelayEstimator*)handle;
262
263 if (handle == NULL) {
264 return;
265 }
266
267 free(self->mean_near_spectrum);
268 self->mean_near_spectrum = NULL;
269
270 WebRtc_FreeBinaryDelayEstimator(self->binary_handle);
271 self->binary_handle = NULL;
272
273 free(self);
274 }
275
WebRtc_CreateDelayEstimator(void * farend_handle,int max_lookahead)276 void* WebRtc_CreateDelayEstimator(void* farend_handle, int max_lookahead) {
277 DelayEstimator* self = NULL;
278 DelayEstimatorFarend* farend = (DelayEstimatorFarend*)farend_handle;
279
280 if (farend_handle != NULL) {
281 self = static_cast<DelayEstimator*>(malloc(sizeof(DelayEstimator)));
282 }
283
284 if (self != NULL) {
285 int memory_fail = 0;
286
287 // Allocate memory for the farend spectrum handling.
288 self->binary_handle =
289 WebRtc_CreateBinaryDelayEstimator(farend->binary_farend, max_lookahead);
290 memory_fail |= (self->binary_handle == NULL);
291
292 // Allocate memory for spectrum buffers.
293 self->mean_near_spectrum = static_cast<SpectrumType*>(
294 malloc(farend->spectrum_size * sizeof(SpectrumType)));
295 memory_fail |= (self->mean_near_spectrum == NULL);
296
297 self->spectrum_size = farend->spectrum_size;
298
299 if (memory_fail) {
300 WebRtc_FreeDelayEstimator(self);
301 self = NULL;
302 }
303 }
304
305 return self;
306 }
307
WebRtc_InitDelayEstimator(void * handle)308 int WebRtc_InitDelayEstimator(void* handle) {
309 DelayEstimator* self = (DelayEstimator*)handle;
310
311 if (self == NULL) {
312 return -1;
313 }
314
315 // Initialize binary delay estimator.
316 WebRtc_InitBinaryDelayEstimator(self->binary_handle);
317
318 // Set averaged far and near end spectra to zero.
319 memset(self->mean_near_spectrum, 0,
320 sizeof(SpectrumType) * self->spectrum_size);
321 // Reset initialization indicators.
322 self->near_spectrum_initialized = 0;
323
324 return 0;
325 }
326
WebRtc_SoftResetDelayEstimator(void * handle,int delay_shift)327 int WebRtc_SoftResetDelayEstimator(void* handle, int delay_shift) {
328 DelayEstimator* self = (DelayEstimator*)handle;
329 RTC_DCHECK(self);
330 return WebRtc_SoftResetBinaryDelayEstimator(self->binary_handle, delay_shift);
331 }
332
WebRtc_set_history_size(void * handle,int history_size)333 int WebRtc_set_history_size(void* handle, int history_size) {
334 DelayEstimator* self = static_cast<DelayEstimator*>(handle);
335
336 if ((self == NULL) || (history_size <= 1)) {
337 return -1;
338 }
339 return WebRtc_AllocateHistoryBufferMemory(self->binary_handle, history_size);
340 }
341
WebRtc_history_size(const void * handle)342 int WebRtc_history_size(const void* handle) {
343 const DelayEstimator* self = static_cast<const DelayEstimator*>(handle);
344
345 if (self == NULL) {
346 return -1;
347 }
348 if (self->binary_handle->farend->history_size !=
349 self->binary_handle->history_size) {
350 // Non matching history sizes.
351 return -1;
352 }
353 return self->binary_handle->history_size;
354 }
355
WebRtc_set_lookahead(void * handle,int lookahead)356 int WebRtc_set_lookahead(void* handle, int lookahead) {
357 DelayEstimator* self = (DelayEstimator*)handle;
358 RTC_DCHECK(self);
359 RTC_DCHECK(self->binary_handle);
360 if ((lookahead > self->binary_handle->near_history_size - 1) ||
361 (lookahead < 0)) {
362 return -1;
363 }
364 self->binary_handle->lookahead = lookahead;
365 return self->binary_handle->lookahead;
366 }
367
WebRtc_lookahead(void * handle)368 int WebRtc_lookahead(void* handle) {
369 DelayEstimator* self = (DelayEstimator*)handle;
370 RTC_DCHECK(self);
371 RTC_DCHECK(self->binary_handle);
372 return self->binary_handle->lookahead;
373 }
374
WebRtc_set_allowed_offset(void * handle,int allowed_offset)375 int WebRtc_set_allowed_offset(void* handle, int allowed_offset) {
376 DelayEstimator* self = (DelayEstimator*)handle;
377
378 if ((self == NULL) || (allowed_offset < 0)) {
379 return -1;
380 }
381 self->binary_handle->allowed_offset = allowed_offset;
382 return 0;
383 }
384
WebRtc_get_allowed_offset(const void * handle)385 int WebRtc_get_allowed_offset(const void* handle) {
386 const DelayEstimator* self = (const DelayEstimator*)handle;
387
388 if (self == NULL) {
389 return -1;
390 }
391 return self->binary_handle->allowed_offset;
392 }
393
WebRtc_enable_robust_validation(void * handle,int enable)394 int WebRtc_enable_robust_validation(void* handle, int enable) {
395 DelayEstimator* self = (DelayEstimator*)handle;
396
397 if (self == NULL) {
398 return -1;
399 }
400 if ((enable < 0) || (enable > 1)) {
401 return -1;
402 }
403 RTC_DCHECK(self->binary_handle);
404 self->binary_handle->robust_validation_enabled = enable;
405 return 0;
406 }
407
WebRtc_is_robust_validation_enabled(const void * handle)408 int WebRtc_is_robust_validation_enabled(const void* handle) {
409 const DelayEstimator* self = (const DelayEstimator*)handle;
410
411 if (self == NULL) {
412 return -1;
413 }
414 return self->binary_handle->robust_validation_enabled;
415 }
416
WebRtc_DelayEstimatorProcessFix(void * handle,const uint16_t * near_spectrum,int spectrum_size,int near_q)417 int WebRtc_DelayEstimatorProcessFix(void* handle,
418 const uint16_t* near_spectrum,
419 int spectrum_size,
420 int near_q) {
421 DelayEstimator* self = (DelayEstimator*)handle;
422 uint32_t binary_spectrum = 0;
423
424 if (self == NULL) {
425 return -1;
426 }
427 if (near_spectrum == NULL) {
428 // Empty near end spectrum.
429 return -1;
430 }
431 if (spectrum_size != self->spectrum_size) {
432 // Data sizes don't match.
433 return -1;
434 }
435 if (near_q > 15) {
436 // If |near_q| is larger than 15 we cannot guarantee no wrap around.
437 return -1;
438 }
439
440 // Get binary spectra.
441 binary_spectrum =
442 BinarySpectrumFix(near_spectrum, self->mean_near_spectrum, near_q,
443 &(self->near_spectrum_initialized));
444
445 return WebRtc_ProcessBinarySpectrum(self->binary_handle, binary_spectrum);
446 }
447
WebRtc_DelayEstimatorProcessFloat(void * handle,const float * near_spectrum,int spectrum_size)448 int WebRtc_DelayEstimatorProcessFloat(void* handle,
449 const float* near_spectrum,
450 int spectrum_size) {
451 DelayEstimator* self = (DelayEstimator*)handle;
452 uint32_t binary_spectrum = 0;
453
454 if (self == NULL) {
455 return -1;
456 }
457 if (near_spectrum == NULL) {
458 // Empty near end spectrum.
459 return -1;
460 }
461 if (spectrum_size != self->spectrum_size) {
462 // Data sizes don't match.
463 return -1;
464 }
465
466 // Get binary spectrum.
467 binary_spectrum = BinarySpectrumFloat(near_spectrum, self->mean_near_spectrum,
468 &(self->near_spectrum_initialized));
469
470 return WebRtc_ProcessBinarySpectrum(self->binary_handle, binary_spectrum);
471 }
472
WebRtc_last_delay(void * handle)473 int WebRtc_last_delay(void* handle) {
474 DelayEstimator* self = (DelayEstimator*)handle;
475
476 if (self == NULL) {
477 return -1;
478 }
479
480 return WebRtc_binary_last_delay(self->binary_handle);
481 }
482
WebRtc_last_delay_quality(void * handle)483 float WebRtc_last_delay_quality(void* handle) {
484 DelayEstimator* self = (DelayEstimator*)handle;
485 RTC_DCHECK(self);
486 return WebRtc_binary_last_delay_quality(self->binary_handle);
487 }
488
489 } // namespace webrtc
490