Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 43 namespace webrtc { | 43 namespace webrtc { |
| 44 | 44 |
| 45 // Buffer size (samples) | 45 // Buffer size (samples) |
| 46 static const size_t kBufSizePartitions = 250; // 1 second of audio in 16 kHz. | 46 static const size_t kBufSizePartitions = 250; // 1 second of audio in 16 kHz. |
| 47 | 47 |
| 48 // Metrics | 48 // Metrics |
| 49 static const size_t kSubCountLen = 4; | 49 static const size_t kSubCountLen = 4; |
| 50 static const size_t kCountLen = 50; | 50 static const size_t kCountLen = 50; |
| 51 static const int kDelayMetricsAggregationWindow = 1250; // 5 seconds at 16 kHz. | 51 static const int kDelayMetricsAggregationWindow = 1250; // 5 seconds at 16 kHz. |
| 52 | 52 |
| 53 // Divergence metric is based on audio level, which gets updated every | |
| 54 // |kCountLen + 1| * 10 milliseconds. Divergence metric takes the statistics of | |
| 55 // |kDivergeMetricAggregationWindow| samples. Current value corresponds to 0.5 | |
| 56 // seconds at 16 kHz. | |
| 57 static const int kDivergeMetricAggregationWindow = 25; | |
|
peah-webrtc
2016/04/06 11:01:10
This should probably be called kDivergeMetricAggre
minyue-webrtc
2016/04/06 13:35:37
Done.
| |
| 58 | |
| 53 // Quantities to control H band scaling for SWB input | 59 // Quantities to control H band scaling for SWB input |
| 54 static const float cnScaleHband = 0.4f; // scale for comfort noise in H band. | 60 static const float cnScaleHband = 0.4f; // scale for comfort noise in H band. |
| 55 // Initial bin for averaging nlp gain in low band | 61 // Initial bin for averaging nlp gain in low band |
| 56 static const int freqAvgIc = PART_LEN / 2; | 62 static const int freqAvgIc = PART_LEN / 2; |
| 57 | 63 |
| 58 // Matlab code to produce table: | 64 // Matlab code to produce table: |
| 59 // win = sqrt(hanning(63)); win = [0 ; win(1:32)]; | 65 // win = sqrt(hanning(63)); win = [0 ; win(1:32)]; |
| 60 // fprintf(1, '\t%.14f, %.14f, %.14f,\n', win); | 66 // fprintf(1, '\t%.14f, %.14f, %.14f,\n', win); |
| 61 ALIGN16_BEG const float ALIGN16_END WebRtcAec_sqrtHanning[65] = { | 67 ALIGN16_BEG const float ALIGN16_END WebRtcAec_sqrtHanning[65] = { |
| 62 0.00000000000000f, 0.02454122852291f, 0.04906767432742f, 0.07356456359967f, | 68 0.00000000000000f, 0.02454122852291f, 0.04906767432742f, 0.07356456359967f, |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 143 WebRtcAecWindowData WebRtcAec_WindowData; | 149 WebRtcAecWindowData WebRtcAec_WindowData; |
| 144 | 150 |
| 145 __inline static float MulRe(float aRe, float aIm, float bRe, float bIm) { | 151 __inline static float MulRe(float aRe, float aIm, float bRe, float bIm) { |
| 146 return aRe * bRe - aIm * bIm; | 152 return aRe * bRe - aIm * bIm; |
| 147 } | 153 } |
| 148 | 154 |
| 149 __inline static float MulIm(float aRe, float aIm, float bRe, float bIm) { | 155 __inline static float MulIm(float aRe, float aIm, float bRe, float bIm) { |
| 150 return aRe * bIm + aIm * bRe; | 156 return aRe * bIm + aIm * bRe; |
| 151 } | 157 } |
| 152 | 158 |
| 159 // TODO(minyue): Due to a legacy bug, |framelevel| and |averagelevel| use a | |
| 160 // window, of which the length is 1 unit longer than indicated. Remove "+1" when | |
| 161 // the code is refactored. | |
| 153 PowerLevel::PowerLevel() | 162 PowerLevel::PowerLevel() |
| 154 // TODO(minyue): Due to a legacy bug, |framelevel| and |averagelevel| use a | 163 : framelevel(kSubCountLen + 1), |
| 155 // window, of which the length is 1 unit longer than indicated. Remove "+1" | 164 averagelevel(kCountLen + 1) { |
| 156 // when the code is refactored. | |
| 157 : framelevel(kSubCountLen + 1), | |
| 158 averagelevel(kCountLen + 1) { | |
| 159 } | 165 } |
| 160 | 166 |
| 161 // TODO(minyue): Moving some initialization from WebRtcAec_CreateAec() to ctor. | 167 // TODO(minyue): Moving some initialization from WebRtcAec_CreateAec() to ctor. |
| 162 AecCore::AecCore() = default; | 168 AecCore::AecCore() |
| 169 : divergent_filter_fraction(kDivergeMetricAggregationWindow) { | |
| 170 } | |
| 163 | 171 |
| 164 static int CmpFloat(const void* a, const void* b) { | 172 static int CmpFloat(const void* a, const void* b) { |
| 165 const float* da = (const float*)a; | 173 const float* da = (const float*)a; |
| 166 const float* db = (const float*)b; | 174 const float* db = (const float*)b; |
| 167 | 175 |
| 168 return (*da > *db) - (*da < *db); | 176 return (*da > *db) - (*da < *db); |
| 169 } | 177 } |
| 170 | 178 |
| 171 static void FilterFar(int num_partitions, | 179 static void FilterFar(int num_partitions, |
| 172 int x_fft_buf_block_pos, | 180 int x_fft_buf_block_pos, |
| (...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 555 self->stateCounter = 0; | 563 self->stateCounter = 0; |
| 556 InitLevel(&self->farlevel); | 564 InitLevel(&self->farlevel); |
| 557 InitLevel(&self->nearlevel); | 565 InitLevel(&self->nearlevel); |
| 558 InitLevel(&self->linoutlevel); | 566 InitLevel(&self->linoutlevel); |
| 559 InitLevel(&self->nlpoutlevel); | 567 InitLevel(&self->nlpoutlevel); |
| 560 | 568 |
| 561 InitStats(&self->erl); | 569 InitStats(&self->erl); |
| 562 InitStats(&self->erle); | 570 InitStats(&self->erle); |
| 563 InitStats(&self->aNlp); | 571 InitStats(&self->aNlp); |
| 564 InitStats(&self->rerl); | 572 InitStats(&self->rerl); |
| 573 | |
| 574 self->divergent_filter_fraction.Reset(); | |
| 565 } | 575 } |
| 566 | 576 |
| 567 static float CalculatePower(const float* in, size_t num_samples) { | 577 static float CalculatePower(const float* in, size_t num_samples) { |
| 568 size_t k; | 578 size_t k; |
| 569 float energy = 0.0f; | 579 float energy = 0.0f; |
| 570 | 580 |
| 571 for (k = 0; k < num_samples; ++k) { | 581 for (k = 0; k < num_samples; ++k) { |
| 572 energy += in[k] * in[k]; | 582 energy += in[k] * in[k]; |
| 573 } | 583 } |
| 574 return energy / num_samples; | 584 return energy / num_samples; |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 598 | 608 |
| 599 const float noisyPower = 300000.0f; | 609 const float noisyPower = 300000.0f; |
| 600 | 610 |
| 601 float actThreshold; | 611 float actThreshold; |
| 602 float echo, suppressedEcho; | 612 float echo, suppressedEcho; |
| 603 | 613 |
| 604 if (aec->echoState) { // Check if echo is likely present | 614 if (aec->echoState) { // Check if echo is likely present |
| 605 aec->stateCounter++; | 615 aec->stateCounter++; |
| 606 } | 616 } |
| 607 | 617 |
| 618 if (aec->linoutlevel.framelevel.EndOfBlock()) { | |
| 619 const float near_level = aec->nearlevel.framelevel.GetLatestMean(); | |
| 620 const float level_increase = | |
| 621 aec->linoutlevel.framelevel.GetLatestMean() - near_level; | |
| 622 const bool output_signal_active = | |
| 623 aec->nlpoutlevel.framelevel.GetLatestMean() > | |
| 624 actThresholdClean * aec->nlpoutlevel.minlevel; | |
| 625 // Level increase should be, in principle, negative, when the filter | |
| 626 // does not diverge. Here we allow some margin (0.01 * near end level) and | |
| 627 // numerical error (1.0). We count divergence only when the AEC output | |
| 628 // signal is active. | |
| 629 aec->divergent_filter_fraction.AddObservation(output_signal_active && | |
| 630 level_increase > std::max(0.01 * near_level, 1.0)); | |
|
peah-webrtc
2016/04/06 11:01:10
If this would be a general and common task maybe a
minyue-webrtc
2016/04/06 13:35:37
Done.
| |
| 631 } | |
| 632 | |
| 608 if (aec->farlevel.averagelevel.EndOfBlock()) { | 633 if (aec->farlevel.averagelevel.EndOfBlock()) { |
| 609 if (aec->farlevel.minlevel < noisyPower) { | 634 if (aec->farlevel.minlevel < noisyPower) { |
| 610 actThreshold = actThresholdClean; | 635 actThreshold = actThresholdClean; |
| 611 } else { | 636 } else { |
| 612 actThreshold = actThresholdNoisy; | 637 actThreshold = actThresholdNoisy; |
| 613 } | 638 } |
| 614 | 639 |
| 615 const float far_average_level = aec->farlevel.averagelevel.GetLatestMean(); | 640 const float far_average_level = aec->farlevel.averagelevel.GetLatestMean(); |
| 616 | 641 |
| 617 // The last condition is to let estimation be made in active far-end | 642 // The last condition is to let estimation be made in active far-end |
| (...skipping 1274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1892 | 1917 |
| 1893 int WebRtcAec_system_delay(AecCore* self) { | 1918 int WebRtcAec_system_delay(AecCore* self) { |
| 1894 return self->system_delay; | 1919 return self->system_delay; |
| 1895 } | 1920 } |
| 1896 | 1921 |
| 1897 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { | 1922 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { |
| 1898 assert(delay >= 0); | 1923 assert(delay >= 0); |
| 1899 self->system_delay = delay; | 1924 self->system_delay = delay; |
| 1900 } | 1925 } |
| 1901 } // namespace webrtc | 1926 } // namespace webrtc |
| OLD | NEW |