From c0ad4aa4321323bce1f91189fde2aab1790064e0 Mon Sep 17 00:00:00 2001
From: XiaWuSharve
Date: Tue, 1 Sep 2026 14:02:48 +0800
Subject: [PATCH 1/3] expose CaptureCompressionGain API for Java
---
build-to-aar | 4 ++++
.../org/webrtc/ExternalAudioProcessingFactory.java | 10 ++++++++++
.../src/external_audio_processing_factory.cc | 9 +++++++++
modules/audio_processing/audio_processing_impl.cc | 7 +++++++
4 files changed, 30 insertions(+)
create mode 100755 build-to-aar
diff --git a/build-to-aar b/build-to-aar
new file mode 100755
index 0000000000..19e1964931
--- /dev/null
+++ b/build-to-aar
@@ -0,0 +1,4 @@
+rsync -av --exclude='.*' ./ ../src/
+cd ../src
+./tools_webrtc/android/build_aar.py --output libwebrtc.aar --arch arm64-v8a x86_64 --extra-gn-args='treat_warnings_as_errors=false'
+cp libwebrtc.aar /mnt/e/seek/
\ No newline at end of file
diff --git a/extensions/android/audio-processing/java/org/webrtc/ExternalAudioProcessingFactory.java b/extensions/android/audio-processing/java/org/webrtc/ExternalAudioProcessingFactory.java
index 78f238b029..3ad4c27f34 100644
--- a/extensions/android/audio-processing/java/org/webrtc/ExternalAudioProcessingFactory.java
+++ b/extensions/android/audio-processing/java/org/webrtc/ExternalAudioProcessingFactory.java
@@ -79,6 +79,15 @@ public void setCapturePostProcessing(@Nullable AudioProcessing processing) {
capturePostProcessingPtr = newPtr;
}
+ /**
+ * Sets the compressionGainDb for the capture audio processing module.
+ * ranging [0, 90].
+ */
+ public void setCaptureCompressionGain(int compressionGainDb) {
+ checkExternalAudioProcessorExists();
+ nativeSetCaptureCompressionGain(compressionGainDb);
+ }
+
/**
* Sets the render pre processing module.
* This module is applied to the audio signal after receiving from the audio
@@ -135,6 +144,7 @@ private void checkExternalAudioProcessorExists() {
}
}
+ private static native void nativeSetCaptureCompressionGain(int compressionGainDb);
private static native long nativeGetDefaultApm();
private static native long nativeSetCapturePostProcessing(AudioProcessing processing);
private static native long nativeSetRenderPreProcessing(AudioProcessing processing);
diff --git a/extensions/android/audio-processing/src/external_audio_processing_factory.cc b/extensions/android/audio-processing/src/external_audio_processing_factory.cc
index 3b43c95df8..1d8c271871 100644
--- a/extensions/android/audio-processing/src/external_audio_processing_factory.cc
+++ b/extensions/android/audio-processing/src/external_audio_processing_factory.cc
@@ -83,6 +83,15 @@ static jlong JNI_ExternalAudioProcessingFactory_GetDefaultApm(JNIEnv* env) {
return webrtc::jni::jlongFromPointer(default_processor->apm().get());
}
+static void JNI_ExternalAudioProcessingFactory_SetCaptureCompressionGain(
+ JNIEnv* env,
+ jint compression_gain_db) {
+ if (!default_processor) {
+ return;
+ }
+ default_processor->apm().get()->SetRuntimeSetting(AudioProcessing::RuntimeSetting::CreateCompressionGainDb(compression_gain_db));
+}
+
static jlong JNI_ExternalAudioProcessingFactory_SetCapturePostProcessing(
JNIEnv* env,
const JavaParamRef& j_processing) {
diff --git a/modules/audio_processing/audio_processing_impl.cc b/modules/audio_processing/audio_processing_impl.cc
index aac8c37980..feb675e9c8 100644
--- a/modules/audio_processing/audio_processing_impl.cc
+++ b/modules/audio_processing/audio_processing_impl.cc
@@ -969,9 +969,11 @@ int AudioProcessingImpl::ProcessStream(const float* const* src,
}
void AudioProcessingImpl::HandleCaptureRuntimeSettings() {
+ RTC_LOG(LS_INFO) << "AudioProcessingImpl::HandleCaptureRuntimeSettings: started to handle capture runtime settings";
RuntimeSetting setting;
int num_settings_processed = 0;
while (capture_runtime_settings_.Remove(&setting)) {
+ RTC_LOG(LS_INFO) << "AudioProcessingImpl::HandleCaptureRuntimeSettings: handling capture runtime settings";
if (aec_dump_) {
aec_dump_->WriteRuntimeSetting(setting);
}
@@ -1016,6 +1018,7 @@ void AudioProcessingImpl::HandleCaptureRuntimeSettings() {
// TODO(bugs.chromium.org/9138): Log setting handling by Aec Dump.
break;
case RuntimeSetting::Type::kCaptureCompressionGain: {
+ RTC_LOG(LS_INFO) << "AudioProcessingImpl::HandleCaptureRuntimeSettings: received kCaptureCompressionGain";
if (!submodules_.agc_manager &&
!(submodules_.gain_controller2 &&
config_.gain_controller2.input_volume_controller.enabled)) {
@@ -1027,7 +1030,11 @@ void AudioProcessingImpl::HandleCaptureRuntimeSettings() {
int error =
submodules_.gain_control->set_compression_gain_db(int_value);
RTC_DCHECK_EQ(kNoError, error);
+ } else {
+ RTC_LOG(LS_WARNING) << "AudioProcessingImpl::HandleCaptureRuntimeSettings: no gain_control, skip kCaptureCompressionGain";
}
+ } else {
+ RTC_LOG(LS_WARNING) << "AudioProcessingImpl::HandleCaptureRuntimeSettings: no agc_manager || gain_controller2 || input_volume_controller enabled, skip kCaptureCompressionGain";
}
break;
}
From 1df80249323e104d79400048a7cb8549173c09d9 Mon Sep 17 00:00:00 2001
From: XiaWuSharve
Date: Wed, 2 Sep 2026 03:10:56 +0800
Subject: [PATCH 2/3] expose gain controller 1 configuration
---
build-to-aar | 4 --
.../ExternalAudioProcessingFactory.java | 38 ++++++++++++++++++-
.../src/external_audio_processing_factory.cc | 30 +++++++++++++++
.../audio_processing/audio_processing_impl.cc | 13 ++++++-
4 files changed, 78 insertions(+), 7 deletions(-)
delete mode 100755 build-to-aar
diff --git a/build-to-aar b/build-to-aar
deleted file mode 100755
index 19e1964931..0000000000
--- a/build-to-aar
+++ /dev/null
@@ -1,4 +0,0 @@
-rsync -av --exclude='.*' ./ ../src/
-cd ../src
-./tools_webrtc/android/build_aar.py --output libwebrtc.aar --arch arm64-v8a x86_64 --extra-gn-args='treat_warnings_as_errors=false'
-cp libwebrtc.aar /mnt/e/seek/
\ No newline at end of file
diff --git a/extensions/android/audio-processing/java/org/webrtc/ExternalAudioProcessingFactory.java b/extensions/android/audio-processing/java/org/webrtc/ExternalAudioProcessingFactory.java
index 3ad4c27f34..f8638169f7 100644
--- a/extensions/android/audio-processing/java/org/webrtc/ExternalAudioProcessingFactory.java
+++ b/extensions/android/audio-processing/java/org/webrtc/ExternalAudioProcessingFactory.java
@@ -80,7 +80,7 @@ public void setCapturePostProcessing(@Nullable AudioProcessing processing) {
}
/**
- * Sets the compressionGainDb for the capture audio processing module.
+ * Runtime sets the compressionGainDb for the capture audio processing module.
* ranging [0, 90].
*/
public void setCaptureCompressionGain(int compressionGainDb) {
@@ -88,6 +88,16 @@ public void setCaptureCompressionGain(int compressionGainDb) {
nativeSetCaptureCompressionGain(compressionGainDb);
}
+ /**
+ * Sets the compressionGainDb for the capture audio processing module.
+ * targetLevelDbfs: default(3)
+ * compressionGainDb: ranging [0, 90].
+ */
+ public void enableGainController1(AgcMode mode, int targetLevelDbfs, int compressionGainDb, boolean enableLimiter) {
+ checkExternalAudioProcessorExists();
+ nativeEnableGainController1(mode.ordinal(), targetLevelDbfs, compressionGainDb, enableLimiter);
+ }
+
/**
* Sets the render pre processing module.
* This module is applied to the audio signal after receiving from the audio
@@ -144,7 +154,33 @@ private void checkExternalAudioProcessorExists() {
}
}
+ public enum Agc1Mode {
+ // Adaptive mode intended for use if an analog volume control is
+ // available on the capture device. It will require the user to provide
+ // coupling between the OS mixer controls and AGC through the
+ // stream_analog_level() functions.
+ // It consists of an analog gain prescription for the audio device and a
+ // digital compression stage.
+ ADAPTIVE_ANALOG,
+ // Adaptive mode intended for situations in which an analog volume
+ // control is unavailable. It operates in a similar fashion to the
+ // adaptive analog mode, but with scaling instead applied in the digital
+ // domain. As with the analog mode, it additionally uses a digital
+ // compression stage.
+ ADAPTIVE_DIGITAL,
+ // Fixed mode which enables only the digital compression stage also used
+ // by the two adaptive modes.
+ // It is distinguished from the adaptive modes by considering only a
+ // short time-window of the input signal. It applies a fixed gain
+ // through most of the input level range, and compresses (gradually
+ // reduces gain with increasing level) the input signal at higher
+ // levels. This mode is preferred on embedded devices where the capture
+ // signal level is predictable, so that a known gain can be applied.
+ FIXED_DIGITAL
+ }
+
private static native void nativeSetCaptureCompressionGain(int compressionGainDb);
+ private static native void nativeEnableGainController1(int mode, int targetLevelDbfs, int compressionGainDb, boolean enableLimiter);
private static native long nativeGetDefaultApm();
private static native long nativeSetCapturePostProcessing(AudioProcessing processing);
private static native long nativeSetRenderPreProcessing(AudioProcessing processing);
diff --git a/extensions/android/audio-processing/src/external_audio_processing_factory.cc b/extensions/android/audio-processing/src/external_audio_processing_factory.cc
index 1d8c271871..d2fc3a68b7 100644
--- a/extensions/android/audio-processing/src/external_audio_processing_factory.cc
+++ b/extensions/android/audio-processing/src/external_audio_processing_factory.cc
@@ -92,6 +92,36 @@ static void JNI_ExternalAudioProcessingFactory_SetCaptureCompressionGain(
default_processor->apm().get()->SetRuntimeSetting(AudioProcessing::RuntimeSetting::CreateCompressionGainDb(compression_gain_db));
}
+
+static void JNI_ExternalAudioProcessingFactory_EnableGainController1(
+ JNIEnv* env,
+ jint mode,
+ jint target_level_dbfs,
+ jint compression_gain_db,
+ jboolean enable_limiter
+ ) {
+ if (!default_processor) {
+ return;
+ }
+ if (!default_processor->apm()) {
+ return;
+ }
+ webrtc::AudioProcessing::Config config = default_processor->apm()->GetConfig();
+ config.gain_controller1.enabled = true;
+ config.gain_controller2.enabled = false;
+ if (mode == 0) {
+ config.gain_controller1.mode = webrtc::AudioProcessing::Config::GainController1::kAdaptiveAnalog;
+ } else if (mode == 1) {
+ config.gain_controller1.mode = webrtc::AudioProcessing::Config::GainController1::kAdaptiveDigital;
+ } else if (mode == 2) {
+ config.gain_controller1.mode = webrtc::AudioProcessing::Config::GainController1::kFixedDigital;
+ }
+ config.gain_controller1.target_level_dbfs = target_level_dbfs;
+ config.gain_controller1.compression_gain_db = compression_gain_db;
+ config.gain_controller1.enable_limiter = enable_limiter;
+ default_processor->apm()->ApplyConfig(config);
+}
+
static jlong JNI_ExternalAudioProcessingFactory_SetCapturePostProcessing(
JNIEnv* env,
const JavaParamRef& j_processing) {
diff --git a/modules/audio_processing/audio_processing_impl.cc b/modules/audio_processing/audio_processing_impl.cc
index feb675e9c8..a6e7c8f732 100644
--- a/modules/audio_processing/audio_processing_impl.cc
+++ b/modules/audio_processing/audio_processing_impl.cc
@@ -969,7 +969,6 @@ int AudioProcessingImpl::ProcessStream(const float* const* src,
}
void AudioProcessingImpl::HandleCaptureRuntimeSettings() {
- RTC_LOG(LS_INFO) << "AudioProcessingImpl::HandleCaptureRuntimeSettings: started to handle capture runtime settings";
RuntimeSetting setting;
int num_settings_processed = 0;
while (capture_runtime_settings_.Remove(&setting)) {
@@ -1034,7 +1033,11 @@ void AudioProcessingImpl::HandleCaptureRuntimeSettings() {
RTC_LOG(LS_WARNING) << "AudioProcessingImpl::HandleCaptureRuntimeSettings: no gain_control, skip kCaptureCompressionGain";
}
} else {
- RTC_LOG(LS_WARNING) << "AudioProcessingImpl::HandleCaptureRuntimeSettings: no agc_manager || gain_controller2 || input_volume_controller enabled, skip kCaptureCompressionGain";
+ RTC_LOG(LS_WARNING) << "AudioProcessingImpl::HandleCaptureRuntimeSettings: \n"
+ << "agc_manager: " << submodules_.agc_manager << "\n"
+ << "gain_controller2: " << submodules_.gain_controller2 << "\n"
+ << "config_.gain_controller2.input_volume_controller.enabled: " << config_.gain_controller2.input_volume_controller.enabled << "\n"
+ << ", skip kCaptureCompressionGain";
}
break;
}
@@ -2005,6 +2008,12 @@ void AudioProcessingImpl::InitializeEchoController() {
}
void AudioProcessingImpl::InitializeGainController1() {
+ RTC_LOG(LS_INFO) << "initalizing GainController1 with config: "
+ << "config_.gain_controller1.enabled: " << config_.gain_controller1.enabled << ", "
+ << "config_.gain_controller1.mode: " << config_.gain_controller1.mode << ", "
+ << "config_.gain_controller1.target_level_dbfs: " << config_.gain_controller1.target_level_dbfs << ", "
+ << "config_.gain_controller1.compression_gain_db: " << config_.gain_controller1.compression_gain_db << ", "
+ << "config_.gain_controller1.enable_limiter: " << config_.gain_controller1.enable_limiter << ", ";
if (config_.gain_controller2.enabled &&
config_.gain_controller2.input_volume_controller.enabled &&
config_.gain_controller1.enabled &&
From 5f79e20d759a31f6a022bcdc97916944ee474e4b Mon Sep 17 00:00:00 2001
From: XiaWuSharve
Date: Wed, 2 Sep 2026 03:32:57 +0800
Subject: [PATCH 3/3] fix syntex error
---
.../java/org/webrtc/ExternalAudioProcessingFactory.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/extensions/android/audio-processing/java/org/webrtc/ExternalAudioProcessingFactory.java b/extensions/android/audio-processing/java/org/webrtc/ExternalAudioProcessingFactory.java
index f8638169f7..ba1ee6f5a8 100644
--- a/extensions/android/audio-processing/java/org/webrtc/ExternalAudioProcessingFactory.java
+++ b/extensions/android/audio-processing/java/org/webrtc/ExternalAudioProcessingFactory.java
@@ -93,7 +93,7 @@ public void setCaptureCompressionGain(int compressionGainDb) {
* targetLevelDbfs: default(3)
* compressionGainDb: ranging [0, 90].
*/
- public void enableGainController1(AgcMode mode, int targetLevelDbfs, int compressionGainDb, boolean enableLimiter) {
+ public void enableGainController1(Agc1Mode mode, int targetLevelDbfs, int compressionGainDb, boolean enableLimiter) {
checkExternalAudioProcessorExists();
nativeEnableGainController1(mode.ordinal(), targetLevelDbfs, compressionGainDb, enableLimiter);
}