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