AECM: Added namespaces

This CL adds namespaces to AECM.

Bug: webrtc:5298
Change-Id: Ibb124ef9eb46c4bd762847b6763b37a6eeb85433
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/171105
Commit-Queue: Per Åhgren <peah@webrtc.org>
Reviewed-by: Sam Zackrisson <saza@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30849}
This commit is contained in:
Per Åhgren 2020-03-20 16:45:09 +01:00 committed by Commit Bot
parent 71fda3613c
commit be36db1024
7 changed files with 177 additions and 130 deletions

View File

@ -24,11 +24,35 @@ extern "C" {
#include "rtc_base/checks.h"
#include "rtc_base/numerics/safe_conversions.h"
namespace webrtc {
namespace {
#ifdef AEC_DEBUG
FILE* dfile;
FILE* testfile;
#endif
// Initialization table for echo channel in 8 kHz
static const int16_t kChannelStored8kHz[PART_LEN1] = {
2040, 1815, 1590, 1498, 1405, 1395, 1385, 1418, 1451, 1506, 1562,
1644, 1726, 1804, 1882, 1918, 1953, 1982, 2010, 2025, 2040, 2034,
2027, 2021, 2014, 1997, 1980, 1925, 1869, 1800, 1732, 1683, 1635,
1604, 1572, 1545, 1517, 1481, 1444, 1405, 1367, 1331, 1294, 1270,
1245, 1239, 1233, 1247, 1260, 1282, 1303, 1338, 1373, 1407, 1441,
1470, 1499, 1524, 1549, 1565, 1582, 1601, 1621, 1649, 1676};
// Initialization table for echo channel in 16 kHz
static const int16_t kChannelStored16kHz[PART_LEN1] = {
2040, 1590, 1405, 1385, 1451, 1562, 1726, 1882, 1953, 2010, 2040,
2027, 2014, 1980, 1869, 1732, 1635, 1572, 1517, 1444, 1367, 1294,
1245, 1233, 1260, 1303, 1373, 1441, 1499, 1549, 1582, 1621, 1676,
1741, 1802, 1861, 1921, 1983, 2040, 2102, 2170, 2265, 2375, 2515,
2651, 2781, 2922, 3075, 3253, 3471, 3738, 3976, 4151, 4258, 4308,
4288, 4270, 4253, 4237, 4179, 4086, 3947, 3757, 3484, 3153};
} // namespace
const int16_t WebRtcAecm_kCosTable[] = {
8192, 8190, 8187, 8180, 8172, 8160, 8147, 8130, 8112, 8091, 8067,
8041, 8012, 7982, 7948, 7912, 7874, 7834, 7791, 7745, 7697, 7647,
@ -99,23 +123,6 @@ const int16_t WebRtcAecm_kSinTable[] = {
-2667, -2531, -2395, -2258, -2120, -1981, -1842, -1703, -1563, -1422, -1281,
-1140, -998, -856, -713, -571, -428, -285, -142};
// Initialization table for echo channel in 8 kHz
static const int16_t kChannelStored8kHz[PART_LEN1] = {
2040, 1815, 1590, 1498, 1405, 1395, 1385, 1418, 1451, 1506, 1562,
1644, 1726, 1804, 1882, 1918, 1953, 1982, 2010, 2025, 2040, 2034,
2027, 2021, 2014, 1997, 1980, 1925, 1869, 1800, 1732, 1683, 1635,
1604, 1572, 1545, 1517, 1481, 1444, 1405, 1367, 1331, 1294, 1270,
1245, 1239, 1233, 1247, 1260, 1282, 1303, 1338, 1373, 1407, 1441,
1470, 1499, 1524, 1549, 1565, 1582, 1601, 1621, 1649, 1676};
// Initialization table for echo channel in 16 kHz
static const int16_t kChannelStored16kHz[PART_LEN1] = {
2040, 1590, 1405, 1385, 1451, 1562, 1726, 1882, 1953, 2010, 2040,
2027, 2014, 1980, 1869, 1732, 1635, 1572, 1517, 1444, 1367, 1294,
1245, 1233, 1260, 1303, 1373, 1441, 1499, 1549, 1582, 1621, 1676,
1741, 1802, 1861, 1921, 1983, 2040, 2102, 2170, 2265, 2375, 2515,
2651, 2781, 2922, 3075, 3253, 3471, 3738, 3976, 4151, 4258, 4308,
4288, 4270, 4253, 4237, 4179, 4086, 3947, 3757, 3484, 3153};
// Moves the pointer to the next entry and inserts |far_spectrum| and
// corresponding Q-domain in its buffer.
@ -1113,3 +1120,5 @@ void WebRtcAecm_FetchFarFrame(AecmCore* const aecm,
sizeof(int16_t) * readLen);
aecm->farBufReadPos += readLen;
}
} // namespace webrtc

View File

@ -19,6 +19,10 @@ extern "C" {
}
#include "modules/audio_processing/aecm/aecm_defines.h"
struct RealFFT;
namespace webrtc {
#ifdef _MSC_VER // visual c++
#define ALIGN8_BEG __declspec(align(8))
#define ALIGN8_END
@ -432,4 +436,6 @@ void WebRtcAecm_ResetAdaptiveChannel_mips(AecmCore* aecm);
#endif
#endif
} // namespace webrtc
#endif

View File

@ -27,6 +27,10 @@ extern "C" {
#include "rtc_base/numerics/safe_conversions.h"
#include "rtc_base/sanitizer.h"
namespace webrtc {
namespace {
// Square root of Hanning window in Q14.
static const ALIGN8_BEG int16_t WebRtcAecm_kSqrtHanning[] ALIGN8_END = {
0, 399, 798, 1196, 1594, 1990, 2386, 2780, 3172, 3562, 3951,
@ -57,7 +61,115 @@ static const int16_t kNoiseEstIncCount = 5;
static void ComfortNoise(AecmCore* aecm,
const uint16_t* dfa,
ComplexInt16* out,
const int16_t* lambda);
const int16_t* lambda) {
int16_t i;
int16_t tmp16;
int32_t tmp32;
int16_t randW16[PART_LEN];
int16_t uReal[PART_LEN1];
int16_t uImag[PART_LEN1];
int32_t outLShift32;
int16_t noiseRShift16[PART_LEN1];
int16_t shiftFromNearToNoise = kNoiseEstQDomain - aecm->dfaCleanQDomain;
int16_t minTrackShift;
RTC_DCHECK_GE(shiftFromNearToNoise, 0);
RTC_DCHECK_LT(shiftFromNearToNoise, 16);
if (aecm->noiseEstCtr < 100) {
// Track the minimum more quickly initially.
aecm->noiseEstCtr++;
minTrackShift = 6;
} else {
minTrackShift = 9;
}
// Estimate noise power.
for (i = 0; i < PART_LEN1; i++) {
// Shift to the noise domain.
tmp32 = (int32_t)dfa[i];
outLShift32 = tmp32 << shiftFromNearToNoise;
if (outLShift32 < aecm->noiseEst[i]) {
// Reset "too low" counter
aecm->noiseEstTooLowCtr[i] = 0;
// Track the minimum.
if (aecm->noiseEst[i] < (1 << minTrackShift)) {
// For small values, decrease noiseEst[i] every
// |kNoiseEstIncCount| block. The regular approach below can not
// go further down due to truncation.
aecm->noiseEstTooHighCtr[i]++;
if (aecm->noiseEstTooHighCtr[i] >= kNoiseEstIncCount) {
aecm->noiseEst[i]--;
aecm->noiseEstTooHighCtr[i] = 0; // Reset the counter
}
} else {
aecm->noiseEst[i] -=
((aecm->noiseEst[i] - outLShift32) >> minTrackShift);
}
} else {
// Reset "too high" counter
aecm->noiseEstTooHighCtr[i] = 0;
// Ramp slowly upwards until we hit the minimum again.
if ((aecm->noiseEst[i] >> 19) > 0) {
// Avoid overflow.
// Multiplication with 2049 will cause wrap around. Scale
// down first and then multiply
aecm->noiseEst[i] >>= 11;
aecm->noiseEst[i] *= 2049;
} else if ((aecm->noiseEst[i] >> 11) > 0) {
// Large enough for relative increase
aecm->noiseEst[i] *= 2049;
aecm->noiseEst[i] >>= 11;
} else {
// Make incremental increases based on size every
// |kNoiseEstIncCount| block
aecm->noiseEstTooLowCtr[i]++;
if (aecm->noiseEstTooLowCtr[i] >= kNoiseEstIncCount) {
aecm->noiseEst[i] += (aecm->noiseEst[i] >> 9) + 1;
aecm->noiseEstTooLowCtr[i] = 0; // Reset counter
}
}
}
}
for (i = 0; i < PART_LEN1; i++) {
tmp32 = aecm->noiseEst[i] >> shiftFromNearToNoise;
if (tmp32 > 32767) {
tmp32 = 32767;
aecm->noiseEst[i] = tmp32 << shiftFromNearToNoise;
}
noiseRShift16[i] = (int16_t)tmp32;
tmp16 = ONE_Q14 - lambda[i];
noiseRShift16[i] = (int16_t)((tmp16 * noiseRShift16[i]) >> 14);
}
// Generate a uniform random array on [0 2^15-1].
WebRtcSpl_RandUArray(randW16, PART_LEN, &aecm->seed);
// Generate noise according to estimated energy.
uReal[0] = 0; // Reject LF noise.
uImag[0] = 0;
for (i = 1; i < PART_LEN1; i++) {
// Get a random index for the cos and sin tables over [0 359].
tmp16 = (int16_t)((359 * randW16[i - 1]) >> 15);
// Tables are in Q13.
uReal[i] =
(int16_t)((noiseRShift16[i] * WebRtcAecm_kCosTable[tmp16]) >> 13);
uImag[i] =
(int16_t)((-noiseRShift16[i] * WebRtcAecm_kSinTable[tmp16]) >> 13);
}
uImag[PART_LEN] = 0;
for (i = 0; i < PART_LEN1; i++) {
out[i].real = WebRtcSpl_AddSatW16(out[i].real, uReal[i]);
out[i].imag = WebRtcSpl_AddSatW16(out[i].imag, uImag[i]);
}
}
static void WindowAndFFT(AecmCore* aecm,
int16_t* fft,
@ -255,6 +367,8 @@ static int TimeToFrequencyDomain(AecmCore* aecm,
return time_signal_scaling;
}
} // namespace
int RTC_NO_SANITIZE("signed-integer-overflow") // bugs.webrtc.org/8200
WebRtcAecm_ProcessBlock(AecmCore* aecm,
const int16_t* farend,
@ -554,115 +668,4 @@ int RTC_NO_SANITIZE("signed-integer-overflow") // bugs.webrtc.org/8200
return 0;
}
static void ComfortNoise(AecmCore* aecm,
const uint16_t* dfa,
ComplexInt16* out,
const int16_t* lambda) {
int16_t i;
int16_t tmp16;
int32_t tmp32;
int16_t randW16[PART_LEN];
int16_t uReal[PART_LEN1];
int16_t uImag[PART_LEN1];
int32_t outLShift32;
int16_t noiseRShift16[PART_LEN1];
int16_t shiftFromNearToNoise = kNoiseEstQDomain - aecm->dfaCleanQDomain;
int16_t minTrackShift;
RTC_DCHECK_GE(shiftFromNearToNoise, 0);
RTC_DCHECK_LT(shiftFromNearToNoise, 16);
if (aecm->noiseEstCtr < 100) {
// Track the minimum more quickly initially.
aecm->noiseEstCtr++;
minTrackShift = 6;
} else {
minTrackShift = 9;
}
// Estimate noise power.
for (i = 0; i < PART_LEN1; i++) {
// Shift to the noise domain.
tmp32 = (int32_t)dfa[i];
outLShift32 = tmp32 << shiftFromNearToNoise;
if (outLShift32 < aecm->noiseEst[i]) {
// Reset "too low" counter
aecm->noiseEstTooLowCtr[i] = 0;
// Track the minimum.
if (aecm->noiseEst[i] < (1 << minTrackShift)) {
// For small values, decrease noiseEst[i] every
// |kNoiseEstIncCount| block. The regular approach below can not
// go further down due to truncation.
aecm->noiseEstTooHighCtr[i]++;
if (aecm->noiseEstTooHighCtr[i] >= kNoiseEstIncCount) {
aecm->noiseEst[i]--;
aecm->noiseEstTooHighCtr[i] = 0; // Reset the counter
}
} else {
aecm->noiseEst[i] -=
((aecm->noiseEst[i] - outLShift32) >> minTrackShift);
}
} else {
// Reset "too high" counter
aecm->noiseEstTooHighCtr[i] = 0;
// Ramp slowly upwards until we hit the minimum again.
if ((aecm->noiseEst[i] >> 19) > 0) {
// Avoid overflow.
// Multiplication with 2049 will cause wrap around. Scale
// down first and then multiply
aecm->noiseEst[i] >>= 11;
aecm->noiseEst[i] *= 2049;
} else if ((aecm->noiseEst[i] >> 11) > 0) {
// Large enough for relative increase
aecm->noiseEst[i] *= 2049;
aecm->noiseEst[i] >>= 11;
} else {
// Make incremental increases based on size every
// |kNoiseEstIncCount| block
aecm->noiseEstTooLowCtr[i]++;
if (aecm->noiseEstTooLowCtr[i] >= kNoiseEstIncCount) {
aecm->noiseEst[i] += (aecm->noiseEst[i] >> 9) + 1;
aecm->noiseEstTooLowCtr[i] = 0; // Reset counter
}
}
}
}
for (i = 0; i < PART_LEN1; i++) {
tmp32 = aecm->noiseEst[i] >> shiftFromNearToNoise;
if (tmp32 > 32767) {
tmp32 = 32767;
aecm->noiseEst[i] = tmp32 << shiftFromNearToNoise;
}
noiseRShift16[i] = (int16_t)tmp32;
tmp16 = ONE_Q14 - lambda[i];
noiseRShift16[i] = (int16_t)((tmp16 * noiseRShift16[i]) >> 14);
}
// Generate a uniform random array on [0 2^15-1].
WebRtcSpl_RandUArray(randW16, PART_LEN, &aecm->seed);
// Generate noise according to estimated energy.
uReal[0] = 0; // Reject LF noise.
uImag[0] = 0;
for (i = 1; i < PART_LEN1; i++) {
// Get a random index for the cos and sin tables over [0 359].
tmp16 = (int16_t)((359 * randW16[i - 1]) >> 15);
// Tables are in Q13.
uReal[i] =
(int16_t)((noiseRShift16[i] * WebRtcAecm_kCosTable[tmp16]) >> 13);
uImag[i] =
(int16_t)((-noiseRShift16[i] * WebRtcAecm_kSinTable[tmp16]) >> 13);
}
uImag[PART_LEN] = 0;
for (i = 0; i < PART_LEN1; i++) {
out[i].real = WebRtcSpl_AddSatW16(out[i].real, uReal[i]);
out[i].imag = WebRtcSpl_AddSatW16(out[i].imag, uImag[i]);
}
}
} // namespace webrtc

View File

@ -14,6 +14,10 @@
#include "rtc_base/checks.h"
#include "rtc_base/numerics/safe_conversions.h"
namespace webrtc {
namespace {
static const ALIGN8_BEG int16_t WebRtcAecm_kSqrtHanning[] ALIGN8_END = {
0, 399, 798, 1196, 1594, 1990, 2386, 2780, 3172, 3562, 3951,
4337, 4720, 5101, 5478, 5853, 6224, 6591, 6954, 7313, 7668, 8019,
@ -47,6 +51,8 @@ static int16_t coefTable_ifft[] = {
100, 344, 420, 216, 164, 472, 292, 56, 36, 312, 452, 184, 196, 440, 324,
120, 68, 376, 388, 248, 132, 504, 260};
} // namespace
static void ComfortNoise(AecmCore* aecm,
const uint16_t* dfa,
ComplexInt16* out,
@ -1646,3 +1652,5 @@ static void ComfortNoise(AecmCore* aecm,
sgn = ((int)tt) >> 31;
out[PART_LEN].imag = sgn == (int16_t)(tt >> 15) ? (int16_t)tt : (16384 ^ sgn);
}
} // namespace webrtc

View File

@ -14,6 +14,10 @@
#include "modules/audio_processing/aecm/aecm_core.h"
#include "rtc_base/checks.h"
namespace webrtc {
namespace {
// TODO(kma): Re-write the corresponding assembly file, the offset
// generating script and makefile, to replace these C functions.
@ -28,6 +32,8 @@ static inline void AddLanes(uint32_t* ptr, uint32x4_t v) {
#endif
}
} // namespace
void WebRtcAecm_CalcLinearEnergiesNeon(AecmCore* aecm,
const uint16_t* far_spectrum,
int32_t* echo_est,
@ -196,3 +202,5 @@ void WebRtcAecm_ResetAdaptiveChannelNeon(AecmCore* aecm) {
aecm->channelAdapt16[PART_LEN] = aecm->channelStored[PART_LEN];
aecm->channelAdapt32[PART_LEN] = (int32_t)aecm->channelStored[PART_LEN] << 16;
}
} // namespace webrtc

View File

@ -23,6 +23,10 @@ extern "C" {
}
#include "modules/audio_processing/aecm/aecm_core.h"
namespace webrtc {
namespace {
#define BUF_SIZE_FRAMES 50 // buffer size (frames)
// Maximum length of resampled signal. Must be an integer multiple of frames
// (ceil(1/(1 + MIN_SKEW)*2) + 1)*FRAME_LEN
@ -75,6 +79,8 @@ typedef struct {
AecmCore* aecmCore;
} AecMobile;
} // namespace
// Estimates delay to set the position of the farend buffer read pointer
// (controlled by knownDelay)
static int WebRtcAecm_EstBufDelay(AecMobile* aecm, short msInSndCardBuf);
@ -590,3 +596,5 @@ static int WebRtcAecm_DelayComp(AecMobile* aecm) {
return 0;
}
} // namespace webrtc

View File

@ -14,6 +14,8 @@
#include <stddef.h>
#include <stdint.h>
namespace webrtc {
enum { AecmFalse = 0, AecmTrue };
// Errors
@ -201,4 +203,7 @@ size_t WebRtcAecm_echo_path_size_bytes();
#ifdef __cplusplus
}
#endif
} // namespace webrtc
#endif // MODULES_AUDIO_PROCESSING_AECM_ECHO_CONTROL_MOBILE_H_