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 int subCountLen = 4; | 49 static const int subCountLen = 4; |
50 static const int countLen = 50; | 50 static const int countLen = 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 // Diverge metric is based on audio level, which gets updated which every | |
tlegrand-webrtc
2016/03/17 12:28:39
You haven't addressed my comments from Patch Set 1
minyue-webrtc
2016/04/03 21:42:06
Sorry, I might have missed it. Now it is addressed
| |
54 // |subCountLen + 1| * 10 milliseconds. Diverge 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; | |
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 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
549 self->stateCounter = 0; | 555 self->stateCounter = 0; |
550 InitLevel(&self->farlevel); | 556 InitLevel(&self->farlevel); |
551 InitLevel(&self->nearlevel); | 557 InitLevel(&self->nearlevel); |
552 InitLevel(&self->linoutlevel); | 558 InitLevel(&self->linoutlevel); |
553 InitLevel(&self->nlpoutlevel); | 559 InitLevel(&self->nlpoutlevel); |
554 | 560 |
555 InitStats(&self->erl); | 561 InitStats(&self->erl); |
556 InitStats(&self->erle); | 562 InitStats(&self->erle); |
557 InitStats(&self->aNlp); | 563 InitStats(&self->aNlp); |
558 InitStats(&self->rerl); | 564 InitStats(&self->rerl); |
565 | |
566 self->fraction_filter_divergent->Clear(); | |
559 } | 567 } |
560 | 568 |
561 static float CalculatePower(const float* in, size_t num_samples) { | 569 static float CalculatePower(const float* in, size_t num_samples) { |
562 size_t k; | 570 size_t k; |
563 float energy = 0.0f; | 571 float energy = 0.0f; |
564 | 572 |
565 for (k = 0; k < num_samples; ++k) { | 573 for (k = 0; k < num_samples; ++k) { |
566 energy += in[k] * in[k]; | 574 energy += in[k] * in[k]; |
567 } | 575 } |
568 return energy / num_samples; | 576 return energy / num_samples; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
606 // a per-sample energy (i.e., power). | 614 // a per-sample energy (i.e., power). |
607 const float noisyPower = 300000.0f * 2.0f / PART_LEN2; | 615 const float noisyPower = 300000.0f * 2.0f / PART_LEN2; |
608 | 616 |
609 float actThreshold; | 617 float actThreshold; |
610 float echo, suppressedEcho; | 618 float echo, suppressedEcho; |
611 | 619 |
612 if (aec->echoState) { // Check if echo is likely present | 620 if (aec->echoState) { // Check if echo is likely present |
613 aec->stateCounter++; | 621 aec->stateCounter++; |
614 } | 622 } |
615 | 623 |
624 if (aec->linoutlevel.sfrcounter == 0) { | |
625 const float level_increase = | |
626 aec->linoutlevel.framelevel - aec->nearlevel.framelevel; | |
627 // Level increase should be, in principle, negative, when the filter | |
628 // does not diverge. Here we allow some margin (0.001 * near end level) and | |
629 // numerical error (1.0). | |
630 aec->fraction_filter_divergent->AddSample(level_increase > | |
631 std::max(0.001 * aec->nearlevel.framelevel, 1.0) ? 1.0 : 0.0); | |
632 } | |
633 | |
616 if (aec->farlevel.frcounter == 0) { | 634 if (aec->farlevel.frcounter == 0) { |
617 if (aec->farlevel.minlevel < noisyPower) { | 635 if (aec->farlevel.minlevel < noisyPower) { |
618 actThreshold = actThresholdClean; | 636 actThreshold = actThresholdClean; |
619 } else { | 637 } else { |
620 actThreshold = actThresholdNoisy; | 638 actThreshold = actThresholdNoisy; |
621 } | 639 } |
622 | 640 |
623 if ((aec->stateCounter > (0.5f * countLen * subCountLen)) && | 641 if ((aec->stateCounter > (0.5f * countLen * subCountLen)) && |
624 (aec->farlevel.sfrcounter == 0) | 642 (aec->farlevel.sfrcounter == 0) |
625 | 643 |
(...skipping 732 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1358 // For high bands | 1376 // For high bands |
1359 for (i = 0; i < aec->num_bands - 1; ++i) { | 1377 for (i = 0; i < aec->num_bands - 1; ++i) { |
1360 WebRtc_WriteBuffer(aec->outFrBufH[i], outputH[i], PART_LEN); | 1378 WebRtc_WriteBuffer(aec->outFrBufH[i], outputH[i], PART_LEN); |
1361 } | 1379 } |
1362 | 1380 |
1363 RTC_AEC_DEBUG_WAV_WRITE(aec->outFile, output, PART_LEN); | 1381 RTC_AEC_DEBUG_WAV_WRITE(aec->outFile, output, PART_LEN); |
1364 } | 1382 } |
1365 | 1383 |
1366 AecCore* WebRtcAec_CreateAec() { | 1384 AecCore* WebRtcAec_CreateAec() { |
1367 int i; | 1385 int i; |
1368 AecCore* aec = reinterpret_cast<AecCore*>(malloc(sizeof(AecCore))); | 1386 AecCore* aec = new AecCore; |
1369 if (!aec) { | 1387 if (!aec) { |
1370 return NULL; | 1388 return NULL; |
1371 } | 1389 } |
1372 | 1390 |
1373 aec->nearFrBuf = WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, sizeof(float)); | 1391 aec->nearFrBuf = WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, sizeof(float)); |
1374 if (!aec->nearFrBuf) { | 1392 if (!aec->nearFrBuf) { |
1375 WebRtcAec_FreeAec(aec); | 1393 WebRtcAec_FreeAec(aec); |
1376 return NULL; | 1394 return NULL; |
1377 } | 1395 } |
1378 | 1396 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1422 return NULL; | 1440 return NULL; |
1423 } | 1441 } |
1424 // We create the delay_estimator with the same amount of maximum lookahead as | 1442 // We create the delay_estimator with the same amount of maximum lookahead as |
1425 // the delay history size (kHistorySizeBlocks) for symmetry reasons. | 1443 // the delay history size (kHistorySizeBlocks) for symmetry reasons. |
1426 aec->delay_estimator = WebRtc_CreateDelayEstimator( | 1444 aec->delay_estimator = WebRtc_CreateDelayEstimator( |
1427 aec->delay_estimator_farend, kHistorySizeBlocks); | 1445 aec->delay_estimator_farend, kHistorySizeBlocks); |
1428 if (aec->delay_estimator == NULL) { | 1446 if (aec->delay_estimator == NULL) { |
1429 WebRtcAec_FreeAec(aec); | 1447 WebRtcAec_FreeAec(aec); |
1430 return NULL; | 1448 return NULL; |
1431 } | 1449 } |
1450 | |
1451 aec->fraction_filter_divergent.reset( | |
1452 new webrtc::MeanCalculator(kDivergeMetricAggregationWindow)); | |
tlegrand-webrtc
2016/03/17 12:28:39
Do you need webrtc:: here? Looks like we are in th
minyue-webrtc
2016/04/03 21:42:05
True. the namespace was added recently. now I can
| |
1453 if (aec->fraction_filter_divergent.get() == nullptr) { | |
tlegrand-webrtc
2016/03/17 12:28:39
Can you explain what happens here?
minyue-webrtc
2016/04/03 21:42:06
This is to check if the memory is allocated correc
| |
1454 WebRtcAec_FreeAec(aec); | |
1455 return NULL; | |
1456 } | |
1457 | |
1432 #ifdef WEBRTC_ANDROID | 1458 #ifdef WEBRTC_ANDROID |
1433 aec->delay_agnostic_enabled = 1; // DA-AEC enabled by default. | 1459 aec->delay_agnostic_enabled = 1; // DA-AEC enabled by default. |
1434 // DA-AEC assumes the system is causal from the beginning and will self adjust | 1460 // DA-AEC assumes the system is causal from the beginning and will self adjust |
1435 // the lookahead when shifting is required. | 1461 // the lookahead when shifting is required. |
1436 WebRtc_set_lookahead(aec->delay_estimator, 0); | 1462 WebRtc_set_lookahead(aec->delay_estimator, 0); |
1437 #else | 1463 #else |
1438 aec->delay_agnostic_enabled = 0; | 1464 aec->delay_agnostic_enabled = 0; |
1439 WebRtc_set_lookahead(aec->delay_estimator, kLookaheadBlocks); | 1465 WebRtc_set_lookahead(aec->delay_estimator, kLookaheadBlocks); |
1440 #endif | 1466 #endif |
1441 aec->extended_filter_enabled = 0; | 1467 aec->extended_filter_enabled = 0; |
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1896 | 1922 |
1897 int WebRtcAec_system_delay(AecCore* self) { | 1923 int WebRtcAec_system_delay(AecCore* self) { |
1898 return self->system_delay; | 1924 return self->system_delay; |
1899 } | 1925 } |
1900 | 1926 |
1901 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { | 1927 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { |
1902 assert(delay >= 0); | 1928 assert(delay >= 0); |
1903 self->system_delay = delay; | 1929 self->system_delay = delay; |
1904 } | 1930 } |
1905 } // namespace webrtc | 1931 } // namespace webrtc |
OLD | NEW |