diff --git a/extensions/android/audio-processing/java/org/webrtc/ExternalAudioProcessingFactory.java b/extensions/android/audio-processing/java/org/webrtc/ExternalAudioProcessingFactory.java index 78f238b029..ba1ee6f5a8 100644 --- a/extensions/android/audio-processing/java/org/webrtc/ExternalAudioProcessingFactory.java +++ b/extensions/android/audio-processing/java/org/webrtc/ExternalAudioProcessingFactory.java @@ -79,6 +79,25 @@ public void setCapturePostProcessing(@Nullable AudioProcessing processing) { capturePostProcessingPtr = newPtr; } + /** + * Runtime sets the compressionGainDb for the capture audio processing module. + * ranging [0, 90]. + */ + public void setCaptureCompressionGain(int compressionGainDb) { + checkExternalAudioProcessorExists(); + nativeSetCaptureCompressionGain(compressionGainDb); + } + + /** + * Sets the compressionGainDb for the capture audio processing module. + * targetLevelDbfs: default(3) + * compressionGainDb: ranging [0, 90]. + */ + public void enableGainController1(Agc1Mode 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 @@ -135,6 +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 3b43c95df8..d2fc3a68b7 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,45 @@ 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 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 aac8c37980..a6e7c8f732 100644 --- a/modules/audio_processing/audio_processing_impl.cc +++ b/modules/audio_processing/audio_processing_impl.cc @@ -972,6 +972,7 @@ void AudioProcessingImpl::HandleCaptureRuntimeSettings() { 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 +1017,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 +1029,15 @@ 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: \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; } @@ -1998,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 &&