/* * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #include "modules/audio_processing/capture_levels_adjuster/capture_levels_adjuster.h" #include "modules/audio_processing/audio_buffer.h" #include "rtc_base/checks.h" #include "rtc_base/numerics/safe_minmax.h" namespace webrtc { namespace { constexpr int kMinAnalogMicGainLevel = 0; constexpr int kMaxAnalogMicGainLevel = 255; float ComputeLevelBasedGain(int emulated_analog_mic_gain_level) { static_assert( kMinAnalogMicGainLevel == 0, "The minimum gain level must be 0 for the maths below to work."); static_assert(kMaxAnalogMicGainLevel > 0, "The minimum gain level must be larger than 0 for the maths " "below to work."); constexpr float kGainToLevelMultiplier = 1.f / kMaxAnalogMicGainLevel; RTC_DCHECK_GE(emulated_analog_mic_gain_level, kMinAnalogMicGainLevel); RTC_DCHECK_LE(emulated_analog_mic_gain_level, kMaxAnalogMicGainLevel); return kGainToLevelMultiplier * emulated_analog_mic_gain_level; } float ComputePreGain(float pre_gain, int emulated_analog_mic_gain_level, bool emulated_analog_mic_gain_enabled) { return emulated_analog_mic_gain_enabled ? pre_gain * ComputeLevelBasedGain(emulated_analog_mic_gain_level) : pre_gain; } } // namespace CaptureLevelsAdjuster::CaptureLevelsAdjuster( bool emulated_analog_mic_gain_enabled, int emulated_analog_mic_gain_level, float pre_gain, float post_gain) : emulated_analog_mic_gain_enabled_(emulated_analog_mic_gain_enabled), emulated_analog_mic_gain_level_(emulated_analog_mic_gain_level), pre_gain_(pre_gain), pre_adjustment_gain_(ComputePreGain(pre_gain_, emulated_analog_mic_gain_level_, emulated_analog_mic_gain_enabled_)), pre_scaler_(pre_adjustment_gain_), post_scaler_(post_gain) {} void CaptureLevelsAdjuster::ApplyPreLevelAdjustment(AudioBuffer& audio_buffer) { pre_scaler_.Process(audio_buffer); } void CaptureLevelsAdjuster::ApplyPostLevelAdjustment( AudioBuffer& audio_buffer) { post_scaler_.Process(audio_buffer); } void CaptureLevelsAdjuster::SetPreGain(float pre_gain) { pre_gain_ = pre_gain; UpdatePreAdjustmentGain(); } void CaptureLevelsAdjuster::SetPostGain(float post_gain) { post_scaler_.SetGain(post_gain); } void CaptureLevelsAdjuster::SetAnalogMicGainLevel(int level) { RTC_DCHECK_GE(level, kMinAnalogMicGainLevel); RTC_DCHECK_LE(level, kMaxAnalogMicGainLevel); int clamped_level = rtc::SafeClamp(level, kMinAnalogMicGainLevel, kMaxAnalogMicGainLevel); emulated_analog_mic_gain_level_ = clamped_level; UpdatePreAdjustmentGain(); } void CaptureLevelsAdjuster::UpdatePreAdjustmentGain() { pre_adjustment_gain_ = ComputePreGain(pre_gain_, emulated_analog_mic_gain_level_, emulated_analog_mic_gain_enabled_); pre_scaler_.SetGain(pre_adjustment_gain_); } } // namespace webrtc