summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/webrtc/modules/audio_processing/utility/delay_estimator.c
diff options
context:
space:
mode:
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.c106
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,