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 500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
511 static void GetHighbandGain(const float* lambda, float* nlpGainHband) { | 511 static void GetHighbandGain(const float* lambda, float* nlpGainHband) { |
512 int i; | 512 int i; |
513 | 513 |
514 *nlpGainHband = 0.0f; | 514 *nlpGainHband = 0.0f; |
515 for (i = freqAvgIc; i < PART_LEN1 - 1; i++) { | 515 for (i = freqAvgIc; i < PART_LEN1 - 1; i++) { |
516 *nlpGainHband += lambda[i]; | 516 *nlpGainHband += lambda[i]; |
517 } | 517 } |
518 *nlpGainHband /= static_cast<float>(PART_LEN1 - 1 - freqAvgIc); | 518 *nlpGainHband /= static_cast<float>(PART_LEN1 - 1 - freqAvgIc); |
519 } | 519 } |
520 | 520 |
521 static void ComfortNoise(AecCore* aec, | 521 static void GenerateComplexNoise(uint32_t* seed, float noise[2][PART_LEN1]) { |
522 float efw[2][PART_LEN1], | 522 const float kPi2 = 6.28318530717959f; |
523 float comfortNoiseHband[2][PART_LEN1], | |
524 const float* noisePow, | |
525 const float* lambda) { | |
526 int i, num; | |
527 float rand[PART_LEN]; | |
528 float noise, noiseAvg, tmp, tmpAvg; | |
529 int16_t randW16[PART_LEN]; | 523 int16_t randW16[PART_LEN]; |
530 float u[2][PART_LEN1]; | 524 WebRtcSpl_RandUArray(randW16, PART_LEN, seed); |
531 | 525 |
532 const float pi2 = 6.28318530717959f; | 526 noise[0][0] = 0; |
| 527 noise[1][0] = 0; |
| 528 for (size_t i = 1; i < PART_LEN1; i++) { |
| 529 float tmp = kPi2 * randW16[i - 1] / 32768.f; |
| 530 noise[0][i] = cosf(tmp); |
| 531 noise[1][i] = -sinf(tmp); |
| 532 } |
| 533 noise[1][PART_LEN] = 0; |
| 534 } |
533 | 535 |
534 // Generate a uniform random array on [0 1] | 536 static void ComfortNoise(bool generate_high_frequency_noise, |
535 WebRtcSpl_RandUArray(randW16, PART_LEN, &aec->seed); | 537 uint32_t* seed, |
536 for (i = 0; i < PART_LEN; i++) { | 538 float e_fft[2][PART_LEN1], |
537 rand[i] = static_cast<float>(randW16[i]) / 32768; | 539 float high_frequency_comfort_noise[2][PART_LEN1], |
| 540 const float* noise_spectrum, |
| 541 const float* suppressor_gain) { |
| 542 float complex_noise[2][PART_LEN1]; |
| 543 |
| 544 GenerateComplexNoise(seed, complex_noise); |
| 545 |
| 546 // Shape, scale and add comfort noise. |
| 547 for (int i = 1; i < PART_LEN1; ++i) { |
| 548 float noise_scaling = |
| 549 sqrtf(WEBRTC_SPL_MAX(1 - suppressor_gain[i] * suppressor_gain[i], 0)) * |
| 550 sqrtf(noise_spectrum[i]); |
| 551 e_fft[0][i] += noise_scaling * complex_noise[0][i]; |
| 552 e_fft[1][i] += noise_scaling * complex_noise[1][i]; |
538 } | 553 } |
539 | 554 |
540 // Reject LF noise | 555 // Form comfort noise for higher frequencies. |
541 u[0][0] = 0; | 556 if (generate_high_frequency_noise) { |
542 u[1][0] = 0; | 557 // Compute average noise power and nlp gain over the second half of freq |
543 for (i = 1; i < PART_LEN1; i++) { | 558 // spectrum (i.e., 4->8khz). |
544 tmp = pi2 * rand[i - 1]; | 559 int start_avg_band = PART_LEN1 / 2; |
| 560 float upper_bands_noise_power = 0.f; |
| 561 float upper_bands_suppressor_gain = 0.f; |
| 562 for (int i = start_avg_band; i < PART_LEN1; ++i) { |
| 563 upper_bands_noise_power += sqrtf(noise_spectrum[i]); |
| 564 upper_bands_suppressor_gain += |
| 565 sqrtf(WEBRTC_SPL_MAX(1 - suppressor_gain[i] * suppressor_gain[i], 0)); |
| 566 } |
| 567 upper_bands_noise_power /= (PART_LEN1 - start_avg_band); |
| 568 upper_bands_suppressor_gain /= (PART_LEN1 - start_avg_band); |
545 | 569 |
546 noise = sqrtf(noisePow[i]); | 570 // Shape, scale and add comfort noise. |
547 u[0][i] = noise * cosf(tmp); | 571 float noise_scaling = upper_bands_suppressor_gain * upper_bands_noise_power; |
548 u[1][i] = -noise * sinf(tmp); | 572 high_frequency_comfort_noise[0][0] = 0; |
549 } | 573 high_frequency_comfort_noise[1][0] = 0; |
550 u[1][PART_LEN] = 0; | 574 for (int i = 1; i < PART_LEN1; ++i) { |
551 | 575 high_frequency_comfort_noise[0][i] = noise_scaling * complex_noise[0][i]; |
552 for (i = 0; i < PART_LEN1; i++) { | 576 high_frequency_comfort_noise[1][i] = noise_scaling * complex_noise[1][i]; |
553 // This is the proper weighting to match the background noise power | |
554 tmp = sqrtf(WEBRTC_SPL_MAX(1 - lambda[i] * lambda[i], 0)); | |
555 // tmp = 1 - lambda[i]; | |
556 efw[0][i] += tmp * u[0][i]; | |
557 efw[1][i] += tmp * u[1][i]; | |
558 } | |
559 | |
560 // For H band comfort noise | |
561 // TODO(peah): don't compute noise and "tmp" twice. Use the previous results. | |
562 noiseAvg = 0.0; | |
563 tmpAvg = 0.0; | |
564 num = 0; | |
565 if (aec->num_bands > 1) { | |
566 // average noise scale | |
567 // average over second half of freq spectrum (i.e., 4->8khz) | |
568 // TODO(peah): we shouldn't need num. We know how many elements we're | |
569 // summing. | |
570 for (i = PART_LEN1 >> 1; i < PART_LEN1; i++) { | |
571 num++; | |
572 noiseAvg += sqrtf(noisePow[i]); | |
573 } | 577 } |
574 noiseAvg /= static_cast<float>(num); | 578 high_frequency_comfort_noise[1][PART_LEN] = 0; |
575 | |
576 // average nlp scale | |
577 // average over second half of freq spectrum (i.e., 4->8khz) | |
578 // TODO(peah): we shouldn't need num. We know how many elements | |
579 // we're summing. | |
580 num = 0; | |
581 for (i = PART_LEN1 >> 1; i < PART_LEN1; i++) { | |
582 num++; | |
583 tmpAvg += sqrtf(WEBRTC_SPL_MAX(1 - lambda[i] * lambda[i], 0)); | |
584 } | |
585 tmpAvg /= static_cast<float>(num); | |
586 | |
587 // Use average noise for H band | |
588 // TODO(peah): we should probably have a new random vector here. | |
589 // Reject LF noise | |
590 u[0][0] = 0; | |
591 u[1][0] = 0; | |
592 for (i = 1; i < PART_LEN1; i++) { | |
593 tmp = pi2 * rand[i - 1]; | |
594 | |
595 // Use average noise for H band | |
596 u[0][i] = noiseAvg * static_cast<float>(cos(tmp)); | |
597 u[1][i] = -noiseAvg * static_cast<float>(sin(tmp)); | |
598 } | |
599 u[1][PART_LEN] = 0; | |
600 | |
601 for (i = 0; i < PART_LEN1; i++) { | |
602 // Use average NLP weight for H band | |
603 comfortNoiseHband[0][i] = tmpAvg * u[0][i]; | |
604 comfortNoiseHband[1][i] = tmpAvg * u[1][i]; | |
605 } | |
606 } else { | 579 } else { |
607 memset(comfortNoiseHband, 0, | 580 memset(high_frequency_comfort_noise, 0, |
608 2 * PART_LEN1 * sizeof(comfortNoiseHband[0][0])); | 581 2 * PART_LEN1 * sizeof(high_frequency_comfort_noise[0][0])); |
609 } | 582 } |
610 } | 583 } |
611 | 584 |
612 static void InitLevel(PowerLevel* level) { | 585 static void InitLevel(PowerLevel* level) { |
613 const float kBigFloat = 1E17f; | 586 const float kBigFloat = 1E17f; |
614 level->averagelevel.Reset(); | 587 level->averagelevel.Reset(); |
615 level->framelevel.Reset(); | 588 level->framelevel.Reset(); |
616 level->minlevel = kBigFloat; | 589 level->minlevel = kBigFloat; |
617 } | 590 } |
618 | 591 |
(...skipping 549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1168 // diverged. | 1141 // diverged. |
1169 if (aec->divergeState) { | 1142 if (aec->divergeState) { |
1170 memcpy(efw, dfw, sizeof(efw[0][0]) * 2 * PART_LEN1); | 1143 memcpy(efw, dfw, sizeof(efw[0][0]) * 2 * PART_LEN1); |
1171 } | 1144 } |
1172 | 1145 |
1173 FormSuppressionGain(aec, cohde, cohxd, hNl); | 1146 FormSuppressionGain(aec, cohde, cohxd, hNl); |
1174 | 1147 |
1175 WebRtcAec_Suppress(hNl, efw); | 1148 WebRtcAec_Suppress(hNl, efw); |
1176 | 1149 |
1177 // Add comfort noise. | 1150 // Add comfort noise. |
1178 ComfortNoise(aec, efw, comfortNoiseHband, aec->noisePow, hNl); | 1151 ComfortNoise(aec->num_bands > 1, &aec->seed, efw, comfortNoiseHband, |
| 1152 aec->noisePow, hNl); |
1179 | 1153 |
1180 // Inverse error fft. | 1154 // Inverse error fft. |
1181 ScaledInverseFft(efw, fft, 2.0f, 1); | 1155 ScaledInverseFft(efw, fft, 2.0f, 1); |
1182 | 1156 |
1183 // Overlap and add to obtain output. | 1157 // Overlap and add to obtain output. |
1184 for (i = 0; i < PART_LEN; i++) { | 1158 for (i = 0; i < PART_LEN; i++) { |
1185 output[i] = (fft[i] * WebRtcAec_sqrtHanning[i] + | 1159 output[i] = (fft[i] * WebRtcAec_sqrtHanning[i] + |
1186 aec->outBuf[i] * WebRtcAec_sqrtHanning[PART_LEN - i]); | 1160 aec->outBuf[i] * WebRtcAec_sqrtHanning[PART_LEN - i]); |
1187 | 1161 |
1188 // Saturate output to keep it in the allowed range. | 1162 // Saturate output to keep it in the allowed range. |
(...skipping 778 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1967 | 1941 |
1968 int WebRtcAec_system_delay(AecCore* self) { | 1942 int WebRtcAec_system_delay(AecCore* self) { |
1969 return self->system_delay; | 1943 return self->system_delay; |
1970 } | 1944 } |
1971 | 1945 |
1972 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { | 1946 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { |
1973 assert(delay >= 0); | 1947 assert(delay >= 0); |
1974 self->system_delay = delay; | 1948 self->system_delay = delay; |
1975 } | 1949 } |
1976 } // namespace webrtc | 1950 } // namespace webrtc |
OLD | NEW |