Skip to content

Commit e518a9f

Browse files
authored
feat: add legacy AGC1 and update AGC2 in the AudioProcessingConfig (#205)
* feat: add Pipeline to AudioProcessingConfig * feat: enhance gain control configuration with AGC1 and AGC2 * feat: add input volume controller to AGC2 * feat: add capture level adjustment configuration to AudioProcessingConfig * test: increase connection timeout in PortAllocatorConfigIntegrationTest
1 parent 4b7d4d3 commit e518a9f

File tree

9 files changed

+906
-119
lines changed

9 files changed

+906
-119
lines changed

docs/guide/audio/audio_processing.md

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -123,22 +123,54 @@ config.noiseSuppression.level = NoiseSuppression.Level.MODERATE;
123123

124124
### Gain Control
125125

126-
Gain control adjusts the audio level automatically:
126+
Gain control adjusts the audio level automatically. WebRTC provides two gain controllers:
127+
- GainController (AGC1, legacy/classic)
128+
- GainControllerDigital (newer digital AGC)
129+
130+
In most applications you should enable only one of them at a time.
131+
132+
#### Legacy Gain Controller (AGC1)
133+
AGC1 can operate in analog or digital modes and includes an optional limiter.
134+
135+
```java
136+
// Enable the legacy AGC1
137+
config.gainController.enabled = true;
138+
139+
// Select mode: AdaptiveAnalog, AdaptiveDigital, or FixedDigital
140+
config.gainController.mode = AudioProcessingConfig.GainController.Mode.AdaptiveAnalog;
141+
142+
// Set the target level (in dBFS) and compression gain (in dB)
143+
config.gainController.targetLevelDbfs = 3; // common default
144+
config.gainController.compressionGainDb = 9; // common default
145+
146+
// Enable the limiter to reduce clipping
147+
config.gainController.enableLimiter = true;
148+
149+
// Optional: tune analog gain controller sub-settings
150+
config.gainController.analogGainController.enabled = true;
151+
config.gainController.analogGainController.enableDigitalAdaptive = true;
152+
// Clipping predictor (optional)
153+
config.gainController.analogGainController.clippingPredictor.enabled = false;
154+
```
155+
156+
When using AdaptiveAnalog mode, integrate with your system microphone level if possible so AGC1 can adjust the hardware/OS capture volume. Use AdaptiveDigital if you cannot control device gain. FixedDigital applies a constant digital gain.
157+
158+
#### Digital Gain Controller
127159

128160
```java
129-
// Enable gain control
130-
config.gainControl.enabled = true;
161+
// Enable the newer digital AGC
162+
config.gainControllerDigital.enabled = true;
131163

132164
// Configure fixed digital gain (in dB)
133-
config.gainControl.fixedDigital.gainDb = 5.0f;
165+
config.gainControllerDigital.fixedDigital.gainDb = 5.0f;
134166

135167
// Or configure adaptive digital gain
136-
config.gainControl.adaptiveDigital.enabled = true;
137-
config.gainControl.adaptiveDigital.headroomDb = 3.0f;
138-
config.gainControl.adaptiveDigital.maxGainDb = 30.0f;
139-
config.gainControl.adaptiveDigital.initialGainDb = 8.0f;
140-
config.gainControl.adaptiveDigital.maxGainChangeDbPerSecond = 3.0f;
141-
config.gainControl.adaptiveDigital.maxOutputNoiseLevelDbfs = -50.0f;
168+
config.gainControllerDigital.adaptiveDigital.enabled = true;
169+
config.gainControllerDigital.adaptiveDigital.headroomDb = 3.0f;
170+
config.gainControllerDigital.adaptiveDigital.maxGainDb = 30.0f;
171+
config.gainControllerDigital.adaptiveDigital.initialGainDb = 8.0f;
172+
config.gainControllerDigital.adaptiveDigital.maxGainChangeDbPerSecond = 3.0f;
173+
config.gainControllerDigital.adaptiveDigital.maxOutputNoiseLevelDbfs = -50.0f;
142174
```
143175

144176
### High-Pass Filter

webrtc-jni/src/main/cpp/include/media/audio/AudioProcessingConfig.h

Lines changed: 98 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,33 @@ namespace jni
3434
explicit JavaAudioProcessingConfigClass(JNIEnv * env);
3535

3636
jclass cls;
37+
jfieldID pipeline;
3738
jfieldID echoCanceller;
38-
jfieldID gainControl;
39+
jfieldID gainController;
40+
jfieldID gainControllerDigital;
3941
jfieldID highPassFilter;
4042
jfieldID noiseSuppression;
43+
jfieldID captureLevelAdjustment;
4144
};
4245

4346
webrtc::AudioProcessing::Config toNative(JNIEnv * env, const JavaRef<jobject> & javaType);
47+
webrtc::AudioProcessing::Config::Pipeline toPipeline(JNIEnv* env, const JavaLocalRef<jobject> & javaType);
48+
webrtc::AudioProcessing::Config::GainController1 toGainController1(JNIEnv * env, const JavaLocalRef<jobject> & javaType);
4449
webrtc::AudioProcessing::Config::GainController2 toGainController2(JNIEnv * env, const JavaLocalRef<jobject> & javaType);
4550

4651

