diff --git a/webrtc/modules/audio_processing/utility/delay_estimator.c b/webrtc/modules/audio_processing/utility/delay_estimator.c index dc429af1c8..c67e174a0a 100644 --- a/webrtc/modules/audio_processing/utility/delay_estimator.c +++ b/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) { @@ -363,6 +359,7 @@ BinaryDelayEstimator* WebRtc_CreateBinaryDelayEstimator( self->farend = farend; self->near_history_size = lookahead + 1; self->robust_validation_enabled = 0; // Disabled by default. + self->allowed_offset = 0; // Allocate memory for spectrum buffers. The extra array element in // |mean_bit_counts| and |histogram| is a dummy element only used while diff --git a/webrtc/modules/audio_processing/utility/delay_estimator.h b/webrtc/modules/audio_processing/utility/delay_estimator.h index 7ffb81b8b1..b9a24bb5a2 100644 --- a/webrtc/modules/audio_processing/utility/delay_estimator.h +++ b/webrtc/modules/audio_processing/utility/delay_estimator.h @@ -44,6 +44,7 @@ typedef struct { // Robust validation int robust_validation_enabled; + int allowed_offset; int last_candidate_delay; int compare_delay; int candidate_hits; diff --git a/webrtc/modules/audio_processing/utility/delay_estimator_unittest.cc b/webrtc/modules/audio_processing/utility/delay_estimator_unittest.cc index c7e671a9d5..83d1aed2d5 100644 --- a/webrtc/modules/audio_processing/utility/delay_estimator_unittest.cc +++ b/webrtc/modules/audio_processing/utility/delay_estimator_unittest.cc @@ -246,6 +246,14 @@ TEST_F(DelayEstimatorTest, CorrectErrorReturnsOfWrapper) { EXPECT_EQ(-1, WebRtc_AddFarSpectrumFix(farend_handle_, far_u16_, spectrum_size_, 16)); + // WebRtc_set_allowed_offset() should return -1 if we have: + // 1) NULL pointer as |handle|. + // 2) |allowed_offset| < 0. + EXPECT_EQ(-1, WebRtc_set_allowed_offset(NULL, 0)); + EXPECT_EQ(-1, WebRtc_set_allowed_offset(handle_, -1)); + + EXPECT_EQ(-1, WebRtc_get_allowed_offset(NULL)); + // WebRtc_enable_robust_validation() should return -1 if we have: // 1) NULL pointer as |handle|. // 2) Incorrect |enable| value (not 0 or 1). @@ -294,14 +302,26 @@ TEST_F(DelayEstimatorTest, CorrectErrorReturnsOfWrapper) { WebRtc_FreeDelayEstimator(handle); } +TEST_F(DelayEstimatorTest, VerifyAllowedOffset) { + // Is set to zero by default. + EXPECT_EQ(0, WebRtc_get_allowed_offset(handle_)); + for (int i = 1; i >= 0; i--) { + EXPECT_EQ(0, WebRtc_set_allowed_offset(handle_, i)); + EXPECT_EQ(i, WebRtc_get_allowed_offset(handle_)); + Init(); + // Unaffected over a reset. + EXPECT_EQ(i, WebRtc_get_allowed_offset(handle_)); + } +} + TEST_F(DelayEstimatorTest, VerifyEnableRobustValidation) { // Disabled by default. EXPECT_EQ(0, WebRtc_is_robust_validation_enabled(handle_)); - // Unaffected over a reset for (int i = 1; i >= 0; i--) { EXPECT_EQ(0, WebRtc_enable_robust_validation(handle_, i)); EXPECT_EQ(i, WebRtc_is_robust_validation_enabled(handle_)); Init(); + // Unaffected over a reset. EXPECT_EQ(i, WebRtc_is_robust_validation_enabled(handle_)); } } @@ -393,7 +413,7 @@ TEST_F(DelayEstimatorTest, CorrectErrorReturnsOfBinaryEstimator) { BinaryDelayEstimator* binary_handle = binary_; // WebRtc_CreateBinaryDelayEstimator() should return -1 if we have a NULL - // pointer as |binary_handle| or invalid input values. Upon failure, the + // pointer as |binary_farend| or invalid input values. Upon failure, the // |binary_handle| should be NULL. // Make sure we have a non-NULL value at start, so we can detect NULL after // create failure. @@ -402,9 +422,6 @@ TEST_F(DelayEstimatorTest, CorrectErrorReturnsOfBinaryEstimator) { binary_handle = binary_; binary_handle = WebRtc_CreateBinaryDelayEstimator(binary_farend_, -1); EXPECT_TRUE(binary_handle == NULL); - binary_handle = binary_; - binary_handle = WebRtc_CreateBinaryDelayEstimator(0, 0); - EXPECT_TRUE(binary_handle == NULL); } TEST_F(DelayEstimatorTest, MeanEstimatorFix) { diff --git a/webrtc/modules/audio_processing/utility/delay_estimator_wrapper.c b/webrtc/modules/audio_processing/utility/delay_estimator_wrapper.c index ce4431844e..e48dc98721 100644 --- a/webrtc/modules/audio_processing/utility/delay_estimator_wrapper.c +++ b/webrtc/modules/audio_processing/utility/delay_estimator_wrapper.c @@ -312,6 +312,25 @@ int WebRtc_InitDelayEstimator(void* handle) { return 0; } +int WebRtc_set_allowed_offset(void* handle, int allowed_offset) { + DelayEstimator* self = (DelayEstimator*) handle; + + if ((self == NULL) || (allowed_offset < 0)) { + return -1; + } + self->binary_handle->allowed_offset = allowed_offset; + return 0; +} + +int WebRtc_get_allowed_offset(const void* handle) { + DelayEstimator* self = (DelayEstimator*) handle; + + if (self == NULL) { + return -1; + } + return self->binary_handle->allowed_offset; +} + int WebRtc_enable_robust_validation(void* handle, int enable) { DelayEstimator* self = (DelayEstimator*) handle; @@ -321,18 +340,16 @@ int WebRtc_enable_robust_validation(void* handle, int enable) { if ((enable < 0) || (enable > 1)) { return -1; } - assert(self->binary_handle != NULL); self->binary_handle->robust_validation_enabled = enable; return 0; } -int WebRtc_is_robust_validation_enabled(void* handle) { +int WebRtc_is_robust_validation_enabled(const void* handle) { DelayEstimator* self = (DelayEstimator*) handle; if (self == NULL) { return -1; } - assert(self->binary_handle != NULL); return self->binary_handle->robust_validation_enabled; } diff --git a/webrtc/modules/audio_processing/utility/delay_estimator_wrapper.h b/webrtc/modules/audio_processing/utility/delay_estimator_wrapper.h index 50bcddeddc..5d11cd24db 100644 --- a/webrtc/modules/audio_processing/utility/delay_estimator_wrapper.h +++ b/webrtc/modules/audio_processing/utility/delay_estimator_wrapper.h @@ -123,17 +123,34 @@ void* WebRtc_CreateDelayEstimator(void* farend_handle, int lookahead); // int WebRtc_InitDelayEstimator(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 +// the echo control filter length minus the expected echo duration, i.e., the +// delay offset the echo control can handle without quality regression. The +// default value, used if not set manually, is zero. Note that |allowed_offset| +// has to be non-negative. +// Inputs: +// - handle : Pointer to the delay estimation instance. +// - allowed_offset : The amount of delay offset, measured in partitions, +// the echo control filter can handle. +int WebRtc_set_allowed_offset(void* handle, int allowed_offset); + +// Returns the |allowed_offset| in number of partitions. +int WebRtc_get_allowed_offset(const void* handle); + // TODO(bjornv): Implement this functionality. Currently, enabling it has no // impact, hence this is an empty API. // Enables/Disables a robust validation functionality in the delay estimation. -// This is by default disabled upon initialization. +// This is by default set to disabled at create time. The state is preserved +// over a reset. // Inputs: // - handle : Pointer to the delay estimation instance. // - enable : Enable (1) or disable (0) this feature. int WebRtc_enable_robust_validation(void* handle, int enable); // Returns 1 if robust validation is enabled and 0 if disabled. -int WebRtc_is_robust_validation_enabled(void* handle); +int WebRtc_is_robust_validation_enabled(const void* handle); // Estimates and returns the delay between the far-end and near-end blocks. The // value will be offset by the lookahead (i.e. the lookahead should be