Note: We no longer publish the latest version of our code here. We primarily use a kumc-bmi github organization. The heron ETL repository, in particular, is not public. Peers in the informatics community should see MultiSiteDev for details on requesting access.

source: webrtc/webrtc/modules/audio_processing/utility/delay_estimator_wrapper.c @ 0:4bda6873e34c

pub_scrub_3792 tip
Last change on this file since 0:4bda6873e34c was 0:4bda6873e34c, checked in by Michael Prittie <mprittie@…>, 6 years ago

Scrubbed password for publication.

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