1 /*
2  *  Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 #include "modules/audio_processing/capture_levels_adjuster/capture_levels_adjuster.h"
11 
12 #include "modules/audio_processing/audio_buffer.h"
13 #include "rtc_base/checks.h"
14 #include "rtc_base/numerics/safe_minmax.h"
15 
16 namespace webrtc {
17 
18 namespace {
19 
20 constexpr int kMinAnalogMicGainLevel = 0;
21 constexpr int kMaxAnalogMicGainLevel = 255;
22 
ComputeLevelBasedGain(int emulated_analog_mic_gain_level)23 float ComputeLevelBasedGain(int emulated_analog_mic_gain_level) {
24   static_assert(
25       kMinAnalogMicGainLevel == 0,
26       "The minimum gain level must be 0 for the maths below to work.");
27   static_assert(kMaxAnalogMicGainLevel > 0,
28                 "The minimum gain level must be larger than 0 for the maths "
29                 "below to work.");
30   constexpr float kGainToLevelMultiplier = 1.f / kMaxAnalogMicGainLevel;
31 
32   RTC_DCHECK_GE(emulated_analog_mic_gain_level, kMinAnalogMicGainLevel);
33   RTC_DCHECK_LE(emulated_analog_mic_gain_level, kMaxAnalogMicGainLevel);
34   return kGainToLevelMultiplier * emulated_analog_mic_gain_level;
35 }
36 
ComputePreGain(float pre_gain,int emulated_analog_mic_gain_level,bool emulated_analog_mic_gain_enabled)37 float ComputePreGain(float pre_gain,
38                      int emulated_analog_mic_gain_level,
39                      bool emulated_analog_mic_gain_enabled) {
40   return emulated_analog_mic_gain_enabled
41              ? pre_gain * ComputeLevelBasedGain(emulated_analog_mic_gain_level)
42              : pre_gain;
43 }
44 
45 }  // namespace
46 
CaptureLevelsAdjuster(bool emulated_analog_mic_gain_enabled,int emulated_analog_mic_gain_level,float pre_gain,float post_gain)47 CaptureLevelsAdjuster::CaptureLevelsAdjuster(
48     bool emulated_analog_mic_gain_enabled,
49     int emulated_analog_mic_gain_level,
50     float pre_gain,
51     float post_gain)
52     : emulated_analog_mic_gain_enabled_(emulated_analog_mic_gain_enabled),
53       emulated_analog_mic_gain_level_(emulated_analog_mic_gain_level),
54       pre_gain_(pre_gain),
55       pre_adjustment_gain_(ComputePreGain(pre_gain_,
56                                           emulated_analog_mic_gain_level_,
57                                           emulated_analog_mic_gain_enabled_)),
58       pre_scaler_(pre_adjustment_gain_),
59       post_scaler_(post_gain) {}
60 
ApplyPreLevelAdjustment(AudioBuffer & audio_buffer)61 void CaptureLevelsAdjuster::ApplyPreLevelAdjustment(AudioBuffer& audio_buffer) {
62   pre_scaler_.Process(audio_buffer);
63 }
64 
ApplyPostLevelAdjustment(AudioBuffer & audio_buffer)65 void CaptureLevelsAdjuster::ApplyPostLevelAdjustment(
66     AudioBuffer& audio_buffer) {
67   post_scaler_.Process(audio_buffer);
68 }
69 
SetPreGain(float pre_gain)70 void CaptureLevelsAdjuster::SetPreGain(float pre_gain) {
71   pre_gain_ = pre_gain;
72   UpdatePreAdjustmentGain();
73 }
74 
SetPostGain(float post_gain)75 void CaptureLevelsAdjuster::SetPostGain(float post_gain) {
76   post_scaler_.SetGain(post_gain);
77 }
78 
SetAnalogMicGainLevel(int level)79 void CaptureLevelsAdjuster::SetAnalogMicGainLevel(int level) {
80   RTC_DCHECK_GE(level, kMinAnalogMicGainLevel);
81   RTC_DCHECK_LE(level, kMaxAnalogMicGainLevel);
82   int clamped_level =
83       rtc::SafeClamp(level, kMinAnalogMicGainLevel, kMaxAnalogMicGainLevel);
84 
85   emulated_analog_mic_gain_level_ = clamped_level;
86   UpdatePreAdjustmentGain();
87 }
88 
UpdatePreAdjustmentGain()89 void CaptureLevelsAdjuster::UpdatePreAdjustmentGain() {
90   pre_adjustment_gain_ =
91       ComputePreGain(pre_gain_, emulated_analog_mic_gain_level_,
92                      emulated_analog_mic_gain_enabled_);
93   pre_scaler_.SetGain(pre_adjustment_gain_);
94 }
95 
96 }  // namespace webrtc
97