diff options
Diffstat (limited to 'chromium/third_party/webrtc/modules/audio_processing/utility/delay_estimator.c')
-rw-r--r-- | chromium/third_party/webrtc/modules/audio_processing/utility/delay_estimator.c | 106 |
1 files changed, 77 insertions, 29 deletions
diff --git a/chromium/third_party/webrtc/modules/audio_processing/utility/delay_estimator.c b/chromium/third_party/webrtc/modules/audio_processing/utility/delay_estimator.c index 6d6e9bc97bb..3b2043267ff 100644 --- a/chromium/third_party/webrtc/modules/audio_processing/utility/delay_estimator.c +++ b/chromium/third_party/webrtc/modules/audio_processing/utility/delay_estimator.c @@ -30,10 +30,6 @@ static const float kMinHistogramThreshold = 1.5f; static const int kMinRequiredHits = 10; static const int kMaxHitsWhenPossiblyNonCausal = 10; static const int kMaxHitsWhenPossiblyCausal = 1000; -// TODO(bjornv): Make kMaxDelayDifference a configurable parameter, since it -// corresponds to the filter length if the delay estimation is used in echo -// control. -static const int kMaxDelayDifference = 32; static const float kQ14Scaling = 1.f / (1 << 14); // Scaling by 2^14 to get Q0. static const float kFractionSlope = 0.05f; static const float kMinFractionWhenPossiblyCausal = 0.5f; @@ -195,8 +191,8 @@ static int HistogramBasedValidation(const BinaryDelayEstimator* self, // depending on the distance between the |candidate_delay| and |last_delay|. // TODO(bjornv): How much can we gain by turning the fraction calculation // into tables? - if (delay_difference >= kMaxDelayDifference) { - fraction = 1.f - kFractionSlope * (delay_difference - kMaxDelayDifference); + if (delay_difference > self->allowed_offset) { + fraction = 1.f - kFractionSlope * (delay_difference - self->allowed_offset); fraction = (fraction > kMinFractionWhenPossiblyCausal ? fraction : kMinFractionWhenPossiblyCausal); } else if (delay_difference < 0) { @@ -308,6 +304,39 @@ void WebRtc_InitBinaryDelayEstimatorFarend(BinaryDelayEstimatorFarend* self) { memset(self->far_bit_counts, 0, sizeof(int) * self->history_size); } +void WebRtc_SoftResetBinaryDelayEstimatorFarend( + BinaryDelayEstimatorFarend* self, int delay_shift) { + int abs_shift = abs(delay_shift); + int shift_size = 0; + int dest_index = 0; + int src_index = 0; + int padding_index = 0; + + assert(self != NULL); + shift_size = self->history_size - abs_shift; + assert(shift_size > 0); + if (delay_shift == 0) { + return; + } else if (delay_shift > 0) { + dest_index = abs_shift; + } else if (delay_shift < 0) { + src_index = abs_shift; + padding_index = shift_size; + } + + // Shift and zero pad buffers. + memmove(&self->binary_far_history[dest_index], + &self->binary_far_history[src_index], + sizeof(*self->binary_far_history) * shift_size); + memset(&self->binary_far_history[padding_index], 0, + sizeof(*self->binary_far_history) * abs_shift); + memmove(&self->far_bit_counts[dest_index], + &self->far_bit_counts[src_index], + sizeof(*self->far_bit_counts) * shift_size); + memset(&self->far_bit_counts[padding_index], 0, + sizeof(*self->far_bit_counts) * abs_shift); +} + void WebRtc_AddBinaryFarSpectrum(BinaryDelayEstimatorFarend* handle, uint32_t binary_far_spectrum) { assert(handle != NULL); @@ -349,10 +378,10 @@ void WebRtc_FreeBinaryDelayEstimator(BinaryDelayEstimator* self) { } BinaryDelayEstimator* WebRtc_CreateBinaryDelayEstimator( - BinaryDelayEstimatorFarend* farend, int lookahead) { + BinaryDelayEstimatorFarend* farend, int max_lookahead) { BinaryDelayEstimator* self = NULL; - if ((farend != NULL) && (lookahead >= 0)) { + if ((farend != NULL) && (max_lookahead >= 0)) { // Sanity conditions fulfilled. self = malloc(sizeof(BinaryDelayEstimator)); } @@ -361,7 +390,11 @@ BinaryDelayEstimator* WebRtc_CreateBinaryDelayEstimator( int malloc_fail = 0; self->farend = farend; - self->near_history_size = lookahead + 1; + self->near_history_size = max_lookahead + 1; + self->robust_validation_enabled = 0; // Disabled by default. + self->allowed_offset = 0; + + self->lookahead = max_lookahead; // Allocate memory for spectrum buffers. The extra array element in // |mean_bit_counts| and |histogram| is a dummy element only used while @@ -374,7 +407,7 @@ BinaryDelayEstimator* WebRtc_CreateBinaryDelayEstimator( malloc_fail |= (self->bit_counts == NULL); // Allocate memory for history buffers. - self->binary_near_history = malloc((lookahead + 1) * sizeof(uint32_t)); + self->binary_near_history = malloc((max_lookahead + 1) * sizeof(uint32_t)); malloc_fail |= (self->binary_near_history == NULL); self->histogram = malloc((farend->history_size + 1) * sizeof(float)); @@ -400,26 +433,40 @@ void WebRtc_InitBinaryDelayEstimator(BinaryDelayEstimator* self) { self->mean_bit_counts[i] = (20 << 9); // 20 in Q9. self->histogram[i] = 0.f; } - self->minimum_probability = (32 << 9); // 32 in Q9. - self->last_delay_probability = (32 << 9); // 32 in Q9. + self->minimum_probability = kMaxBitCountsQ9; // 32 in Q9. + self->last_delay_probability = (int) kMaxBitCountsQ9; // 32 in Q9. // Default return value if we're unable to estimate. -1 is used for errors. self->last_delay = -2; - self->robust_validation_enabled = 0; // Disabled by default. self->last_candidate_delay = -2; self->compare_delay = self->farend->history_size; self->candidate_hits = 0; self->last_delay_histogram = 0.f; } +int WebRtc_SoftResetBinaryDelayEstimator(BinaryDelayEstimator* self, + int delay_shift) { + int lookahead = 0; + assert(self != NULL); + lookahead = self->lookahead; + self->lookahead -= delay_shift; + if (self->lookahead < 0) { + self->lookahead = 0; + } + if (self->lookahead > self->near_history_size - 1) { + self->lookahead = self->near_history_size - 1; + } + return lookahead - self->lookahead; +} + int WebRtc_ProcessBinarySpectrum(BinaryDelayEstimator* self, uint32_t binary_near_spectrum) { int i = 0; int candidate_delay = -1; int valid_candidate = 0; - int32_t value_best_candidate = 32 << 9; // 32 in Q9, (max |mean_bit_counts|). + int32_t value_best_candidate = kMaxBitCountsQ9; int32_t value_worst_candidate = 0; int32_t valley_depth = 0; @@ -430,8 +477,7 @@ int WebRtc_ProcessBinarySpectrum(BinaryDelayEstimator* self, memmove(&(self->binary_near_history[1]), &(self->binary_near_history[0]), (self->near_history_size - 1) * sizeof(uint32_t)); self->binary_near_history[0] = binary_near_spectrum; - binary_near_spectrum = - self->binary_near_history[self->near_history_size - 1]; + binary_near_spectrum = self->binary_near_history[self->lookahead]; } // Compare with delayed spectra and store the |bit_counts| for each delay. @@ -547,21 +593,23 @@ int WebRtc_binary_last_delay(BinaryDelayEstimator* self) { return self->last_delay; } -int WebRtc_binary_last_delay_quality(BinaryDelayEstimator* self) { - int delay_quality = 0; +float WebRtc_binary_last_delay_quality(BinaryDelayEstimator* self) { + float quality = 0; assert(self != NULL); - // |last_delay_probability| is the opposite of quality and states how deep the - // minimum of the cost function is. The value states how many non-matching - // bits we have between the binary spectra for the corresponding delay - // estimate. The range is thus from 0 to 32, since we use 32 bits in the - // binary spectra. - - // Return the |delay_quality| = 1 - |last_delay_probability| / 32 (in Q14). - delay_quality = (32 << 9) - self->last_delay_probability; - if (delay_quality < 0) { - delay_quality = 0; + + if (self->robust_validation_enabled) { + // Simply a linear function of the histogram height at delay estimate. + quality = self->histogram[self->compare_delay] / kHistogramMax; + } else { + // Note that |last_delay_probability| states how deep the minimum of the + // cost function is, so it is rather an error probability. + quality = (float) (kMaxBitCountsQ9 - self->last_delay_probability) / + kMaxBitCountsQ9; + if (quality < 0) { + quality = 0; + } } - return delay_quality; + return quality; } void WebRtc_MeanEstimatorFix(int32_t new_value, |