APM: Change the AGC C code to be built as C++ code

This CL changes so that the AGC legacy C code is built as C++.

The CL also
-removes #defines from the header files.
-adds namespaces
-removes unused code.

To simplify the review, the CL is partitioned into different patchsets
where each comprising of one step in the modification of the code
(e.g., patch set 1 performs the renaming of the .c files to .cc).

Bug: webrtc:5298
Change-Id: I362b17bde91142b2f2166acba4f2f888efd50fa1
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/171064
Commit-Queue: Per Åhgren <peah@webrtc.org>
Reviewed-by: Alessio Bazzica <alessiob@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30847}
This commit is contained in:
Per Åhgren 2020-03-20 15:50:14 +01:00 committed by Commit Bot
parent 9d66198d35
commit 5b139d6f9b
7 changed files with 99 additions and 176 deletions

View File

@ -180,8 +180,8 @@ rtc_library("audio_processing") {
"aec3",
"aecm:aecm_core",
"agc",
"agc:agc_legacy_c",
"agc:gain_control_interface",
"agc:legacy_agc",
"agc2:adaptive_digital",
"agc2:fixed_digital",
"agc2:gain_applier",

View File

@ -56,7 +56,7 @@ rtc_library("level_estimation") {
]
}
rtc_library("agc_legacy_c") {
rtc_library("legacy_agc") {
visibility = [
":*",
"..:*",
@ -65,9 +65,9 @@ rtc_library("agc_legacy_c") {
# this.
sources = [
"legacy/analog_agc.c",
"legacy/analog_agc.cc",
"legacy/analog_agc.h",
"legacy/digital_agc.c",
"legacy/digital_agc.cc",
"legacy/digital_agc.h",
"legacy/gain_control.h",
]

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
/* analog_agc.c
/*
*
* Using a feedback system, determines an appropriate analog volume level
* given an input signal and current volume level. Targets a conservative
@ -23,6 +23,16 @@
#include "rtc_base/checks.h"
namespace webrtc {
namespace {
// Errors
#define AGC_UNSPECIFIED_ERROR 18000
#define AGC_UNINITIALIZED_ERROR 18002
#define AGC_NULL_POINTER_ERROR 18003
#define AGC_BAD_PARAMETER_ERROR 18004
/* The slope of in Q13*/
static const int16_t kSlope1[8] = {21793, 12517, 7189, 4129,
2372, 1362, 472, 78};
@ -69,9 +79,6 @@ static const size_t kNumSubframes = 10;
*/
#define DIFF_REF_TO_ANALOG 5
#ifdef MIC_LEVEL_FEEDBACK
#define NUM_BLOCKS_IN_SAT_BEFORE_CHANGE_TARGET 7
#endif
/* Size of analog gain table */
#define GAIN_TBL_LEN 32
/* Matlab code:
@ -125,6 +132,8 @@ static const int32_t kTargetLevelTable[64] = {
337, 268, 213, 169, 134, 107, 85,
67};
} // namespace
int WebRtcAgc_AddMic(void* state,
int16_t* const* in_mic,
size_t num_bands,
@ -135,7 +144,7 @@ int WebRtcAgc_AddMic(void* state,
size_t i;
int16_t n, L, tmp16, tmp_speech[16];
LegacyAgc* stt;
stt = (LegacyAgc*)state;
stt = reinterpret_cast<LegacyAgc*>(state);
if (stt->fs == 8000) {
L = 8;
@ -222,7 +231,7 @@ int WebRtcAgc_AddMic(void* state,
WebRtcSpl_DownsampleBy2(&in_mic[0][i * 32], 32, tmp_speech,
stt->filterState);
} else {
memcpy(tmp_speech, &in_mic[0][i * 16], 16 * sizeof(short));
memcpy(tmp_speech, &in_mic[0][i * 16], 16 * sizeof(int16_t));
}
/* Compute energy in blocks of 16 samples */
ptr[i] = WebRtcSpl_DotProductWithScale(tmp_speech, tmp_speech, 16, 4);
@ -242,7 +251,7 @@ int WebRtcAgc_AddMic(void* state,
}
int WebRtcAgc_AddFarend(void* state, const int16_t* in_far, size_t samples) {
LegacyAgc* stt = (LegacyAgc*)state;
LegacyAgc* stt = reinterpret_cast<LegacyAgc*>(state);
int err = WebRtcAgc_GetAddFarendError(state, samples);
@ -254,7 +263,7 @@ int WebRtcAgc_AddFarend(void* state, const int16_t* in_far, size_t samples) {
int WebRtcAgc_GetAddFarendError(void* state, size_t samples) {
LegacyAgc* stt;
stt = (LegacyAgc*)state;
stt = reinterpret_cast<LegacyAgc*>(state);
if (stt == NULL)
return -1;
@ -291,7 +300,7 @@ int WebRtcAgc_VirtualMic(void* agcInst,
const int16_t kZeroCrossingLowLim = 15;
const int16_t kZeroCrossingHighLim = 20;
stt = (LegacyAgc*)agcInst;
stt = reinterpret_cast<LegacyAgc*>(agcInst);
/*
* Before applying gain decide if this is a low-level signal.
@ -394,15 +403,6 @@ int WebRtcAgc_VirtualMic(void* agcInst,
void WebRtcAgc_UpdateAgcThresholds(LegacyAgc* stt) {
int16_t tmp16;
#ifdef MIC_LEVEL_FEEDBACK
int zeros;
if (stt->micLvlSat) {
/* Lower the analog target level since we have reached its maximum */
zeros = WebRtcSpl_NormW32(stt->Rxx160_LPw32);
stt->targetIdxOffset = (3 * zeros - stt->targetIdx - 2) / 4;
}
#endif
/* Set analog target level in envelope dBOv scale */
tmp16 = (DIFF_REF_TO_ANALOG * stt->compressionGaindB) + ANALOG_TARGET_LEVEL_2;
@ -415,9 +415,6 @@ void WebRtcAgc_UpdateAgcThresholds(LegacyAgc* stt) {
/* Adjust for different parameter interpretation in FixedDigital mode */
stt->analogTarget = stt->compressionGaindB;
}
#ifdef MIC_LEVEL_FEEDBACK
stt->analogTarget += stt->targetIdxOffset;
#endif
/* Since the offset between RMS and ENV is not constant, we should make this
* into a
* table, but for now, we'll stick with a constant, tuned for the chosen
@ -425,25 +422,22 @@ void WebRtcAgc_UpdateAgcThresholds(LegacyAgc* stt) {
* target level.
*/
stt->targetIdx = ANALOG_TARGET_LEVEL + OFFSET_ENV_TO_RMS;
#ifdef MIC_LEVEL_FEEDBACK
stt->targetIdx += stt->targetIdxOffset;
#endif
/* Analog adaptation limits */
/* analogTargetLevel = round((32767*10^(-targetIdx/20))^2*16/2^7) */
stt->analogTargetLevel =
RXX_BUFFER_LEN * kTargetLevelTable[stt->targetIdx]; /* ex. -20 dBov */
kRxxBufferLen * kTargetLevelTable[stt->targetIdx]; /* ex. -20 dBov */
stt->startUpperLimit =
RXX_BUFFER_LEN * kTargetLevelTable[stt->targetIdx - 1]; /* -19 dBov */
kRxxBufferLen * kTargetLevelTable[stt->targetIdx - 1]; /* -19 dBov */
stt->startLowerLimit =
RXX_BUFFER_LEN * kTargetLevelTable[stt->targetIdx + 1]; /* -21 dBov */
kRxxBufferLen * kTargetLevelTable[stt->targetIdx + 1]; /* -21 dBov */
stt->upperPrimaryLimit =
RXX_BUFFER_LEN * kTargetLevelTable[stt->targetIdx - 2]; /* -18 dBov */
kRxxBufferLen * kTargetLevelTable[stt->targetIdx - 2]; /* -18 dBov */
stt->lowerPrimaryLimit =
RXX_BUFFER_LEN * kTargetLevelTable[stt->targetIdx + 2]; /* -22 dBov */
kRxxBufferLen * kTargetLevelTable[stt->targetIdx + 2]; /* -22 dBov */
stt->upperSecondaryLimit =
RXX_BUFFER_LEN * kTargetLevelTable[stt->targetIdx - 5]; /* -15 dBov */
kRxxBufferLen * kTargetLevelTable[stt->targetIdx - 5]; /* -15 dBov */
stt->lowerSecondaryLimit =
RXX_BUFFER_LEN * kTargetLevelTable[stt->targetIdx + 5]; /* -25 dBov */
kRxxBufferLen * kTargetLevelTable[stt->targetIdx + 5]; /* -25 dBov */
stt->upperLimit = stt->startUpperLimit;
stt->lowerLimit = stt->startLowerLimit;
}
@ -507,7 +501,6 @@ void WebRtcAgc_ZeroCtrl(LegacyAgc* stt, int32_t* inMicLevel, int32_t* env) {
stt->micVol = *inMicLevel;
}
stt->activeSpeech = 0;
stt->Rxx16_LPw32Max = 0;
@ -592,7 +585,7 @@ int32_t WebRtcAgc_ProcessAnalog(void* state,
uint8_t saturated = 0;
LegacyAgc* stt;
stt = (LegacyAgc*)state;
stt = reinterpret_cast<LegacyAgc*>(state);
inMicLevelTmp = inMicLevel << stt->scale;
if (inMicLevelTmp > stt->maxAnalog) {
@ -625,9 +618,6 @@ int32_t WebRtcAgc_ProcessAnalog(void* state,
tmp32 = ((stt->maxLevel - stt->minLevel) * 51) >> 9;
inMicLevelTmp = (stt->minLevel + tmp32);
stt->micVol = inMicLevelTmp;
#ifdef MIC_LEVEL_FEEDBACK
// stt->numBlocksMicLvlSat = 0;
#endif
}
if (inMicLevelTmp != stt->micVol) {
@ -676,7 +666,6 @@ int32_t WebRtcAgc_ProcessAnalog(void* state,
}
inMicLevelTmp = stt->micVol;
if (stt->micVol < stt->minOutput) {
*saturationWarning = 1;
}
@ -701,9 +690,6 @@ int32_t WebRtcAgc_ProcessAnalog(void* state,
stt->upperLimit = stt->startUpperLimit;
stt->lowerLimit = stt->startLowerLimit;
#ifdef MIC_LEVEL_FEEDBACK
// stt->numBlocksMicLvlSat = 0;
#endif
}
/* Check if the input speech is zero. If so the mic volume
@ -731,7 +717,7 @@ int32_t WebRtcAgc_ProcessAnalog(void* state,
/* Circular buffer */
stt->Rxx16pos++;
if (stt->Rxx16pos == RXX_BUFFER_LEN) {
if (stt->Rxx16pos == kRxxBufferLen) {
stt->Rxx16pos = 0;
}
@ -755,7 +741,7 @@ int32_t WebRtcAgc_ProcessAnalog(void* state,
} else if (stt->activeSpeech == 250) {
stt->activeSpeech += 2;
tmp32 = stt->Rxx16_LPw32Max >> 3;
stt->Rxx160_LPw32 = tmp32 * RXX_BUFFER_LEN;
stt->Rxx160_LPw32 = tmp32 * kRxxBufferLen;
}
tmp32 = (stt->Rxx160w32 - stt->Rxx160_LPw32) >> kAlphaLongTerm;
@ -796,9 +782,6 @@ int32_t WebRtcAgc_ProcessAnalog(void* state,
*/
stt->activeSpeech = 0;
stt->Rxx16_LPw32Max = 0;
#ifdef MIC_LEVEL_FEEDBACK
// stt->numBlocksMicLvlSat = 0;
#endif
}
} else if (stt->Rxx160_LPw32 > stt->upperLimit) {
stt->msTooHigh += 2;
@ -828,10 +811,6 @@ int32_t WebRtcAgc_ProcessAnalog(void* state,
stt->micVol = lastMicVol - 1;
}
inMicLevelTmp = stt->micVol;
#ifdef MIC_LEVEL_FEEDBACK
// stt->numBlocksMicLvlSat = 0;
#endif
}
} else if (stt->Rxx160_LPw32 < stt->lowerSecondaryLimit) {
stt->msTooHigh = 0;
@ -871,16 +850,6 @@ int32_t WebRtcAgc_ProcessAnalog(void* state,
}
inMicLevelTmp = stt->micVol;
#ifdef MIC_LEVEL_FEEDBACK
/* Count ms in level saturation */
// if (stt->micVol > stt->maxAnalog) {
if (stt->micVol > 150) {
/* mic level is saturated */
stt->numBlocksMicLvlSat++;
fprintf(stderr, "Sat mic Level: %d\n", stt->numBlocksMicLvlSat);
}
#endif
}
} else if (stt->Rxx160_LPw32 < stt->lowerLimit) {
stt->msTooHigh = 0;
@ -920,16 +889,6 @@ int32_t WebRtcAgc_ProcessAnalog(void* state,
}
inMicLevelTmp = stt->micVol;
#ifdef MIC_LEVEL_FEEDBACK
/* Count ms in level saturation */
// if (stt->micVol > stt->maxAnalog) {
if (stt->micVol > 150) {
/* mic level is saturated */
stt->numBlocksMicLvlSat++;
fprintf(stderr, "Sat mic Level: %d\n", stt->numBlocksMicLvlSat);
}
#endif
}
} else {
/* The signal is inside the desired range which is:
@ -948,22 +907,6 @@ int32_t WebRtcAgc_ProcessAnalog(void* state,
stt->micVol = inMicLevelTmp;
}
#ifdef MIC_LEVEL_FEEDBACK
if (stt->numBlocksMicLvlSat > NUM_BLOCKS_IN_SAT_BEFORE_CHANGE_TARGET) {
stt->micLvlSat = 1;
fprintf(stderr, "target before = %d (%d)\n", stt->analogTargetLevel,
stt->targetIdx);
WebRtcAgc_UpdateAgcThresholds(stt);
WebRtcAgc_CalculateGainTable(
&(stt->digitalAgc.gainTable[0]), stt->compressionGaindB,
stt->targetLevelDbfs, stt->limiterEnable, stt->analogTarget);
stt->numBlocksMicLvlSat = 0;
stt->micLvlSat = 0;
fprintf(stderr, "target offset = %d\n", stt->targetIdxOffset);
fprintf(stderr, "target after = %d (%d)\n", stt->analogTargetLevel,
stt->targetIdx);
}
#endif
}
}
@ -998,7 +941,7 @@ int WebRtcAgc_Analyze(void* agcInst,
int16_t echo,
uint8_t* saturationWarning,
int32_t gains[11]) {
LegacyAgc* stt = (LegacyAgc*)agcInst;
LegacyAgc* stt = reinterpret_cast<LegacyAgc*>(agcInst);
if (stt == NULL) {
return -1;
@ -1020,7 +963,6 @@ int WebRtcAgc_Analyze(void* agcInst,
// TODO(minyue): PUT IN RANGE CHECKING FOR INPUT LEVELS
*outMicLevel = inMicLevel;
int32_t error =
WebRtcAgc_ComputeDigitalGains(&stt->digitalAgc, in_near, num_bands,
stt->fs, stt->lowLevelSignal, gains);
@ -1051,17 +993,17 @@ int WebRtcAgc_Analyze(void* agcInst,
}
int WebRtcAgc_Process(const void* agcInst,
const int32_t gains[11],
const int32_t gains[11],
const int16_t* const* in_near,
size_t num_bands,
int16_t* const* out) {
int16_t* const* out) {
const LegacyAgc* stt = (const LegacyAgc*)agcInst;
return WebRtcAgc_ApplyDigitalGains(gains, num_bands, stt->fs, in_near, out);
}
int WebRtcAgc_set_config(void* agcInst, WebRtcAgcConfig agcConfig) {
LegacyAgc* stt;
stt = (LegacyAgc*)agcInst;
stt = reinterpret_cast<LegacyAgc*>(agcInst);
if (stt == NULL) {
return -1;
@ -1109,7 +1051,7 @@ int WebRtcAgc_set_config(void* agcInst, WebRtcAgcConfig agcConfig) {
int WebRtcAgc_get_config(void* agcInst, WebRtcAgcConfig* config) {
LegacyAgc* stt;
stt = (LegacyAgc*)agcInst;
stt = reinterpret_cast<LegacyAgc*>(agcInst);
if (stt == NULL) {
return -1;
@ -1133,7 +1075,7 @@ int WebRtcAgc_get_config(void* agcInst, WebRtcAgcConfig* config) {
}
void* WebRtcAgc_Create() {
LegacyAgc* stt = malloc(sizeof(LegacyAgc));
LegacyAgc* stt = static_cast<LegacyAgc*>(malloc(sizeof(LegacyAgc)));
stt->initFlag = 0;
stt->lastError = 0;
@ -1144,7 +1086,7 @@ void* WebRtcAgc_Create() {
void WebRtcAgc_Free(void* state) {
LegacyAgc* stt;
stt = (LegacyAgc*)state;
stt = reinterpret_cast<LegacyAgc*>(state);
free(stt);
}
@ -1162,7 +1104,7 @@ int WebRtcAgc_Init(void* agcInst,
LegacyAgc* stt;
/* typecast state pointer */
stt = (LegacyAgc*)agcInst;
stt = reinterpret_cast<LegacyAgc*>(agcInst);
if (WebRtcAgc_InitDigital(&stt->digitalAgc, agcMode) != 0) {
stt->lastError = AGC_UNINITIALIZED_ERROR;
@ -1172,13 +1114,13 @@ int WebRtcAgc_Init(void* agcInst,
/* Analog AGC variables */
stt->envSum = 0;
/* mode = 0 - Only saturation protection
* 1 - Analog Automatic Gain Control [-targetLevelDbfs (default -3
* dBOv)]
* 2 - Digital Automatic Gain Control [-targetLevelDbfs (default -3
* dBOv)]
* 3 - Fixed Digital Gain [compressionGaindB (default 8 dB)]
*/
/* mode = 0 - Only saturation protection
* 1 - Analog Automatic Gain Control [-targetLevelDbfs (default -3
* dBOv)]
* 2 - Digital Automatic Gain Control [-targetLevelDbfs (default -3
* dBOv)]
* 3 - Fixed Digital Gain [compressionGaindB (default 8 dB)]
*/
if (agcMode < kAgcModeUnchanged || agcMode > kAgcModeFixedDigital) {
return -1;
}
@ -1229,10 +1171,6 @@ int WebRtcAgc_Init(void* agcInst,
}
stt->micRef = stt->micVol;
stt->micGainIdx = 127;
#ifdef MIC_LEVEL_FEEDBACK
stt->numBlocksMicLvlSat = 0;
stt->micLvlSat = 0;
#endif
/* Minimum output volume is 4% higher than the available lowest volume level
*/
@ -1256,11 +1194,10 @@ int WebRtcAgc_Init(void* agcInst,
stt->vadThreshold = kNormalVadThreshold;
stt->inActive = 0;
for (i = 0; i < RXX_BUFFER_LEN; i++) {
for (i = 0; i < kRxxBufferLen; i++) {
stt->Rxx16_vectorw32[i] = (int32_t)1000; /* -54dBm0 */
}
stt->Rxx160w32 =
125 * RXX_BUFFER_LEN; /* (stt->Rxx16_vectorw32[0]>>3) = 125 */
stt->Rxx160w32 = 125 * kRxxBufferLen; /* (stt->Rxx16_vectorw32[0]>>3) = 125 */
stt->Rxx16pos = 0;
stt->Rxx16_LPw32 = (int32_t)16284; /* Q(-4) */
@ -1274,10 +1211,6 @@ int WebRtcAgc_Init(void* agcInst,
}
stt->inQueue = 0;
#ifdef MIC_LEVEL_FEEDBACK
stt->targetIdxOffset = 0;
#endif
WebRtcSpl_MemSetW32(stt->filterState, 0, 8);
stt->initFlag = kInitCheck;
@ -1301,3 +1234,5 @@ int WebRtcAgc_Init(void* agcInst,
return 0;
}
}
} // namespace webrtc

View File

@ -11,11 +11,12 @@
#ifndef MODULES_AUDIO_PROCESSING_AGC_LEGACY_ANALOG_AGC_H_
#define MODULES_AUDIO_PROCESSING_AGC_LEGACY_ANALOG_AGC_H_
//#define MIC_LEVEL_FEEDBACK
#include "modules/audio_processing/agc/legacy/digital_agc.h"
#include "modules/audio_processing/agc/legacy/gain_control.h"
namespace webrtc {
/* Analog Automatic Gain Control variables:
* Constant declarations (inner limits inside which no changes are done)
* In the beginning the range is narrower to widen as soon as the measure
@ -28,7 +29,7 @@
* of our measure Rxx160_LP. Remember that the levels are in blocks of 16 in
* Q(-7). (Example matlab code: round(db2pow(-21.2)*16/2^7) )
*/
#define RXX_BUFFER_LEN 10
constexpr int16_t kRxxBufferLen = 10;
static const int16_t kMsecSpeechInner = 520;
static const int16_t kMsecSpeechOuter = 340;
@ -54,17 +55,14 @@ typedef struct {
// Target level parameters
// Based on the above: analogTargetLevel = round((32767*10^(-22/20))^2*16/2^7)
int32_t analogTargetLevel; // = RXX_BUFFER_LEN * 846805; -22 dBfs
int32_t startUpperLimit; // = RXX_BUFFER_LEN * 1066064; -21 dBfs
int32_t startLowerLimit; // = RXX_BUFFER_LEN * 672641; -23 dBfs
int32_t upperPrimaryLimit; // = RXX_BUFFER_LEN * 1342095; -20 dBfs
int32_t lowerPrimaryLimit; // = RXX_BUFFER_LEN * 534298; -24 dBfs
int32_t upperSecondaryLimit; // = RXX_BUFFER_LEN * 2677832; -17 dBfs
int32_t lowerSecondaryLimit; // = RXX_BUFFER_LEN * 267783; -27 dBfs
int32_t analogTargetLevel; // = kRxxBufferLen * 846805; -22 dBfs
int32_t startUpperLimit; // = kRxxBufferLen * 1066064; -21 dBfs
int32_t startLowerLimit; // = kRxxBufferLen * 672641; -23 dBfs
int32_t upperPrimaryLimit; // = kRxxBufferLen * 1342095; -20 dBfs
int32_t lowerPrimaryLimit; // = kRxxBufferLen * 534298; -24 dBfs
int32_t upperSecondaryLimit; // = kRxxBufferLen * 2677832; -17 dBfs
int32_t lowerSecondaryLimit; // = kRxxBufferLen * 267783; -27 dBfs
uint16_t targetIdx; // Table index for corresponding target level
#ifdef MIC_LEVEL_FEEDBACK
uint16_t targetIdxOffset; // Table index offset for level compensation
#endif
int16_t analogTarget; // Digital reference level in ENV scale
// Analog AGC specific variables
@ -75,7 +73,7 @@ typedef struct {
int32_t Rxx16_LPw32; // Low pass filtered subframe energies
int32_t Rxx160_LPw32; // Low pass filtered frame energies
int32_t Rxx16_LPw32Max; // Keeps track of largest energy subframe
int32_t Rxx16_vectorw32[RXX_BUFFER_LEN]; // Array with subframe energies
int32_t Rxx16_vectorw32[kRxxBufferLen]; // Array with subframe energies
int32_t Rxx16w32_array[2][5]; // Energy values of microphone signal
int32_t env[2][10]; // Envelope values of subframes
@ -108,10 +106,6 @@ typedef struct {
int32_t lastInMicLevel;
int16_t scale; // Scale factor for internal volume levels
#ifdef MIC_LEVEL_FEEDBACK
int16_t numBlocksMicLvlSat;
uint8_t micLvlSat;
#endif
// Structs for VAD and digital_agc
AgcVad vadMic;
DigitalAgc digitalAgc;
@ -119,4 +113,6 @@ typedef struct {
int16_t lowLevelSignal;
} LegacyAgc;
} // namespace webrtc
#endif // MODULES_AUDIO_PROCESSING_AGC_LEGACY_ANALOG_AGC_H_

View File

@ -8,16 +8,16 @@
* be found in the AUTHORS file in the root of the source tree.
*/
/* digital_agc.c
*
*/
#include "modules/audio_processing/agc/legacy/digital_agc.h"
#include <string.h>
#include "rtc_base/checks.h"
#include "modules/audio_processing/agc/legacy/gain_control.h"
#include "rtc_base/checks.h"
namespace webrtc {
namespace {
// To generate the gaintable, copy&paste the following lines to a Matlab window:
// MaxGain = 6; MinGain = 0; CompRatio = 3; Knee = 1;
@ -55,12 +55,19 @@ static const uint16_t kGenFuncTable[kGenFuncTableSize] = {
static const int16_t kAvgDecayTime = 250; // frames; < 3000
// the 32 most significant bits of A(19) * B(26) >> 13
#define AGC_MUL32(A, B) (((B) >> 13) * (A) + (((0x00001FFF & (B)) * (A)) >> 13))
// C + the 32 most significant bits of A * B
#define AGC_SCALEDIFF32(A, B, C) \
((C) + ((B) >> 16) * (A) + (((0x0000FFFF & (B)) * (A)) >> 16))
} // namespace
int32_t WebRtcAgc_CalculateGainTable(int32_t* gainTable, // Q16
int16_t digCompGaindB, // Q0
int16_t targetLevelDbfs, // Q0
uint8_t limiterEnable,
int16_t analogTarget) // Q0
{
int16_t analogTarget) { // Q0
// This function generates the compressor gain table used in the fixed digital
// part.
uint32_t tmpU32no1, tmpU32no2, absInLevel, logApprox;
@ -186,8 +193,7 @@ int32_t WebRtcAgc_CalculateGainTable(int32_t* gainTable, // Q16
// Calculate ratio
// Shift |numFIX| as much as possible.
// Ensure we avoid wrap-around in |den| as well.
if (numFIX > (den >> 8) || -numFIX > (den >> 8)) // |den| is Q8.
{
if (numFIX > (den >> 8) || -numFIX > (den >> 8)) { // |den| is Q8.
zeros = WebRtcSpl_NormW32(numFIX);
} else {
zeros = WebRtcSpl_NormW32(den) + 8;
@ -196,7 +202,7 @@ int32_t WebRtcAgc_CalculateGainTable(int32_t* gainTable, // Q16
// Shift den so we end up in Qy1
tmp32no1 = WEBRTC_SPL_SHIFT_W32(den, zeros - 9); // Q(zeros - 1)
y32 = numFIX / tmp32no1; // in Q15
y32 = numFIX / tmp32no1; // in Q15
// This is to do rounding in Q14.
y32 = y32 >= 0 ? (y32 + 1) >> 1 : -((-y32 + 1) >> 1);
@ -394,8 +400,9 @@ int32_t WebRtcAgc_ComputeDigitalGains(DigitalAgc* stt,
tmp32 = ((uint32_t)cur_level << zeros) & 0x7FFFFFFF;
frac = (int16_t)(tmp32 >> 19); // Q12.
// Interpolate between gainTable[zeros] and gainTable[zeros-1].
tmp32 = ((stt->gainTable[zeros - 1] - stt->gainTable[zeros]) *
(int64_t)frac) >> 12;
tmp32 =
((stt->gainTable[zeros - 1] - stt->gainTable[zeros]) * (int64_t)frac) >>
12;
gains[k + 1] = stt->gainTable[zeros] + tmp32;
}
@ -476,8 +483,10 @@ int32_t WebRtcAgc_ComputeDigitalGains(DigitalAgc* stt,
return 0;
}
int32_t WebRtcAgc_ApplyDigitalGains(const int32_t gains[11], size_t num_bands,
uint32_t FS, const int16_t* const* in_near,
int32_t WebRtcAgc_ApplyDigitalGains(const int32_t gains[11],
size_t num_bands,
uint32_t FS,
const int16_t* const* in_near,
int16_t* const* out) {
// Apply gain
// handle first sub frame separately
@ -531,11 +540,9 @@ int32_t WebRtcAgc_ApplyDigitalGains(const int32_t gains[11], size_t num_bands,
tmp64 = tmp64 >> 16;
if (tmp64 > 32767) {
out[i][k * L + n] = 32767;
}
else if (tmp64 < -32768) {
} else if (tmp64 < -32768) {
out[i][k * L + n] = -32768;
}
else {
} else {
out[i][k * L + n] = (int16_t)(tmp64);
}
}
@ -572,10 +579,9 @@ void WebRtcAgc_InitVad(AgcVad* state) {
}
}
int16_t WebRtcAgc_ProcessVad(AgcVad* state, // (i) VAD state
const int16_t* in, // (i) Speech signal
size_t nrSamples) // (i) number of samples
{
int16_t WebRtcAgc_ProcessVad(AgcVad* state, // (i) VAD state
const int16_t* in, // (i) Speech signal
size_t nrSamples) { // (i) number of samples
uint32_t nrg;
int32_t out, tmp32, tmp32b;
uint16_t tmpU16;
@ -704,3 +710,5 @@ int16_t WebRtcAgc_ProcessVad(AgcVad* state, // (i) VAD state
return state->logRatio; // Q10
}
} // namespace webrtc

View File

@ -13,11 +13,7 @@
#include "common_audio/signal_processing/include/signal_processing_library.h"
// the 32 most significant bits of A(19) * B(26) >> 13
#define AGC_MUL32(A, B) (((B) >> 13) * (A) + (((0x00001FFF & (B)) * (A)) >> 13))
// C + the 32 most significant bits of A * B
#define AGC_SCALEDIFF32(A, B, C) \
((C) + ((B) >> 16) * (A) + (((0x0000FFFF & (B)) * (A)) >> 16))
namespace webrtc {
typedef struct {
int32_t downState[8];
@ -74,4 +70,6 @@ int32_t WebRtcAgc_CalculateGainTable(int32_t* gainTable, // Q16
uint8_t limiterEnable,
int16_t analogTarget);
} // namespace webrtc
#endif // MODULES_AUDIO_PROCESSING_AGC_LEGACY_DIGITAL_AGC_H_

View File

@ -11,15 +11,7 @@
#ifndef MODULES_AUDIO_PROCESSING_AGC_LEGACY_GAIN_CONTROL_H_
#define MODULES_AUDIO_PROCESSING_AGC_LEGACY_GAIN_CONTROL_H_
// Errors
#define AGC_UNSPECIFIED_ERROR 18000
#define AGC_UNSUPPORTED_FUNCTION_ERROR 18001
#define AGC_UNINITIALIZED_ERROR 18002
#define AGC_NULL_POINTER_ERROR 18003
#define AGC_BAD_PARAMETER_ERROR 18004
// Warnings
#define AGC_BAD_PARAMETER_WARNING 18050
namespace webrtc {
enum {
kAgcModeUnchanged,
@ -36,10 +28,6 @@ typedef struct {
uint8_t limiterEnable; // default kAgcTrue (on)
} WebRtcAgcConfig;
#if defined(__cplusplus)
extern "C" {
#endif
/*
* This function analyses the number of samples passed to
* farend and produces any error code that could arise.
@ -260,8 +248,6 @@ int WebRtcAgc_Init(void* agcInst,
int16_t agcMode,
uint32_t fs);
#if defined(__cplusplus)
}
#endif
} // namespace webrtc
#endif // MODULES_AUDIO_PROCESSING_AGC_LEGACY_GAIN_CONTROL_H_