Add control for choosing between AEC3 and AECM (#67)

This commit is contained in:
Peter Thatcher 2022-02-23 18:59:14 -07:00 committed by GitHub
parent c3195def8f
commit 54cfdf3754
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 58 additions and 21 deletions

View file

@ -435,10 +435,6 @@ bool WebRtcVoiceEngine::ApplyOptions(const AudioOptions& options_in) {
<< options_in.ToString();
AudioOptions options = options_in; // The options are modified below.
// Set and adjust echo canceller options.
// Use desktop AEC by default, when not using hardware AEC.
bool use_mobile_software_aec = false;
#if defined(WEBRTC_IOS)
if (options.ios_force_software_aec_HACK &&
*options.ios_force_software_aec_HACK) {
@ -452,8 +448,6 @@ bool WebRtcVoiceEngine::ApplyOptions(const AudioOptions& options_in) {
options.echo_cancellation = false;
RTC_LOG(LS_INFO) << "Always disable AEC on iOS. Use built-in instead.";
}
#elif defined(WEBRTC_ANDROID)
use_mobile_software_aec = true;
#endif
// Override noise suppression options for Android.
@ -592,7 +586,8 @@ bool WebRtcVoiceEngine::ApplyOptions(const AudioOptions& options_in) {
if (options.echo_cancellation) {
apm_config.echo_canceller.enabled = *options.echo_cancellation;
apm_config.echo_canceller.mobile_mode = use_mobile_software_aec;
// RingRTC change to allow control of AEC3 vs AECM
apm_config.echo_canceller.mobile_mode = adm()->UseAecm();
}
if (options.auto_gain_control) {

View file

@ -140,6 +140,9 @@ class AudioDeviceModule : public rtc::RefCountInterface {
virtual bool BuiltInAECIsAvailable() const = 0;
virtual bool BuiltInAGCIsAvailable() const = 0;
virtual bool BuiltInNSIsAvailable() const = 0;
// RingRTC change to allow control of AEC3 vs AECM
// When using software AEC, use AECM instead of AEC3.
virtual bool UseAecm() const { return false; }
// Enables the built-in audio effects. Only supported on Android.
virtual int32_t EnableBuiltInAEC(bool enable) = 0;

View file

@ -50,6 +50,8 @@ public class JavaAudioDeviceModule implements AudioDeviceModule {
private boolean useStereoOutput;
private AudioAttributes audioAttributes;
private boolean useLowLatency;
// RingRTC change to allow control of AEC3 vs AECM
private boolean useAecm;
private Builder(Context context) {
this.context = context;
@ -57,6 +59,7 @@ public class JavaAudioDeviceModule implements AudioDeviceModule {
this.inputSampleRate = WebRtcAudioManager.getSampleRate(audioManager);
this.outputSampleRate = WebRtcAudioManager.getSampleRate(audioManager);
this.useLowLatency = false;
this.useAecm = false;
}
public Builder setScheduler(ScheduledExecutorService scheduler) {
@ -213,6 +216,15 @@ public class JavaAudioDeviceModule implements AudioDeviceModule {
return this;
}
// RingRTC change to allow control of AEC3 vs AECM
/**
* Control if AECM is used or AEC3. The default is AEC3.
*/
public Builder setUseAecm(boolean useAecm) {
this.useAecm = useAecm;
return this;
}
/**
* Construct an AudioDeviceModule based on the supplied arguments. The caller takes ownership
* and is responsible for calling release().
@ -251,7 +263,7 @@ public class JavaAudioDeviceModule implements AudioDeviceModule {
final WebRtcAudioTrack audioOutput = new WebRtcAudioTrack(context, audioManager,
audioAttributes, audioTrackErrorCallback, audioTrackStateCallback, useLowLatency);
return new JavaAudioDeviceModule(context, audioManager, audioInput, audioOutput,
inputSampleRate, outputSampleRate, useStereoInput, useStereoOutput);
inputSampleRate, outputSampleRate, useStereoInput, useStereoOutput, useAecm);
}
}
@ -359,13 +371,15 @@ public class JavaAudioDeviceModule implements AudioDeviceModule {
private final int outputSampleRate;
private final boolean useStereoInput;
private final boolean useStereoOutput;
private final boolean useAecm;
private final Object nativeLock = new Object();
private long nativeAudioDeviceModule;
private JavaAudioDeviceModule(Context context, AudioManager audioManager,
WebRtcAudioRecord audioInput, WebRtcAudioTrack audioOutput, int inputSampleRate,
int outputSampleRate, boolean useStereoInput, boolean useStereoOutput) {
int outputSampleRate, boolean useStereoInput, boolean useStereoOutput,
boolean useAecm) {
this.context = context;
this.audioManager = audioManager;
this.audioInput = audioInput;
@ -374,6 +388,7 @@ public class JavaAudioDeviceModule implements AudioDeviceModule {
this.outputSampleRate = outputSampleRate;
this.useStereoInput = useStereoInput;
this.useStereoOutput = useStereoOutput;
this.useAecm = useAecm;
}
@Override
@ -381,7 +396,8 @@ public class JavaAudioDeviceModule implements AudioDeviceModule {
synchronized (nativeLock) {
if (nativeAudioDeviceModule == 0) {
nativeAudioDeviceModule = nativeCreateAudioDeviceModule(context, audioManager, audioInput,
audioOutput, inputSampleRate, outputSampleRate, useStereoInput, useStereoOutput);
audioOutput, inputSampleRate, outputSampleRate, useStereoInput, useStereoOutput,
useAecm);
}
return nativeAudioDeviceModule;
}
@ -423,5 +439,6 @@ public class JavaAudioDeviceModule implements AudioDeviceModule {
private static native long nativeCreateAudioDeviceModule(Context context,
AudioManager audioManager, WebRtcAudioRecord audioInput, WebRtcAudioTrack audioOutput,
int inputSampleRate, int outputSampleRate, boolean useStereoInput, boolean useStereoOutput);
int inputSampleRate, int outputSampleRate, boolean useStereoInput, boolean useStereoOutput,
boolean useAecm);
}

View file

@ -69,7 +69,8 @@ rtc::scoped_refptr<AudioDeviceModule> CreateAAudioAudioDeviceModule(
false /* use_stereo_output */,
jni::kLowLatencyModeDelayEstimateInMilliseconds,
std::make_unique<jni::AAudioRecorder>(input_parameters),
std::make_unique<jni::AAudioPlayer>(output_parameters));
std::make_unique<jni::AAudioPlayer>(output_parameters),
false /* use_aecm */);
}
#endif
@ -98,7 +99,8 @@ rtc::scoped_refptr<AudioDeviceModule> CreateJavaAudioDeviceModule(
AudioDeviceModule::kAndroidJavaAudio, false /* use_stereo_input */,
false /* use_stereo_output */,
jni::kHighLatencyModeDelayEstimateInMilliseconds, std::move(audio_input),
std::move(audio_output));
std::move(audio_output)
false /* use_aecm */);
}
rtc::scoped_refptr<AudioDeviceModule> CreateOpenSLESAudioDeviceModule(
@ -121,7 +123,8 @@ rtc::scoped_refptr<AudioDeviceModule> CreateOpenSLESAudioDeviceModule(
AudioDeviceModule::kAndroidOpenSLESAudio, false /* use_stereo_input */,
false /* use_stereo_output */,
jni::kLowLatencyModeDelayEstimateInMilliseconds, std::move(audio_input),
std::move(audio_output));
std::move(audio_output),
false /* use_aecm */);
}
rtc::scoped_refptr<AudioDeviceModule>
@ -150,7 +153,8 @@ CreateJavaInputAndOpenSLESOutputAudioDeviceModule(JNIEnv* env,
AudioDeviceModule::kAndroidJavaInputAndOpenSLESOutputAudio,
false /* use_stereo_input */, false /* use_stereo_output */,
jni::kLowLatencyModeDelayEstimateInMilliseconds, std::move(audio_input),
std::move(audio_output));
std::move(audio_output),
false /* use_aecm */);
}
} // namespace webrtc

