From 5614cf16e71e59e4785deca05249d9a06f746d66 Mon Sep 17 00:00:00 2001 From: "bjornv@webrtc.org" Date: Tue, 27 Jan 2015 18:09:52 +0000 Subject: [PATCH] audio_processing: Use fixed aggregation window in delay metrics Previously, the delay estimate history was reset every time the metrics were pulled. This required all clients to be on the same thread and make use of one call. Now we use a fixed aggregation window of one second and when a client pulls the metrics you get the latest value. Under certain circumstances like tests you would like to have the aggregation window set to the recording length. We therefore turn on the fixed aggregation window after the first call. BUG=2994 TESTED=locally on Mac and trybots R=kwiberg@webrtc.org Review URL: https://webrtc-codereview.appspot.com/38759004 Cr-Commit-Position: refs/heads/master@{#8170} git-svn-id: http://webrtc.googlecode.com/svn/trunk@8170 4adac7df-926f-26a2-2b94-8c16560cd09d --- .../modules/audio_processing/aec/aec_core.c | 28 ++++++++++++------- .../audio_processing/aec/aec_core_internal.h | 2 ++ 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/webrtc/modules/audio_processing/aec/aec_core.c b/webrtc/modules/audio_processing/aec/aec_core.c index 5af3651b93..1f864fcdc8 100644 --- a/webrtc/modules/audio_processing/aec/aec_core.c +++ b/webrtc/modules/audio_processing/aec/aec_core.c @@ -39,6 +39,7 @@ static const size_t kBufSizePartitions = 250; // 1 second of audio in 16 kHz. // Metrics static const int subCountLen = 4; static const int countLen = 50; +static const int kDelayMetricsAggregationWindow = 250; // One second at 16 kHz. // Quantities to control H band scaling for SWB input static const int flagHbandCn = 1; // flag for adding comfort noise in H band @@ -772,16 +773,11 @@ static void UpdateMetrics(AecCore* aec) { static void UpdateDelayMetrics(AecCore* self) { int i = 0; int delay_values = 0; - int num_delay_values = 0; int median = 0; const int kMsPerBlock = PART_LEN / (self->mult * 8); int64_t l1_norm = 0; - // 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) { + if (self->num_delay_values == 0) { // We have no new delay value data. Even though -1 is a valid |median| in // the sense that we allow negative values, it will practically never be // used since multiples of |kMsPerBlock| will always be returned. @@ -792,7 +788,8 @@ static void UpdateDelayMetrics(AecCore* self) { return; } - delay_values = num_delay_values >> 1; // Start value for median count down. + // Start value for median count down. + delay_values = self->num_delay_values >> 1; // Get median of delay values since last update. for (i = 0; i < kHistorySizeBlocks; i++) { delay_values -= self->delay_histogram[i]; @@ -809,11 +806,12 @@ static void UpdateDelayMetrics(AecCore* self) { for (i = 0; i < kHistorySizeBlocks; i++) { l1_norm += abs(i - median) * self->delay_histogram[i]; } - self->delay_std = (int)((l1_norm + num_delay_values / 2) / num_delay_values) * - kMsPerBlock; + self->delay_std = (int)((l1_norm + self->num_delay_values / 2) / + self->num_delay_values) * kMsPerBlock; // Reset histogram. memset(self->delay_histogram, 0, sizeof(self->delay_histogram)); + self->num_delay_values = 0; return; } @@ -1247,6 +1245,11 @@ static void ProcessBlock(AecCore* aec) { if (delay_estimate >= 0) { // Update delay estimate buffer. aec->delay_histogram[delay_estimate]++; + aec->num_delay_values++; + } + if (aec->delay_metrics_delivered == 1 && + aec->num_delay_values >= kDelayMetricsAggregationWindow) { + UpdateDelayMetrics(aec); } } } @@ -1555,7 +1558,9 @@ int WebRtcAec_InitAec(AecCore* aec, int sampFreq) { return -1; } aec->delay_logging_enabled = 0; + aec->delay_metrics_delivered = 0; memset(aec->delay_histogram, 0, sizeof(aec->delay_histogram)); + aec->num_delay_values = 0; aec->delay_median = -1; aec->delay_std = -1; @@ -1838,7 +1843,10 @@ int WebRtcAec_GetDelayMetricsCore(AecCore* self, int* median, int* std) { return -1; } - UpdateDelayMetrics(self); + if (self->delay_metrics_delivered == 0) { + UpdateDelayMetrics(self); + self->delay_metrics_delivered = 1; + } *median = self->delay_median; *std = self->delay_std; diff --git a/webrtc/modules/audio_processing/aec/aec_core_internal.h b/webrtc/modules/audio_processing/aec/aec_core_internal.h index e0ae193270..b9950f6f38 100644 --- a/webrtc/modules/audio_processing/aec/aec_core_internal.h +++ b/webrtc/modules/audio_processing/aec/aec_core_internal.h @@ -126,7 +126,9 @@ struct AecCore { int flag_Hband_cn; // for comfort noise float cn_scale_Hband; // scale for comfort noise in H band + int delay_metrics_delivered; int delay_histogram[kHistorySizeBlocks]; + int num_delay_values; int delay_median; int delay_std; int delay_logging_enabled;