Changed the digital AGC1 gain to properly support multichannel
Beyond making the digital AGC1 code properly support
multichannel, this CL also
-Removes deprecated debug logging code.
-Converts the gain application to be fully in floating point
which
--Is less computationally complex.
--Does not quantize the samples to 16 bit before applying the
gains.
Bug: webrtc:10859
Change-Id: I6020ba8ae7e311dfc93a72783a2bb68d935f90c5
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/159861
Commit-Queue: Per Åhgren <peah@webrtc.org>
Reviewed-by: Gustaf Ullberg <gustaf@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#29886}
diff --git a/modules/audio_processing/agc/legacy/analog_agc.c b/modules/audio_processing/agc/legacy/analog_agc.c
index 662e88b..6b75728 100644
--- a/modules/audio_processing/agc/legacy/analog_agc.c
+++ b/modules/audio_processing/agc/legacy/analog_agc.c
@@ -20,9 +20,6 @@
#include "modules/audio_processing/agc/legacy/analog_agc.h"
#include <stdlib.h>
-#ifdef WEBRTC_AGC_DEBUG_DUMP
-#include <stdio.h>
-#endif
#include "rtc_base/checks.h"
@@ -510,12 +507,6 @@
stt->micVol = *inMicLevel;
}
-#ifdef WEBRTC_AGC_DEBUG_DUMP
- fprintf(stt->fpt,
- "\t\tAGC->zeroCntrl, frame %d: 500 ms under threshold,"
- " micVol: %d\n",
- stt->fcount, stt->micVol);
-#endif
stt->activeSpeech = 0;
stt->Rxx16_LPw32Max = 0;
@@ -605,16 +596,8 @@
inMicLevelTmp = inMicLevel << stt->scale;
if (inMicLevelTmp > stt->maxAnalog) {
-#ifdef WEBRTC_AGC_DEBUG_DUMP
- fprintf(stt->fpt, "\tAGC->ProcessAnalog, frame %d: micLvl > maxAnalog\n",
- stt->fcount);
-#endif
return -1;
} else if (inMicLevelTmp < stt->minLevel) {
-#ifdef WEBRTC_AGC_DEBUG_DUMP
- fprintf(stt->fpt, "\tAGC->ProcessAnalog, frame %d: micLvl < minLevel\n",
- stt->fcount);
-#endif
return -1;
}
@@ -645,12 +628,6 @@
#ifdef MIC_LEVEL_FEEDBACK
// stt->numBlocksMicLvlSat = 0;
#endif
-#ifdef WEBRTC_AGC_DEBUG_DUMP
- fprintf(stt->fpt,
- "\tAGC->ProcessAnalog, frame %d: micLvl < minLevel by manual"
- " decrease, raise vol\n",
- stt->fcount);
-#endif
}
if (inMicLevelTmp != stt->micVol) {
@@ -699,11 +676,6 @@
}
inMicLevelTmp = stt->micVol;
-#ifdef WEBRTC_AGC_DEBUG_DUMP
- fprintf(stt->fpt,
- "\tAGC->ProcessAnalog, frame %d: saturated, micVol = %d\n",
- stt->fcount, stt->micVol);
-#endif
if (stt->micVol < stt->minOutput) {
*saturationWarning = 1;
@@ -827,12 +799,6 @@
#ifdef MIC_LEVEL_FEEDBACK
// stt->numBlocksMicLvlSat = 0;
#endif
-#ifdef WEBRTC_AGC_DEBUG_DUMP
- fprintf(stt->fpt,
- "\tAGC->ProcessAnalog, frame %d: measure >"
- " 2ndUpperLim, micVol = %d, maxLevel = %d\n",
- stt->fcount, stt->micVol, stt->maxLevel);
-#endif
}
} else if (stt->Rxx160_LPw32 > stt->upperLimit) {
stt->msTooHigh += 2;
@@ -866,12 +832,6 @@
#ifdef MIC_LEVEL_FEEDBACK
// stt->numBlocksMicLvlSat = 0;
#endif
-#ifdef WEBRTC_AGC_DEBUG_DUMP
- fprintf(stt->fpt,
- "\tAGC->ProcessAnalog, frame %d: measure >"
- " UpperLim, micVol = %d, maxLevel = %d\n",
- stt->fcount, stt->micVol, stt->maxLevel);
-#endif
}
} else if (stt->Rxx160_LPw32 < stt->lowerSecondaryLimit) {
stt->msTooHigh = 0;
@@ -921,12 +881,6 @@
fprintf(stderr, "Sat mic Level: %d\n", stt->numBlocksMicLvlSat);
}
#endif
-#ifdef WEBRTC_AGC_DEBUG_DUMP
- fprintf(stt->fpt,
- "\tAGC->ProcessAnalog, frame %d: measure <"
- " 2ndLowerLim, micVol = %d\n",
- stt->fcount, stt->micVol);
-#endif
}
} else if (stt->Rxx160_LPw32 < stt->lowerLimit) {
stt->msTooHigh = 0;
@@ -976,12 +930,6 @@
fprintf(stderr, "Sat mic Level: %d\n", stt->numBlocksMicLvlSat);
}
#endif
-#ifdef WEBRTC_AGC_DEBUG_DUMP
- fprintf(stt->fpt,
- "\tAGC->ProcessAnalog, frame %d: measure < LowerLim, micVol "
- "= %d\n",
- stt->fcount, stt->micVol);
-#endif
}
} else {
/* The signal is inside the desired range which is:
@@ -1041,24 +989,20 @@
return 0;
}
-int WebRtcAgc_Process(void* agcInst,
+int WebRtcAgc_Analyze(void* agcInst,
const int16_t* const* in_near,
size_t num_bands,
size_t samples,
- int16_t* const* out,
int32_t inMicLevel,
int32_t* outMicLevel,
int16_t echo,
- uint8_t* saturationWarning) {
- LegacyAgc* stt;
+ uint8_t* saturationWarning,
+ int32_t gains[11]) {
+ LegacyAgc* stt = (LegacyAgc*)agcInst;
- stt = (LegacyAgc*)agcInst;
-
- //
if (stt == NULL) {
return -1;
}
- //
if (stt->fs == 8000) {
if (samples != 80) {
@@ -1076,18 +1020,14 @@
// TODO(minyue): PUT IN RANGE CHECKING FOR INPUT LEVELS
*outMicLevel = inMicLevel;
-#ifdef WEBRTC_AGC_DEBUG_DUMP
- stt->fcount++;
-#endif
- if (WebRtcAgc_ProcessDigital(&stt->digitalAgc, in_near, num_bands, out,
- stt->fs, stt->lowLevelSignal) == -1) {
-#ifdef WEBRTC_AGC_DEBUG_DUMP
- fprintf(stt->fpt, "AGC->Process, frame %d: Error from DigAGC\n\n",
- stt->fcount);
-#endif
+ int32_t error =
+ WebRtcAgc_ComputeDigitalGains(&stt->digitalAgc, in_near, num_bands,
+ stt->fs, stt->lowLevelSignal, gains);
+ if (error == -1) {
return -1;
}
+
if (stt->agcMode < kAgcModeFixedDigital &&
(stt->lowLevelSignal == 0 || stt->agcMode != kAgcModeAdaptiveDigital)) {
if (WebRtcAgc_ProcessAnalog(agcInst, inMicLevel, outMicLevel,
@@ -1096,10 +1036,6 @@
return -1;
}
}
-#ifdef WEBRTC_AGC_DEBUG_DUMP
- fprintf(stt->agcLog, "%5d\t%d\t%d\t%d\t%d\n", stt->fcount, inMicLevel,
- *outMicLevel, stt->maxLevel, stt->micVol);
-#endif
/* update queue */
if (stt->inQueue > 1) {
@@ -1114,6 +1050,15 @@
return 0;
}
+int WebRtcAgc_Process(const void* agcInst,
+ const int32_t gains[11],
+ const int16_t* const* in_near,
+ size_t num_bands,
+ 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;
@@ -1152,10 +1097,6 @@
if (WebRtcAgc_CalculateGainTable(
&(stt->digitalAgc.gainTable[0]), stt->compressionGaindB,
stt->targetLevelDbfs, stt->limiterEnable, stt->analogTarget) == -1) {
-#ifdef WEBRTC_AGC_DEBUG_DUMP
- fprintf(stt->fpt, "AGC->set_config, frame %d: Error from calcGainTable\n\n",
- stt->fcount);
-#endif
return -1;
}
/* Store the config in a WebRtcAgcConfig */
@@ -1194,12 +1135,6 @@
void* WebRtcAgc_Create() {
LegacyAgc* stt = malloc(sizeof(LegacyAgc));
-#ifdef WEBRTC_AGC_DEBUG_DUMP
- stt->fpt = fopen("./agc_test_log.txt", "wt");
- stt->agcLog = fopen("./agc_debug_log.txt", "wt");
- stt->digitalAgc.logFile = fopen("./agc_log.txt", "wt");
-#endif
-
stt->initFlag = 0;
stt->lastError = 0;
@@ -1210,11 +1145,6 @@
LegacyAgc* stt;
stt = (LegacyAgc*)state;
-#ifdef WEBRTC_AGC_DEBUG_DUMP
- fclose(stt->fpt);
- fclose(stt->agcLog);
- fclose(stt->digitalAgc.logFile);
-#endif
free(stt);
}
@@ -1249,14 +1179,7 @@
* dBOv)]
* 3 - Fixed Digital Gain [compressionGaindB (default 8 dB)]
*/
-#ifdef WEBRTC_AGC_DEBUG_DUMP
- stt->fcount = 0;
- fprintf(stt->fpt, "AGC->Init\n");
-#endif
if (agcMode < kAgcModeUnchanged || agcMode > kAgcModeFixedDigital) {
-#ifdef WEBRTC_AGC_DEBUG_DUMP
- fprintf(stt->fpt, "AGC->Init: error, incorrect mode\n\n");
-#endif
return -1;
}
stt->agcMode = agcMode;
@@ -1310,10 +1233,6 @@
stt->numBlocksMicLvlSat = 0;
stt->micLvlSat = 0;
#endif
-#ifdef WEBRTC_AGC_DEBUG_DUMP
- fprintf(stt->fpt, "AGC->Init: minLevel = %d, maxAnalog = %d, maxLevel = %d\n",
- stt->minLevel, stt->maxAnalog, stt->maxLevel);
-#endif
/* Minimum output volume is 4% higher than the available lowest volume level
*/
@@ -1377,14 +1296,8 @@
/* Only positive values are allowed that are not too large */
if ((minLevel >= maxLevel) || (maxLevel & 0xFC000000)) {
-#ifdef WEBRTC_AGC_DEBUG_DUMP
- fprintf(stt->fpt, "minLevel, maxLevel value(s) are invalid\n\n");
-#endif
return -1;
} else {
-#ifdef WEBRTC_AGC_DEBUG_DUMP
- fprintf(stt->fpt, "\n");
-#endif
return 0;
}
}
diff --git a/modules/audio_processing/agc/legacy/analog_agc.h b/modules/audio_processing/agc/legacy/analog_agc.h
index 619d95a..b36edfe 100644
--- a/modules/audio_processing/agc/legacy/analog_agc.h
+++ b/modules/audio_processing/agc/legacy/analog_agc.h
@@ -12,9 +12,6 @@
#define MODULES_AUDIO_PROCESSING_AGC_LEGACY_ANALOG_AGC_H_
//#define MIC_LEVEL_FEEDBACK
-#ifdef WEBRTC_AGC_DEBUG_DUMP
-#include <stdio.h>
-#endif
#include "modules/audio_processing/agc/legacy/digital_agc.h"
#include "modules/audio_processing/agc/legacy/gain_control.h"
@@ -119,12 +116,6 @@
AgcVad vadMic;
DigitalAgc digitalAgc;
-#ifdef WEBRTC_AGC_DEBUG_DUMP
- FILE* fpt;
- FILE* agcLog;
- int32_t fcount;
-#endif
-
int16_t lowLevelSignal;
} LegacyAgc;
diff --git a/modules/audio_processing/agc/legacy/digital_agc.c b/modules/audio_processing/agc/legacy/digital_agc.c
index d1c30bd..e408b15 100644
--- a/modules/audio_processing/agc/legacy/digital_agc.c
+++ b/modules/audio_processing/agc/legacy/digital_agc.c
@@ -15,9 +15,6 @@
#include "modules/audio_processing/agc/legacy/digital_agc.h"
#include <string.h>
-#ifdef WEBRTC_AGC_DEBUG_DUMP
-#include <stdio.h>
-#endif
#include "rtc_base/checks.h"
#include "modules/audio_processing/agc/legacy/gain_control.h"
@@ -254,9 +251,6 @@
stt->gain = 65536;
stt->gatePrevious = 0;
stt->agcMode = agcMode;
-#ifdef WEBRTC_AGC_DEBUG_DUMP
- stt->frameCounter = 0;
-#endif
// initialize VADs
WebRtcAgc_InitVad(&stt->vadNearend);
@@ -275,27 +269,25 @@
return 0;
}
-int32_t WebRtcAgc_ProcessDigital(DigitalAgc* stt,
- const int16_t* const* in_near,
- size_t num_bands,
- int16_t* const* out,
- uint32_t FS,
- int16_t lowlevelSignal) {
- // array for gains (one value per ms, incl start & end)
- int32_t gains[11];
-
- int32_t out_tmp, tmp32;
+// Gains is an 11 element long array (one value per ms, incl start & end).
+int32_t WebRtcAgc_ComputeDigitalGains(DigitalAgc* stt,
+ const int16_t* const* in_near,
+ size_t num_bands,
+ uint32_t FS,
+ int16_t lowlevelSignal,
+ int32_t gains[11]) {
+ int32_t tmp32;
int32_t env[10];
int32_t max_nrg;
int32_t cur_level;
- int32_t gain32, delta;
+ int32_t gain32;
int16_t logratio;
int16_t lower_thr, upper_thr;
int16_t zeros = 0, zeros_fast, frac = 0;
int16_t decay;
int16_t gate, gain_adj;
int16_t k;
- size_t n, i, L;
+ size_t n, L;
int16_t L2; // samples/subframe
// determine number of samples per ms
@@ -309,14 +301,8 @@
return -1;
}
- for (i = 0; i < num_bands; ++i) {
- if (in_near[i] != out[i]) {
- // Only needed if they don't already point to the same place.
- memcpy(out[i], in_near[i], 10 * L * sizeof(in_near[i][0]));
- }
- }
// VAD for near end
- logratio = WebRtcAgc_ProcessVad(&stt->vadNearend, out[0], L * 10);
+ logratio = WebRtcAgc_ProcessVad(&stt->vadNearend, in_near[0], L * 10);
// Account for far end VAD
if (stt->vadFarend.counter > 10) {
@@ -358,18 +344,13 @@
decay = 0;
}
}
-#ifdef WEBRTC_AGC_DEBUG_DUMP
- stt->frameCounter++;
- fprintf(stt->logFile, "%5.2f\t%d\t%d\t%d\t", (float)(stt->frameCounter) / 100,
- logratio, decay, stt->vadNearend.stdLongTerm);
-#endif
// Find max amplitude per sub frame
// iterate over sub frames
for (k = 0; k < 10; k++) {
// iterate over samples
max_nrg = 0;
for (n = 0; n < L; n++) {
- int32_t nrg = out[0][k * L + n] * out[0][k * L + n];
+ int32_t nrg = in_near[0][k * L + n] * in_near[0][k * L + n];
if (nrg > max_nrg) {
max_nrg = nrg;
}
@@ -416,12 +397,6 @@
tmp32 = ((stt->gainTable[zeros - 1] - stt->gainTable[zeros]) *
(int64_t)frac) >> 12;
gains[k + 1] = stt->gainTable[zeros] + tmp32;
-#ifdef WEBRTC_AGC_DEBUG_DUMP
- if (k == 0) {
- fprintf(stt->logFile, "%d\t%d\t%d\t%d\t%d\n", env[0], cur_level,
- stt->capacitorFast, stt->capacitorSlow, zeros);
- }
-#endif
}
// Gate processing (lower gain during absence of speech)
@@ -498,20 +473,47 @@
// save start gain for next frame
stt->gain = gains[10];
+ return 0;
+}
+
+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
- delta = (gains[1] - gains[0]) * (1 << (4 - L2));
- gain32 = gains[0] * (1 << 4);
+ size_t L;
+ int16_t L2; // samples/subframe
+
+ // determine number of samples per ms
+ if (FS == 8000) {
+ L = 8;
+ L2 = 3;
+ } else if (FS == 16000 || FS == 32000 || FS == 48000) {
+ L = 16;
+ L2 = 4;
+ } else {
+ return -1;
+ }
+
+ for (size_t i = 0; i < num_bands; ++i) {
+ if (in_near[i] != out[i]) {
+ // Only needed if they don't already point to the same place.
+ memcpy(out[i], in_near[i], 10 * L * sizeof(in_near[i][0]));
+ }
+ }
+
// iterate over samples
- for (n = 0; n < L; n++) {
- for (i = 0; i < num_bands; ++i) {
- out_tmp = (int64_t)out[i][n] * ((gain32 + 127) >> 7) >> 16;
+ int32_t delta = (gains[1] - gains[0]) * (1 << (4 - L2));
+ int32_t gain32 = gains[0] * (1 << 4);
+ for (size_t n = 0; n < L; n++) {
+ for (size_t i = 0; i < num_bands; ++i) {
+ int32_t out_tmp = (int64_t)out[i][n] * ((gain32 + 127) >> 7) >> 16;
if (out_tmp > 4095) {
out[i][n] = (int16_t)32767;
} else if (out_tmp < -4096) {
out[i][n] = (int16_t)-32768;
} else {
- tmp32 = ((int64_t)out[i][n] * (gain32 >> 4)) >> 16;
+ int32_t tmp32 = ((int64_t)out[i][n] * (gain32 >> 4)) >> 16;
out[i][n] = (int16_t)tmp32;
}
}
@@ -519,12 +521,12 @@
gain32 += delta;
}
// iterate over subframes
- for (k = 1; k < 10; k++) {
+ for (int k = 1; k < 10; k++) {
delta = (gains[k + 1] - gains[k]) * (1 << (4 - L2));
gain32 = gains[k] * (1 << 4);
// iterate over samples
- for (n = 0; n < L; n++) {
- for (i = 0; i < num_bands; ++i) {
+ for (size_t n = 0; n < L; n++) {
+ for (size_t i = 0; i < num_bands; ++i) {
int64_t tmp64 = ((int64_t)(out[i][k * L + n])) * (gain32 >> 4);
tmp64 = tmp64 >> 16;
if (tmp64 > 32767) {
@@ -540,7 +542,6 @@
gain32 += delta;
}
}
-
return 0;
}
diff --git a/modules/audio_processing/agc/legacy/digital_agc.h b/modules/audio_processing/agc/legacy/digital_agc.h
index f086294..5a2bbfe 100644
--- a/modules/audio_processing/agc/legacy/digital_agc.h
+++ b/modules/audio_processing/agc/legacy/digital_agc.h
@@ -11,9 +11,6 @@
#ifndef MODULES_AUDIO_PROCESSING_AGC_LEGACY_DIGITAL_AGC_H_
#define MODULES_AUDIO_PROCESSING_AGC_LEGACY_DIGITAL_AGC_H_
-#ifdef WEBRTC_AGC_DEBUG_DUMP
-#include <stdio.h>
-#endif
#include "common_audio/signal_processing/include/signal_processing_library.h"
// the 32 most significant bits of A(19) * B(26) >> 13
@@ -44,20 +41,22 @@
int16_t agcMode;
AgcVad vadNearend;
AgcVad vadFarend;
-#ifdef WEBRTC_AGC_DEBUG_DUMP
- FILE* logFile;
- int frameCounter;
-#endif
} DigitalAgc;
int32_t WebRtcAgc_InitDigital(DigitalAgc* digitalAgcInst, int16_t agcMode);
-int32_t WebRtcAgc_ProcessDigital(DigitalAgc* digitalAgcInst,
- const int16_t* const* inNear,
- size_t num_bands,
- int16_t* const* out,
- uint32_t FS,
- int16_t lowLevelSignal);
+int32_t WebRtcAgc_ComputeDigitalGains(DigitalAgc* digitalAgcInst,
+ const int16_t* const* inNear,
+ size_t num_bands,
+ uint32_t FS,
+ int16_t lowLevelSignal,
+ int32_t gains[11]);
+
+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);
int32_t WebRtcAgc_AddFarendToDigital(DigitalAgc* digitalAgcInst,
const int16_t* inFar,
diff --git a/modules/audio_processing/agc/legacy/gain_control.h b/modules/audio_processing/agc/legacy/gain_control.h
index a0ac96d..588874b 100644
--- a/modules/audio_processing/agc/legacy/gain_control.h
+++ b/modules/audio_processing/agc/legacy/gain_control.h
@@ -127,12 +127,12 @@
int32_t* micLevelOut);
/*
- * This function processes a 10 ms frame and adjusts (normalizes) the gain both
- * analog and digitally. The gain adjustments are done only during active
- * periods of speech. The length of the speech vectors must be given in samples
- * (80 when FS=8000, and 160 when FS=16000, FS=32000 or FS=48000). The echo
- * parameter can be used to ensure the AGC will not adjust upward in the
- * presence of echo.
+ * This function analyses a 10 ms frame and produces the analog and digital
+ * gains required to normalize the signal. The gain adjustments are done only
+ * during active periods of speech. The length of the speech vectors must be
+ * given in samples (80 when FS=8000, and 160 when FS=16000, FS=32000 or
+ * FS=48000). The echo parameter can be used to ensure the AGC will not adjust
+ * upward in the presence of echo.
*
* This function should be called after processing the near-end microphone
* signal, in any case after any echo cancellation.
@@ -150,25 +150,47 @@
*
* Output:
* - outMicLevel : Adjusted microphone volume level
- * - out : Gain-adjusted near-end speech vector
- * : May be the same vector as the input.
* - saturationWarning : A returned value of 1 indicates a saturation event
* has occurred and the volume cannot be further
* reduced. Otherwise will be set to 0.
+ * - gains : Vector of gains to apply for digital normalization
*
* Return value:
* : 0 - Normal operation.
* : -1 - Error
*/
-int WebRtcAgc_Process(void* agcInst,
+int WebRtcAgc_Analyze(void* agcInst,
const int16_t* const* inNear,
size_t num_bands,
size_t samples,
- int16_t* const* out,
int32_t inMicLevel,
int32_t* outMicLevel,
int16_t echo,
- uint8_t* saturationWarning);
+ uint8_t* saturationWarning,
+ int32_t gains[11]);
+
+/*
+ * This function processes a 10 ms frame by applying precomputed digital gains.
+ *
+ * Input:
+ * - agcInst : AGC instance
+ * - gains : Vector of gains to apply for digital normalization
+ * - in_near : Near-end input speech vector for each band
+ * - num_bands : Number of bands in input/output vector
+ *
+ * Output:
+ * - out : Gain-adjusted near-end speech vector
+ * : May be the same vector as the input.
+ *
+ * Return value:
+ * : 0 - Normal operation.
+ * : -1 - Error
+ */
+int WebRtcAgc_Process(const void* agcInst,
+ const int32_t gains[11],
+ const int16_t* const* in_near,
+ size_t num_bands,
+ int16_t* const* out);
/*
* This function sets the config parameters (targetLevelDbfs,
diff --git a/modules/audio_processing/gain_control_impl.cc b/modules/audio_processing/gain_control_impl.cc
index 7265d7b..d3573f8 100644
--- a/modules/audio_processing/gain_control_impl.cc
+++ b/modules/audio_processing/gain_control_impl.cc
@@ -18,8 +18,8 @@
#include "modules/audio_processing/include/audio_processing.h"
#include "modules/audio_processing/logging/apm_data_dumper.h"
#include "rtc_base/checks.h"
-#include "rtc_base/constructor_magic.h"
#include "rtc_base/logging.h"
+#include "system_wrappers/include/field_trial.h"
namespace webrtc {
@@ -39,59 +39,65 @@
return -1;
}
+// Checks whether the legacy digital gain application should be used.
+bool UseLegacyDigitalGainApplier() {
+ return field_trial::IsEnabled("WebRTC-UseLegacyDigitalGainApplier");
+}
+
+// Floating point variant of WebRtcAgc_Process.
+void ApplyDigitalGain(const int32_t gains[11],
+ size_t num_bands,
+ float* const* out) {
+ constexpr float kScaling = 1.f / 65536.f;
+ constexpr int kNumSubSections = 16;
+ constexpr float kOneByNumSubSections = 1.f / kNumSubSections;
+
+ float gains_scaled[11];
+ for (int k = 0; k < 11; ++k) {
+ gains_scaled[k] = gains[k] * kScaling;
+ }
+
+ for (size_t b = 0; b < num_bands; ++b) {
+ float* out_band = out[b];
+ for (int k = 0, sample = 0; k < 10; ++k) {
+ const float delta =
+ (gains_scaled[k + 1] - gains_scaled[k]) * kOneByNumSubSections;
+ float gain = gains_scaled[k];
+ for (int n = 0; n < kNumSubSections; ++n, ++sample) {
+ RTC_DCHECK_EQ(k * kNumSubSections + n, sample);
+ out_band[sample] *= gain;
+ out_band[sample] =
+ std::min(32767.f, std::max(-32768.f, out_band[sample]));
+ gain += delta;
+ }
+ }
+ }
+}
+
} // namespace
-class GainControlImpl::GainController {
- public:
- explicit GainController() {
- state_ = WebRtcAgc_Create();
- RTC_CHECK(state_);
+struct GainControlImpl::MonoAgcState {
+ MonoAgcState() {
+ state = WebRtcAgc_Create();
+ RTC_CHECK(state);
}
- ~GainController() {
- RTC_DCHECK(state_);
- WebRtcAgc_Free(state_);
+ ~MonoAgcState() {
+ RTC_DCHECK(state);
+ WebRtcAgc_Free(state);
}
- Handle* state() {
- RTC_DCHECK(state_);
- return state_;
- }
-
- void Initialize(int minimum_capture_level,
- int maximum_capture_level,
- Mode mode,
- int sample_rate_hz,
- int capture_level) {
- RTC_DCHECK(state_);
- int error =
- WebRtcAgc_Init(state_, minimum_capture_level, maximum_capture_level,
- MapSetting(mode), sample_rate_hz);
- RTC_DCHECK_EQ(0, error);
-
- set_capture_level(capture_level);
- }
-
- void set_capture_level(int capture_level) { capture_level_ = capture_level; }
-
- int get_capture_level() {
- RTC_DCHECK(capture_level_);
- return *capture_level_;
- }
-
- private:
- Handle* state_;
- // TODO(peah): Remove the optional once the initialization is moved into the
- // ctor.
- absl::optional<int> capture_level_;
-
- RTC_DISALLOW_COPY_AND_ASSIGN(GainController);
+ MonoAgcState(const MonoAgcState&) = delete;
+ MonoAgcState& operator=(const MonoAgcState&) = delete;
+ int32_t gains[11];
+ Handle* state;
};
int GainControlImpl::instance_counter_ = 0;
GainControlImpl::GainControlImpl()
: data_dumper_(new ApmDataDumper(instance_counter_)),
+ use_legacy_gain_applier_(UseLegacyDigitalGainApplier()),
mode_(kAdaptiveAnalog),
minimum_capture_level_(0),
maximum_capture_level_(255),
@@ -102,7 +108,7 @@
was_analog_level_set_(false),
stream_is_saturated_(false) {}
-GainControlImpl::~GainControlImpl() {}
+GainControlImpl::~GainControlImpl() = default;
void GainControlImpl::ProcessRenderAudio(
rtc::ArrayView<const int16_t> packed_render_audio) {
@@ -110,8 +116,8 @@
return;
}
- for (auto& gain_controller : gain_controllers_) {
- WebRtcAgc_AddFarend(gain_controller->state(), packed_render_audio.data(),
+ for (size_t ch = 0; ch < mono_agcs_.size(); ++ch) {
+ WebRtcAgc_AddFarend(mono_agcs_[ch]->state, packed_render_audio.data(),
packed_render_audio.size());
}
}
@@ -120,27 +126,28 @@
const AudioBuffer& audio,
std::vector<int16_t>* packed_buffer) {
RTC_DCHECK_GE(AudioBuffer::kMaxSplitFrameLength, audio.num_frames_per_band());
- std::array<int16_t, AudioBuffer::kMaxSplitFrameLength> mixed_low_pass_data;
- rtc::ArrayView<const int16_t> mixed_low_pass(mixed_low_pass_data.data(),
- audio.num_frames_per_band());
+ std::array<int16_t, AudioBuffer::kMaxSplitFrameLength>
+ mixed_16_kHz_render_data;
+ rtc::ArrayView<const int16_t> mixed_16_kHz_render(
+ mixed_16_kHz_render_data.data(), audio.num_frames_per_band());
if (audio.num_channels() == 1) {
FloatS16ToS16(audio.split_bands_const(0)[kBand0To8kHz],
- audio.num_frames_per_band(), mixed_low_pass_data.data());
+ audio.num_frames_per_band(), mixed_16_kHz_render_data.data());
} else {
const int num_channels = static_cast<int>(audio.num_channels());
for (size_t i = 0; i < audio.num_frames_per_band(); ++i) {
- int32_t value =
- FloatS16ToS16(audio.split_channels_const(kBand0To8kHz)[0][i]);
- for (int j = 1; j < num_channels; ++j) {
- value += FloatS16ToS16(audio.split_channels_const(kBand0To8kHz)[j][i]);
+ int32_t sum = 0;
+ for (int ch = 0; ch < num_channels; ++ch) {
+ sum += FloatS16ToS16(audio.split_channels_const(kBand0To8kHz)[ch][i]);
}
- mixed_low_pass_data[i] = value / num_channels;
+ mixed_16_kHz_render_data[i] = sum / num_channels;
}
}
packed_buffer->clear();
- packed_buffer->insert(packed_buffer->end(), mixed_low_pass.data(),
- (mixed_low_pass.data() + audio.num_frames_per_band()));
+ packed_buffer->insert(
+ packed_buffer->end(), mixed_16_kHz_render.data(),
+ (mixed_16_kHz_render.data() + audio.num_frames_per_band()));
}
int GainControlImpl::AnalyzeCaptureAudio(const AudioBuffer& audio) {
@@ -151,7 +158,7 @@
RTC_DCHECK(num_proc_channels_);
RTC_DCHECK_GE(AudioBuffer::kMaxSplitFrameLength, audio.num_frames_per_band());
RTC_DCHECK_EQ(audio.num_channels(), *num_proc_channels_);
- RTC_DCHECK_LE(*num_proc_channels_, gain_controllers_.size());
+ RTC_DCHECK_LE(*num_proc_channels_, mono_agcs_.size());
int16_t split_band_data[AudioBuffer::kMaxNumBands]
[AudioBuffer::kMaxSplitFrameLength];
@@ -159,39 +166,35 @@
split_band_data[0], split_band_data[1], split_band_data[2]};
if (mode_ == kAdaptiveAnalog) {
- int capture_channel = 0;
- for (auto& gain_controller : gain_controllers_) {
- gain_controller->set_capture_level(analog_capture_level_);
+ for (size_t ch = 0; ch < mono_agcs_.size(); ++ch) {
+ capture_levels_[ch] = analog_capture_level_;
- audio.ExportSplitChannelData(capture_channel, split_bands);
+ audio.ExportSplitChannelData(ch, split_bands);
int err =
- WebRtcAgc_AddMic(gain_controller->state(), split_bands,
+ WebRtcAgc_AddMic(mono_agcs_[ch]->state, split_bands,
audio.num_bands(), audio.num_frames_per_band());
if (err != AudioProcessing::kNoError) {
return AudioProcessing::kUnspecifiedError;
}
- ++capture_channel;
}
} else if (mode_ == kAdaptiveDigital) {
- int capture_channel = 0;
- for (auto& gain_controller : gain_controllers_) {
+ for (size_t ch = 0; ch < mono_agcs_.size(); ++ch) {
int32_t capture_level_out = 0;
- audio.ExportSplitChannelData(capture_channel, split_bands);
+ audio.ExportSplitChannelData(ch, split_bands);
int err =
- WebRtcAgc_VirtualMic(gain_controller->state(), split_bands,
+ WebRtcAgc_VirtualMic(mono_agcs_[ch]->state, split_bands,
audio.num_bands(), audio.num_frames_per_band(),
analog_capture_level_, &capture_level_out);
- gain_controller->set_capture_level(capture_level_out);
+ capture_levels_[ch] = capture_level_out;
if (err != AudioProcessing::kNoError) {
return AudioProcessing::kUnspecifiedError;
}
- ++capture_channel;
}
}
@@ -214,57 +217,78 @@
RTC_DCHECK_EQ(audio->num_channels(), *num_proc_channels_);
stream_is_saturated_ = false;
- int capture_channel = 0;
- for (auto& gain_controller : gain_controllers_) {
- int32_t capture_level_out = 0;
- uint8_t saturation_warning = 0;
-
+ bool error_reported = false;
+ for (size_t ch = 0; ch < mono_agcs_.size(); ++ch) {
int16_t split_band_data[AudioBuffer::kMaxNumBands]
[AudioBuffer::kMaxSplitFrameLength];
int16_t* split_bands[AudioBuffer::kMaxNumBands] = {
split_band_data[0], split_band_data[1], split_band_data[2]};
- audio->ExportSplitChannelData(capture_channel, split_bands);
+ audio->ExportSplitChannelData(ch, split_bands);
// The call to stream_has_echo() is ok from a deadlock perspective
// as the capture lock is allready held.
- int err = WebRtcAgc_Process(
- gain_controller->state(), split_bands, audio->num_bands(),
- audio->num_frames_per_band(), split_bands,
- gain_controller->get_capture_level(), &capture_level_out,
- stream_has_echo, &saturation_warning);
+ int32_t new_capture_level = 0;
+ uint8_t saturation_warning = 0;
+ int err_analyze = WebRtcAgc_Analyze(
+ mono_agcs_[ch]->state, split_bands, audio->num_bands(),
+ audio->num_frames_per_band(), capture_levels_[ch], &new_capture_level,
+ stream_has_echo, &saturation_warning, mono_agcs_[ch]->gains);
+ capture_levels_[ch] = new_capture_level;
- audio->ImportSplitChannelData(capture_channel, split_bands);
+ error_reported = error_reported || err_analyze != AudioProcessing::kNoError;
- if (err != AudioProcessing::kNoError) {
- return AudioProcessing::kUnspecifiedError;
+ stream_is_saturated_ = stream_is_saturated_ || saturation_warning == 1;
+ }
+
+ // Choose the minimun gain for application
+ size_t index_to_apply = 0;
+ for (size_t ch = 1; ch < mono_agcs_.size(); ++ch) {
+ if (mono_agcs_[index_to_apply]->gains[10] < mono_agcs_[ch]->gains[10]) {
+ index_to_apply = ch;
}
+ }
- gain_controller->set_capture_level(capture_level_out);
- if (saturation_warning == 1) {
- stream_is_saturated_ = true;
+ if (use_legacy_gain_applier_) {
+ for (size_t ch = 0; ch < mono_agcs_.size(); ++ch) {
+ int16_t split_band_data[AudioBuffer::kMaxNumBands]
+ [AudioBuffer::kMaxSplitFrameLength];
+ int16_t* split_bands[AudioBuffer::kMaxNumBands] = {
+ split_band_data[0], split_band_data[1], split_band_data[2]};
+ audio->ExportSplitChannelData(ch, split_bands);
+
+ int err_process = WebRtcAgc_Process(
+ mono_agcs_[ch]->state, mono_agcs_[index_to_apply]->gains, split_bands,
+ audio->num_bands(), split_bands);
+ RTC_DCHECK_EQ(err_process, 0);
+
+ audio->ImportSplitChannelData(ch, split_bands);
}
-
- ++capture_channel;
+ } else {
+ for (size_t ch = 0; ch < mono_agcs_.size(); ++ch) {
+ ApplyDigitalGain(mono_agcs_[index_to_apply]->gains, audio->num_bands(),
+ audio->split_bands(ch));
+ }
}
RTC_DCHECK_LT(0ul, *num_proc_channels_);
if (mode_ == kAdaptiveAnalog) {
- // Take the analog level to be the average across the handles.
- analog_capture_level_ = 0;
- for (auto& gain_controller : gain_controllers_) {
- analog_capture_level_ += gain_controller->get_capture_level();
+ // Take the analog level to be the minimum accross all channels.
+ analog_capture_level_ = capture_levels_[0];
+ for (size_t ch = 1; ch < mono_agcs_.size(); ++ch) {
+ analog_capture_level_ =
+ std::min(analog_capture_level_, capture_levels_[ch]);
}
+ }
- analog_capture_level_ /= (*num_proc_channels_);
+ if (error_reported) {
+ return AudioProcessing::kUnspecifiedError;
}
was_analog_level_set_ = false;
+
return AudioProcessing::kNoError;
}
-int GainControlImpl::compression_gain_db() const {
- return compression_gain_db_;
-}
// TODO(ajm): ensure this is called under kAdaptiveAnalog.
int GainControlImpl::set_stream_analog_level(int level) {
@@ -282,9 +306,6 @@
int GainControlImpl::stream_analog_level() const {
data_dumper_->DumpRaw("gain_control_stream_analog_level", 1,
&analog_capture_level_);
- // TODO(ajm): enable this assertion?
- // RTC_DCHECK_EQ(kAdaptiveAnalog, mode_);
-
return analog_capture_level_;
}
@@ -301,10 +322,6 @@
return AudioProcessing::kNoError;
}
-bool GainControlImpl::is_enabled() const {
- return enabled_;
-}
-
int GainControlImpl::set_mode(Mode mode) {
if (MapSetting(mode) == -1) {
return AudioProcessing::kBadParameterError;
@@ -317,49 +334,21 @@
return AudioProcessing::kNoError;
}
-GainControl::Mode GainControlImpl::mode() const {
- return mode_;
-}
int GainControlImpl::set_analog_level_limits(int minimum, int maximum) {
- if (minimum < 0) {
+ if (minimum < 0 || maximum > 65535 || maximum < minimum) {
return AudioProcessing::kBadParameterError;
}
- if (maximum > 65535) {
- return AudioProcessing::kBadParameterError;
- }
+ minimum_capture_level_ = minimum;
+ maximum_capture_level_ = maximum;
- if (maximum < minimum) {
- return AudioProcessing::kBadParameterError;
- }
-
- size_t num_proc_channels_local = 0u;
- int sample_rate_hz_local = 0;
- {
- minimum_capture_level_ = minimum;
- maximum_capture_level_ = maximum;
-
- RTC_DCHECK(num_proc_channels_);
- RTC_DCHECK(sample_rate_hz_);
- num_proc_channels_local = *num_proc_channels_;
- sample_rate_hz_local = *sample_rate_hz_;
- }
- Initialize(num_proc_channels_local, sample_rate_hz_local);
+ RTC_DCHECK(num_proc_channels_);
+ RTC_DCHECK(sample_rate_hz_);
+ Initialize(*num_proc_channels_, *sample_rate_hz_);
return AudioProcessing::kNoError;
}
-int GainControlImpl::analog_level_minimum() const {
- return minimum_capture_level_;
-}
-
-int GainControlImpl::analog_level_maximum() const {
- return maximum_capture_level_;
-}
-
-bool GainControlImpl::stream_is_saturated() const {
- return stream_is_saturated_;
-}
int GainControlImpl::set_target_level_dbfs(int level) {
if (level > 31 || level < 0) {
@@ -369,10 +358,6 @@
return Configure();
}
-int GainControlImpl::target_level_dbfs() const {
- return target_level_dbfs_;
-}
-
int GainControlImpl::set_compression_gain_db(int gain) {
if (gain < 0 || gain > 90) {
RTC_LOG(LS_ERROR) << "set_compression_gain_db(" << gain << ") failed.";
@@ -387,10 +372,6 @@
return Configure();
}
-bool GainControlImpl::is_limiter_enabled() const {
- return limiter_enabled_;
-}
-
void GainControlImpl::Initialize(size_t num_proc_channels, int sample_rate_hz) {
data_dumper_->InitiateNewSetOfRecordings();
@@ -401,13 +382,18 @@
return;
}
- gain_controllers_.resize(*num_proc_channels_);
- for (auto& gain_controller : gain_controllers_) {
- if (!gain_controller) {
- gain_controller.reset(new GainController());
+ mono_agcs_.resize(*num_proc_channels_);
+ capture_levels_.resize(*num_proc_channels_);
+ for (size_t ch = 0; ch < mono_agcs_.size(); ++ch) {
+ if (!mono_agcs_[ch]) {
+ mono_agcs_[ch].reset(new MonoAgcState());
}
- gain_controller->Initialize(minimum_capture_level_, maximum_capture_level_,
- mode_, *sample_rate_hz_, analog_capture_level_);
+
+ int error = WebRtcAgc_Init(mono_agcs_[ch]->state, minimum_capture_level_,
+ maximum_capture_level_, MapSetting(mode_),
+ *sample_rate_hz_);
+ RTC_DCHECK_EQ(error, 0);
+ capture_levels_[ch] = analog_capture_level_;
}
Configure();
@@ -424,11 +410,10 @@
config.limiterEnable = limiter_enabled_;
int error = AudioProcessing::kNoError;
- for (auto& gain_controller : gain_controllers_) {
- const int handle_error =
- WebRtcAgc_set_config(gain_controller->state(), config);
- if (handle_error != AudioProcessing::kNoError) {
- error = handle_error;
+ for (size_t ch = 0; ch < mono_agcs_.size(); ++ch) {
+ int error_ch = WebRtcAgc_set_config(mono_agcs_[ch]->state, config);
+ if (error_ch != AudioProcessing::kNoError) {
+ error = error_ch;
}
}
return error;
diff --git a/modules/audio_processing/gain_control_impl.h b/modules/audio_processing/gain_control_impl.h
index da61c11..5ddf5ec 100644
--- a/modules/audio_processing/gain_control_impl.h
+++ b/modules/audio_processing/gain_control_impl.h
@@ -20,7 +20,6 @@
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "modules/audio_processing/agc/gain_control.h"
-#include "rtc_base/constructor_magic.h"
namespace webrtc {
@@ -45,13 +44,13 @@
std::vector<int16_t>* packed_buffer);
// GainControl implementation.
- bool is_enabled() const override;
+ bool is_enabled() const override { return enabled_; }
int stream_analog_level() const override;
- bool is_limiter_enabled() const override;
- Mode mode() const override;
+ bool is_limiter_enabled() const override { return limiter_enabled_; }
+ Mode mode() const override { return mode_; }
int Enable(bool enable) override;
int set_mode(Mode mode) override;
- int compression_gain_db() const override;
+ int compression_gain_db() const override { return compression_gain_db_; }
int set_analog_level_limits(int minimum, int maximum) override;
int set_compression_gain_db(int gain) override;
int set_target_level_dbfs(int level) override;
@@ -59,13 +58,13 @@
int set_stream_analog_level(int level) override;
private:
- class GainController;
+ struct MonoAgcState;
// GainControl implementation.
- int target_level_dbfs() const override;
- int analog_level_minimum() const override;
- int analog_level_maximum() const override;
- bool stream_is_saturated() const override;
+ int target_level_dbfs() const override { return target_level_dbfs_; }
+ int analog_level_minimum() const override { return minimum_capture_level_; }
+ int analog_level_maximum() const override { return maximum_capture_level_; }
+ bool stream_is_saturated() const override { return stream_is_saturated_; }
int Configure();
@@ -73,6 +72,7 @@
bool enabled_ = false;
+ const bool use_legacy_gain_applier_;
Mode mode_;
int minimum_capture_level_;
int maximum_capture_level_;
@@ -83,7 +83,8 @@
bool was_analog_level_set_;
bool stream_is_saturated_;
- std::vector<std::unique_ptr<GainController>> gain_controllers_;
+ std::vector<std::unique_ptr<MonoAgcState>> mono_agcs_;
+ std::vector<int> capture_levels_;
absl::optional<size_t> num_proc_channels_;
absl::optional<int> sample_rate_hz_;
diff --git a/modules/audio_processing/gain_control_unittest.cc b/modules/audio_processing/gain_control_unittest.cc
index 81e6899..c1078b4 100644
--- a/modules/audio_processing/gain_control_unittest.cc
+++ b/modules/audio_processing/gain_control_unittest.cc
@@ -136,21 +136,6 @@
#if !(defined(WEBRTC_ARCH_ARM64) || defined(WEBRTC_ARCH_ARM) || \
defined(WEBRTC_ANDROID))
TEST(GainControlBitExactnessTest,
- Mono8kHz_AdaptiveAnalog_Tl10_SL50_CG5_Lim_AL0_100) {
-#else
-TEST(GainControlBitExactnessTest,
- DISABLED_Mono8kHz_AdaptiveAnalog_Tl10_SL50_CG5_Lim_AL0_100) {
-#endif
- const int kStreamAnalogLevelReference = 50;
- const float kOutputReference[] = {-0.006622f, -0.002747f, 0.001587f};
- RunBitExactnessTest(8000, 1, GainControl::Mode::kAdaptiveAnalog, 10, 50, 5,
- true, 0, 100, kStreamAnalogLevelReference,
- kOutputReference);
-}
-
-#if !(defined(WEBRTC_ARCH_ARM64) || defined(WEBRTC_ARCH_ARM) || \
- defined(WEBRTC_ANDROID))
-TEST(GainControlBitExactnessTest,
Mono16kHz_AdaptiveAnalog_Tl10_SL50_CG5_Lim_AL0_100) {
#else
TEST(GainControlBitExactnessTest,
@@ -212,21 +197,6 @@
#if !(defined(WEBRTC_ARCH_ARM64) || defined(WEBRTC_ARCH_ARM) || \
defined(WEBRTC_ANDROID))
TEST(GainControlBitExactnessTest,
- Mono8kHz_AdaptiveDigital_Tl10_SL50_CG5_Lim_AL0_100) {
-#else
-TEST(GainControlBitExactnessTest,
- DISABLED_Mono8kHz_AdaptiveDigital_Tl10_SL50_CG5_Lim_AL0_100) {
-#endif
- const int kStreamAnalogLevelReference = 50;
- const float kOutputReference[] = {-0.004028f, -0.001678f, 0.000946f};
- RunBitExactnessTest(8000, 1, GainControl::Mode::kAdaptiveDigital, 10, 50, 5,
- true, 0, 100, kStreamAnalogLevelReference,
- kOutputReference);
-}
-
-#if !(defined(WEBRTC_ARCH_ARM64) || defined(WEBRTC_ARCH_ARM) || \
- defined(WEBRTC_ANDROID))
-TEST(GainControlBitExactnessTest,
Mono16kHz_AdaptiveDigital_Tl10_SL50_CG5_Lim_AL0_100) {
#else
TEST(GainControlBitExactnessTest,
@@ -264,7 +234,7 @@
DISABLED_Mono32kHz_AdaptiveDigital_Tl10_SL50_CG5_Lim_AL0_100) {
#endif
const int kStreamAnalogLevelReference = 50;
- const float kOutputReference[] = {-0.006104f, -0.005524f, -0.004974f};
+ const float kOutputReference[] = {-0.006134f, -0.005524f, -0.005005f};
RunBitExactnessTest(32000, 1, GainControl::Mode::kAdaptiveDigital, 10, 50, 5,
true, 0, 100, kStreamAnalogLevelReference,
kOutputReference);
@@ -279,7 +249,7 @@
DISABLED_Mono48kHz_AdaptiveDigital_Tl10_SL50_CG5_Lim_AL0_100) {
#endif
const int kStreamAnalogLevelReference = 50;
- const float kOutputReference[] = {-0.006104f, -0.005524f, -0.004974f};
+ const float kOutputReference[] = {-0.006134f, -0.005524f, -0.005005};
RunBitExactnessTest(32000, 1, GainControl::Mode::kAdaptiveDigital, 10, 50, 5,
true, 0, 100, kStreamAnalogLevelReference,
kOutputReference);
@@ -288,21 +258,6 @@
#if !(defined(WEBRTC_ARCH_ARM64) || defined(WEBRTC_ARCH_ARM) || \
defined(WEBRTC_ANDROID))
TEST(GainControlBitExactnessTest,
- Mono8kHz_FixedDigital_Tl10_SL50_CG5_Lim_AL0_100) {
-#else
-TEST(GainControlBitExactnessTest,
- DISABLED_Mono8kHz_FixedDigital_Tl10_SL50_CG5_Lim_AL0_100) {
-#endif
- const int kStreamAnalogLevelReference = 50;
- const float kOutputReference[] = {-0.011871f, -0.004944f, 0.002838f};
- RunBitExactnessTest(8000, 1, GainControl::Mode::kFixedDigital, 10, 50, 5,
- true, 0, 100, kStreamAnalogLevelReference,
- kOutputReference);
-}
-
-#if !(defined(WEBRTC_ARCH_ARM64) || defined(WEBRTC_ARCH_ARM) || \
- defined(WEBRTC_ANDROID))
-TEST(GainControlBitExactnessTest,
Mono16kHz_FixedDigital_Tl10_SL50_CG5_Lim_AL0_100) {
#else
TEST(GainControlBitExactnessTest,
@@ -324,8 +279,8 @@
DISABLED_Stereo16kHz_FixedDigital_Tl10_SL50_CG5_Lim_AL0_100) {
#endif
const int kStreamAnalogLevelReference = 50;
- const float kOutputReference[] = {-0.048950f, -0.028503f, -0.050354f,
- -0.048950f, -0.028503f, -0.050354f};
+ const float kOutputReference[] = {-0.048896f, -0.028479f, -0.050345f,
+ -0.048896f, -0.028479f, -0.050345f};
RunBitExactnessTest(16000, 2, GainControl::Mode::kFixedDigital, 10, 50, 5,
true, 0, 100, kStreamAnalogLevelReference,
kOutputReference);
@@ -340,7 +295,7 @@
DISABLED_Mono32kHz_FixedDigital_Tl10_SL50_CG5_Lim_AL0_100) {
#endif
const int kStreamAnalogLevelReference = 50;
- const float kOutputReference[] = {-0.018188f, -0.016418f, -0.014862f};
+ const float kOutputReference[] = {-0.018158f, -0.016357f, -0.014832f};
RunBitExactnessTest(32000, 1, GainControl::Mode::kFixedDigital, 10, 50, 5,
true, 0, 100, kStreamAnalogLevelReference,
kOutputReference);
@@ -355,7 +310,7 @@
DISABLED_Mono48kHz_FixedDigital_Tl10_SL50_CG5_Lim_AL0_100) {
#endif
const int kStreamAnalogLevelReference = 50;
- const float kOutputReference[] = {-0.018188f, -0.016418f, -0.014862f};
+ const float kOutputReference[] = {-0.018158f, -0.016357f, -0.014832f};
RunBitExactnessTest(32000, 1, GainControl::Mode::kFixedDigital, 10, 50, 5,
true, 0, 100, kStreamAnalogLevelReference,
kOutputReference);
diff --git a/resources/audio_processing/output_data_fixed.pb.sha1 b/resources/audio_processing/output_data_fixed.pb.sha1
index 066449e..f279050 100644
--- a/resources/audio_processing/output_data_fixed.pb.sha1
+++ b/resources/audio_processing/output_data_fixed.pb.sha1
@@ -1 +1 @@
-f85386d49e89027aa14f2aad36537a8a4e887a61
\ No newline at end of file
+4010b1fe15eda1b42968cdb3f9fed399e1aa7197
\ No newline at end of file
diff --git a/resources/audio_processing/output_data_float.pb.sha1 b/resources/audio_processing/output_data_float.pb.sha1
index 341f036..38c5251 100644
--- a/resources/audio_processing/output_data_float.pb.sha1
+++ b/resources/audio_processing/output_data_float.pb.sha1
@@ -1 +1 @@
-734cc6174a5dac2fd87de267fe8d12519fe18321
\ No newline at end of file
+8d368435bbc80edab08205c6f21db1416e119119
\ No newline at end of file