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(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(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(DelayEstimator));
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, uint16_t* far_spectrum,
201                             int spectrum_size, int far_q) {
202  DelayEstimatorFarend* self = (DelayEstimatorFarend*) handle;
203  uint32_t binary_spectrum = 0;
204
205  if (self == NULL) {
206    return -1;
207  }
208  if (far_spectrum == NULL) {
209    // Empty far end spectrum.
210    return -1;
211  }
212  if (spectrum_size != self->spectrum_size) {
213    // Data sizes don't match.
214    return -1;
215  }
216  if (far_q > 15) {
217    // If |far_q| is larger than 15 we cannot guarantee no wrap around.
218    return -1;
219  }
220
221  // Get binary spectrum.
222  binary_spectrum = BinarySpectrumFix(far_spectrum, self->mean_far_spectrum,
223                                      far_q, &(self->far_spectrum_initialized));
224  WebRtc_AddBinaryFarSpectrum(self->binary_farend, binary_spectrum);
225
226  return 0;
227}
228
229int WebRtc_AddFarSpectrumFloat(void* handle, float* far_spectrum,
230                               int spectrum_size) {
231  DelayEstimatorFarend* self = (DelayEstimatorFarend*) handle;
232  uint32_t binary_spectrum = 0;
233
234  if (self == NULL) {
235    return -1;
236  }
237  if (far_spectrum == NULL) {
238    // Empty far end spectrum.
239    return -1;
240  }
241  if (spectrum_size != self->spectrum_size) {
242    // Data sizes don't match.
243    return -1;
244  }
245
246  // Get binary spectrum.
247  binary_spectrum = BinarySpectrumFloat(far_spectrum, self->mean_far_spectrum,
248                                        &(self->far_spectrum_initialized));
249  WebRtc_AddBinaryFarSpectrum(self->binary_farend, binary_spectrum);
250
251  return 0;
252}
253
254void WebRtc_FreeDelayEstimator(void* handle) {
255  DelayEstimator* self = (DelayEstimator*) handle;
256
257  if (handle == NULL) {
258    return;
259  }
260
261  free(self->mean_near_spectrum);
262  self->mean_near_spectrum = NULL;
263
264  WebRtc_FreeBinaryDelayEstimator(self->binary_handle);
265  self->binary_handle = NULL;
266
267  free(self);
268}
269
270void* WebRtc_CreateDelayEstimator(void* farend_handle, int max_lookahead) {
271  DelayEstimator* self = NULL;
272  DelayEstimatorFarend* farend = (DelayEstimatorFarend*) farend_handle;
273
274  if (farend_handle != NULL) {
275    self = malloc(sizeof(DelayEstimator));
276  }
277
278  if (self != NULL) {
279    int memory_fail = 0;
280
281    // Allocate memory for the farend spectrum handling.
282    self->binary_handle =
283        WebRtc_CreateBinaryDelayEstimator(farend->binary_farend, max_lookahead);
284    memory_fail |= (self->binary_handle == NULL);
285
286    // Allocate memory for spectrum buffers.
287    self->mean_near_spectrum = malloc(farend->spectrum_size *
288                                      sizeof(SpectrumType));
289    memory_fail |= (self->mean_near_spectrum == NULL);
290
291    self->spectrum_size = farend->spectrum_size;
292
293    if (memory_fail) {
294      WebRtc_FreeDelayEstimator(self);
295      self = NULL;
296    }
297  }
298
299  return self;
300}
301
302int WebRtc_InitDelayEstimator(void* handle) {
303  DelayEstimator* self = (DelayEstimator*) handle;
304
305  if (self == NULL) {
306    return -1;
307  }
308
309  // Initialize binary delay estimator.
310  WebRtc_InitBinaryDelayEstimator(self->binary_handle);
311
312  // Set averaged far and near end spectra to zero.
313  memset(self->mean_near_spectrum, 0,
314         sizeof(SpectrumType) * self->spectrum_size);
315  // Reset initialization indicators.
316  self->near_spectrum_initialized = 0;
317
318  return 0;
319}
320
321int WebRtc_SoftResetDelayEstimator(void* handle, int delay_shift) {
322  DelayEstimator* self = (DelayEstimator*) handle;
323  assert(self != NULL);
324  return WebRtc_SoftResetBinaryDelayEstimator(self->binary_handle, delay_shift);
325}
326
327int WebRtc_set_lookahead(void* handle, int lookahead) {
328  DelayEstimator* self = (DelayEstimator*) handle;
329  assert(self != NULL);
330  assert(self->binary_handle != NULL);
331  if ((lookahead > self->binary_handle->near_history_size - 1) ||
332      (lookahead < 0)) {
333    return -1;
334  }
335  self->binary_handle->lookahead = lookahead;
336  return self->binary_handle->lookahead;
337}
338
339int WebRtc_lookahead(void* handle) {
340  DelayEstimator* self = (DelayEstimator*) handle;
341  assert(self != NULL);
342  assert(self->binary_handle != NULL);
343  return self->binary_handle->lookahead;
344}
345
346int WebRtc_set_allowed_offset(void* handle, int allowed_offset) {
347  DelayEstimator* self = (DelayEstimator*) handle;
348
349  if ((self == NULL) || (allowed_offset < 0)) {
350    return -1;
351  }
352  self->binary_handle->allowed_offset = allowed_offset;
353  return 0;
354}
355
356int WebRtc_get_allowed_offset(const void* handle) {
357  const DelayEstimator* self = (const DelayEstimator*) handle;
358
359  if (self == NULL) {
360    return -1;
361  }
362  return self->binary_handle->allowed_offset;
363}
364
365int WebRtc_enable_robust_validation(void* handle, int enable) {
366  DelayEstimator* self = (DelayEstimator*) handle;
367
368  if (self == NULL) {
369    return -1;
370  }
371  if ((enable < 0) || (enable > 1)) {
372    return -1;
373  }
374  assert(self->binary_handle != NULL);
375  self->binary_handle->robust_validation_enabled = enable;
376  return 0;
377}
378
379int WebRtc_is_robust_validation_enabled(const void* handle) {
380  const DelayEstimator* self = (const DelayEstimator*) handle;
381
382  if (self == NULL) {
383    return -1;
384  }
385  return self->binary_handle->robust_validation_enabled;
386}
387
388int WebRtc_DelayEstimatorProcessFix(void* handle,
389                                    uint16_t* near_spectrum,
390                                    int spectrum_size,
391                                    int near_q) {
392  DelayEstimator* self = (DelayEstimator*) handle;
393  uint32_t binary_spectrum = 0;
394
395  if (self == NULL) {
396    return -1;
397  }
398  if (near_spectrum == NULL) {
399    // Empty near end spectrum.
400    return -1;
401  }
402  if (spectrum_size != self->spectrum_size) {
403    // Data sizes don't match.
404    return -1;
405  }
406  if (near_q > 15) {
407    // If |near_q| is larger than 15 we cannot guarantee no wrap around.
408    return -1;
409  }
410
411  // Get binary spectra.
412  binary_spectrum = BinarySpectrumFix(near_spectrum,
413                                      self->mean_near_spectrum,
414                                      near_q,
415                                      &(self->near_spectrum_initialized));
416
417  return WebRtc_ProcessBinarySpectrum(self->binary_handle, binary_spectrum);
418}
419
420int WebRtc_DelayEstimatorProcessFloat(void* handle,
421                                      float* near_spectrum,
422                                      int spectrum_size) {
423  DelayEstimator* self = (DelayEstimator*) handle;
424  uint32_t binary_spectrum = 0;
425
426  if (self == NULL) {
427    return -1;
428  }
429  if (near_spectrum == NULL) {
430    // Empty near end spectrum.
431    return -1;
432  }
433  if (spectrum_size != self->spectrum_size) {
434    // Data sizes don't match.
435    return -1;
436  }
437
438  // Get binary spectrum.
439  binary_spectrum = BinarySpectrumFloat(near_spectrum, self->mean_near_spectrum,
440                                        &(self->near_spectrum_initialized));
441
442  return WebRtc_ProcessBinarySpectrum(self->binary_handle, binary_spectrum);
443}
444
445int WebRtc_last_delay(void* handle) {
446  DelayEstimator* self = (DelayEstimator*) handle;
447
448  if (self == NULL) {
449    return -1;
450  }
451
452  return WebRtc_binary_last_delay(self->binary_handle);
453}
454
455float WebRtc_last_delay_quality(void* handle) {
456  DelayEstimator* self = (DelayEstimator*) handle;
457  assert(self != NULL);
458  return WebRtc_binary_last_delay_quality(self->binary_handle);
459}
460