• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2011 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 "delay_estimator_wrapper.h"
12 
13 #include <assert.h>
14 #include <stdlib.h>
15 #include <string.h>
16 
17 #include "delay_estimator.h"
18 
19 typedef union {
20   float float_;
21   int32_t int32_;
22 } SpectrumType;
23 
24 typedef struct {
25   // Pointers to mean values of spectrum.
26   SpectrumType* mean_far_spectrum;
27   SpectrumType* mean_near_spectrum;
28   // |mean_*_spectrum| initialization indicator.
29   int far_spectrum_initialized;
30   int near_spectrum_initialized;
31 
32   int spectrum_size;
33 
34   // Binary spectrum based delay estimator
35   BinaryDelayEstimator* binary_handle;
36 } DelayEstimator;
37 
38 // Only bit |kBandFirst| through bit |kBandLast| are processed and
39 // |kBandFirst| - |kBandLast| must be < 32.
40 static const int kBandFirst = 12;
41 static const int kBandLast = 43;
42 
SetBit(uint32_t in,int pos)43 static __inline uint32_t SetBit(uint32_t in, int pos) {
44   uint32_t mask = (1 << pos);
45   uint32_t out = (in | mask);
46 
47   return out;
48 }
49 
50 // Calculates the mean recursively. Same version as WebRtc_MeanEstimatorFix(),
51 // but for float.
52 //
53 // Inputs:
54 //    - new_value             : New additional value.
55 //    - scale                 : Scale for smoothing (should be less than 1.0).
56 //
57 // Input/Output:
58 //    - mean_value            : Pointer to the mean value for updating.
59 //
MeanEstimatorFloat(float new_value,float scale,float * mean_value)60 static void MeanEstimatorFloat(float new_value,
61                                float scale,
62                                float* mean_value) {
63   assert(scale < 1.0f);
64   *mean_value += (new_value - *mean_value) * scale;
65 }
66 
67 // Computes the binary spectrum by comparing the input |spectrum| with a
68 // |threshold_spectrum|. Float and fixed point versions.
69 //
70 // Inputs:
71 //      - spectrum            : Spectrum of which the binary spectrum should be
72 //                              calculated.
73 //      - threshold_spectrum  : Threshold spectrum with which the input
74 //                              spectrum is compared.
75 // Return:
76 //      - out                 : Binary spectrum.
77 //
BinarySpectrumFix(uint16_t * spectrum,SpectrumType * threshold_spectrum,int q_domain,int * threshold_initialized)78 static uint32_t BinarySpectrumFix(uint16_t* spectrum,
79                                   SpectrumType* threshold_spectrum,
80                                   int q_domain,
81                                   int* threshold_initialized) {
82   int i = kBandFirst;
83   uint32_t out = 0;
84 
85   assert(q_domain < 16);
86 
87   if (!(*threshold_initialized)) {
88     // Set the |threshold_spectrum| to half the input |spectrum| as starting
89     // value. This speeds up the convergence.
90     for (i = kBandFirst; i <= kBandLast; i++) {
91       if (spectrum[i] > 0) {
92         // Convert input spectrum from Q(|q_domain|) to Q15.
93         int32_t spectrum_q15 = ((int32_t) spectrum[i]) << (15 - q_domain);
94         threshold_spectrum[i].int32_ = (spectrum_q15 >> 1);
95         *threshold_initialized = 1;
96       }
97     }
98   }
99   for (i = kBandFirst; i <= kBandLast; i++) {
100     // Convert input spectrum from Q(|q_domain|) to Q15.
101     int32_t spectrum_q15 = ((int32_t) spectrum[i]) << (15 - q_domain);
102     // Update the |threshold_spectrum|.
103     WebRtc_MeanEstimatorFix(spectrum_q15, 6, &(threshold_spectrum[i].int32_));
104     // Convert |spectrum| at current frequency bin to a binary value.
105     if (spectrum_q15 > threshold_spectrum[i].int32_) {
106       out = SetBit(out, i - kBandFirst);
107     }
108   }
109 
110   return out;
111 }
112 
BinarySpectrumFloat(float * spectrum,SpectrumType * threshold_spectrum,int * threshold_initialized)113 static uint32_t BinarySpectrumFloat(float* spectrum,
114                                     SpectrumType* threshold_spectrum,
115                                     int* threshold_initialized) {
116   int i = kBandFirst;
117   uint32_t out = 0;
118   const float kScale = 1 / 64.0;
119 
120   if (!(*threshold_initialized)) {
121     // Set the |threshold_spectrum| to half the input |spectrum| as starting
122     // value. This speeds up the convergence.
123     for (i = kBandFirst; i <= kBandLast; i++) {
124       if (spectrum[i] > 0.0f) {
125         threshold_spectrum[i].float_ = (spectrum[i] / 2);
126         *threshold_initialized = 1;
127       }
128     }
129   }
130 
131   for (i = kBandFirst; i <= kBandLast; i++) {
132     // Update the |threshold_spectrum|.
133     MeanEstimatorFloat(spectrum[i], kScale, &(threshold_spectrum[i].float_));
134     // Convert |spectrum| at current frequency bin to a binary value.
135     if (spectrum[i] > threshold_spectrum[i].float_) {
136       out = SetBit(out, i - kBandFirst);
137     }
138   }
139 
140   return out;
141 }
142 
WebRtc_FreeDelayEstimator(void * handle)143 int WebRtc_FreeDelayEstimator(void* handle) {
144   DelayEstimator* self = (DelayEstimator*) handle;
145 
146   if (self == NULL) {
147     return -1;
148   }
149 
150   if (self->mean_far_spectrum != NULL) {
151     free(self->mean_far_spectrum);
152     self->mean_far_spectrum = NULL;
153   }
154   if (self->mean_near_spectrum != NULL) {
155     free(self->mean_near_spectrum);
156     self->mean_near_spectrum = NULL;
157   }
158 
159   WebRtc_FreeBinaryDelayEstimator(self->binary_handle);
160 
161   free(self);
162 
163   return 0;
164 }
165 
WebRtc_CreateDelayEstimator(void ** handle,int spectrum_size,int max_delay,int lookahead)166 int WebRtc_CreateDelayEstimator(void** handle,
167                                 int spectrum_size,
168                                 int max_delay,
169                                 int lookahead) {
170   DelayEstimator* self = NULL;
171 
172   // Check if the sub band used in the delay estimation is small enough to fit
173   // the binary spectra in a uint32_t.
174   assert(kBandLast - kBandFirst < 32);
175 
176   if (handle == NULL) {
177     return -1;
178   }
179   if (spectrum_size < kBandLast) {
180     return -1;
181   }
182 
183   self = malloc(sizeof(DelayEstimator));
184   *handle = self;
185   if (self == NULL) {
186     return -1;
187   }
188 
189   self->mean_far_spectrum = NULL;
190   self->mean_near_spectrum = NULL;
191 
192   // Create binary delay estimator.
193   if (WebRtc_CreateBinaryDelayEstimator(&self->binary_handle,
194                                         max_delay,
195                                         lookahead) != 0) {
196     WebRtc_FreeDelayEstimator(self);
197     self = NULL;
198     return -1;
199   }
200   // Allocate memory for spectrum buffers.
201   self->mean_far_spectrum = malloc(spectrum_size * sizeof(SpectrumType));
202   if (self->mean_far_spectrum == NULL) {
203     WebRtc_FreeDelayEstimator(self);
204     self = NULL;
205     return -1;
206   }
207   self->mean_near_spectrum = malloc(spectrum_size * sizeof(SpectrumType));
208   if (self->mean_near_spectrum == NULL) {
209     WebRtc_FreeDelayEstimator(self);
210     self = NULL;
211     return -1;
212   }
213 
214   self->spectrum_size = spectrum_size;
215 
216   return 0;
217 }
218 
WebRtc_InitDelayEstimator(void * handle)219 int WebRtc_InitDelayEstimator(void* handle) {
220   DelayEstimator* self = (DelayEstimator*) handle;
221 
222   if (self == NULL) {
223     return -1;
224   }
225 
226   // Initialize binary delay estimator.
227   if (WebRtc_InitBinaryDelayEstimator(self->binary_handle) != 0) {
228     return -1;
229   }
230   // Set averaged far and near end spectra to zero.
231   memset(self->mean_far_spectrum, 0,
232          sizeof(SpectrumType) * self->spectrum_size);
233   memset(self->mean_near_spectrum, 0,
234          sizeof(SpectrumType) * self->spectrum_size);
235   // Reset initialization indicators.
236   self->far_spectrum_initialized = 0;
237   self->near_spectrum_initialized = 0;
238 
239   return 0;
240 }
241 
WebRtc_DelayEstimatorProcessFix(void * handle,uint16_t * far_spectrum,uint16_t * near_spectrum,int spectrum_size,int far_q,int near_q)242 int WebRtc_DelayEstimatorProcessFix(void* handle,
243                                     uint16_t* far_spectrum,
244                                     uint16_t* near_spectrum,
245                                     int spectrum_size,
246                                     int far_q,
247                                     int near_q) {
248   DelayEstimator* self = (DelayEstimator*) handle;
249   uint32_t binary_far_spectrum = 0;
250   uint32_t binary_near_spectrum = 0;
251 
252   if (self == NULL) {
253     return -1;
254   }
255   if (far_spectrum == NULL) {
256     // Empty far end spectrum.
257     return -1;
258   }
259   if (near_spectrum == NULL) {
260     // Empty near end spectrum.
261     return -1;
262   }
263   if (spectrum_size != self->spectrum_size) {
264     // Data sizes don't match.
265     return -1;
266   }
267   if (far_q > 15) {
268     // If |far_q| is larger than 15 we cannot guarantee no wrap around.
269     return -1;
270   }
271   if (near_q > 15) {
272     // If |near_q| is larger than 15 we cannot guarantee no wrap around.
273     return -1;
274   }
275 
276   // Get binary spectra.
277   binary_far_spectrum = BinarySpectrumFix(far_spectrum,
278                                           self->mean_far_spectrum,
279                                           far_q,
280                                           &(self->far_spectrum_initialized));
281   binary_near_spectrum = BinarySpectrumFix(near_spectrum,
282                                            self->mean_near_spectrum,
283                                            near_q,
284                                            &(self->near_spectrum_initialized));
285 
286   return WebRtc_ProcessBinarySpectrum(self->binary_handle,
287                                       binary_far_spectrum,
288                                       binary_near_spectrum);
289 }
290 
WebRtc_DelayEstimatorProcessFloat(void * handle,float * far_spectrum,float * near_spectrum,int spectrum_size)291 int WebRtc_DelayEstimatorProcessFloat(void* handle,
292                                       float* far_spectrum,
293                                       float* near_spectrum,
294                                       int spectrum_size) {
295   DelayEstimator* self = (DelayEstimator*) handle;
296   uint32_t binary_far_spectrum = 0;
297   uint32_t binary_near_spectrum = 0;
298 
299   if (self == NULL) {
300     return -1;
301   }
302   if (far_spectrum == NULL) {
303     // Empty far end spectrum.
304     return -1;
305   }
306   if (near_spectrum == NULL) {
307     // Empty near end spectrum.
308     return -1;
309   }
310   if (spectrum_size != self->spectrum_size) {
311     // Data sizes don't match.
312     return -1;
313   }
314 
315   // Get binary spectra.
316   binary_far_spectrum = BinarySpectrumFloat(far_spectrum,
317                                             self->mean_far_spectrum,
318                                             &(self->far_spectrum_initialized));
319   binary_near_spectrum = BinarySpectrumFloat(near_spectrum,
320                                              self->mean_near_spectrum,
321                                              &(self->near_spectrum_initialized));
322 
323   return WebRtc_ProcessBinarySpectrum(self->binary_handle,
324                                       binary_far_spectrum,
325                                       binary_near_spectrum);
326 }
327 
WebRtc_last_delay(void * handle)328 int WebRtc_last_delay(void* handle) {
329   DelayEstimator* self = (DelayEstimator*) handle;
330 
331   if (self == NULL) {
332     return -1;
333   }
334 
335   return WebRtc_binary_last_delay(self->binary_handle);
336 }
337