blob: 8f707fc3b524295ae2439d98412d2aba6f3c4733 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
bjornv@webrtc.org0c6f9312012-01-30 09:39:08 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
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
pbos@webrtc.org7fad4b82013-05-28 08:11:59 +000011#include "webrtc/modules/audio_processing/gain_control_impl.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000012
kwiberg4485ffb2016-04-26 08:14:39 -070013#include "webrtc/base/constructormagic.h"
peahbfa97112016-03-10 21:09:04 -080014#include "webrtc/base/optional.h"
andrew@webrtc.org56e4a052014-02-27 22:23:17 +000015#include "webrtc/modules/audio_processing/audio_buffer.h"
bjornv@webrtc.orgb395a5e2014-12-16 10:38:10 +000016#include "webrtc/modules/audio_processing/agc/legacy/gain_control.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000017
niklase@google.com470e71d2011-07-07 08:21:25 +000018namespace webrtc {
19
20typedef void Handle;
21
niklase@google.com470e71d2011-07-07 08:21:25 +000022namespace {
pbos@webrtc.orgb7192b82013-04-10 07:50:54 +000023int16_t MapSetting(GainControl::Mode mode) {
niklase@google.com470e71d2011-07-07 08:21:25 +000024 switch (mode) {
25 case GainControl::kAdaptiveAnalog:
26 return kAgcModeAdaptiveAnalog;
niklase@google.com470e71d2011-07-07 08:21:25 +000027 case GainControl::kAdaptiveDigital:
28 return kAgcModeAdaptiveDigital;
niklase@google.com470e71d2011-07-07 08:21:25 +000029 case GainControl::kFixedDigital:
30 return kAgcModeFixedDigital;
niklase@google.com470e71d2011-07-07 08:21:25 +000031 }
peahbfa97112016-03-10 21:09:04 -080032 RTC_DCHECK(false);
mflodman@webrtc.org657b2a42012-02-06 11:06:01 +000033 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +000034}
niklase@google.com470e71d2011-07-07 08:21:25 +000035
peah2446e5a2015-11-18 06:11:13 -080036} // namespace
peah4d291f72015-11-16 23:52:25 -080037
peahbfa97112016-03-10 21:09:04 -080038class GainControlImpl::GainController {
39 public:
40 explicit GainController() {
41 state_ = WebRtcAgc_Create();
42 RTC_CHECK(state_);
43 }
44
45 ~GainController() {
46 RTC_DCHECK(state_);
47 WebRtcAgc_Free(state_);
48 }
49
50 Handle* state() {
51 RTC_DCHECK(state_);
52 return state_;
53 }
54
55 void Initialize(int minimum_capture_level,
56 int maximum_capture_level,
57 Mode mode,
58 int sample_rate_hz,
59 int capture_level) {
60 RTC_DCHECK(state_);
61 int error =
62 WebRtcAgc_Init(state_, minimum_capture_level, maximum_capture_level,
63 MapSetting(mode), sample_rate_hz);
64 RTC_DCHECK_EQ(0, error);
65
66 set_capture_level(capture_level);
67 }
68
69 void set_capture_level(int capture_level) {
70 capture_level_ = rtc::Optional<int>(capture_level);
71 }
72
73 int get_capture_level() {
74 RTC_DCHECK(capture_level_);
75 return *capture_level_;
76 }
77
78 private:
79 Handle* state_;
80 // TODO(peah): Remove the optional once the initialization is moved into the
81 // ctor.
82 rtc::Optional<int> capture_level_;
83
84 RTC_DISALLOW_COPY_AND_ASSIGN(GainController);
85};
86
peahb8fbb542016-03-15 02:28:08 -070087GainControlImpl::GainControlImpl(rtc::CriticalSection* crit_render,
peahdf3efa82015-11-28 12:35:15 -080088 rtc::CriticalSection* crit_capture)
peahb8fbb542016-03-15 02:28:08 -070089 : crit_render_(crit_render),
peahdf3efa82015-11-28 12:35:15 -080090 crit_capture_(crit_capture),
peah4d291f72015-11-16 23:52:25 -080091 mode_(kAdaptiveAnalog),
92 minimum_capture_level_(0),
93 maximum_capture_level_(255),
94 limiter_enabled_(true),
95 target_level_dbfs_(3),
96 compression_gain_db_(9),
97 analog_capture_level_(0),
98 was_analog_level_set_(false),
peah701d6282016-10-25 05:42:20 -070099 stream_is_saturated_(false) {
peahdf3efa82015-11-28 12:35:15 -0800100 RTC_DCHECK(crit_render);
101 RTC_DCHECK(crit_capture);
102}
niklase@google.com470e71d2011-07-07 08:21:25 +0000103
104GainControlImpl::~GainControlImpl() {}
105
peah701d6282016-10-25 05:42:20 -0700106void GainControlImpl::ProcessRenderAudio(
107 rtc::ArrayView<const int16_t> packed_render_audio) {
108 rtc::CritScope cs_capture(crit_capture_);
peahbfa97112016-03-10 21:09:04 -0800109 if (!enabled_) {
peah4d291f72015-11-16 23:52:25 -0800110 return;
111 }
112
peah701d6282016-10-25 05:42:20 -0700113 for (auto& gain_controller : gain_controllers_) {
114 WebRtcAgc_AddFarend(gain_controller->state(), packed_render_audio.data(),
115 packed_render_audio.size());
peah4d291f72015-11-16 23:52:25 -0800116 }
117}
118
peah701d6282016-10-25 05:42:20 -0700119void GainControlImpl::PackRenderAudioBuffer(
120 AudioBuffer* audio,
121 std::vector<int16_t>* packed_buffer) {
122 RTC_DCHECK_GE(160u, audio->num_frames_per_band());
123
124 packed_buffer->clear();
125 packed_buffer->insert(
126 packed_buffer->end(), audio->mixed_low_pass_data(),
127 (audio->mixed_low_pass_data() + audio->num_frames_per_band()));
128}
129
niklase@google.com470e71d2011-07-07 08:21:25 +0000130int GainControlImpl::AnalyzeCaptureAudio(AudioBuffer* audio) {
peahdf3efa82015-11-28 12:35:15 -0800131 rtc::CritScope cs(crit_capture_);
132
peahbfa97112016-03-10 21:09:04 -0800133 if (!enabled_) {
peahdf3efa82015-11-28 12:35:15 -0800134 return AudioProcessing::kNoError;
niklase@google.com470e71d2011-07-07 08:21:25 +0000135 }
136
peahb8fbb542016-03-15 02:28:08 -0700137 RTC_DCHECK(num_proc_channels_);
peahbfa97112016-03-10 21:09:04 -0800138 RTC_DCHECK_GE(160u, audio->num_frames_per_band());
peahb8fbb542016-03-15 02:28:08 -0700139 RTC_DCHECK_EQ(audio->num_channels(), *num_proc_channels_);
140 RTC_DCHECK_LE(*num_proc_channels_, gain_controllers_.size());
niklase@google.com470e71d2011-07-07 08:21:25 +0000141
142 if (mode_ == kAdaptiveAnalog) {
peahbfa97112016-03-10 21:09:04 -0800143 int capture_channel = 0;
144 for (auto& gain_controller : gain_controllers_) {
145 gain_controller->set_capture_level(analog_capture_level_);
146 int err = WebRtcAgc_AddMic(
147 gain_controller->state(), audio->split_bands(capture_channel),
148 audio->num_bands(), audio->num_frames_per_band());
niklase@google.com470e71d2011-07-07 08:21:25 +0000149
peahdf3efa82015-11-28 12:35:15 -0800150 if (err != AudioProcessing::kNoError) {
peahbfa97112016-03-10 21:09:04 -0800151 return AudioProcessing::kUnspecifiedError;
niklase@google.com470e71d2011-07-07 08:21:25 +0000152 }
peahbfa97112016-03-10 21:09:04 -0800153 ++capture_channel;
niklase@google.com470e71d2011-07-07 08:21:25 +0000154 }
155 } else if (mode_ == kAdaptiveDigital) {
peahbfa97112016-03-10 21:09:04 -0800156 int capture_channel = 0;
157 for (auto& gain_controller : gain_controllers_) {
pbos@webrtc.orgb7192b82013-04-10 07:50:54 +0000158 int32_t capture_level_out = 0;
peahbfa97112016-03-10 21:09:04 -0800159 int err = WebRtcAgc_VirtualMic(
160 gain_controller->state(), audio->split_bands(capture_channel),
161 audio->num_bands(), audio->num_frames_per_band(),
162 analog_capture_level_, &capture_level_out);
niklase@google.com470e71d2011-07-07 08:21:25 +0000163
peahbfa97112016-03-10 21:09:04 -0800164 gain_controller->set_capture_level(capture_level_out);
niklase@google.com470e71d2011-07-07 08:21:25 +0000165
peahdf3efa82015-11-28 12:35:15 -0800166 if (err != AudioProcessing::kNoError) {
peahbfa97112016-03-10 21:09:04 -0800167 return AudioProcessing::kUnspecifiedError;
niklase@google.com470e71d2011-07-07 08:21:25 +0000168 }
peahbfa97112016-03-10 21:09:04 -0800169 ++capture_channel;
niklase@google.com470e71d2011-07-07 08:21:25 +0000170 }
171 }
172
peahdf3efa82015-11-28 12:35:15 -0800173 return AudioProcessing::kNoError;
niklase@google.com470e71d2011-07-07 08:21:25 +0000174}
175
peahb8fbb542016-03-15 02:28:08 -0700176int GainControlImpl::ProcessCaptureAudio(AudioBuffer* audio,
177 bool stream_has_echo) {
peahdf3efa82015-11-28 12:35:15 -0800178 rtc::CritScope cs(crit_capture_);
179
peahbfa97112016-03-10 21:09:04 -0800180 if (!enabled_) {
peahdf3efa82015-11-28 12:35:15 -0800181 return AudioProcessing::kNoError;
niklase@google.com470e71d2011-07-07 08:21:25 +0000182 }
183
184 if (mode_ == kAdaptiveAnalog && !was_analog_level_set_) {
peahdf3efa82015-11-28 12:35:15 -0800185 return AudioProcessing::kStreamParameterNotSetError;
niklase@google.com470e71d2011-07-07 08:21:25 +0000186 }
187
peahb8fbb542016-03-15 02:28:08 -0700188 RTC_DCHECK(num_proc_channels_);
peahbfa97112016-03-10 21:09:04 -0800189 RTC_DCHECK_GE(160u, audio->num_frames_per_band());
peahb8fbb542016-03-15 02:28:08 -0700190 RTC_DCHECK_EQ(audio->num_channels(), *num_proc_channels_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000191
192 stream_is_saturated_ = false;
peahbfa97112016-03-10 21:09:04 -0800193 int capture_channel = 0;
194 for (auto& gain_controller : gain_controllers_) {
pbos@webrtc.orgb7192b82013-04-10 07:50:54 +0000195 int32_t capture_level_out = 0;
196 uint8_t saturation_warning = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000197
peahdf3efa82015-11-28 12:35:15 -0800198 // The call to stream_has_echo() is ok from a deadlock perspective
199 // as the capture lock is allready held.
niklase@google.com470e71d2011-07-07 08:21:25 +0000200 int err = WebRtcAgc_Process(
peahbfa97112016-03-10 21:09:04 -0800201 gain_controller->state(), audio->split_bands_const(capture_channel),
202 audio->num_bands(), audio->num_frames_per_band(),
203 audio->split_bands(capture_channel),
204 gain_controller->get_capture_level(), &capture_level_out,
peahb8fbb542016-03-15 02:28:08 -0700205 stream_has_echo, &saturation_warning);
niklase@google.com470e71d2011-07-07 08:21:25 +0000206
peahdf3efa82015-11-28 12:35:15 -0800207 if (err != AudioProcessing::kNoError) {
peahbfa97112016-03-10 21:09:04 -0800208 return AudioProcessing::kUnspecifiedError;
niklase@google.com470e71d2011-07-07 08:21:25 +0000209 }
210
peahbfa97112016-03-10 21:09:04 -0800211 gain_controller->set_capture_level(capture_level_out);
niklase@google.com470e71d2011-07-07 08:21:25 +0000212 if (saturation_warning == 1) {
213 stream_is_saturated_ = true;
214 }
peahbfa97112016-03-10 21:09:04 -0800215
216 ++capture_channel;
niklase@google.com470e71d2011-07-07 08:21:25 +0000217 }
218
peahb8fbb542016-03-15 02:28:08 -0700219 RTC_DCHECK_LT(0ul, *num_proc_channels_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000220 if (mode_ == kAdaptiveAnalog) {
221 // Take the analog level to be the average across the handles.
222 analog_capture_level_ = 0;
peahbfa97112016-03-10 21:09:04 -0800223 for (auto& gain_controller : gain_controllers_) {
224 analog_capture_level_ += gain_controller->get_capture_level();
niklase@google.com470e71d2011-07-07 08:21:25 +0000225 }
226
peahb8fbb542016-03-15 02:28:08 -0700227 analog_capture_level_ /= (*num_proc_channels_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000228 }
229
230 was_analog_level_set_ = false;
peahdf3efa82015-11-28 12:35:15 -0800231 return AudioProcessing::kNoError;
niklase@google.com470e71d2011-07-07 08:21:25 +0000232}
233
aluebs11d4a422016-04-28 14:58:32 -0700234int GainControlImpl::compression_gain_db() const {
235 rtc::CritScope cs(crit_capture_);
236 return compression_gain_db_;
237}
238
niklase@google.com470e71d2011-07-07 08:21:25 +0000239// TODO(ajm): ensure this is called under kAdaptiveAnalog.
240int GainControlImpl::set_stream_analog_level(int level) {
peahdf3efa82015-11-28 12:35:15 -0800241 rtc::CritScope cs(crit_capture_);
242
niklase@google.com470e71d2011-07-07 08:21:25 +0000243 was_analog_level_set_ = true;
244 if (level < minimum_capture_level_ || level > maximum_capture_level_) {
peahdf3efa82015-11-28 12:35:15 -0800245 return AudioProcessing::kBadParameterError;
niklase@google.com470e71d2011-07-07 08:21:25 +0000246 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000247 analog_capture_level_ = level;
248
peahdf3efa82015-11-28 12:35:15 -0800249 return AudioProcessing::kNoError;
niklase@google.com470e71d2011-07-07 08:21:25 +0000250}
251
252int GainControlImpl::stream_analog_level() {
peahdf3efa82015-11-28 12:35:15 -0800253 rtc::CritScope cs(crit_capture_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000254 // TODO(ajm): enable this assertion?
kwiberg9e2be5f2016-09-14 05:23:22 -0700255 //RTC_DCHECK_EQ(kAdaptiveAnalog, mode_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000256
257 return analog_capture_level_;
258}
259
260int GainControlImpl::Enable(bool enable) {
peahdf3efa82015-11-28 12:35:15 -0800261 rtc::CritScope cs_render(crit_render_);
262 rtc::CritScope cs_capture(crit_capture_);
peahbfa97112016-03-10 21:09:04 -0800263 if (enable && !enabled_) {
264 enabled_ = enable; // Must be set before Initialize() is called.
peahb8fbb542016-03-15 02:28:08 -0700265
266 RTC_DCHECK(num_proc_channels_);
267 RTC_DCHECK(sample_rate_hz_);
268 Initialize(*num_proc_channels_, *sample_rate_hz_);
peahbfa97112016-03-10 21:09:04 -0800269 } else {
270 enabled_ = enable;
271 }
272 return AudioProcessing::kNoError;
niklase@google.com470e71d2011-07-07 08:21:25 +0000273}
274
275bool GainControlImpl::is_enabled() const {
peahdf3efa82015-11-28 12:35:15 -0800276 rtc::CritScope cs(crit_capture_);
peahbfa97112016-03-10 21:09:04 -0800277 return enabled_;
niklase@google.com470e71d2011-07-07 08:21:25 +0000278}
279
280int GainControlImpl::set_mode(Mode mode) {
peahdf3efa82015-11-28 12:35:15 -0800281 rtc::CritScope cs_render(crit_render_);
282 rtc::CritScope cs_capture(crit_capture_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000283 if (MapSetting(mode) == -1) {
peahdf3efa82015-11-28 12:35:15 -0800284 return AudioProcessing::kBadParameterError;
niklase@google.com470e71d2011-07-07 08:21:25 +0000285 }
286
287 mode_ = mode;
peahb8fbb542016-03-15 02:28:08 -0700288 RTC_DCHECK(num_proc_channels_);
289 RTC_DCHECK(sample_rate_hz_);
290 Initialize(*num_proc_channels_, *sample_rate_hz_);
peahbfa97112016-03-10 21:09:04 -0800291 return AudioProcessing::kNoError;
niklase@google.com470e71d2011-07-07 08:21:25 +0000292}
293
294GainControl::Mode GainControlImpl::mode() const {
peahdf3efa82015-11-28 12:35:15 -0800295 rtc::CritScope cs(crit_capture_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000296 return mode_;
297}
298
299int GainControlImpl::set_analog_level_limits(int minimum,
300 int maximum) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000301 if (minimum < 0) {
peahdf3efa82015-11-28 12:35:15 -0800302 return AudioProcessing::kBadParameterError;
niklase@google.com470e71d2011-07-07 08:21:25 +0000303 }
304
305 if (maximum > 65535) {
peahdf3efa82015-11-28 12:35:15 -0800306 return AudioProcessing::kBadParameterError;
niklase@google.com470e71d2011-07-07 08:21:25 +0000307 }
308
309 if (maximum < minimum) {
peahdf3efa82015-11-28 12:35:15 -0800310 return AudioProcessing::kBadParameterError;
niklase@google.com470e71d2011-07-07 08:21:25 +0000311 }
312
peah7c931ad2016-03-24 12:52:02 -0700313 size_t num_proc_channels_local = 0u;
314 int sample_rate_hz_local = 0;
315 {
316 rtc::CritScope cs(crit_capture_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000317
peah7c931ad2016-03-24 12:52:02 -0700318 minimum_capture_level_ = minimum;
319 maximum_capture_level_ = maximum;
320
321 RTC_DCHECK(num_proc_channels_);
322 RTC_DCHECK(sample_rate_hz_);
323 num_proc_channels_local = *num_proc_channels_;
324 sample_rate_hz_local = *sample_rate_hz_;
325 }
326 Initialize(num_proc_channels_local, sample_rate_hz_local);
peahbfa97112016-03-10 21:09:04 -0800327 return AudioProcessing::kNoError;
niklase@google.com470e71d2011-07-07 08:21:25 +0000328}
329
330int GainControlImpl::analog_level_minimum() const {
peahdf3efa82015-11-28 12:35:15 -0800331 rtc::CritScope cs(crit_capture_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000332 return minimum_capture_level_;
333}
334
335int GainControlImpl::analog_level_maximum() const {
peahdf3efa82015-11-28 12:35:15 -0800336 rtc::CritScope cs(crit_capture_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000337 return maximum_capture_level_;
338}
339
340bool GainControlImpl::stream_is_saturated() const {
peahdf3efa82015-11-28 12:35:15 -0800341 rtc::CritScope cs(crit_capture_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000342 return stream_is_saturated_;
343}
344
345int GainControlImpl::set_target_level_dbfs(int level) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000346 if (level > 31 || level < 0) {
peahdf3efa82015-11-28 12:35:15 -0800347 return AudioProcessing::kBadParameterError;
niklase@google.com470e71d2011-07-07 08:21:25 +0000348 }
peahbfa97112016-03-10 21:09:04 -0800349 {
350 rtc::CritScope cs(crit_capture_);
351 target_level_dbfs_ = level;
352 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000353 return Configure();
354}
355
356int GainControlImpl::target_level_dbfs() const {
peahdf3efa82015-11-28 12:35:15 -0800357 rtc::CritScope cs(crit_capture_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000358 return target_level_dbfs_;
359}
360
361int GainControlImpl::set_compression_gain_db(int gain) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000362 if (gain < 0 || gain > 90) {
peahdf3efa82015-11-28 12:35:15 -0800363 return AudioProcessing::kBadParameterError;
niklase@google.com470e71d2011-07-07 08:21:25 +0000364 }
peahbfa97112016-03-10 21:09:04 -0800365 {
366 rtc::CritScope cs(crit_capture_);
367 compression_gain_db_ = gain;
368 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000369 return Configure();
370}
371
niklase@google.com470e71d2011-07-07 08:21:25 +0000372int GainControlImpl::enable_limiter(bool enable) {
peahbfa97112016-03-10 21:09:04 -0800373 {
374 rtc::CritScope cs(crit_capture_);
375 limiter_enabled_ = enable;
376 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000377 return Configure();
378}
379
380bool GainControlImpl::is_limiter_enabled() const {
peahdf3efa82015-11-28 12:35:15 -0800381 rtc::CritScope cs(crit_capture_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000382 return limiter_enabled_;
383}
384
peahb8fbb542016-03-15 02:28:08 -0700385void GainControlImpl::Initialize(size_t num_proc_channels, int sample_rate_hz) {
peahbfa97112016-03-10 21:09:04 -0800386 rtc::CritScope cs_render(crit_render_);
387 rtc::CritScope cs_capture(crit_capture_);
peahb8fbb542016-03-15 02:28:08 -0700388
389 num_proc_channels_ = rtc::Optional<size_t>(num_proc_channels);
390 sample_rate_hz_ = rtc::Optional<int>(sample_rate_hz);
391
peahbfa97112016-03-10 21:09:04 -0800392 if (!enabled_) {
393 return;
niklase@google.com470e71d2011-07-07 08:21:25 +0000394 }
395
peahb8fbb542016-03-15 02:28:08 -0700396 gain_controllers_.resize(*num_proc_channels_);
peahbfa97112016-03-10 21:09:04 -0800397 for (auto& gain_controller : gain_controllers_) {
398 if (!gain_controller) {
399 gain_controller.reset(new GainController());
400 }
401 gain_controller->Initialize(minimum_capture_level_, maximum_capture_level_,
peahb8fbb542016-03-15 02:28:08 -0700402 mode_, *sample_rate_hz_, analog_capture_level_);
peahbfa97112016-03-10 21:09:04 -0800403 }
404
405 Configure();
peah4d291f72015-11-16 23:52:25 -0800406}
407
peahbfa97112016-03-10 21:09:04 -0800408int GainControlImpl::Configure() {
peahdf3efa82015-11-28 12:35:15 -0800409 rtc::CritScope cs_render(crit_render_);
410 rtc::CritScope cs_capture(crit_capture_);
pbos@webrtc.orge468bc92014-12-18 09:11:33 +0000411 WebRtcAgcConfig config;
niklase@google.com470e71d2011-07-07 08:21:25 +0000412 // TODO(ajm): Flip the sign here (since AGC expects a positive value) if we
413 // change the interface.
kwiberg9e2be5f2016-09-14 05:23:22 -0700414 //RTC_DCHECK_LE(target_level_dbfs_, 0);
pbos@webrtc.orgb7192b82013-04-10 07:50:54 +0000415 //config.targetLevelDbfs = static_cast<int16_t>(-target_level_dbfs_);
416 config.targetLevelDbfs = static_cast<int16_t>(target_level_dbfs_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000417 config.compressionGaindB =
pbos@webrtc.orgb7192b82013-04-10 07:50:54 +0000418 static_cast<int16_t>(compression_gain_db_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000419 config.limiterEnable = limiter_enabled_;
420
peahbfa97112016-03-10 21:09:04 -0800421 int error = AudioProcessing::kNoError;
422 for (auto& gain_controller : gain_controllers_) {
423 const int handle_error =
424 WebRtcAgc_set_config(gain_controller->state(), config);
425 if (handle_error != AudioProcessing::kNoError) {
426 error = handle_error;
427 }
428 }
429 return error;
niklase@google.com470e71d2011-07-07 08:21:25 +0000430}
niklase@google.com470e71d2011-07-07 08:21:25 +0000431} // namespace webrtc