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 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 434 | 434 |
| 435 *nlpGainHband = (float)0.0; | 435 *nlpGainHband = (float)0.0; |
| 436 for (i = freqAvgIc; i < PART_LEN1 - 1; i++) { | 436 for (i = freqAvgIc; i < PART_LEN1 - 1; i++) { |
| 437 *nlpGainHband += lambda[i]; | 437 *nlpGainHband += lambda[i]; |
| 438 } | 438 } |
| 439 *nlpGainHband /= (float)(PART_LEN1 - 1 - freqAvgIc); | 439 *nlpGainHband /= (float)(PART_LEN1 - 1 - freqAvgIc); |
| 440 } | 440 } |
| 441 | 441 |
| 442 static void ComfortNoise(AecCore* aec, | 442 static void ComfortNoise(AecCore* aec, |
| 443 float efw[2][PART_LEN1], | 443 float efw[2][PART_LEN1], |
| 444 complex_t* comfortNoiseHband, | 444 float comfortNoiseHband[2][PART_LEN1], |
| 445 const float* noisePow, | 445 const float* noisePow, |
| 446 const float* lambda) { | 446 const float* lambda) { |
| 447 int i, num; | 447 int i, num; |
| 448 float rand[PART_LEN]; | 448 float rand[PART_LEN]; |
| 449 float noise, noiseAvg, tmp, tmpAvg; | 449 float noise, noiseAvg, tmp, tmpAvg; |
| 450 int16_t randW16[PART_LEN]; | 450 int16_t randW16[PART_LEN]; |
| 451 complex_t u[PART_LEN1]; | 451 float u[2][PART_LEN1]; |
| 452 | 452 |
| 453 const float pi2 = 6.28318530717959f; | 453 const float pi2 = 6.28318530717959f; |
| 454 | 454 |
| 455 // Generate a uniform random array on [0 1] | 455 // Generate a uniform random array on [0 1] |
| 456 WebRtcSpl_RandUArray(randW16, PART_LEN, &aec->seed); | 456 WebRtcSpl_RandUArray(randW16, PART_LEN, &aec->seed); |
| 457 for (i = 0; i < PART_LEN; i++) { | 457 for (i = 0; i < PART_LEN; i++) { |
| 458 rand[i] = ((float)randW16[i]) / 32768; | 458 rand[i] = ((float)randW16[i]) / 32768; |
| 459 } | 459 } |
| 460 | 460 |
| 461 // Reject LF noise | 461 // Reject LF noise |
| 462 u[0][0] = 0; | 462 u[0][0] = 0; |
| 463 u[0][1] = 0; | 463 u[1][0] = 0; |
| 464 for (i = 1; i < PART_LEN1; i++) { | 464 for (i = 1; i < PART_LEN1; i++) { |
| 465 tmp = pi2 * rand[i - 1]; | 465 tmp = pi2 * rand[i - 1]; |
| 466 | 466 |
| 467 noise = sqrtf(noisePow[i]); | 467 noise = sqrtf(noisePow[i]); |
| 468 u[i][0] = noise * cosf(tmp); | 468 u[0][i] = noise * cosf(tmp); |
| 469 u[i][1] = -noise * sinf(tmp); | 469 u[1][i] = -noise * sinf(tmp); |
| 470 } | 470 } |
| 471 u[PART_LEN][1] = 0; | 471 u[1][PART_LEN] = 0; |
| 472 | 472 |
| 473 for (i = 0; i < PART_LEN1; i++) { | 473 for (i = 0; i < PART_LEN1; i++) { |
| 474 // This is the proper weighting to match the background noise power | 474 // This is the proper weighting to match the background noise power |
| 475 tmp = sqrtf(WEBRTC_SPL_MAX(1 - lambda[i] * lambda[i], 0)); | 475 tmp = sqrtf(WEBRTC_SPL_MAX(1 - lambda[i] * lambda[i], 0)); |
| 476 // tmp = 1 - lambda[i]; | 476 // tmp = 1 - lambda[i]; |
| 477 efw[0][i] += tmp * u[i][0]; | 477 efw[0][i] += tmp * u[0][i]; |
| 478 efw[1][i] += tmp * u[i][1]; | 478 efw[1][i] += tmp * u[1][i]; |
| 479 } | 479 } |
| 480 | 480 |
| 481 // For H band comfort noise | 481 // For H band comfort noise |
| 482 // TODO: don't compute noise and "tmp" twice. Use the previous results. | 482 // TODO: don't compute noise and "tmp" twice. Use the previous results. |
| 483 noiseAvg = 0.0; | 483 noiseAvg = 0.0; |
| 484 tmpAvg = 0.0; | 484 tmpAvg = 0.0; |
| 485 num = 0; | 485 num = 0; |
| 486 if (aec->num_bands > 1 && flagHbandCn == 1) { | 486 if (aec->num_bands > 1 && flagHbandCn == 1) { |
| 487 | 487 |
| 488 // average noise scale | 488 // average noise scale |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 501 for (i = PART_LEN1 >> 1; i < PART_LEN1; i++) { | 501 for (i = PART_LEN1 >> 1; i < PART_LEN1; i++) { |
| 502 num++; | 502 num++; |
| 503 tmpAvg += sqrtf(WEBRTC_SPL_MAX(1 - lambda[i] * lambda[i], 0)); | 503 tmpAvg += sqrtf(WEBRTC_SPL_MAX(1 - lambda[i] * lambda[i], 0)); |
| 504 } | 504 } |
| 505 tmpAvg /= (float)num; | 505 tmpAvg /= (float)num; |
| 506 | 506 |
| 507 // Use average noise for H band | 507 // Use average noise for H band |
| 508 // TODO: we should probably have a new random vector here. | 508 // TODO: we should probably have a new random vector here. |
| 509 // Reject LF noise | 509 // Reject LF noise |
| 510 u[0][0] = 0; | 510 u[0][0] = 0; |
| 511 u[0][1] = 0; | 511 u[1][0] = 0; |
| 512 for (i = 1; i < PART_LEN1; i++) { | 512 for (i = 1; i < PART_LEN1; i++) { |
| 513 tmp = pi2 * rand[i - 1]; | 513 tmp = pi2 * rand[i - 1]; |
| 514 | 514 |
| 515 // Use average noise for H band | 515 // Use average noise for H band |
| 516 u[i][0] = noiseAvg * (float)cos(tmp); | 516 u[0][i] = noiseAvg * (float)cos(tmp); |
| 517 u[i][1] = -noiseAvg * (float)sin(tmp); | 517 u[1][i] = -noiseAvg * (float)sin(tmp); |
| 518 } | 518 } |
| 519 u[PART_LEN][1] = 0; | 519 u[1][PART_LEN] = 0; |
| 520 | 520 |
| 521 for (i = 0; i < PART_LEN1; i++) { | 521 for (i = 0; i < PART_LEN1; i++) { |
| 522 // Use average NLP weight for H band | 522 // Use average NLP weight for H band |
| 523 comfortNoiseHband[i][0] = tmpAvg * u[i][0]; | 523 comfortNoiseHband[0][i] = tmpAvg * u[0][i]; |
| 524 comfortNoiseHband[i][1] = tmpAvg * u[i][1]; | 524 comfortNoiseHband[1][i] = tmpAvg * u[1][i]; |
| 525 } | 525 } |
| 526 } | 526 } |
| 527 else { | |
|
minyue-webrtc
2015/12/04 09:49:43
move 527 to 526
peah-webrtc
2015/12/04 23:02:48
Done.
| |
| 528 memset(comfortNoiseHband, 0, | |
| 529 2 * PART_LEN1 * sizeof(comfortNoiseHband[0][0])); | |
|
minyue-webrtc
2015/12/04 09:49:44
I prefer use sizeof(comfortNoiseHband), since it i
peah-webrtc
2015/12/04 23:02:48
Me too, but it does not work for multidimensional
minyue-webrtc
2015/12/08 12:33:01
Acknowledged.
| |
| 530 } | |
| 527 } | 531 } |
| 528 | 532 |
| 529 static void InitLevel(PowerLevel* level) { | 533 static void InitLevel(PowerLevel* level) { |
| 530 const float kBigFloat = 1E17f; | 534 const float kBigFloat = 1E17f; |
| 531 | 535 |
| 532 level->averagelevel = 0; | 536 level->averagelevel = 0; |
| 533 level->framelevel = 0; | 537 level->framelevel = 0; |
| 534 level->minlevel = kBigFloat; | 538 level->minlevel = kBigFloat; |
| 535 level->frsum = 0; | 539 level->frsum = 0; |
| 536 level->sfrsum = 0; | 540 level->sfrsum = 0; |
| (...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1003 } | 1007 } |
| 1004 | 1008 |
| 1005 | 1009 |
| 1006 static void EchoSuppression(AecCore* aec, | 1010 static void EchoSuppression(AecCore* aec, |
| 1007 float* echo_subtractor_output, | 1011 float* echo_subtractor_output, |
| 1008 float* output, | 1012 float* output, |
| 1009 float* const* outputH) { | 1013 float* const* outputH) { |
| 1010 float efw[2][PART_LEN1]; | 1014 float efw[2][PART_LEN1]; |
| 1011 float xfw[2][PART_LEN1]; | 1015 float xfw[2][PART_LEN1]; |
| 1012 float dfw[2][PART_LEN1]; | 1016 float dfw[2][PART_LEN1]; |
| 1013 complex_t comfortNoiseHband[PART_LEN1]; | 1017 float comfortNoiseHband[2][PART_LEN1]; |
| 1014 float fft[PART_LEN2]; | 1018 float fft[PART_LEN2]; |
| 1015 float scale, dtmp; | 1019 float scale, dtmp; |
| 1016 float nlpGainHband; | 1020 float nlpGainHband; |
| 1017 int i; | 1021 int i; |
| 1018 size_t j; | 1022 size_t j; |
| 1019 | 1023 |
| 1020 // Coherence and non-linear filter | 1024 // Coherence and non-linear filter |
| 1021 float cohde[PART_LEN1], cohxd[PART_LEN1]; | 1025 float cohde[PART_LEN1], cohxd[PART_LEN1]; |
| 1022 float hNlDeAvg, hNlXdAvg; | 1026 float hNlDeAvg, hNlXdAvg; |
| 1023 float hNl[PART_LEN1]; | 1027 float hNl[PART_LEN1]; |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1172 // Smooth the overdrive. | 1176 // Smooth the overdrive. |
| 1173 if (aec->overDrive < aec->overDriveSm) { | 1177 if (aec->overDrive < aec->overDriveSm) { |
| 1174 aec->overDriveSm = 0.99f * aec->overDriveSm + 0.01f * aec->overDrive; | 1178 aec->overDriveSm = 0.99f * aec->overDriveSm + 0.01f * aec->overDrive; |
| 1175 } else { | 1179 } else { |
| 1176 aec->overDriveSm = 0.9f * aec->overDriveSm + 0.1f * aec->overDrive; | 1180 aec->overDriveSm = 0.9f * aec->overDriveSm + 0.1f * aec->overDrive; |
| 1177 } | 1181 } |
| 1178 | 1182 |
| 1179 WebRtcAec_OverdriveAndSuppress(aec, hNl, hNlFb, efw); | 1183 WebRtcAec_OverdriveAndSuppress(aec, hNl, hNlFb, efw); |
| 1180 | 1184 |
| 1181 // Add comfort noise. | 1185 // Add comfort noise. |
| 1182 memset(comfortNoiseHband, 0, sizeof(comfortNoiseHband)); | |
| 1183 WebRtcAec_ComfortNoise(aec, efw, comfortNoiseHband, aec->noisePow, hNl); | 1186 WebRtcAec_ComfortNoise(aec, efw, comfortNoiseHband, aec->noisePow, hNl); |
| 1184 | 1187 |
| 1185 // TODO(bjornv): Investigate how to take the windowing below into account if | 1188 // TODO(bjornv): Investigate how to take the windowing below into account if |
| 1186 // needed. | 1189 // needed. |
| 1187 if (aec->metricsMode == 1) { | 1190 if (aec->metricsMode == 1) { |
| 1188 // Note that we have a scaling by two in the time domain |eBuf|. | 1191 // Note that we have a scaling by two in the time domain |eBuf|. |
| 1189 // In addition the time domain signal is windowed before transformation, | 1192 // In addition the time domain signal is windowed before transformation, |
| 1190 // losing half the energy on the average. We take care of the first | 1193 // losing half the energy on the average. We take care of the first |
| 1191 // scaling only in UpdateMetrics(). | 1194 // scaling only in UpdateMetrics(). |
| 1192 UpdateLevel(&aec->nlpoutlevel, efw); | 1195 UpdateLevel(&aec->nlpoutlevel, efw); |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 1219 if (aec->num_bands > 1) { | 1222 if (aec->num_bands > 1) { |
| 1220 | 1223 |
| 1221 // H band gain | 1224 // H band gain |
| 1222 // average nlp over low band: average over second half of freq spectrum | 1225 // average nlp over low band: average over second half of freq spectrum |
| 1223 // (4->8khz) | 1226 // (4->8khz) |
| 1224 GetHighbandGain(hNl, &nlpGainHband); | 1227 GetHighbandGain(hNl, &nlpGainHband); |
| 1225 | 1228 |
| 1226 // Inverse comfort_noise | 1229 // Inverse comfort_noise |
| 1227 if (flagHbandCn == 1) { | 1230 if (flagHbandCn == 1) { |
| 1228 fft[0] = comfortNoiseHband[0][0]; | 1231 fft[0] = comfortNoiseHband[0][0]; |
| 1229 fft[1] = comfortNoiseHband[PART_LEN][0]; | 1232 fft[1] = comfortNoiseHband[0][PART_LEN]; |
| 1230 for (i = 1; i < PART_LEN; i++) { | 1233 for (i = 1; i < PART_LEN; i++) { |
| 1231 fft[2 * i] = comfortNoiseHband[i][0]; | 1234 fft[2 * i] = comfortNoiseHband[0][i]; |
| 1232 fft[2 * i + 1] = comfortNoiseHband[i][1]; | 1235 fft[2 * i + 1] = comfortNoiseHband[1][i]; |
| 1233 } | 1236 } |
| 1234 aec_rdft_inverse_128(fft); | 1237 aec_rdft_inverse_128(fft); |
| 1235 scale = 2.0f / PART_LEN2; | 1238 scale = 2.0f / PART_LEN2; |
| 1236 } | 1239 } |
| 1237 | 1240 |
| 1238 // compute gain factor | 1241 // compute gain factor |
| 1239 for (j = 0; j < aec->num_bands - 1; ++j) { | 1242 for (j = 0; j < aec->num_bands - 1; ++j) { |
| 1240 for (i = 0; i < PART_LEN; i++) { | 1243 for (i = 0; i < PART_LEN; i++) { |
| 1241 dtmp = aec->dBufH[j][i]; | 1244 dtmp = aec->dBufH[j][i]; |
| 1242 dtmp = dtmp * nlpGainHband; // for variable gain | 1245 dtmp = dtmp * nlpGainHband; // for variable gain |
| (...skipping 739 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1982 int WebRtcAec_extended_filter_enabled(AecCore* self) { | 1985 int WebRtcAec_extended_filter_enabled(AecCore* self) { |
| 1983 return self->extended_filter_enabled; | 1986 return self->extended_filter_enabled; |
| 1984 } | 1987 } |
| 1985 | 1988 |
| 1986 int WebRtcAec_system_delay(AecCore* self) { return self->system_delay; } | 1989 int WebRtcAec_system_delay(AecCore* self) { return self->system_delay; } |
| 1987 | 1990 |
| 1988 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { | 1991 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { |
| 1989 assert(delay >= 0); | 1992 assert(delay >= 0); |
| 1990 self->system_delay = delay; | 1993 self->system_delay = delay; |
| 1991 } | 1994 } |
| OLD | NEW |