View file

@ -59,7 +59,9 @@ class AndroidAudioDeviceModule : public AudioDeviceModule {
bool is_stereo_record_supported,
uint16_t playout_delay_ms,
std::unique_ptr<AudioInput> audio_input,
std::unique_ptr<AudioOutput> audio_output)
std::unique_ptr<AudioOutput> audio_output,
// RingRTC change to allow control of AEC3 vs AEC3
bool use_aecm)
: audio_layer_(audio_layer),
is_stereo_playout_supported_(is_stereo_playout_supported),
is_stereo_record_supported_(is_stereo_record_supported),
@ -67,6 +69,7 @@ class AndroidAudioDeviceModule : public AudioDeviceModule {
task_queue_factory_(CreateDefaultTaskQueueFactory()),
input_(std::move(audio_input)),
output_(std::move(audio_output)),
use_aecm_(use_aecm),
initialized_(false) {
RTC_CHECK(input_);
RTC_CHECK(output_);
@ -542,6 +545,13 @@ class AndroidAudioDeviceModule : public AudioDeviceModule {
return isAvailable;
}
// RingRTC change to allow control of AEC3 vs AECM
bool UseAecm() const override {
RTC_DLOG(INFO) << __FUNCTION__;
RTC_DLOG(INFO) << "output: " << use_aecm_;
return use_aecm_;
}
// TODO(henrika): add implementation for OpenSL ES based audio as well.
int32_t EnableBuiltInAEC(bool enable) override {
RTC_DLOG(INFO) << __FUNCTION__ << "(" << enable << ")";
@ -593,6 +603,7 @@ class AndroidAudioDeviceModule : public AudioDeviceModule {
const std::unique_ptr<AudioInput> input_;
const std::unique_ptr<AudioOutput> output_;
std::unique_ptr<AudioDeviceBuffer> audio_device_buffer_;
const bool use_aecm_ = false;
bool initialized_;
};
@ -639,11 +650,13 @@ rtc::scoped_refptr<AudioDeviceModule> CreateAudioDeviceModuleFromInputAndOutput(
bool is_stereo_record_supported,
uint16_t playout_delay_ms,
std::unique_ptr<AudioInput> audio_input,
std::unique_ptr<AudioOutput> audio_output) {
std::unique_ptr<AudioOutput> audio_output,
// RingRTC change to allow control of AEC3 vs AECM
bool use_aecm) {
RTC_DLOG(INFO) << __FUNCTION__;
return rtc::make_ref_counted<AndroidAudioDeviceModule>(
audio_layer, is_stereo_playout_supported, is_stereo_record_supported,
playout_delay_ms, std::move(audio_input), std::move(audio_output));
playout_delay_ms, std::move(audio_input), std::move(audio_output), use_aecm);
}
} // namespace jni

View file

@ -93,7 +93,9 @@ rtc::scoped_refptr<AudioDeviceModule> CreateAudioDeviceModuleFromInputAndOutput(
bool is_stereo_record_supported,
uint16_t playout_delay_ms,
std::unique_ptr<AudioInput> audio_input,
std::unique_ptr<AudioOutput> audio_output);
std::unique_ptr<AudioOutput> audio_output,
// RingRTC change to allow control of AEC3 vs AECM
bool use_aecm);
} // namespace jni

View file

@ -27,7 +27,9 @@ static jlong JNI_JavaAudioDeviceModule_CreateAudioDeviceModule(
int input_sample_rate,
int output_sample_rate,
jboolean j_use_stereo_input,
jboolean j_use_stereo_output) {
jboolean j_use_stereo_output,
// RingRTC change to allow control of AEC3 vs AECM
jboolean j_use_aecm) {
AudioParameters input_parameters;
AudioParameters output_parameters;
GetAudioParameters(env, j_context, j_audio_manager, input_sample_rate,
@ -43,7 +45,8 @@ static jlong JNI_JavaAudioDeviceModule_CreateAudioDeviceModule(
AudioDeviceModule::kAndroidJavaAudio,
j_use_stereo_input, j_use_stereo_output,
kHighLatencyModeDelayEstimateInMilliseconds,
std::move(audio_input), std::move(audio_output))
std::move(audio_input), std::move(audio_output),
j_use_aecm)
.release());
}