Home | History | Annotate | Download | only in utility
      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/include/compile_assert_c.h"
     20 
     21 // Only bit |kBandFirst| through bit |kBandLast| are processed and
     22 // |kBandFirst| - |kBandLast| must be < 32.
     23 enum { kBandFirst = 12 };
     24 enum { kBandLast = 43 };
     25 
     26 static __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 //
     43 static 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 //
     61 static uint32_t BinarySpectrumFix(const 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 
     96 static uint32_t BinarySpectrumFloat(const 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 
    126 void 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 
    142 void* 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(DelayEstimatorFarend));
    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 
    175 int 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 
    194 void WebRtc_SoftResetDelayEstimatorFarend(void* handle, int delay_shift) {
    195   DelayEstimatorFarend* self = (DelayEstimatorFarend*) handle;
    196   assert(self != NULL);
    197   WebRtc_SoftResetBinaryDelayEstimatorFarend(self->binary_farend, delay_shift);
    198 }
    199 
    200 int WebRtc_AddFarSpectrumFix(void* handle,
    201                              const uint16_t* far_spectrum,
    202                              int spectrum_size,
    203                              int far_q) {
    204   DelayEstimatorFarend* self = (DelayEstimatorFarend*) handle;
    205   uint32_t binary_spectrum = 0;
    206 
    207   if (self == NULL) {
    208     return -1;
    209   }
    210   if (far_spectrum == NULL) {
    211     // Empty far end spectrum.
    212     return -1;
    213   }
    214   if (spectrum_size != self->spectrum_size) {
    215     // Data sizes don't match.
    216     return -1;
    217   }
    218   if (far_q > 15) {
    219     // If |far_q| is larger than 15 we cannot guarantee no wrap around.
    220     return -1;
    221   }
    222 
    223   // Get binary spectrum.
    224   binary_spectrum = BinarySpectrumFix(far_spectrum, self->mean_far_spectrum,
    225                                       far_q, &(self->far_spectrum_initialized));
    226   WebRtc_AddBinaryFarSpectrum(self->binary_farend, binary_spectrum);
    227 
    228   return 0;
    229 }
    230 
    231 int WebRtc_AddFarSpectrumFloat(void* handle,
    232                                const float* far_spectrum,
    233                                int spectrum_size) {
    234   DelayEstimatorFarend* self = (DelayEstimatorFarend*) handle;
    235   uint32_t binary_spectrum = 0;
    236 
    237   if (self == NULL) {
    238     return -1;
    239   }
    240   if (far_spectrum == NULL) {
    241     // Empty far end spectrum.
    242     return -1;
    243   }
    244   if (spectrum_size != self->spectrum_size) {
    245     // Data sizes don't match.
    246     return -1;
    247   }
    248 
    249   // Get binary spectrum.
    250   binary_spectrum = BinarySpectrumFloat(far_spectrum, self->mean_far_spectrum,
    251                                         &(self->far_spectrum_initialized));
    252   WebRtc_AddBinaryFarSpectrum(self->binary_farend, binary_spectrum);
    253 
    254   return 0;
    255 }
    256 
    257 void WebRtc_FreeDelayEstimator(void* handle) {
    258   DelayEstimator* self = (DelayEstimator*) handle;
    259 
    260   if (handle == NULL) {
    261     return;
    262   }
    263 
    264   free(self->mean_near_spectrum);
    265   self->mean_near_spectrum = NULL;
    266 
    267   WebRtc_FreeBinaryDelayEstimator(self->binary_handle);
    268   self->binary_handle = NULL;
    269 
    270   free(self);
    271 }
    272 
    273 void* WebRtc_CreateDelayEstimator(void* farend_handle, int max_lookahead) {
    274   DelayEstimator* self = NULL;
    275   DelayEstimatorFarend* farend = (DelayEstimatorFarend*) farend_handle;
    276 
    277   if (farend_handle != NULL) {
    278     self = malloc(sizeof(DelayEstimator));
    279   }
    280 
    281   if (self != NULL) {
    282     int memory_fail = 0;
    283 
    284     // Allocate memory for the farend spectrum handling.
    285     self->binary_handle =
    286         WebRtc_CreateBinaryDelayEstimator(farend->binary_farend, max_lookahead);
    287     memory_fail |= (self->binary_handle == NULL);
    288 
    289     // Allocate memory for spectrum buffers.
    290     self->mean_near_spectrum = malloc(farend->spectrum_size *
    291                                       sizeof(SpectrumType));
    292     memory_fail |= (self->mean_near_spectrum == NULL);
    293 
    294     self->spectrum_size = farend->spectrum_size;
    295 
    296     if (memory_fail) {
    297       WebRtc_FreeDelayEstimator(self);
    298       self = NULL;
    299     }
    300   }
    301 
    302   return self;
    303 }
    304 
    305 int WebRtc_InitDelayEstimator(void* handle) {
    306   DelayEstimator* self = (DelayEstimator*) handle;
    307 
    308   if (self == NULL) {
    309     return -1;
    310   }
    311 
    312   // Initialize binary delay estimator.
    313   WebRtc_InitBinaryDelayEstimator(self->binary_handle);
    314 
    315   // Set averaged far and near end spectra to zero.
    316   memset(self->mean_near_spectrum, 0,
    317          sizeof(SpectrumType) * self->spectrum_size);
    318   // Reset initialization indicators.
    319   self->near_spectrum_initialized = 0;
    320 
    321   return 0;
    322 }
    323 
    324 int WebRtc_SoftResetDelayEstimator(void* handle, int delay_shift) {
    325   DelayEstimator* self = (DelayEstimator*) handle;
    326   assert(self != NULL);
    327   return WebRtc_SoftResetBinaryDelayEstimator(self->binary_handle, delay_shift);
    328 }
    329 
    330 int WebRtc_set_history_size(void* handle, int history_size) {
    331   DelayEstimator* self = handle;
    332 
    333   if ((self == NULL) || (history_size <= 1)) {
    334     return -1;
    335   }
    336   return WebRtc_AllocateHistoryBufferMemory(self->binary_handle, history_size);
    337 }
    338 
    339 int WebRtc_history_size(const void* handle) {
    340   const DelayEstimator* self = handle;
    341 
    342   if (self == NULL) {
    343     return -1;
    344   }
    345   if (self->binary_handle->farend->history_size !=
    346       self->binary_handle->history_size) {
    347     // Non matching history sizes.
    348     return -1;
    349   }
    350   return self->binary_handle->history_size;
    351 }
    352 
    353 int WebRtc_set_lookahead(void* handle, int lookahead) {
    354   DelayEstimator* self = (DelayEstimator*) handle;
    355   assert(self != NULL);
    356   assert(self->binary_handle != NULL);
    357   if ((lookahead > self->binary_handle->near_history_size - 1) ||
    358       (lookahead < 0)) {
    359     return -1;
    360   }
    361   self->binary_handle->lookahead = lookahead;
    362   return self->binary_handle->lookahead;
    363 }
    364 
    365 int WebRtc_lookahead(void* handle) {
    366   DelayEstimator* self = (DelayEstimator*) handle;
    367   assert(self != NULL);
    368   assert(self->binary_handle != NULL);
    369   return self->binary_handle->lookahead;
    370 }
    371 
    372 int WebRtc_set_allowed_offset(void* handle, int allowed_offset) {
    373   DelayEstimator* self = (DelayEstimator*) handle;
    374 
    375   if ((self == NULL) || (allowed_offset < 0)) {
    376     return -1;
    377   }
    378   self->binary_handle->allowed_offset = allowed_offset;
    379   return 0;
    380 }
    381 
    382 int WebRtc_get_allowed_offset(const void* handle) {
    383   const DelayEstimator* self = (const DelayEstimator*) handle;
    384 
    385   if (self == NULL) {
    386     return -1;
    387   }
    388   return self->binary_handle->allowed_offset;
    389 }
    390 
    391 int WebRtc_enable_robust_validation(void* handle, int enable) {
    392   DelayEstimator* self = (DelayEstimator*) handle;
    393 
    394   if (self == NULL) {
    395     return -1;
    396   }
    397   if ((enable < 0) || (enable > 1)) {
    398     return -1;
    399   }
    400   assert(self->binary_handle != NULL);
    401   self->binary_handle->robust_validation_enabled = enable;
    402   return 0;
    403 }
    404 
    405 int WebRtc_is_robust_validation_enabled(const void* handle) {
    406   const DelayEstimator* self = (const DelayEstimator*) handle;
    407 
    408   if (self == NULL) {
    409     return -1;
    410   }
    411   return self->binary_handle->robust_validation_enabled;
    412 }
    413 
    414 int WebRtc_DelayEstimatorProcessFix(void* handle,
    415                                     const uint16_t* near_spectrum,
    416                                     int spectrum_size,
    417                                     int near_q) {
    418   DelayEstimator* self = (DelayEstimator*) handle;
    419   uint32_t binary_spectrum = 0;
    420 
    421   if (self == NULL) {
    422     return -1;
    423   }
    424   if (near_spectrum == NULL) {
    425     // Empty near end spectrum.
    426     return -1;
    427   }
    428   if (spectrum_size != self->spectrum_size) {
    429     // Data sizes don't match.
    430     return -1;
    431   }
    432   if (near_q > 15) {
    433     // If |near_q| is larger than 15 we cannot guarantee no wrap around.
    434     return -1;
    435   }
    436 
    437   // Get binary spectra.
    438   binary_spectrum = BinarySpectrumFix(near_spectrum,
    439                                       self->mean_near_spectrum,
    440                                       near_q,
    441                                       &(self->near_spectrum_initialized));
    442 
    443   return WebRtc_ProcessBinarySpectrum(self->binary_handle, binary_spectrum);
    444 }
    445 
    446 int WebRtc_DelayEstimatorProcessFloat(void* handle,
    447                                       const float* near_spectrum,
    448                                       int spectrum_size) {
    449   DelayEstimator* self = (DelayEstimator*) handle;
    450   uint32_t binary_spectrum = 0;
    451 
    452   if (self == NULL) {
    453     return -1;
    454   }
    455   if (near_spectrum == NULL) {
    456     // Empty near end spectrum.
    457     return -1;
    458   }
    459   if (spectrum_size != self->spectrum_size) {
    460     // Data sizes don't match.
    461     return -1;
    462   }
    463 
    464   // Get binary spectrum.
    465   binary_spectrum = BinarySpectrumFloat(near_spectrum, self->mean_near_spectrum,
    466                                         &(self->near_spectrum_initialized));
    467 
    468   return WebRtc_ProcessBinarySpectrum(self->binary_handle, binary_spectrum);
    469 }
    470 
    471 int WebRtc_last_delay(void* handle) {
    472   DelayEstimator* self = (DelayEstimator*) handle;
    473 
    474   if (self == NULL) {
    475     return -1;
    476   }
    477 
    478   return WebRtc_binary_last_delay(self->binary_handle);
    479 }
    480 
    481 float WebRtc_last_delay_quality(void* handle) {
    482   DelayEstimator* self = (DelayEstimator*) handle;
    483   assert(self != NULL);
    484   return WebRtc_binary_last_delay_quality(self->binary_handle);
    485 }
    486