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