blob: a3323657483b68303bd5867a8ca1d6cb0d184f53 [file] [log] [blame]
Alex Loikoe36e8bb2018-02-16 11:54:07 +01001/*
2 * Copyright (c) 2018 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#include "modules/audio_processing/agc2/fixed_gain_controller.h"
12
13#include <algorithm>
14#include <cmath>
15
16#include "api/array_view.h"
17#include "common_audio/include/audio_util.h"
18#include "modules/audio_processing/agc2/agc2_common.h"
19#include "modules/audio_processing/logging/apm_data_dumper.h"
20#include "rtc_base/checks.h"
21#include "rtc_base/logging.h"
22#include "rtc_base/numerics/safe_minmax.h"
23
24namespace webrtc {
25namespace {
26
27// Returns true when the gain factor is so close to 1 that it would
28// not affect int16 samples.
29bool CloseToOne(float gain_factor) {
30 return 1.f - 1.f / kMaxSampleValue <= gain_factor &&
31 gain_factor <= 1.f + 1.f / kMaxSampleValue;
32}
33} // namespace
34
35FixedGainController::FixedGainController(ApmDataDumper* apm_data_dumper)
36 : apm_data_dumper_(apm_data_dumper) {
37 RTC_DCHECK_LT(0.f, gain_to_apply_);
38 RTC_DLOG(LS_INFO) << "Gain to apply: " << gain_to_apply_;
39}
40
41void FixedGainController::SetGain(float gain_to_apply_db) {
42 // Changes in gain_to_apply_ cause discontinuities. We assume
43 // gain_to_apply_ is set in the beginning of the call. If it is
44 // frequently changed, we should add interpolation between the
45 // values.
46 gain_to_apply_ = DbToRatio(gain_to_apply_db);
47}
48
49void FixedGainController::SetSampleRate(size_t sample_rate_hz) {
50 // TODO(aleloi): propagate the new sample rate to the GainCurveApplier.
51}
52
53void FixedGainController::EnableLimiter(bool enable_limiter) {
54 enable_limiter_ = enable_limiter;
55}
56
57void FixedGainController::Process(AudioFrameView<float> signal) {
58 // Apply fixed digital gain; interpolate if necessary. One of the
59 // planned usages of the FGC is to only use the limiter. In that
60 // case, the gain would be 1.0. Not doing the multiplications speeds
61 // it up considerably. Hence the check.
62 if (!CloseToOne(gain_to_apply_)) {
63 for (size_t k = 0; k < signal.num_channels(); ++k) {
64 rtc::ArrayView<float> channel_view = signal.channel(k);
65 for (auto& sample : channel_view) {
66 sample *= gain_to_apply_;
67 }
68 }
69 }
70
71 // Use the limiter (if configured to).
72 if (enable_limiter_) {
73 // TODO(aleloi): Process the signal with the
74 // GainCurveApplier. This will be done in the upcoming CLs.
75
76 // Dump data for debug.
77 const auto channel_view = signal.channel(0);
78 apm_data_dumper_->DumpRaw("agc2_fixed_digital_gain_curve_applier",
79 channel_view.size(), channel_view.data());
80 }
81
82 // Hard-clipping.
83 for (size_t k = 0; k < signal.num_channels(); ++k) {
84 rtc::ArrayView<float> channel_view = signal.channel(k);
85 for (auto& sample : channel_view) {
86 sample = rtc::SafeClamp(sample, kMinSampleValue, kMaxSampleValue);
87 }
88 }
89}
90} // namespace webrtc