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 |
11 #include "webrtc/modules/audio_processing/ns/noise_suppression_x.h" | 11 #include "webrtc/modules/audio_processing/ns/noise_suppression_x.h" |
12 | 12 |
13 #include <assert.h> | |
14 #include <math.h> | 13 #include <math.h> |
15 #include <stdlib.h> | 14 #include <stdlib.h> |
16 #include <string.h> | 15 #include <string.h> |
17 | 16 |
| 17 #include "webrtc/base/checks.h" |
18 #include "webrtc/common_audio/signal_processing/include/real_fft.h" | 18 #include "webrtc/common_audio/signal_processing/include/real_fft.h" |
19 #include "webrtc/modules/audio_processing/ns/nsx_core.h" | 19 #include "webrtc/modules/audio_processing/ns/nsx_core.h" |
20 #include "webrtc/system_wrappers/include/cpu_features_wrapper.h" | 20 #include "webrtc/system_wrappers/include/cpu_features_wrapper.h" |
21 | 21 |
22 #if defined(WEBRTC_HAS_NEON) | 22 #if defined(WEBRTC_HAS_NEON) |
23 /* Tables are defined in ARM assembly files. */ | 23 /* Tables are defined in ARM assembly files. */ |
24 extern const int16_t WebRtcNsx_kLogTable[9]; | 24 extern const int16_t WebRtcNsx_kLogTable[9]; |
25 extern const int16_t WebRtcNsx_kCounterDiv[201]; | 25 extern const int16_t WebRtcNsx_kCounterDiv[201]; |
26 extern const int16_t WebRtcNsx_kLogTableFrac[256]; | 26 extern const int16_t WebRtcNsx_kLogTableFrac[256]; |
27 #else | 27 #else |
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
337 int16_t* q_noise) { | 337 int16_t* q_noise) { |
338 int16_t lmagn[HALF_ANAL_BLOCKL], counter, countDiv; | 338 int16_t lmagn[HALF_ANAL_BLOCKL], counter, countDiv; |
339 int16_t countProd, delta, zeros, frac; | 339 int16_t countProd, delta, zeros, frac; |
340 int16_t log2, tabind, logval, tmp16, tmp16no1, tmp16no2; | 340 int16_t log2, tabind, logval, tmp16, tmp16no1, tmp16no2; |
341 const int16_t log2_const = 22713; // Q15 | 341 const int16_t log2_const = 22713; // Q15 |
342 const int16_t width_factor = 21845; | 342 const int16_t width_factor = 21845; |
343 | 343 |
344 size_t i, s, offset; | 344 size_t i, s, offset; |
345 | 345 |
346 tabind = inst->stages - inst->normData; | 346 tabind = inst->stages - inst->normData; |
347 assert(tabind < 9); | 347 RTC_DCHECK_LT(tabind, 9); |
348 assert(tabind > -9); | 348 RTC_DCHECK_GT(tabind, -9); |
349 if (tabind < 0) { | 349 if (tabind < 0) { |
350 logval = -WebRtcNsx_kLogTable[-tabind]; | 350 logval = -WebRtcNsx_kLogTable[-tabind]; |
351 } else { | 351 } else { |
352 logval = WebRtcNsx_kLogTable[tabind]; | 352 logval = WebRtcNsx_kLogTable[tabind]; |
353 } | 353 } |
354 | 354 |
355 // lmagn(i)=log(magn(i))=log(2)*log2(magn(i)) | 355 // lmagn(i)=log(magn(i))=log(2)*log2(magn(i)) |
356 // magn is in Q(-stages), and the real lmagn values are: | 356 // magn is in Q(-stages), and the real lmagn values are: |
357 // real_lmagn(i)=log(magn(i)*2^stages)=log(magn(i))+log(2^stages) | 357 // real_lmagn(i)=log(magn(i)*2^stages)=log(magn(i))+log(2^stages) |
358 // lmagn in Q8 | 358 // lmagn in Q8 |
359 for (i = 0; i < inst->magnLen; i++) { | 359 for (i = 0; i < inst->magnLen; i++) { |
360 if (magn[i]) { | 360 if (magn[i]) { |
361 zeros = WebRtcSpl_NormU32((uint32_t)magn[i]); | 361 zeros = WebRtcSpl_NormU32((uint32_t)magn[i]); |
362 frac = (int16_t)((((uint32_t)magn[i] << zeros) | 362 frac = (int16_t)((((uint32_t)magn[i] << zeros) |
363 & 0x7FFFFFFF) >> 23); | 363 & 0x7FFFFFFF) >> 23); |
364 // log2(magn(i)) | 364 // log2(magn(i)) |
365 assert(frac < 256); | 365 RTC_DCHECK_LT(frac, 256); |
366 log2 = (int16_t)(((31 - zeros) << 8) | 366 log2 = (int16_t)(((31 - zeros) << 8) |
367 + WebRtcNsx_kLogTableFrac[frac]); | 367 + WebRtcNsx_kLogTableFrac[frac]); |
368 // log2(magn(i))*log(2) | 368 // log2(magn(i))*log(2) |
369 lmagn[i] = (int16_t)((log2 * log2_const) >> 15); | 369 lmagn[i] = (int16_t)((log2 * log2_const) >> 15); |
370 // + log(2^stages) | 370 // + log(2^stages) |
371 lmagn[i] += logval; | 371 lmagn[i] += logval; |
372 } else { | 372 } else { |
373 lmagn[i] = logval;//0; | 373 lmagn[i] = logval;//0; |
374 } | 374 } |
375 } | 375 } |
376 | 376 |
377 // loop over simultaneous estimates | 377 // loop over simultaneous estimates |
378 for (s = 0; s < SIMULT; s++) { | 378 for (s = 0; s < SIMULT; s++) { |
379 offset = s * inst->magnLen; | 379 offset = s * inst->magnLen; |
380 | 380 |
381 // Get counter values from state | 381 // Get counter values from state |
382 counter = inst->noiseEstCounter[s]; | 382 counter = inst->noiseEstCounter[s]; |
383 assert(counter < 201); | 383 RTC_DCHECK_LT(counter, 201); |
384 countDiv = WebRtcNsx_kCounterDiv[counter]; | 384 countDiv = WebRtcNsx_kCounterDiv[counter]; |
385 countProd = (int16_t)(counter * countDiv); | 385 countProd = (int16_t)(counter * countDiv); |
386 | 386 |
387 // quant_est(...) | 387 // quant_est(...) |
388 for (i = 0; i < inst->magnLen; i++) { | 388 for (i = 0; i < inst->magnLen; i++) { |
389 // compute delta | 389 // compute delta |
390 if (inst->noiseEstDensity[offset + i] > 512) { | 390 if (inst->noiseEstDensity[offset + i] > 512) { |
391 // Get the value for delta by shifting intead of dividing. | 391 // Get the value for delta by shifting intead of dividing. |
392 int factor = WebRtcSpl_NormW16(inst->noiseEstDensity[offset + i]); | 392 int factor = WebRtcSpl_NormW16(inst->noiseEstDensity[offset + i]); |
393 delta = (int16_t)(FACTOR_Q16 >> (14 - factor)); | 393 delta = (int16_t)(FACTOR_Q16 >> (14 - factor)); |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
536 out[i] = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND( | 536 out[i] = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND( |
537 inst->window[i], inst->analysisBuffer[i], 14); // Q0 | 537 inst->window[i], inst->analysisBuffer[i], 14); // Q0 |
538 } | 538 } |
539 } | 539 } |
540 | 540 |
541 // Normalize the real-valued signal |in|, the input to forward FFT. | 541 // Normalize the real-valued signal |in|, the input to forward FFT. |
542 static void NormalizeRealBufferC(NoiseSuppressionFixedC* inst, | 542 static void NormalizeRealBufferC(NoiseSuppressionFixedC* inst, |
543 const int16_t* in, | 543 const int16_t* in, |
544 int16_t* out) { | 544 int16_t* out) { |
545 size_t i = 0; | 545 size_t i = 0; |
546 assert(inst->normData >= 0); | 546 RTC_DCHECK_GE(inst->normData, 0); |
547 for (i = 0; i < inst->anaLen; ++i) { | 547 for (i = 0; i < inst->anaLen; ++i) { |
548 out[i] = in[i] << inst->normData; // Q(normData) | 548 out[i] = in[i] << inst->normData; // Q(normData) |
549 } | 549 } |
550 } | 550 } |
551 | 551 |
552 // Declare function pointers. | 552 // Declare function pointers. |
553 NoiseEstimation WebRtcNsx_NoiseEstimation; | 553 NoiseEstimation WebRtcNsx_NoiseEstimation; |
554 PrepareSpectrum WebRtcNsx_PrepareSpectrum; | 554 PrepareSpectrum WebRtcNsx_PrepareSpectrum; |
555 SynthesisUpdate WebRtcNsx_SynthesisUpdate; | 555 SynthesisUpdate WebRtcNsx_SynthesisUpdate; |
556 AnalysisUpdate WebRtcNsx_AnalysisUpdate; | 556 AnalysisUpdate WebRtcNsx_AnalysisUpdate; |
(...skipping 30 matching lines...) Expand all Loading... |
587 uint32_t* noise_estimate, | 587 uint32_t* noise_estimate, |
588 uint32_t* noise_estimate_avg) { | 588 uint32_t* noise_estimate_avg) { |
589 int32_t tmp32no1 = 0; | 589 int32_t tmp32no1 = 0; |
590 int32_t tmp32no2 = 0; | 590 int32_t tmp32no2 = 0; |
591 | 591 |
592 int16_t int_part = 0; | 592 int16_t int_part = 0; |
593 int16_t frac_part = 0; | 593 int16_t frac_part = 0; |
594 | 594 |
595 // Use pink noise estimate | 595 // Use pink noise estimate |
596 // noise_estimate = 2^(pinkNoiseNumerator + pinkNoiseExp * log2(j)) | 596 // noise_estimate = 2^(pinkNoiseNumerator + pinkNoiseExp * log2(j)) |
597 assert(freq_index >= 0); | 597 RTC_DCHECK_GE(freq_index, 0); |
598 assert(freq_index < 129); | 598 RTC_DCHECK_LT(freq_index, 129); |
599 tmp32no2 = (pink_noise_exp_avg * kLogIndex[freq_index]) >> 15; // Q11 | 599 tmp32no2 = (pink_noise_exp_avg * kLogIndex[freq_index]) >> 15; // Q11 |
600 tmp32no1 = pink_noise_num_avg - tmp32no2; // Q11 | 600 tmp32no1 = pink_noise_num_avg - tmp32no2; // Q11 |
601 | 601 |
602 // Calculate output: 2^tmp32no1 | 602 // Calculate output: 2^tmp32no1 |
603 // Output in Q(minNorm-stages) | 603 // Output in Q(minNorm-stages) |
604 tmp32no1 += (inst->minNorm - inst->stages) << 11; | 604 tmp32no1 += (inst->minNorm - inst->stages) << 11; |
605 if (tmp32no1 > 0) { | 605 if (tmp32no1 > 0) { |
606 int_part = (int16_t)(tmp32no1 >> 11); | 606 int_part = (int16_t)(tmp32no1 >> 11); |
607 frac_part = (int16_t)(tmp32no1 & 0x000007ff); // Q11 | 607 frac_part = (int16_t)(tmp32no1 & 0x000007ff); // Q11 |
608 // Piecewise linear approximation of 'b' in | 608 // Piecewise linear approximation of 'b' in |
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1031 // flatness = exp( sum(log(magn[i]))/N - log(sum(magn[i])/N) ) | 1031 // flatness = exp( sum(log(magn[i]))/N - log(sum(magn[i])/N) ) |
1032 // = exp( sum(log(magn[i]))/N ) * N / sum(magn[i]) | 1032 // = exp( sum(log(magn[i]))/N ) * N / sum(magn[i]) |
1033 // = 2^( sum(log2(magn[i]))/N - (log2(sum(magn[i])) - log2(N)) ) [Thi
s is used] | 1033 // = 2^( sum(log2(magn[i]))/N - (log2(sum(magn[i])) - log2(N)) ) [Thi
s is used] |
1034 for (i = 1; i < inst->magnLen; i++) { | 1034 for (i = 1; i < inst->magnLen; i++) { |
1035 // First bin is excluded from spectrum measures. Number of bins is now a pow
er of 2 | 1035 // First bin is excluded from spectrum measures. Number of bins is now a pow
er of 2 |
1036 if (magn[i]) { | 1036 if (magn[i]) { |
1037 zeros = WebRtcSpl_NormU32((uint32_t)magn[i]); | 1037 zeros = WebRtcSpl_NormU32((uint32_t)magn[i]); |
1038 frac = (int16_t)(((uint32_t)((uint32_t)(magn[i]) << zeros) | 1038 frac = (int16_t)(((uint32_t)((uint32_t)(magn[i]) << zeros) |
1039 & 0x7FFFFFFF) >> 23); | 1039 & 0x7FFFFFFF) >> 23); |
1040 // log2(magn(i)) | 1040 // log2(magn(i)) |
1041 assert(frac < 256); | 1041 RTC_DCHECK_LT(frac, 256); |
1042 tmpU32 = (uint32_t)(((31 - zeros) << 8) | 1042 tmpU32 = (uint32_t)(((31 - zeros) << 8) |
1043 + WebRtcNsx_kLogTableFrac[frac]); // Q8 | 1043 + WebRtcNsx_kLogTableFrac[frac]); // Q8 |
1044 avgSpectralFlatnessNum += tmpU32; // Q8 | 1044 avgSpectralFlatnessNum += tmpU32; // Q8 |
1045 } else { | 1045 } else { |
1046 //if at least one frequency component is zero, treat separately | 1046 //if at least one frequency component is zero, treat separately |
1047 tmpU32 = WEBRTC_SPL_UMUL_32_16(inst->featureSpecFlat, SPECT_FLAT_TAVG_Q14)
; // Q24 | 1047 tmpU32 = WEBRTC_SPL_UMUL_32_16(inst->featureSpecFlat, SPECT_FLAT_TAVG_Q14)
; // Q24 |
1048 inst->featureSpecFlat -= tmpU32 >> 14; // Q10 | 1048 inst->featureSpecFlat -= tmpU32 >> 14; // Q10 |
1049 return; | 1049 return; |
1050 } | 1050 } |
1051 } | 1051 } |
1052 //ratio and inverse log: check for case of log(0) | 1052 //ratio and inverse log: check for case of log(0) |
1053 zeros = WebRtcSpl_NormU32(avgSpectralFlatnessDen); | 1053 zeros = WebRtcSpl_NormU32(avgSpectralFlatnessDen); |
1054 frac = (int16_t)(((avgSpectralFlatnessDen << zeros) & 0x7FFFFFFF) >> 23); | 1054 frac = (int16_t)(((avgSpectralFlatnessDen << zeros) & 0x7FFFFFFF) >> 23); |
1055 // log2(avgSpectralFlatnessDen) | 1055 // log2(avgSpectralFlatnessDen) |
1056 assert(frac < 256); | 1056 RTC_DCHECK_LT(frac, 256); |
1057 tmp32 = (int32_t)(((31 - zeros) << 8) + WebRtcNsx_kLogTableFrac[frac]); // Q8 | 1057 tmp32 = (int32_t)(((31 - zeros) << 8) + WebRtcNsx_kLogTableFrac[frac]); // Q8 |
1058 logCurSpectralFlatness = (int32_t)avgSpectralFlatnessNum; | 1058 logCurSpectralFlatness = (int32_t)avgSpectralFlatnessNum; |
1059 logCurSpectralFlatness += ((int32_t)(inst->stages - 1) << (inst->stages + 7));
// Q(8+stages-1) | 1059 logCurSpectralFlatness += ((int32_t)(inst->stages - 1) << (inst->stages + 7));
// Q(8+stages-1) |
1060 logCurSpectralFlatness -= (tmp32 << (inst->stages - 1)); | 1060 logCurSpectralFlatness -= (tmp32 << (inst->stages - 1)); |
1061 logCurSpectralFlatness <<= (10 - inst->stages); // Q17 | 1061 logCurSpectralFlatness <<= (10 - inst->stages); // Q17 |
1062 tmp32 = (int32_t)(0x00020000 | (WEBRTC_SPL_ABS_W32(logCurSpectralFlatness) | 1062 tmp32 = (int32_t)(0x00020000 | (WEBRTC_SPL_ABS_W32(logCurSpectralFlatness) |
1063 & 0x0001FFFF)); //Q17 | 1063 & 0x0001FFFF)); //Q17 |
1064 intPart = 7 - (logCurSpectralFlatness >> 17); // Add 7 for output in Q10. | 1064 intPart = 7 - (logCurSpectralFlatness >> 17); // Add 7 for output in Q10. |
1065 if (intPart > 0) { | 1065 if (intPart > 0) { |
1066 currentSpectralFlatness = tmp32 >> intPart; | 1066 currentSpectralFlatness = tmp32 >> intPart; |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1279 inst->initMagnEst[inst->anaLen2] += | 1279 inst->initMagnEst[inst->anaLen2] += |
1280 magnU16[inst->anaLen2] >> right_shifts_in_magnU16; | 1280 magnU16[inst->anaLen2] >> right_shifts_in_magnU16; |
1281 | 1281 |
1282 log2 = 0; | 1282 log2 = 0; |
1283 if (magnU16[inst->anaLen2]) { | 1283 if (magnU16[inst->anaLen2]) { |
1284 // Calculate log2(magnU16[inst->anaLen2]) | 1284 // Calculate log2(magnU16[inst->anaLen2]) |
1285 zeros = WebRtcSpl_NormU32((uint32_t)magnU16[inst->anaLen2]); | 1285 zeros = WebRtcSpl_NormU32((uint32_t)magnU16[inst->anaLen2]); |
1286 frac = (int16_t)((((uint32_t)magnU16[inst->anaLen2] << zeros) & | 1286 frac = (int16_t)((((uint32_t)magnU16[inst->anaLen2] << zeros) & |
1287 0x7FFFFFFF) >> 23); // Q8 | 1287 0x7FFFFFFF) >> 23); // Q8 |
1288 // log2(magnU16(i)) in Q8 | 1288 // log2(magnU16(i)) in Q8 |
1289 assert(frac < 256); | 1289 RTC_DCHECK_LT(frac, 256); |
1290 log2 = (int16_t)(((31 - zeros) << 8) + WebRtcNsx_kLogTableFrac[frac]); | 1290 log2 = (int16_t)(((31 - zeros) << 8) + WebRtcNsx_kLogTableFrac[frac]); |
1291 } | 1291 } |
1292 | 1292 |
1293 sum_log_magn = (int32_t)log2; // Q8 | 1293 sum_log_magn = (int32_t)log2; // Q8 |
1294 // sum_log_i_log_magn in Q17 | 1294 // sum_log_i_log_magn in Q17 |
1295 sum_log_i_log_magn = (kLogIndex[inst->anaLen2] * log2) >> 3; | 1295 sum_log_i_log_magn = (kLogIndex[inst->anaLen2] * log2) >> 3; |
1296 | 1296 |
1297 for (i = 1, j = 2; i < inst->anaLen2; i += 1, j += 2) { | 1297 for (i = 1, j = 2; i < inst->anaLen2; i += 1, j += 2) { |
1298 inst->real[i] = winData[j]; | 1298 inst->real[i] = winData[j]; |
1299 inst->imag[i] = -winData[j + 1]; | 1299 inst->imag[i] = -winData[j + 1]; |
(...skipping 13 matching lines...) Expand all Loading... |
1313 inst->initMagnEst[i] += magnU16[i] >> right_shifts_in_magnU16; | 1313 inst->initMagnEst[i] += magnU16[i] >> right_shifts_in_magnU16; |
1314 | 1314 |
1315 if (i >= kStartBand) { | 1315 if (i >= kStartBand) { |
1316 // For pink noise estimation. Collect data neglecting lower frequency ba
nd | 1316 // For pink noise estimation. Collect data neglecting lower frequency ba
nd |
1317 log2 = 0; | 1317 log2 = 0; |
1318 if (magnU16[i]) { | 1318 if (magnU16[i]) { |
1319 zeros = WebRtcSpl_NormU32((uint32_t)magnU16[i]); | 1319 zeros = WebRtcSpl_NormU32((uint32_t)magnU16[i]); |
1320 frac = (int16_t)((((uint32_t)magnU16[i] << zeros) & | 1320 frac = (int16_t)((((uint32_t)magnU16[i] << zeros) & |
1321 0x7FFFFFFF) >> 23); | 1321 0x7FFFFFFF) >> 23); |
1322 // log2(magnU16(i)) in Q8 | 1322 // log2(magnU16(i)) in Q8 |
1323 assert(frac < 256); | 1323 RTC_DCHECK_LT(frac, 256); |
1324 log2 = (int16_t)(((31 - zeros) << 8) | 1324 log2 = (int16_t)(((31 - zeros) << 8) |
1325 + WebRtcNsx_kLogTableFrac[frac]); | 1325 + WebRtcNsx_kLogTableFrac[frac]); |
1326 } | 1326 } |
1327 sum_log_magn += (int32_t)log2; // Q8 | 1327 sum_log_magn += (int32_t)log2; // Q8 |
1328 // sum_log_i_log_magn in Q17 | 1328 // sum_log_i_log_magn in Q17 |
1329 sum_log_i_log_magn += (kLogIndex[i] * log2) >> 3; | 1329 sum_log_i_log_magn += (kLogIndex[i] * log2) >> 3; |
1330 } | 1330 } |
1331 } | 1331 } |
1332 | 1332 |
1333 // | 1333 // |
1334 //compute simplified noise model during startup | 1334 //compute simplified noise model during startup |
1335 // | 1335 // |
1336 | 1336 |
1337 // Estimate White noise | 1337 // Estimate White noise |
1338 | 1338 |
1339 // Switch whiteNoiseLevel to Q(minNorm-stages) | 1339 // Switch whiteNoiseLevel to Q(minNorm-stages) |
1340 inst->whiteNoiseLevel >>= right_shifts_in_initMagnEst; | 1340 inst->whiteNoiseLevel >>= right_shifts_in_initMagnEst; |
1341 | 1341 |
1342 // Update the average magnitude spectrum, used as noise estimate. | 1342 // Update the average magnitude spectrum, used as noise estimate. |
1343 tmpU32no1 = WEBRTC_SPL_UMUL_32_16(inst->sumMagn, inst->overdrive); | 1343 tmpU32no1 = WEBRTC_SPL_UMUL_32_16(inst->sumMagn, inst->overdrive); |
1344 tmpU32no1 >>= inst->stages + 8; | 1344 tmpU32no1 >>= inst->stages + 8; |
1345 | 1345 |
1346 // Replacing division above with 'stages' shifts | 1346 // Replacing division above with 'stages' shifts |
1347 // Shift to same Q-domain as whiteNoiseLevel | 1347 // Shift to same Q-domain as whiteNoiseLevel |
1348 tmpU32no1 >>= right_shifts_in_magnU16; | 1348 tmpU32no1 >>= right_shifts_in_magnU16; |
1349 // This operation is safe from wrap around as long as END_STARTUP_SHORT < 12
8 | 1349 // This operation is safe from wrap around as long as END_STARTUP_SHORT < 12
8 |
1350 assert(END_STARTUP_SHORT < 128); | 1350 RTC_DCHECK_LT(END_STARTUP_SHORT, 128); |
1351 inst->whiteNoiseLevel += tmpU32no1; // Q(minNorm-stages) | 1351 inst->whiteNoiseLevel += tmpU32no1; // Q(minNorm-stages) |
1352 | 1352 |
1353 // Estimate Pink noise parameters | 1353 // Estimate Pink noise parameters |
1354 // Denominator used in both parameter estimates. | 1354 // Denominator used in both parameter estimates. |
1355 // The value is only dependent on the size of the frequency band (kStartBand
) | 1355 // The value is only dependent on the size of the frequency band (kStartBand
) |
1356 // and to reduce computational complexity stored in a table (kDeterminantEst
Matrix[]) | 1356 // and to reduce computational complexity stored in a table (kDeterminantEst
Matrix[]) |
1357 assert(kStartBand < 66); | 1357 RTC_DCHECK_LT(kStartBand, 66); |
1358 matrix_determinant = kDeterminantEstMatrix[kStartBand]; // Q0 | 1358 matrix_determinant = kDeterminantEstMatrix[kStartBand]; // Q0 |
1359 sum_log_i = kSumLogIndex[kStartBand]; // Q5 | 1359 sum_log_i = kSumLogIndex[kStartBand]; // Q5 |
1360 sum_log_i_square = kSumSquareLogIndex[kStartBand]; // Q2 | 1360 sum_log_i_square = kSumSquareLogIndex[kStartBand]; // Q2 |
1361 if (inst->fs == 8000) { | 1361 if (inst->fs == 8000) { |
1362 // Adjust values to shorter blocks in narrow band. | 1362 // Adjust values to shorter blocks in narrow band. |
1363 tmp_1_w32 = (int32_t)matrix_determinant; | 1363 tmp_1_w32 = (int32_t)matrix_determinant; |
1364 tmp_1_w32 += (kSumLogIndex[65] * sum_log_i) >> 9; | 1364 tmp_1_w32 += (kSumLogIndex[65] * sum_log_i) >> 9; |
1365 tmp_1_w32 -= (kSumLogIndex[65] * kSumLogIndex[65]) >> 10; | 1365 tmp_1_w32 -= (kSumLogIndex[65] * kSumLogIndex[65]) >> 10; |
1366 tmp_1_w32 -= (int32_t)sum_log_i_square << 4; | 1366 tmp_1_w32 -= (int32_t)sum_log_i_square << 4; |
1367 tmp_1_w32 -= ((inst->magnLen - kStartBand) * kSumSquareLogIndex[65]) >> 2; | 1367 tmp_1_w32 -= ((inst->magnLen - kStartBand) * kSumSquareLogIndex[65]) >> 2; |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1462 if (scaleEnergyOut == 0 && !(energyOut & 0x7f800000)) { | 1462 if (scaleEnergyOut == 0 && !(energyOut & 0x7f800000)) { |
1463 energyOut = WEBRTC_SPL_SHIFT_W32(energyOut, 8 + scaleEnergyOut | 1463 energyOut = WEBRTC_SPL_SHIFT_W32(energyOut, 8 + scaleEnergyOut |
1464 - inst->scaleEnergyIn); | 1464 - inst->scaleEnergyIn); |
1465 } else { | 1465 } else { |
1466 // |energyIn| is currently in Q(|scaleEnergyIn|), but to later on end up | 1466 // |energyIn| is currently in Q(|scaleEnergyIn|), but to later on end up |
1467 // with an |energyRatio| in Q8 we need to change the Q-domain to | 1467 // with an |energyRatio| in Q8 we need to change the Q-domain to |
1468 // Q(-8-scaleEnergyOut). | 1468 // Q(-8-scaleEnergyOut). |
1469 inst->energyIn >>= 8 + scaleEnergyOut - inst->scaleEnergyIn; | 1469 inst->energyIn >>= 8 + scaleEnergyOut - inst->scaleEnergyIn; |
1470 } | 1470 } |
1471 | 1471 |
1472 assert(inst->energyIn > 0); | 1472 RTC_DCHECK_GT(inst->energyIn, 0); |
1473 energyRatio = (energyOut + inst->energyIn / 2) / inst->energyIn; // Q8 | 1473 energyRatio = (energyOut + inst->energyIn / 2) / inst->energyIn; // Q8 |
1474 // Limit the ratio to [0, 1] in Q8, i.e., [0, 256] | 1474 // Limit the ratio to [0, 1] in Q8, i.e., [0, 256] |
1475 energyRatio = WEBRTC_SPL_SAT(256, energyRatio, 0); | 1475 energyRatio = WEBRTC_SPL_SAT(256, energyRatio, 0); |
1476 | 1476 |
1477 // all done in lookup tables now | 1477 // all done in lookup tables now |
1478 assert(energyRatio < 257); | 1478 RTC_DCHECK_LT(energyRatio, 257); |
1479 gainFactor1 = kFactor1Table[energyRatio]; // Q8 | 1479 gainFactor1 = kFactor1Table[energyRatio]; // Q8 |
1480 gainFactor2 = inst->factor2Table[energyRatio]; // Q8 | 1480 gainFactor2 = inst->factor2Table[energyRatio]; // Q8 |
1481 | 1481 |
1482 //combine both scales with speech/noise prob: note prior (priorSpeechProb) i
s not frequency dependent | 1482 //combine both scales with speech/noise prob: note prior (priorSpeechProb) i
s not frequency dependent |
1483 | 1483 |
1484 // factor = inst->priorSpeechProb*factor1 + (1.0-inst->priorSpeechProb)*fact
or2; // original code | 1484 // factor = inst->priorSpeechProb*factor1 + (1.0-inst->priorSpeechProb)*fact
or2; // original code |
1485 tmp16no1 = (int16_t)(((16384 - inst->priorNonSpeechProb) * gainFactor1) >> | 1485 tmp16no1 = (int16_t)(((16384 - inst->priorNonSpeechProb) * gainFactor1) >> |
1486 14); // in Q13, where 16384 = Q14(1.0) | 1486 14); // in Q13, where 16384 = Q14(1.0) |
1487 tmp16no2 = (int16_t)((inst->priorNonSpeechProb * gainFactor2) >> 14); | 1487 tmp16no2 = (int16_t)((inst->priorNonSpeechProb * gainFactor2) >> 14); |
1488 gainFactor = tmp16no1 + tmp16no2; // Q13 | 1488 gainFactor = tmp16no1 + tmp16no2; // Q13 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1527 int16_t avgProbSpeechHB, gainModHB, avgFilterGainHB, gainTimeDomainHB; | 1527 int16_t avgProbSpeechHB, gainModHB, avgFilterGainHB, gainTimeDomainHB; |
1528 int16_t pink_noise_exp_avg = 0; | 1528 int16_t pink_noise_exp_avg = 0; |
1529 | 1529 |
1530 size_t i, j; | 1530 size_t i, j; |
1531 int nShifts, postShifts; | 1531 int nShifts, postShifts; |
1532 int norm32no1, norm32no2; | 1532 int norm32no1, norm32no2; |
1533 int flag, sign; | 1533 int flag, sign; |
1534 int q_domain_to_use = 0; | 1534 int q_domain_to_use = 0; |
1535 | 1535 |
1536 // Code for ARMv7-Neon platform assumes the following: | 1536 // Code for ARMv7-Neon platform assumes the following: |
1537 assert(inst->anaLen > 0); | 1537 RTC_DCHECK_GT(inst->anaLen, 0); |
1538 assert(inst->anaLen2 > 0); | 1538 RTC_DCHECK_GT(inst->anaLen2, 0); |
1539 assert(inst->anaLen % 16 == 0); | 1539 RTC_DCHECK_EQ(0, inst->anaLen % 16); |
1540 assert(inst->anaLen2 % 8 == 0); | 1540 RTC_DCHECK_EQ(0, inst->anaLen2 % 8); |
1541 assert(inst->blockLen10ms > 0); | 1541 RTC_DCHECK_GT(inst->blockLen10ms, 0); |
1542 assert(inst->blockLen10ms % 16 == 0); | 1542 RTC_DCHECK_EQ(0, inst->blockLen10ms % 16); |
1543 assert(inst->magnLen == inst->anaLen2 + 1); | 1543 RTC_DCHECK_EQ(inst->magnLen, inst->anaLen2 + 1); |
1544 | 1544 |
1545 #ifdef NS_FILEDEBUG | 1545 #ifdef NS_FILEDEBUG |
1546 if (fwrite(spframe, sizeof(short), | 1546 if (fwrite(spframe, sizeof(short), |
1547 inst->blockLen10ms, inst->infile) != inst->blockLen10ms) { | 1547 inst->blockLen10ms, inst->infile) != inst->blockLen10ms) { |
1548 assert(false); | 1548 RTC_DCHECK(false); |
1549 } | 1549 } |
1550 #endif | 1550 #endif |
1551 | 1551 |
1552 // Check that initialization has been done | 1552 // Check that initialization has been done |
1553 assert(inst->initFlag == 1); | 1553 RTC_DCHECK_EQ(1, inst->initFlag); |
1554 assert((num_bands - 1) <= NUM_HIGH_BANDS_MAX); | 1554 RTC_DCHECK_LE(num_bands - 1, NUM_HIGH_BANDS_MAX); |
1555 | 1555 |
1556 const short* const* speechFrameHB = NULL; | 1556 const short* const* speechFrameHB = NULL; |
1557 short* const* outFrameHB = NULL; | 1557 short* const* outFrameHB = NULL; |
1558 size_t num_high_bands = 0; | 1558 size_t num_high_bands = 0; |
1559 if (num_bands > 1) { | 1559 if (num_bands > 1) { |
1560 speechFrameHB = &speechFrame[1]; | 1560 speechFrameHB = &speechFrame[1]; |
1561 outFrameHB = &outFrame[1]; | 1561 outFrameHB = &outFrame[1]; |
1562 num_high_bands = (size_t)(num_bands - 1); | 1562 num_high_bands = (size_t)(num_bands - 1); |
1563 } | 1563 } |
1564 | 1564 |
(...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1982 //directed decision update of priorSnr | 1982 //directed decision update of priorSnr |
1983 // FLOAT | 1983 // FLOAT |
1984 // priorSnr = DD_PR_SNR * prevNearSnr + (1.0-DD_PR_SNR) * curNearSnr; | 1984 // priorSnr = DD_PR_SNR * prevNearSnr + (1.0-DD_PR_SNR) * curNearSnr; |
1985 | 1985 |
1986 tmpU32no1 = WEBRTC_SPL_UMUL_32_16(prevNearSnr[i], DD_PR_SNR_Q11); // Q22 | 1986 tmpU32no1 = WEBRTC_SPL_UMUL_32_16(prevNearSnr[i], DD_PR_SNR_Q11); // Q22 |
1987 tmpU32no2 = WEBRTC_SPL_UMUL_32_16(curNearSnr, ONE_MINUS_DD_PR_SNR_Q11); // Q
22 | 1987 tmpU32no2 = WEBRTC_SPL_UMUL_32_16(curNearSnr, ONE_MINUS_DD_PR_SNR_Q11); // Q
22 |
1988 priorSnr = tmpU32no1 + tmpU32no2; // Q22 | 1988 priorSnr = tmpU32no1 + tmpU32no2; // Q22 |
1989 | 1989 |
1990 //gain filter | 1990 //gain filter |
1991 tmpU32no1 = inst->overdrive + ((priorSnr + 8192) >> 14); // Q8 | 1991 tmpU32no1 = inst->overdrive + ((priorSnr + 8192) >> 14); // Q8 |
1992 assert(inst->overdrive > 0); | 1992 RTC_DCHECK_GT(inst->overdrive, 0); |
1993 tmpU16no1 = (priorSnr + tmpU32no1 / 2) / tmpU32no1; // Q14 | 1993 tmpU16no1 = (priorSnr + tmpU32no1 / 2) / tmpU32no1; // Q14 |
1994 inst->noiseSupFilter[i] = WEBRTC_SPL_SAT(16384, tmpU16no1, inst->denoiseBoun
d); // 16384 = Q14(1.0) // Q14 | 1994 inst->noiseSupFilter[i] = WEBRTC_SPL_SAT(16384, tmpU16no1, inst->denoiseBoun
d); // 16384 = Q14(1.0) // Q14 |
1995 | 1995 |
1996 // Weight in the parametric Wiener filter during startup | 1996 // Weight in the parametric Wiener filter during startup |
1997 if (inst->blockIndex < END_STARTUP_SHORT) { | 1997 if (inst->blockIndex < END_STARTUP_SHORT) { |
1998 // Weight the two suppression filters | 1998 // Weight the two suppression filters |
1999 tmpU32no1 = inst->noiseSupFilter[i] * inst->blockIndex; | 1999 tmpU32no1 = inst->noiseSupFilter[i] * inst->blockIndex; |
2000 tmpU32no2 = noiseSupFilterTmp[i] * | 2000 tmpU32no2 = noiseSupFilterTmp[i] * |
2001 (END_STARTUP_SHORT - inst->blockIndex); | 2001 (END_STARTUP_SHORT - inst->blockIndex); |
2002 tmpU32no1 += tmpU32no2; | 2002 tmpU32no1 += tmpU32no2; |
(...skipping 15 matching lines...) Expand all Loading... |
2018 for (i = 0; i < inst->magnLen; i++) { | 2018 for (i = 0; i < inst->magnLen; i++) { |
2019 inst->prevNoiseU32[i] = noiseU32[i] >> (5 - norm32no1); // Q(qNoise+11) | 2019 inst->prevNoiseU32[i] = noiseU32[i] >> (5 - norm32no1); // Q(qNoise+11) |
2020 inst->prevMagnU16[i] = magnU16[i]; // Q(qMagn) | 2020 inst->prevMagnU16[i] = magnU16[i]; // Q(qMagn) |
2021 } | 2021 } |
2022 } | 2022 } |
2023 | 2023 |
2024 WebRtcNsx_DataSynthesis(inst, outFrame[0]); | 2024 WebRtcNsx_DataSynthesis(inst, outFrame[0]); |
2025 #ifdef NS_FILEDEBUG | 2025 #ifdef NS_FILEDEBUG |
2026 if (fwrite(outframe, sizeof(short), | 2026 if (fwrite(outframe, sizeof(short), |
2027 inst->blockLen10ms, inst->outfile) != inst->blockLen10ms) { | 2027 inst->blockLen10ms, inst->outfile) != inst->blockLen10ms) { |
2028 assert(false); | 2028 RTC_DCHECK(false); |
2029 } | 2029 } |
2030 #endif | 2030 #endif |
2031 | 2031 |
2032 //for H band: | 2032 //for H band: |
2033 // only update data buffer, then apply time-domain gain is applied derived fro
m L band | 2033 // only update data buffer, then apply time-domain gain is applied derived fro
m L band |
2034 if (num_bands > 1) { | 2034 if (num_bands > 1) { |
2035 // update analysis buffer for H band | 2035 // update analysis buffer for H band |
2036 // append new data to buffer FX | 2036 // append new data to buffer FX |
2037 for (i = 0; i < num_high_bands; ++i) { | 2037 for (i = 0; i < num_high_bands; ++i) { |
2038 memcpy(inst->dataBufHBFX[i], inst->dataBufHBFX[i] + inst->blockLen10ms, | 2038 memcpy(inst->dataBufHBFX[i], inst->dataBufHBFX[i] + inst->blockLen10ms, |
2039 (inst->anaLen - inst->blockLen10ms) * sizeof(*inst->dataBufHBFX[i])); | 2039 (inst->anaLen - inst->blockLen10ms) * sizeof(*inst->dataBufHBFX[i])); |
2040 memcpy(inst->dataBufHBFX[i] + inst->anaLen - inst->blockLen10ms, | 2040 memcpy(inst->dataBufHBFX[i] + inst->anaLen - inst->blockLen10ms, |
2041 speechFrameHB[i], inst->blockLen10ms * sizeof(*inst->dataBufHBFX[i])); | 2041 speechFrameHB[i], inst->blockLen10ms * sizeof(*inst->dataBufHBFX[i])); |
2042 } | 2042 } |
2043 // range for averaging low band quantities for H band gain | 2043 // range for averaging low band quantities for H band gain |
2044 | 2044 |
2045 gainTimeDomainHB = 16384; // 16384 = Q14(1.0) | 2045 gainTimeDomainHB = 16384; // 16384 = Q14(1.0) |
2046 //average speech prob from low band | 2046 //average speech prob from low band |
2047 //average filter gain from low band | 2047 //average filter gain from low band |
2048 //avg over second half (i.e., 4->8kHz) of freq. spectrum | 2048 //avg over second half (i.e., 4->8kHz) of freq. spectrum |
2049 tmpU32no1 = 0; // Q12 | 2049 tmpU32no1 = 0; // Q12 |
2050 tmpU16no1 = 0; // Q8 | 2050 tmpU16no1 = 0; // Q8 |
2051 for (i = inst->anaLen2 - (inst->anaLen2 >> 2); i < inst->anaLen2; i++) { | 2051 for (i = inst->anaLen2 - (inst->anaLen2 >> 2); i < inst->anaLen2; i++) { |
2052 tmpU16no1 += nonSpeechProbFinal[i]; // Q8 | 2052 tmpU16no1 += nonSpeechProbFinal[i]; // Q8 |
2053 tmpU32no1 += (uint32_t)(inst->noiseSupFilter[i]); // Q14 | 2053 tmpU32no1 += (uint32_t)(inst->noiseSupFilter[i]); // Q14 |
2054 } | 2054 } |
2055 assert(inst->stages >= 7); | 2055 RTC_DCHECK_GE(inst->stages, 7); |
2056 avgProbSpeechHB = (4096 - (tmpU16no1 >> (inst->stages - 7))); // Q12 | 2056 avgProbSpeechHB = (4096 - (tmpU16no1 >> (inst->stages - 7))); // Q12 |
2057 avgFilterGainHB = (int16_t)(tmpU32no1 >> (inst->stages - 3)); // Q14 | 2057 avgFilterGainHB = (int16_t)(tmpU32no1 >> (inst->stages - 3)); // Q14 |
2058 | 2058 |
2059 // // original FLOAT code | 2059 // // original FLOAT code |
2060 // // gain based on speech probability: | 2060 // // gain based on speech probability: |
2061 // avg_prob_speech_tt=(float)2.0*avg_prob_speech-(float)1.0; | 2061 // avg_prob_speech_tt=(float)2.0*avg_prob_speech-(float)1.0; |
2062 // gain_mod=(float)0.5*((float)1.0+(float)tanh(avg_prob_speech_tt)); // betw
een 0 and 1 | 2062 // gain_mod=(float)0.5*((float)1.0+(float)tanh(avg_prob_speech_tt)); // betw
een 0 and 1 |
2063 | 2063 |
2064 // gain based on speech probability: | 2064 // gain based on speech probability: |
2065 // original expression: "0.5 * (1 + tanh(2x-1))" | 2065 // original expression: "0.5 * (1 + tanh(2x-1))" |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2098 | 2098 |
2099 //apply gain | 2099 //apply gain |
2100 for (i = 0; i < num_high_bands; ++i) { | 2100 for (i = 0; i < num_high_bands; ++i) { |
2101 for (j = 0; j < inst->blockLen10ms; j++) { | 2101 for (j = 0; j < inst->blockLen10ms; j++) { |
2102 outFrameHB[i][j] = (int16_t)((gainTimeDomainHB * | 2102 outFrameHB[i][j] = (int16_t)((gainTimeDomainHB * |
2103 inst->dataBufHBFX[i][j]) >> 14); // Q0 | 2103 inst->dataBufHBFX[i][j]) >> 14); // Q0 |
2104 } | 2104 } |
2105 } | 2105 } |
2106 } // end of H band gain computation | 2106 } // end of H band gain computation |
2107 } | 2107 } |
OLD | NEW |