From 28e83d1a566c9efedbff391b94962624b5675a50 Mon Sep 17 00:00:00 2001 From: "bjornv@webrtc.org" Date: Mon, 24 Mar 2014 15:26:52 +0000 Subject: [PATCH] DelayEstimator: Updates delay_quality and adds soft reset. These changes are currently not used in webrtc/ but helps in using the delay estimator. * The last_delay_quality() is updated with respect to robust_validation and changed to return float. * Tests are updated wtih respect to above. * Adds the possibility to make a soft reset based on external circumstances like a known delay shift has been made. * The soft reset change the lookahead dynamically. An API to ask for current lookahead has been added as well. BUG=N/A TESTED=trybots, modules_unittest R=aluebs@webrtc.org, andrew@webrtc.org Review URL: https://webrtc-codereview.appspot.com/10409004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@5761 4adac7df-926f-26a2-2b94-8c16560cd09d --- .../modules/audio_processing/aec/aec_core.c | 2 +- .../modules/audio_processing/aecm/aecm_core.c | 2 +- .../utility/delay_estimator.c | 89 ++++++++++++++----- .../utility/delay_estimator.h | 51 ++++++++--- .../utility/delay_estimator_unittest.cc | 64 ++++++++----- .../utility/delay_estimator_wrapper.c | 32 +++++-- .../utility/delay_estimator_wrapper.h | 42 ++++++--- 7 files changed, 207 insertions(+), 75 deletions(-) diff --git a/webrtc/modules/audio_processing/aec/aec_core.c b/webrtc/modules/audio_processing/aec/aec_core.c index 3f3d2c088d..432988f0b4 100644 --- a/webrtc/modules/audio_processing/aec/aec_core.c +++ b/webrtc/modules/audio_processing/aec/aec_core.c @@ -231,7 +231,7 @@ int WebRtcAec_CreateAec(AecCore** aecInst) { return -1; } aec->delay_estimator = WebRtc_CreateDelayEstimator( - aec->delay_estimator_farend, kLookaheadBlocks); + aec->delay_estimator_farend, kLookaheadBlocks, kLookaheadBlocks); if (aec->delay_estimator == NULL) { WebRtcAec_FreeAec(aec); aec = NULL; diff --git a/webrtc/modules/audio_processing/aecm/aecm_core.c b/webrtc/modules/audio_processing/aecm/aecm_core.c index 0f34874612..c1a0910eef 100644 --- a/webrtc/modules/audio_processing/aecm/aecm_core.c +++ b/webrtc/modules/audio_processing/aecm/aecm_core.c @@ -260,7 +260,7 @@ int WebRtcAecm_CreateCore(AecmCore_t **aecmInst) return -1; } aecm->delay_estimator = - WebRtc_CreateDelayEstimator(aecm->delay_estimator_farend, 0); + WebRtc_CreateDelayEstimator(aecm->delay_estimator_farend, 0, 0); if (aecm->delay_estimator == NULL) { WebRtcAecm_FreeCore(aecm); aecm = NULL; diff --git a/webrtc/modules/audio_processing/utility/delay_estimator.c b/webrtc/modules/audio_processing/utility/delay_estimator.c index c67e174a0a..c8d9ba841e 100644 --- a/webrtc/modules/audio_processing/utility/delay_estimator.c +++ b/webrtc/modules/audio_processing/utility/delay_estimator.c @@ -304,6 +304,37 @@ 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; + assert(self != NULL); + + shift_size = self->history_size - abs_shift; + if (delay_shift > 0) { + memmove(&self->binary_far_history[abs_shift], + self->binary_far_history, + sizeof(*self->binary_far_history) * shift_size); + memmove(&self->far_bit_counts[abs_shift], + self->far_bit_counts, + sizeof(*self->far_bit_counts) * shift_size); + memset(self->binary_far_history, 0, + sizeof(*self->binary_far_history) * abs_shift); + memset(self->far_bit_counts, 0, sizeof(*self->far_bit_counts) * abs_shift); + } else if (delay_shift < 0) { + memmove(self->binary_far_history, + &self->binary_far_history[abs_shift], + sizeof(*self->binary_far_history) * shift_size); + memmove(self->far_bit_counts, + &self->far_bit_counts[abs_shift], + sizeof(*self->far_bit_counts) * shift_size); + memset(&self->binary_far_history[shift_size], 0, + sizeof(*self->binary_far_history) * abs_shift); + memset(&self->far_bit_counts[shift_size], 0, + sizeof(*self->far_bit_counts) * abs_shift); + } +} + void WebRtc_AddBinaryFarSpectrum(BinaryDelayEstimatorFarend* handle, uint32_t binary_far_spectrum) { assert(handle != NULL); @@ -345,10 +376,10 @@ void WebRtc_FreeBinaryDelayEstimator(BinaryDelayEstimator* self) { } BinaryDelayEstimator* WebRtc_CreateBinaryDelayEstimator( - BinaryDelayEstimatorFarend* farend, int lookahead) { + BinaryDelayEstimatorFarend* farend, int max_lookahead, int lookahead) { BinaryDelayEstimator* self = NULL; - if ((farend != NULL) && (lookahead >= 0)) { + if ((farend != NULL) && (lookahead >= 0) && (max_lookahead >= lookahead)) { // Sanity conditions fulfilled. self = malloc(sizeof(BinaryDelayEstimator)); } @@ -357,10 +388,12 @@ 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 = lookahead; + // Allocate memory for spectrum buffers. The extra array element in // |mean_bit_counts| and |histogram| is a dummy element only used while // |last_delay| == -2, i.e., before we have a valid estimate. @@ -398,8 +431,8 @@ 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; @@ -410,13 +443,28 @@ void WebRtc_InitBinaryDelayEstimator(BinaryDelayEstimator* self) { 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; @@ -427,8 +475,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. @@ -544,21 +591,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, diff --git a/webrtc/modules/audio_processing/utility/delay_estimator.h b/webrtc/modules/audio_processing/utility/delay_estimator.h index b9a24bb5a2..6574f30824 100644 --- a/webrtc/modules/audio_processing/utility/delay_estimator.h +++ b/webrtc/modules/audio_processing/utility/delay_estimator.h @@ -16,6 +16,8 @@ #include "webrtc/typedefs.h" +static const int32_t kMaxBitCountsQ9 = (32 << 9); // 32 matching bits in Q9. + typedef struct { // Pointer to bit counts. int* far_bit_counts; @@ -51,6 +53,9 @@ typedef struct { float* histogram; float last_delay_histogram; + // For dynamically changing the lookahead when using SoftReset...(). + int lookahead; + // Far-end binary spectrum history buffer etc. BinaryDelayEstimatorFarend* farend; } BinaryDelayEstimator; @@ -91,6 +96,15 @@ BinaryDelayEstimatorFarend* WebRtc_CreateBinaryDelayEstimatorFarend( // void WebRtc_InitBinaryDelayEstimatorFarend(BinaryDelayEstimatorFarend* self); +// Soft resets the delay estimation far-end instance created with +// WebRtc_CreateBinaryDelayEstimatorFarend(...). +// +// Input: +// - delay_shift : The amount of blocks to shift history buffers. +// +void WebRtc_SoftResetBinaryDelayEstimatorFarend( + BinaryDelayEstimatorFarend* self, int delay_shift); + // Adds the binary far-end spectrum to the internal far-end history buffer. This // spectrum is used as reference when calculating the delay using // WebRtc_ProcessBinarySpectrum(). @@ -146,14 +160,18 @@ void WebRtc_FreeBinaryDelayEstimator(BinaryDelayEstimator* self); // where |history_size| was set upon creating the far-end // history buffer size. // +// - max_lookahead : Maximum amount of non-causal lookahead allowed. This +// is to allow for dynamically changing the lookahead on +// the fly. +// // Return value: // - BinaryDelayEstimator* -// : Created |handle|. If the memory can't be allocated -// or if any of the input parameters are invalid NULL -// is returned. +// : Created |handle|. If the memory can't be allocated +// or if any of the input parameters are invalid NULL +// is returned. // BinaryDelayEstimator* WebRtc_CreateBinaryDelayEstimator( - BinaryDelayEstimatorFarend* farend, int lookahead); + BinaryDelayEstimatorFarend* farend, int max_lookahead, int lookahead); // Initializes the delay estimation instance created with // WebRtc_CreateBinaryDelayEstimator(...). @@ -166,6 +184,18 @@ BinaryDelayEstimator* WebRtc_CreateBinaryDelayEstimator( // void WebRtc_InitBinaryDelayEstimator(BinaryDelayEstimator* self); +// Soft resets the delay estimation instance created with +// WebRtc_CreateBinaryDelayEstimator(...). +// +// Input: +// - delay_shift : The amount of blocks to shift history buffers. +// +// Return value: +// - actual_shifts : The actual number of shifts performed. +// +int WebRtc_SoftResetBinaryDelayEstimator(BinaryDelayEstimator* self, + int delay_shift); + // Estimates and returns the delay between the binary far-end and binary near- // end spectra. It is assumed the binary far-end spectrum has been added using // WebRtc_AddBinaryFarSpectrum() prior to this call. The value will be offset by @@ -200,17 +230,12 @@ int WebRtc_binary_last_delay(BinaryDelayEstimator* self); // Returns the estimation quality of the last calculated delay updated by the // function WebRtc_ProcessBinarySpectrum(...). The estimation quality is a value -// in the interval [0, 1] in Q14. The higher the value, the better quality. -// -// Input: -// - self : Pointer to the delay estimation instance. +// in the interval [0, 1]. The higher the value, the better quality. // // Return value: -// - delay_quality : >= 0 - Estimation quality (in Q14) of last -// calculated delay value. -// -2 - Insufficient data for estimation. -// -int WebRtc_binary_last_delay_quality(BinaryDelayEstimator* self); +// - delay_quality : >= 0 - Estimation quality of last calculated +// delay value. +float WebRtc_binary_last_delay_quality(BinaryDelayEstimator* self); // Updates the |mean_value| recursively with a step size of 2^-|factor|. This // function is used internally in the Binary Delay Estimator as well as the diff --git a/webrtc/modules/audio_processing/utility/delay_estimator_unittest.cc b/webrtc/modules/audio_processing/utility/delay_estimator_unittest.cc index c30ab08625..ff0bbeb122 100644 --- a/webrtc/modules/audio_processing/utility/delay_estimator_unittest.cc +++ b/webrtc/modules/audio_processing/utility/delay_estimator_unittest.cc @@ -86,13 +86,14 @@ void DelayEstimatorTest::SetUp() { kMaxDelay + kLookahead); ASSERT_TRUE(farend_handle_ != NULL); farend_self_ = reinterpret_cast(farend_handle_); - handle_ = WebRtc_CreateDelayEstimator(farend_handle_, kLookahead); + handle_ = WebRtc_CreateDelayEstimator(farend_handle_, kLookahead, kLookahead); ASSERT_TRUE(handle_ != NULL); self_ = reinterpret_cast(handle_); binary_farend_ = WebRtc_CreateBinaryDelayEstimatorFarend(kMaxDelay + kLookahead); ASSERT_TRUE(binary_farend_ != NULL); - binary_ = WebRtc_CreateBinaryDelayEstimator(binary_farend_, kLookahead); + binary_ = WebRtc_CreateBinaryDelayEstimator(binary_farend_, kLookahead, + kLookahead); ASSERT_TRUE(binary_ != NULL); } @@ -117,7 +118,7 @@ void DelayEstimatorTest::Init() { EXPECT_EQ(0, farend_self_->far_spectrum_initialized); EXPECT_EQ(0, self_->near_spectrum_initialized); EXPECT_EQ(-2, WebRtc_last_delay(handle_)); // Delay in initial state. - EXPECT_EQ(0, WebRtc_last_delay_quality(handle_)); // Zero quality. + EXPECT_FLOAT_EQ(0, WebRtc_last_delay_quality(handle_)); // Zero quality. } void DelayEstimatorTest::InitBinary() { @@ -190,9 +191,9 @@ void DelayEstimatorTest::RunBinarySpectra(BinaryDelayEstimator* binary1, } // Verify that we have left the initialized state. EXPECT_NE(-2, WebRtc_binary_last_delay(binary1)); - EXPECT_NE(0, WebRtc_binary_last_delay_quality(binary1)); + EXPECT_LT(0, WebRtc_binary_last_delay_quality(binary1)); EXPECT_NE(-2, WebRtc_binary_last_delay(binary2)); - EXPECT_NE(0, WebRtc_binary_last_delay_quality(binary2)); + EXPECT_LT(0, WebRtc_binary_last_delay_quality(binary2)); } void DelayEstimatorTest::RunBinarySpectraTest(int near_offset, @@ -201,6 +202,7 @@ void DelayEstimatorTest::RunBinarySpectraTest(int near_offset, int robust_validation) { BinaryDelayEstimator* binary2 = WebRtc_CreateBinaryDelayEstimator(binary_farend_, + kLookahead + lookahead_offset, kLookahead + lookahead_offset); // Verify the delay for both causal and non-causal systems. For causal systems // the delay is equivalent with a positive |offset| of the far-end sequence. @@ -228,15 +230,16 @@ TEST_F(DelayEstimatorTest, CorrectErrorReturnsOfWrapper) { void* handle = farend_handle_; handle = WebRtc_CreateDelayEstimatorFarend(33, kMaxDelay + kLookahead); EXPECT_TRUE(handle == NULL); - handle = farend_handle_; handle = WebRtc_CreateDelayEstimatorFarend(kSpectrumSize, 1); EXPECT_TRUE(handle == NULL); handle = handle_; - handle = WebRtc_CreateDelayEstimator(NULL, kLookahead); + handle = WebRtc_CreateDelayEstimator(NULL, kLookahead, kLookahead); EXPECT_TRUE(handle == NULL); - handle = handle_; - handle = WebRtc_CreateDelayEstimator(farend_handle_, -1); + handle = WebRtc_CreateDelayEstimator(farend_handle_, kLookahead, -1); + EXPECT_TRUE(handle == NULL); + handle = WebRtc_CreateDelayEstimator(farend_handle_, kLookahead - 1, + kLookahead); EXPECT_TRUE(handle == NULL); // WebRtc_InitDelayEstimatorFarend() and WebRtc_InitDelayEstimator() should @@ -316,10 +319,6 @@ TEST_F(DelayEstimatorTest, CorrectErrorReturnsOfWrapper) { // WebRtc_last_delay() should return -1 if we have a NULL pointer as |handle|. EXPECT_EQ(-1, WebRtc_last_delay(NULL)); - // WebRtc_last_delay_quality() should return -1 if we have a NULL pointer as - // |handle|. - EXPECT_EQ(-1, WebRtc_last_delay_quality(NULL)); - // Free any local memory if needed. WebRtc_FreeDelayEstimator(handle); } @@ -379,6 +378,7 @@ TEST_F(DelayEstimatorTest, CorrectLastDelay) { // (|last_delay| = -2). Then we compare the Process() output with the // last_delay() call. + // TODO(bjornv): Update quality values for robust validation. int last_delay = 0; // Floating point operations. Init(); @@ -389,13 +389,16 @@ TEST_F(DelayEstimatorTest, CorrectLastDelay) { spectrum_size_); if (last_delay != -2) { EXPECT_EQ(last_delay, WebRtc_last_delay(handle_)); - EXPECT_EQ(7203, WebRtc_last_delay_quality(handle_)); + if (!WebRtc_is_robust_validation_enabled(handle_)) { + EXPECT_FLOAT_EQ(7203.f / kMaxBitCountsQ9, + WebRtc_last_delay_quality(handle_)); + } break; } } // Verify that we have left the initialized state. EXPECT_NE(-2, WebRtc_last_delay(handle_)); - EXPECT_NE(0, WebRtc_last_delay_quality(handle_)); + EXPECT_LT(0, WebRtc_last_delay_quality(handle_)); // Fixed point operations. Init(); @@ -406,13 +409,16 @@ TEST_F(DelayEstimatorTest, CorrectLastDelay) { spectrum_size_, 0); if (last_delay != -2) { EXPECT_EQ(last_delay, WebRtc_last_delay(handle_)); - EXPECT_EQ(7203, WebRtc_last_delay_quality(handle_)); + if (!WebRtc_is_robust_validation_enabled(handle_)) { + EXPECT_FLOAT_EQ(7203.f / kMaxBitCountsQ9, + WebRtc_last_delay_quality(handle_)); + } break; } } // Verify that we have left the initialized state. EXPECT_NE(-2, WebRtc_last_delay(handle_)); - EXPECT_NE(0, WebRtc_last_delay_quality(handle_)); + EXPECT_LT(0, WebRtc_last_delay_quality(handle_)); } TEST_F(DelayEstimatorTest, CorrectErrorReturnsOfBinaryEstimatorFarend) { @@ -439,10 +445,14 @@ TEST_F(DelayEstimatorTest, CorrectErrorReturnsOfBinaryEstimator) { // |binary_handle| should be NULL. // Make sure we have a non-NULL value at start, so we can detect NULL after // create failure. - binary_handle = WebRtc_CreateBinaryDelayEstimator(NULL, kLookahead); + binary_handle = WebRtc_CreateBinaryDelayEstimator(NULL, kLookahead, + kLookahead); EXPECT_TRUE(binary_handle == NULL); - binary_handle = binary_; - binary_handle = WebRtc_CreateBinaryDelayEstimator(binary_farend_, -1); + binary_handle = WebRtc_CreateBinaryDelayEstimator(binary_farend_, kLookahead, + -1); + EXPECT_TRUE(binary_handle == NULL); + binary_handle = WebRtc_CreateBinaryDelayEstimator(binary_farend_, + kLookahead - 1, kLookahead); EXPECT_TRUE(binary_handle == NULL); } @@ -525,4 +535,18 @@ TEST_F(DelayEstimatorTest, AllowedOffsetNoImpactWhenRobustValidationDisabled) { binary_->allowed_offset = 0; // Reset reference. } +TEST_F(DelayEstimatorTest, VerifyLookaheadAtCreate) { + void* farend_handle = WebRtc_CreateDelayEstimatorFarend(kSpectrumSize, + kMaxDelay); + ASSERT_TRUE(farend_handle != NULL); + void* handle = WebRtc_CreateDelayEstimator(farend_handle, kLookahead, + kLookahead); + ASSERT_TRUE(handle != NULL); + EXPECT_EQ(kLookahead, WebRtc_lookahead(handle)); + WebRtc_FreeDelayEstimator(handle); + WebRtc_FreeDelayEstimatorFarend(farend_handle); +} + +// TODO(bjornv): Add tests for SoftReset...(...). + } // namespace diff --git a/webrtc/modules/audio_processing/utility/delay_estimator_wrapper.c b/webrtc/modules/audio_processing/utility/delay_estimator_wrapper.c index 1e6eff0835..212e740dd7 100644 --- a/webrtc/modules/audio_processing/utility/delay_estimator_wrapper.c +++ b/webrtc/modules/audio_processing/utility/delay_estimator_wrapper.c @@ -191,6 +191,12 @@ int WebRtc_InitDelayEstimatorFarend(void* handle) { return 0; } +void WebRtc_SoftResetDelayEstimatorFarend(void* handle, int delay_shift) { + DelayEstimatorFarend* self = (DelayEstimatorFarend*) handle; + assert(self != NULL); + WebRtc_SoftResetBinaryDelayEstimatorFarend(self->binary_farend, delay_shift); +} + int WebRtc_AddFarSpectrumFix(void* handle, uint16_t* far_spectrum, int spectrum_size, int far_q) { DelayEstimatorFarend* self = (DelayEstimatorFarend*) handle; @@ -261,7 +267,8 @@ void WebRtc_FreeDelayEstimator(void* handle) { free(self); } -void* WebRtc_CreateDelayEstimator(void* farend_handle, int lookahead) { +void* WebRtc_CreateDelayEstimator(void* farend_handle, int max_lookahead, + int lookahead) { DelayEstimator* self = NULL; DelayEstimatorFarend* farend = (DelayEstimatorFarend*) farend_handle; @@ -274,7 +281,8 @@ void* WebRtc_CreateDelayEstimator(void* farend_handle, int lookahead) { // Allocate memory for the farend spectrum handling. self->binary_handle = - WebRtc_CreateBinaryDelayEstimator(farend->binary_farend, lookahead); + WebRtc_CreateBinaryDelayEstimator(farend->binary_farend, max_lookahead, + lookahead); memory_fail |= (self->binary_handle == NULL); // Allocate memory for spectrum buffers. @@ -312,6 +320,18 @@ int WebRtc_InitDelayEstimator(void* handle) { return 0; } +int WebRtc_SoftResetDelayEstimator(void* handle, int delay_shift) { + DelayEstimator* self = (DelayEstimator*) handle; + assert(self != NULL); + return WebRtc_SoftResetBinaryDelayEstimator(self->binary_handle, delay_shift); +} + +int WebRtc_lookahead(void* handle) { + DelayEstimator* self = (DelayEstimator*) handle; + assert(self != NULL); + return self->binary_handle->lookahead; +} + int WebRtc_set_allowed_offset(void* handle, int allowed_offset) { DelayEstimator* self = (DelayEstimator*) handle; @@ -420,12 +440,8 @@ int WebRtc_last_delay(void* handle) { return WebRtc_binary_last_delay(self->binary_handle); } -int WebRtc_last_delay_quality(void* handle) { +float WebRtc_last_delay_quality(void* handle) { DelayEstimator* self = (DelayEstimator*) handle; - - if (self == NULL) { - return -1; - } - + assert(self != NULL); return WebRtc_binary_last_delay_quality(self->binary_handle); } diff --git a/webrtc/modules/audio_processing/utility/delay_estimator_wrapper.h b/webrtc/modules/audio_processing/utility/delay_estimator_wrapper.h index 5d11cd24db..3de43f3fb5 100644 --- a/webrtc/modules/audio_processing/utility/delay_estimator_wrapper.h +++ b/webrtc/modules/audio_processing/utility/delay_estimator_wrapper.h @@ -52,6 +52,13 @@ void* WebRtc_CreateDelayEstimatorFarend(int spectrum_size, int history_size); // int WebRtc_InitDelayEstimatorFarend(void* handle); +// Soft resets the far-end part of the delay estimation instance returned by +// WebRtc_CreateDelayEstimatorFarend(...). +// Input: +// - delay_shift : The amount of blocks to shift history buffers. +// +void WebRtc_SoftResetDelayEstimatorFarend(void* handle, int delay_shift); + // Adds the far-end spectrum to the far-end history buffer. This spectrum is // used as reference when calculating the delay using // WebRtc_ProcessSpectrum(). @@ -106,12 +113,17 @@ void WebRtc_FreeDelayEstimator(void* handle); // where |history_size| was set upon creating the far-end // history buffer size. // +// - max_lookahead : Maximum amount of non-causal lookahead allowed. This +// is to allow for dynamically changing the lookahead on +// the fly. +// // Return value: // - void* : Created |handle|. If the memory can't be allocated or // if any of the input parameters are invalid NULL is // returned. // -void* WebRtc_CreateDelayEstimator(void* farend_handle, int lookahead); +void* WebRtc_CreateDelayEstimator(void* farend_handle, int max_lookahead, + int lookahead); // Initializes the delay estimation instance returned by // WebRtc_CreateDelayEstimator(...) @@ -123,6 +135,19 @@ void* WebRtc_CreateDelayEstimator(void* farend_handle, int lookahead); // int WebRtc_InitDelayEstimator(void* handle); +// Soft resets the delay estimation instance returned by +// WebRtc_CreateDelayEstimator(...) +// Input: +// - delay_shift : The amount of blocks to shift history buffers. +// +// Return value: +// - actual_shifts : The actual number of shifts performed. +// +int WebRtc_SoftResetDelayEstimator(void* handle, int delay_shift); + +// Returns the amount of lookahead we currently use. +int WebRtc_lookahead(void* handle); + // Sets the |allowed_offset| used in the robust validation scheme. If the // delay estimator is used in an echo control component, this parameter is // related to the filter length. In principle |allowed_offset| should be set to @@ -196,18 +221,11 @@ int WebRtc_last_delay(void* handle); // Returns the estimation quality/probability of the last calculated delay // updated by the function WebRtc_DelayEstimatorProcess(...). The estimation -// quality is a value in the interval [0, 1] in Q9. The higher the value, the -// better quality. -// -// Input: -// - handle : Pointer to the delay estimation instance. +// quality is a value in the interval [0, 1]. The higher the value, the better +// quality. // // Return value: -// - delay_quality : >= 0 - Estimation quality (in Q9) of last calculated -// delay value. -// -1 - Error. -// -2 - Insufficient data for estimation. -// -int WebRtc_last_delay_quality(void* handle); +// - delay_quality : >= 0 - Estimation quality of last calculated delay. +float WebRtc_last_delay_quality(void* handle); #endif // WEBRTC_MODULES_AUDIO_PROCESSING_UTILITY_DELAY_ESTIMATOR_WRAPPER_H_