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 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 // 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 // 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 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 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 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 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 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 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 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