Home | History | Annotate | Download | only in utility
      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