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 499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
510 static void GetHighbandGain(const float* lambda, float* nlpGainHband) { | 510 static void GetHighbandGain(const float* lambda, float* nlpGainHband) { |
511 int i; | 511 int i; |
512 | 512 |
513 *nlpGainHband = 0.0f; | 513 *nlpGainHband = 0.0f; |
514 for (i = freqAvgIc; i < PART_LEN1 - 1; i++) { | 514 for (i = freqAvgIc; i < PART_LEN1 - 1; i++) { |
515 *nlpGainHband += lambda[i]; | 515 *nlpGainHband += lambda[i]; |
516 } | 516 } |
517 *nlpGainHband /= static_cast<float>(PART_LEN1 - 1 - freqAvgIc); | 517 *nlpGainHband /= static_cast<float>(PART_LEN1 - 1 - freqAvgIc); |
518 } | 518 } |
519 | 519 |
520 static void ComfortNoise(AecCore* aec, | 520 static void GenerateComplexNoise(uint32_t* seed, float noise[2][PART_LEN1]) { |
521 float efw[2][PART_LEN1], | 521 const float kPi2 = 6.28318530717959f; |
522 float comfortNoiseHband[2][PART_LEN1], | |
523 const float* noisePow, | |
524 const float* lambda) { | |
525 int i, num; | |
526 float rand[PART_LEN]; | |
527 float noise, noiseAvg, tmp, tmpAvg; | |
528 int16_t randW16[PART_LEN]; | 522 int16_t randW16[PART_LEN]; |
529 float u[2][PART_LEN1]; | 523 WebRtcSpl_RandUArray(randW16, PART_LEN, seed); |
530 | 524 |
531 const float pi2 = 6.28318530717959f; | 525 noise[0][0] = 0; |
526 noise[1][0] = 0; | |
527 for (int i = 1; i < PART_LEN1; i++) { | |
hlundin-webrtc
2016/05/12 11:01:11
I think the correct thing is to have size_t as ind
peah-webrtc
2016/05/13 06:13:27
Done.
| |
528 float tmp = kPi2 * randW16[i - 1] / 32768.f; | |
529 noise[0][i] = cosf(tmp); | |
530 noise[1][i] = -sinf(tmp); | |
531 } | |
532 noise[1][PART_LEN] = 0; | |
533 } | |
532 | 534 |
533 // Generate a uniform random array on [0 1] | 535 static void ComfortNoise(bool generate_high_frequency_noise, |
534 WebRtcSpl_RandUArray(randW16, PART_LEN, &aec->seed); | 536 uint32_t* seed, |
535 for (i = 0; i < PART_LEN; i++) { | 537 float e_fft[2][PART_LEN1], |
536 rand[i] = static_cast<float>(randW16[i]) / 32768; | 538 float high_frequency_comfort_noise[2][PART_LEN1], |
539 const float* noise_spectrum, | |
540 const float* suppressor_gain) { | |
541 float complex_noise[2][PART_LEN1]; | |
542 | |
543 GenerateComplexNoise(seed, complex_noise); | |
544 | |
545 // Shape, scale and add comfort noise. | |
546 for (int i = 1; i < PART_LEN1; ++i) { | |
547 float noise_scaling = | |
548 sqrtf(WEBRTC_SPL_MAX(1 - suppressor_gain[i] * suppressor_gain[i], 0)) * | |
549 sqrtf(noise_spectrum[i]); | |
550 e_fft[0][i] += noise_scaling * complex_noise[0][i]; | |
551 e_fft[1][i] += noise_scaling * complex_noise[1][i]; | |
537 } | 552 } |
538 | 553 |
539 // Reject LF noise | 554 // Form comfort noise for higher frequencies. |
540 u[0][0] = 0; | 555 if (generate_high_frequency_noise) { |
541 u[1][0] = 0; | 556 // Compute average noise power and nlp gain over the second half of freq |
542 for (i = 1; i < PART_LEN1; i++) { | 557 // spectrum (i.e., 4->8khz). |
543 tmp = pi2 * rand[i - 1]; | 558 int start_avg_band = PART_LEN1 >> 1; |
hlundin-webrtc
2016/05/12 11:01:11
Change to /2 while you are at it.
peah-webrtc
2016/05/13 06:13:27
Done.
| |
559 float upper_bands_noise_power = 0.f; | |
560 float upper_bands_suppressor_gain = 0.f; | |
561 for (int i = start_avg_band; i < PART_LEN1; ++i) { | |
562 upper_bands_noise_power += sqrtf(noise_spectrum[i]); | |
563 upper_bands_suppressor_gain += | |
564 sqrtf(WEBRTC_SPL_MAX(1 - suppressor_gain[i] * suppressor_gain[i], 0)); | |
565 } | |
566 upper_bands_noise_power /= (PART_LEN1 - start_avg_band); | |
567 upper_bands_suppressor_gain /= (PART_LEN1 - start_avg_band); | |
544 | 568 |
545 noise = sqrtf(noisePow[i]); | 569 // Shape, scale and add comfort noise. |
546 u[0][i] = noise * cosf(tmp); | 570 float noise_scaling = upper_bands_suppressor_gain * upper_bands_noise_power; |
547 u[1][i] = -noise * sinf(tmp); | 571 high_frequency_comfort_noise[0][0] = 0; |
548 } | 572 high_frequency_comfort_noise[1][0] = 0; |
549 u[1][PART_LEN] = 0; | 573 for (int i = 1; i < PART_LEN1; ++i) { |
550 | 574 high_frequency_comfort_noise[0][i] = noise_scaling * complex_noise[0][i]; |
551 for (i = 0; i < PART_LEN1; i++) { | 575 high_frequency_comfort_noise[1][i] = noise_scaling * complex_noise[1][i]; |
552 // This is the proper weighting to match the background noise power | |
553 tmp = sqrtf(WEBRTC_SPL_MAX(1 - lambda[i] * lambda[i], 0)); | |
554 // tmp = 1 - lambda[i]; | |
555 efw[0][i] += tmp * u[0][i]; | |
556 efw[1][i] += tmp * u[1][i]; | |
557 } | |
558 | |
559 // For H band comfort noise | |
560 // TODO(peah): don't compute noise and "tmp" twice. Use the previous results. | |
561 noiseAvg = 0.0; | |
562 tmpAvg = 0.0; | |
563 num = 0; | |
564 if (aec->num_bands > 1) { | |
565 // average noise scale | |
566 // average over second half of freq spectrum (i.e., 4->8khz) | |
567 // TODO(peah): we shouldn't need num. We know how many elements we're | |
568 // summing. | |
569 for (i = PART_LEN1 >> 1; i < PART_LEN1; i++) { | |
570 num++; | |
571 noiseAvg += sqrtf(noisePow[i]); | |
572 } | 576 } |
573 noiseAvg /= static_cast<float>(num); | 577 high_frequency_comfort_noise[1][PART_LEN] = 0; |
574 | |
575 // average nlp scale | |
576 // average over second half of freq spectrum (i.e., 4->8khz) | |
577 // TODO(peah): we shouldn't need num. We know how many elements | |
578 // we're summing. | |
579 num = 0; | |
580 for (i = PART_LEN1 >> 1; i < PART_LEN1; i++) { | |
581 num++; | |
582 tmpAvg += sqrtf(WEBRTC_SPL_MAX(1 - lambda[i] * lambda[i], 0)); | |
583 } | |
584 tmpAvg /= static_cast<float>(num); | |
585 | |
586 // Use average noise for H band | |
587 // TODO(peah): we should probably have a new random vector here. | |
588 // Reject LF noise | |
589 u[0][0] = 0; | |
590 u[1][0] = 0; | |
591 for (i = 1; i < PART_LEN1; i++) { | |
592 tmp = pi2 * rand[i - 1]; | |
593 | |
594 // Use average noise for H band | |
595 u[0][i] = noiseAvg * static_cast<float>(cos(tmp)); | |
596 u[1][i] = -noiseAvg * static_cast<float>(sin(tmp)); | |
597 } | |
598 u[1][PART_LEN] = 0; | |
599 | |
600 for (i = 0; i < PART_LEN1; i++) { | |
601 // Use average NLP weight for H band | |
602 comfortNoiseHband[0][i] = tmpAvg * u[0][i]; | |
603 comfortNoiseHband[1][i] = tmpAvg * u[1][i]; | |
604 } | |
605 } else { | 578 } else { |
606 memset(comfortNoiseHband, 0, | 579 memset(high_frequency_comfort_noise, 0, |
607 2 * PART_LEN1 * sizeof(comfortNoiseHband[0][0])); | 580 2 * PART_LEN1 * sizeof(high_frequency_comfort_noise[0][0])); |
608 } | 581 } |
609 } | 582 } |
610 | 583 |
611 static void InitLevel(PowerLevel* level) { | 584 static void InitLevel(PowerLevel* level) { |
612 const float kBigFloat = 1E17f; | 585 const float kBigFloat = 1E17f; |
613 level->averagelevel.Reset(); | 586 level->averagelevel.Reset(); |
614 level->framelevel.Reset(); | 587 level->framelevel.Reset(); |
615 level->minlevel = kBigFloat; | 588 level->minlevel = kBigFloat; |
616 } | 589 } |
617 | 590 |
(...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1157 0.99f * aec->overdrive_scaling + 0.01f * aec->overDrive; | 1130 0.99f * aec->overdrive_scaling + 0.01f * aec->overDrive; |
1158 } else { | 1131 } else { |
1159 aec->overdrive_scaling = | 1132 aec->overdrive_scaling = |
1160 0.9f * aec->overdrive_scaling + 0.1f * aec->overDrive; | 1133 0.9f * aec->overdrive_scaling + 0.1f * aec->overDrive; |
1161 } | 1134 } |
1162 | 1135 |
1163 WebRtcAec_Overdrive(aec->overdrive_scaling, hNlFb, hNl); | 1136 WebRtcAec_Overdrive(aec->overdrive_scaling, hNlFb, hNl); |
1164 WebRtcAec_Suppress(hNl, efw); | 1137 WebRtcAec_Suppress(hNl, efw); |
1165 | 1138 |
1166 // Add comfort noise. | 1139 // Add comfort noise. |
1167 ComfortNoise(aec, efw, comfortNoiseHband, aec->noisePow, hNl); | 1140 ComfortNoise(aec->num_bands > 1, &aec->seed, efw, comfortNoiseHband, |
1141 aec->noisePow, hNl); | |
1168 | 1142 |
1169 // Inverse error fft. | 1143 // Inverse error fft. |
1170 ScaledInverseFft(efw, fft, 2.0f, 1); | 1144 ScaledInverseFft(efw, fft, 2.0f, 1); |
1171 | 1145 |
1172 // Overlap and add to obtain output. | 1146 // Overlap and add to obtain output. |
1173 for (i = 0; i < PART_LEN; i++) { | 1147 for (i = 0; i < PART_LEN; i++) { |
1174 output[i] = (fft[i] * WebRtcAec_sqrtHanning[i] + | 1148 output[i] = (fft[i] * WebRtcAec_sqrtHanning[i] + |
1175 aec->outBuf[i] * WebRtcAec_sqrtHanning[PART_LEN - i]); | 1149 aec->outBuf[i] * WebRtcAec_sqrtHanning[PART_LEN - i]); |
1176 | 1150 |
1177 // Saturate output to keep it in the allowed range. | 1151 // Saturate output to keep it in the allowed range. |
(...skipping 778 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1956 | 1930 |
1957 int WebRtcAec_system_delay(AecCore* self) { | 1931 int WebRtcAec_system_delay(AecCore* self) { |
1958 return self->system_delay; | 1932 return self->system_delay; |
1959 } | 1933 } |
1960 | 1934 |
1961 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { | 1935 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { |
1962 assert(delay >= 0); | 1936 assert(delay >= 0); |
1963 self->system_delay = delay; | 1937 self->system_delay = delay; |
1964 } | 1938 } |
1965 } // namespace webrtc | 1939 } // namespace webrtc |
OLD | NEW |