| 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 |