• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2013 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 
11 #ifndef MODULES_AUDIO_PROCESSING_AGC_AGC_MANAGER_DIRECT_H_
12 #define MODULES_AUDIO_PROCESSING_AGC_AGC_MANAGER_DIRECT_H_
13 
14 #include <memory>
15 
16 #include "absl/types/optional.h"
17 #include "modules/audio_processing/agc/agc.h"
18 #include "modules/audio_processing/audio_buffer.h"
19 #include "modules/audio_processing/logging/apm_data_dumper.h"
20 #include "rtc_base/gtest_prod_util.h"
21 
22 namespace webrtc {
23 
24 class MonoAgc;
25 class GainControl;
26 
27 // Direct interface to use AGC to set volume and compression values.
28 // AudioProcessing uses this interface directly to integrate the callback-less
29 // AGC.
30 //
31 // This class is not thread-safe.
32 class AgcManagerDirect final {
33  public:
34   // AgcManagerDirect will configure GainControl internally. The user is
35   // responsible for processing the audio using it after the call to Process.
36   // The operating range of startup_min_level is [12, 255] and any input value
37   // outside that range will be clamped.
38   AgcManagerDirect(int num_capture_channels,
39                    int startup_min_level,
40                    int clipped_level_min,
41                    bool use_agc2_level_estimation,
42                    bool disable_digital_adaptive,
43                    int sample_rate_hz);
44 
45   ~AgcManagerDirect();
46   AgcManagerDirect(const AgcManagerDirect&) = delete;
47   AgcManagerDirect& operator=(const AgcManagerDirect&) = delete;
48 
49   void Initialize();
50   void SetupDigitalGainControl(GainControl* gain_control) const;
51 
52   void AnalyzePreProcess(const AudioBuffer* audio);
53   void Process(const AudioBuffer* audio);
54 
55   // Call when the capture stream has been muted/unmuted. This causes the
56   // manager to disregard all incoming audio; chances are good it's background
57   // noise to which we'd like to avoid adapting.
58   void SetCaptureMuted(bool muted);
59   float voice_probability() const;
60 
stream_analog_level()61   int stream_analog_level() const { return stream_analog_level_; }
62   void set_stream_analog_level(int level);
num_channels()63   int num_channels() const { return num_capture_channels_; }
sample_rate_hz()64   int sample_rate_hz() const { return sample_rate_hz_; }
65 
66   // If available, returns a new compression gain for the digital gain control.
67   absl::optional<int> GetDigitalComressionGain();
68 
69  private:
70   friend class AgcManagerDirectTest;
71 
72   FRIEND_TEST_ALL_PREFIXES(AgcManagerDirectStandaloneTest,
73                            DisableDigitalDisablesDigital);
74   FRIEND_TEST_ALL_PREFIXES(AgcManagerDirectStandaloneTest,
75                            AgcMinMicLevelExperiment);
76 
77   // Dependency injection for testing. Don't delete |agc| as the memory is owned
78   // by the manager.
79   AgcManagerDirect(Agc* agc,
80                    int startup_min_level,
81                    int clipped_level_min,
82                    int sample_rate_hz);
83 
84   void AnalyzePreProcess(const float* const* audio, size_t samples_per_channel);
85 
86   void AggregateChannelLevels();
87 
88   std::unique_ptr<ApmDataDumper> data_dumper_;
89   static int instance_counter_;
90   const bool use_min_channel_level_;
91   const int sample_rate_hz_;
92   const int num_capture_channels_;
93   const bool disable_digital_adaptive_;
94 
95   int frames_since_clipped_;
96   int stream_analog_level_ = 0;
97   bool capture_muted_;
98   int channel_controlling_gain_ = 0;
99 
100   std::vector<std::unique_ptr<MonoAgc>> channel_agcs_;
101   std::vector<absl::optional<int>> new_compressions_to_set_;
102 };
103 
104 class MonoAgc {
105  public:
106   MonoAgc(ApmDataDumper* data_dumper,
107           int startup_min_level,
108           int clipped_level_min,
109           bool use_agc2_level_estimation,
110           bool disable_digital_adaptive,
111           int min_mic_level);
112   ~MonoAgc();
113   MonoAgc(const MonoAgc&) = delete;
114   MonoAgc& operator=(const MonoAgc&) = delete;
115 
116   void Initialize();
117   void SetCaptureMuted(bool muted);
118 
119   void HandleClipping();
120 
121   void Process(const int16_t* audio,
122                size_t samples_per_channel,
123                int sample_rate_hz);
124 
set_stream_analog_level(int level)125   void set_stream_analog_level(int level) { stream_analog_level_ = level; }
stream_analog_level()126   int stream_analog_level() const { return stream_analog_level_; }
voice_probability()127   float voice_probability() const { return agc_->voice_probability(); }
ActivateLogging()128   void ActivateLogging() { log_to_histograms_ = true; }
new_compression()129   absl::optional<int> new_compression() const {
130     return new_compression_to_set_;
131   }
132 
133   // Only used for testing.
set_agc(Agc * agc)134   void set_agc(Agc* agc) { agc_.reset(agc); }
min_mic_level()135   int min_mic_level() const { return min_mic_level_; }
startup_min_level()136   int startup_min_level() const { return startup_min_level_; }
137 
138  private:
139   // Sets a new microphone level, after first checking that it hasn't been
140   // updated by the user, in which case no action is taken.
141   void SetLevel(int new_level);
142 
143   // Set the maximum level the AGC is allowed to apply. Also updates the
144   // maximum compression gain to compensate. The level must be at least
145   // |kClippedLevelMin|.
146   void SetMaxLevel(int level);
147 
148   int CheckVolumeAndReset();
149   void UpdateGain();
150   void UpdateCompressor();
151 
152   const int min_mic_level_;
153   const bool disable_digital_adaptive_;
154   std::unique_ptr<Agc> agc_;
155   int level_ = 0;
156   int max_level_;
157   int max_compression_gain_;
158   int target_compression_;
159   int compression_;
160   float compression_accumulator_;
161   bool capture_muted_ = false;
162   bool check_volume_on_next_process_ = true;
163   bool startup_ = true;
164   int startup_min_level_;
165   int calls_since_last_gain_log_ = 0;
166   int stream_analog_level_ = 0;
167   absl::optional<int> new_compression_to_set_;
168   bool log_to_histograms_ = false;
169   const int clipped_level_min_;
170 };
171 
172 }  // namespace webrtc
173 
174 #endif  // MODULES_AUDIO_PROCESSING_AGC_AGC_MANAGER_DIRECT_H_
175