52+
class JavaPipelineClass : public JavaClass
53+
{
54+
public:
55+
explicit JavaPipelineClass(JNIEnv * env);
56+
57+
jclass cls;
58+
jfieldID maximumInternalProcessingRate;
59+
jfieldID multiChannelRender;
60+
jfieldID multiChannelCapture;
61+
jfieldID captureDownmixMethod;
62+
};
63+
4764
class JavaEchoCancellerClass : public JavaClass
4865
{
4966
public:
@@ -54,17 +71,27 @@ namespace jni
5471
jfieldID enforceHighPassFiltering;
5572
};
5673

57-
class JavaGainControlClass : public JavaClass
74+
class JavaGainControllerDigitalClass : public JavaClass
5875
{
5976
public:
60-
explicit JavaGainControlClass(JNIEnv * env);
77+
explicit JavaGainControllerDigitalClass(JNIEnv * env);
6178

6279
jclass cls;
6380
jfieldID enabled;
81+
jfieldID inputVolumeController;
6482
jfieldID fixedDigital;
6583
jfieldID adaptiveDigital;
6684
};
6785

86+
class JavaInputVolumeControllerClass : public JavaClass
87+
{
88+
public:
89+
explicit JavaInputVolumeControllerClass(JNIEnv * env);
90+
91+
jclass cls;
92+
jfieldID enabled;
93+
};
94+
6895
class JavaGainControlFixedDigitalClass : public JavaClass
6996
{
7097
public:
@@ -88,6 +115,52 @@ namespace jni
88115
jfieldID maxOutputNoiseLevelDbfs;
89116
};
90117

118+
class JavaGainControllerClass : public JavaClass
119+
{
120+
public:
121+
explicit JavaGainControllerClass(JNIEnv * env);
122+
123+
jclass cls;
124+
jfieldID enabled;
125+
jfieldID targetLevelDbfs;
126+
jfieldID compressionGainDb;
127+
jfieldID enableLimiter;
128+
jfieldID mode;
129+
jfieldID analogGainController;
130+
};
131+
132+
class JavaAgc1AnalogGainControllerClass : public JavaClass
133+
{
134+
public:
135+
explicit JavaAgc1AnalogGainControllerClass(JNIEnv * env);
136+
137+
jclass cls;
138+
jfieldID enabled;
139+
jfieldID startupMinVolume;
140+
jfieldID clippedLevelMin;
141+
jfieldID enableDigitalAdaptive;
142+
jfieldID clippedLevelStep;
143+
jfieldID clippedRatioThreshold;
144+
jfieldID clippedWaitFrames;
145+
jfieldID clippingPredictor;
146+
};
147+
148+
class JavaAgc1ClippingPredictorClass : public JavaClass
149+
{
150+
public:
151+
explicit JavaAgc1ClippingPredictorClass(JNIEnv * env);
152+
153+
jclass cls;
154+
jfieldID enabled;
155+
jfieldID mode;
156+
jfieldID windowLength;
157+
jfieldID referenceWindowLength;
158+
jfieldID referenceWindowDelay;
159+
jfieldID clippingThreshold;
160+
jfieldID crestFactorMargin;
161+
jfieldID usePredictedStep;
162+
};
163+
91164
class JavaHighPassFilterClass : public JavaClass
92165
{
93166
public:
@@ -106,6 +179,28 @@ namespace jni
106179
jfieldID enabled;
107180
jfieldID level;
108181
};
182+
183+
class JavaCaptureLevelAdjustmentClass : public JavaClass
184+
{
185+
public:
186+
explicit JavaCaptureLevelAdjustmentClass(JNIEnv * env);
187+
188+
jclass cls;
189+
jfieldID enabled;
190+
jfieldID preGainFactor;
191+
jfieldID postGainFactor;
192+
jfieldID analogMicGainEmulation;
193+
};
194+
195+
class JavaAnalogMicGainEmulationClass : public JavaClass
196+
{
197+
public:
198+
explicit JavaAnalogMicGainEmulationClass(JNIEnv * env);
199+
200+
jclass cls;
201+
jfieldID enabled;
202+
jfieldID initialLevel;
203+
};
109204
}
110205
}
111206

webrtc-jni/src/main/cpp/src/WebRTCContext.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ namespace jni
8585
JavaEnums::add<webrtc::RtpTransceiverDirection>(env, PKG"RTCRtpTransceiverDirection");
8686
JavaEnums::add<webrtc::SdpType>(env, PKG"RTCSdpType");
8787
JavaEnums::add<webrtc::AudioDeviceModule::AudioLayer>(env, PKG_AUDIO"AudioLayer");
88+
JavaEnums::add<webrtc::AudioProcessing::Config::GainController1::Mode>(env, PKG_AUDIO"AudioProcessingConfig$GainController$Mode");
89+
JavaEnums::add<webrtc::AudioProcessing::Config::GainController1::AnalogGainController::ClippingPredictor::Mode>(env, PKG_AUDIO"AudioProcessingConfig$GainController$AnalogGainController$ClippingPredictor$Mode");
90+
JavaEnums::add<webrtc::AudioProcessing::Config::Pipeline::DownmixMethod>(env, PKG_AUDIO"AudioProcessingConfig$Pipeline$DownmixMethod");
8891
JavaEnums::add<webrtc::AudioProcessing::Config::NoiseSuppression::Level>(env, PKG_AUDIO"AudioProcessingConfig$NoiseSuppression$Level");
8992
JavaEnums::add<jni::RTCStats::RTCStatsType>(env, PKG"RTCStatsType");
9093

0 commit comments

Comments
 (0)