diff --git a/webrtc/modules/audio_processing/utility/delay_estimator.c b/webrtc/modules/audio_processing/utility/delay_estimator.c index 3d1d7c49e..355a6b944 100644 --- a/webrtc/modules/audio_processing/utility/delay_estimator.c +++ b/webrtc/modules/audio_processing/utility/delay_estimator.c @@ -157,7 +157,7 @@ int WebRtc_ProcessBinarySpectrum(BinaryDelayEstimator* handle, int i = 0; int candidate_delay = -1; - int32_t value_best_candidate = 16384; // 32 in Q9, (max |mean_bit_counts|). + int32_t value_best_candidate = 32 << 9; // 32 in Q9, (max |mean_bit_counts|). int32_t value_worst_candidate = 0; assert(handle != NULL); @@ -269,6 +269,18 @@ int WebRtc_binary_last_delay(BinaryDelayEstimator* handle) { return handle->last_delay; } +int WebRtc_binary_last_delay_quality(BinaryDelayEstimator* handle) { + assert(handle != 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 quality = 1 - |last_delay_probability| / 32 (in Q14). + return (32 << 9) - handle->last_delay_probability; +} + void WebRtc_MeanEstimatorFix(int32_t new_value, int factor, int32_t* mean_value) { diff --git a/webrtc/modules/audio_processing/utility/delay_estimator.h b/webrtc/modules/audio_processing/utility/delay_estimator.h index 93c4b4e93..97456d195 100644 --- a/webrtc/modules/audio_processing/utility/delay_estimator.h +++ b/webrtc/modules/audio_processing/utility/delay_estimator.h @@ -98,6 +98,20 @@ int WebRtc_ProcessBinarySpectrum(BinaryDelayEstimator* handle, // int WebRtc_binary_last_delay(BinaryDelayEstimator* handle); +// 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: +// - handle : Pointer to the delay estimation instance. +// +// 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* handle); + // 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 // Fixed point wrapper. diff --git a/webrtc/modules/audio_processing/utility/delay_estimator_unittest.cc b/webrtc/modules/audio_processing/utility/delay_estimator_unittest.cc index aaaeff42d..58599a35e 100644 --- a/webrtc/modules/audio_processing/utility/delay_estimator_unittest.cc +++ b/webrtc/modules/audio_processing/utility/delay_estimator_unittest.cc @@ -77,6 +77,8 @@ void DelayEstimatorTest::Init() { // Verify initialization. EXPECT_EQ(0, 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. } void DelayEstimatorTest::InitBinary() { @@ -150,6 +152,10 @@ 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); } @@ -189,11 +195,13 @@ 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_)); break; } } // Verify that we have left the initialized state. EXPECT_NE(-2, WebRtc_last_delay(handle_)); + EXPECT_NE(0, WebRtc_last_delay_quality(handle_)); // Fixed point operations. Init(); @@ -202,11 +210,13 @@ TEST_F(DelayEstimatorTest, CorrectLastDelay) { spectrum_size_, 0, 0); if (last_delay != -2) { EXPECT_EQ(last_delay, WebRtc_last_delay(handle_)); + EXPECT_EQ(7203, 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_)); } TEST_F(DelayEstimatorTest, CorrectErrorReturnsOfBinaryEstimator) { @@ -296,6 +306,7 @@ TEST_F(DelayEstimatorTest, ExactDelayEstimate) { } // Verify that we have left the initialized state. EXPECT_NE(-2, WebRtc_binary_last_delay(binary_handle_)); + EXPECT_NE(0, WebRtc_binary_last_delay_quality(binary_handle_)); } } diff --git a/webrtc/modules/audio_processing/utility/delay_estimator_wrapper.c b/webrtc/modules/audio_processing/utility/delay_estimator_wrapper.c index 74918076c..474cb69ba 100644 --- a/webrtc/modules/audio_processing/utility/delay_estimator_wrapper.c +++ b/webrtc/modules/audio_processing/utility/delay_estimator_wrapper.c @@ -299,3 +299,13 @@ int WebRtc_last_delay(void* handle) { return WebRtc_binary_last_delay(self->binary_handle); } + +int WebRtc_last_delay_quality(void* handle) { + DelayEstimator* self = (DelayEstimator*) handle; + + if (self == NULL) { + return -1; + } + + 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 4591e4bf7..3d243db06 100644 --- a/webrtc/modules/audio_processing/utility/delay_estimator_wrapper.h +++ b/webrtc/modules/audio_processing/utility/delay_estimator_wrapper.h @@ -106,4 +106,20 @@ int WebRtc_DelayEstimatorProcessFloat(void* handle, // 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. +// +// 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); + #endif // WEBRTC_MODULES_AUDIO_PROCESSING_UTILITY_DELAY_ESTIMATOR_WRAPPER_H_