diff --git a/webrtc/modules/audio_processing/aec/aec_core.c b/webrtc/modules/audio_processing/aec/aec_core.c index 931afb9b0d..a8763b3d4a 100644 --- a/webrtc/modules/audio_processing/aec/aec_core.c +++ b/webrtc/modules/audio_processing/aec/aec_core.c @@ -662,6 +662,60 @@ void WebRtcAec_ProcessFrame(aec_t *aec, aec->system_delay -= FRAME_LEN; } +int WebRtcAec_GetDelayMetricsCore(aec_t* self, int* median, int* std) { + int i = 0; + int delay_values = 0; + int num_delay_values = 0; + int my_median = 0; + const int kMsPerBlock = PART_LEN / (self->mult * 8); + float l1_norm = 0; + + assert(self != NULL); + assert(median != NULL); + assert(std != NULL); + + if (self->delay_logging_enabled == 0) { + // Logging disabled. + return -1; + } + + // Get number of delay values since last update. + for (i = 0; i < kHistorySizeBlocks; i++) { + num_delay_values += self->delay_histogram[i]; + } + if (num_delay_values == 0) { + // We have no new delay value data. Even though -1 is a valid estimate, it + // will practically never be used since multiples of |kMsPerBlock| will + // always be returned. + *median = -1; + *std = -1; + return 0; + } + + delay_values = num_delay_values >> 1; // Start value for median count down. + // Get median of delay values since last update. + for (i = 0; i < kHistorySizeBlocks; i++) { + delay_values -= self->delay_histogram[i]; + if (delay_values < 0) { + my_median = i; + break; + } + } + // Account for lookahead. + *median = (my_median - kLookaheadBlocks) * kMsPerBlock; + + // Calculate the L1 norm, with median value as central moment. + for (i = 0; i < kHistorySizeBlocks; i++) { + l1_norm += (float) (fabs(i - my_median) * self->delay_histogram[i]); + } + *std = (int) (l1_norm / (float) num_delay_values + 0.5f) * kMsPerBlock; + + // Reset histogram. + memset(self->delay_histogram, 0, sizeof(self->delay_histogram)); + + return 0; +} + static void ProcessBlock(aec_t* aec) { int i; float d[PART_LEN], y[PART_LEN], e[PART_LEN], dH[PART_LEN]; diff --git a/webrtc/modules/audio_processing/aec/aec_core.h b/webrtc/modules/audio_processing/aec/aec_core.h index 43b69b3163..bab4c91669 100644 --- a/webrtc/modules/audio_processing/aec/aec_core.h +++ b/webrtc/modules/audio_processing/aec/aec_core.h @@ -182,5 +182,8 @@ void WebRtcAec_ProcessFrame(aec_t* aec, // Returns the number of elements moved, and adjusts |system_delay| by the // corresponding amount in ms. int WebRtcAec_MoveFarReadPtr(aec_t* aec, int elements); +// Calculates the median and standard deviation among the delay estimates +// collected since the last call to this function. +int WebRtcAec_GetDelayMetricsCore(aec_t* self, int* median, int* std); #endif // WEBRTC_MODULES_AUDIO_PROCESSING_AEC_MAIN_SOURCE_AEC_CORE_H_ diff --git a/webrtc/modules/audio_processing/aec/echo_cancellation.c b/webrtc/modules/audio_processing/aec/echo_cancellation.c index 2f0ea088fb..dc5c47979c 100644 --- a/webrtc/modules/audio_processing/aec/echo_cancellation.c +++ b/webrtc/modules/audio_processing/aec/echo_cancellation.c @@ -734,12 +734,6 @@ WebRtc_Word32 WebRtcAec_GetMetrics(void *aecInst, AecMetrics *metrics) int WebRtcAec_GetDelayMetrics(void* handle, int* median, int* std) { aecpc_t* self = handle; - int i = 0; - int delay_values = 0; - int num_delay_values = 0; - int my_median = 0; - const int kMsPerBlock = (PART_LEN * 1000) / self->splitSampFreq; - float l1_norm = 0; if (handle == NULL) { return -1; @@ -756,46 +750,12 @@ int WebRtcAec_GetDelayMetrics(void* handle, int* median, int* std) { self->lastError = AEC_UNINITIALIZED_ERROR; return -1; } - if (self->aec->delay_logging_enabled == 0) { - // Logging disabled + if (WebRtcAec_GetDelayMetricsCore(self->aec, median, std) == -1) { + // Logging disabled. self->lastError = AEC_UNSUPPORTED_FUNCTION_ERROR; return -1; } - // Get number of delay values since last update - for (i = 0; i < kHistorySizeBlocks; i++) { - num_delay_values += self->aec->delay_histogram[i]; - } - if (num_delay_values == 0) { - // We have no new delay value data. Even though -1 is a valid estimate, it - // will practically never be used since multiples of |kMsPerBlock| will - // always be returned. - *median = -1; - *std = -1; - return 0; - } - - delay_values = num_delay_values >> 1; // Start value for median count down - // Get median of delay values since last update - for (i = 0; i < kHistorySizeBlocks; i++) { - delay_values -= self->aec->delay_histogram[i]; - if (delay_values < 0) { - my_median = i; - break; - } - } - // Account for lookahead. - *median = (my_median - kLookaheadBlocks) * kMsPerBlock; - - // Calculate the L1 norm, with median value as central moment - for (i = 0; i < kHistorySizeBlocks; i++) { - l1_norm += (float) (fabs(i - my_median) * self->aec->delay_histogram[i]); - } - *std = (int) (l1_norm / (float) num_delay_values + 0.5f) * kMsPerBlock; - - // Reset histogram - memset(self->aec->delay_histogram, 0, sizeof(self->aec->delay_histogram)); - return 0; }