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