blob: 3fc9008db174cc8da48501ffdea075b8cbd55c17 [file] [log] [blame]
Alex Loiko2bac8962018-03-27 13:38:36 +02001/*
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/adaptive_agc.h"
12
Alex Loiko2bac8962018-03-27 13:38:36 +020013#include "common_audio/include/audio_util.h"
Alessio Bazzica253f8362020-11-27 16:02:38 +010014#include "modules/audio_processing/agc2/cpu_features.h"
Alex Loikodb6af362018-06-20 14:14:18 +020015#include "modules/audio_processing/agc2/vad_with_level.h"
Alex Loiko2bac8962018-03-27 13:38:36 +020016#include "modules/audio_processing/logging/apm_data_dumper.h"
Yves Gerey988cc082018-10-23 12:03:01 +020017#include "rtc_base/checks.h"
Alessio Bazzica59f1d1e2020-09-30 22:54:00 +020018#include "rtc_base/logging.h"
Alex Loiko2bac8962018-03-27 13:38:36 +020019
20namespace webrtc {
Alessio Bazzicad5e6f412020-09-30 13:07:57 +020021namespace {
22
Alessio Bazzica61982a72021-04-14 16:17:09 +020023using AdaptiveDigitalConfig =
24 AudioProcessing::Config::GainController2::AdaptiveDigital;
25using NoiseEstimatorType =
26 AudioProcessing::Config::GainController2::NoiseEstimator;
27
Alessio Bazzica524f6822021-01-05 10:28:24 +010028// Detects the available CPU features and applies any kill-switches.
29AvailableCpuFeatures GetAllowedCpuFeatures(
Alessio Bazzica61982a72021-04-14 16:17:09 +020030 const AdaptiveDigitalConfig& config) {
Alessio Bazzica253f8362020-11-27 16:02:38 +010031 AvailableCpuFeatures features = GetAvailableCpuFeatures();
Alessio Bazzica524f6822021-01-05 10:28:24 +010032 if (!config.sse2_allowed) {
33 features.sse2 = false;
34 }
35 if (!config.avx2_allowed) {
Alessio Bazzica253f8362020-11-27 16:02:38 +010036 features.avx2 = false;
37 }
Alessio Bazzica524f6822021-01-05 10:28:24 +010038 if (!config.neon_allowed) {
39 features.neon = false;
40 }
Alessio Bazzica253f8362020-11-27 16:02:38 +010041 return features;
42}
43
Alessio Bazzica61982a72021-04-14 16:17:09 +020044std::unique_ptr<NoiseLevelEstimator> CreateNoiseLevelEstimator(
45 NoiseEstimatorType estimator_type,
46 ApmDataDumper* apm_data_dumper) {
47 switch (estimator_type) {
48 case NoiseEstimatorType::kStationaryNoise:
49 return CreateStationaryNoiseEstimator(apm_data_dumper);
50 case NoiseEstimatorType::kNoiseFloor:
51 return CreateNoiseFloorEstimator(apm_data_dumper);
52 }
53}
54
Alessio Bazzicad5e6f412020-09-30 13:07:57 +020055} // namespace
Alex Loiko2bac8962018-03-27 13:38:36 +020056
Alex Loiko5e784612018-11-01 14:51:56 +010057AdaptiveAgc::AdaptiveAgc(ApmDataDumper* apm_data_dumper,
Alessio Bazzica61982a72021-04-14 16:17:09 +020058 const AdaptiveDigitalConfig& config)
Alessio Bazzica980c4602021-04-14 19:09:17 +020059 : speech_level_estimator_(apm_data_dumper,
60 config.adjacent_speech_frames_threshold),
61 vad_(config.vad_reset_period_ms, GetAllowedCpuFeatures(config)),
62 gain_controller_(apm_data_dumper,
63 config.adjacent_speech_frames_threshold,
64 config.max_gain_change_db_per_second,
Alessio Bazzicad66a6052021-04-29 16:13:25 +020065 config.max_output_noise_level_dbfs,
66 config.dry_run),
Alex Loiko5e784612018-11-01 14:51:56 +010067 apm_data_dumper_(apm_data_dumper),
Alessio Bazzica61982a72021-04-14 16:17:09 +020068 noise_level_estimator_(
Alessio Bazzica980c4602021-04-14 19:09:17 +020069 CreateNoiseLevelEstimator(config.noise_estimator, apm_data_dumper)),
70 saturation_protector_(
71 CreateSaturationProtector(kSaturationProtectorInitialHeadroomDb,
72 kSaturationProtectorExtraHeadroomDb,
73 config.adjacent_speech_frames_threshold,
74 apm_data_dumper)) {
Alex Loiko5e784612018-11-01 14:51:56 +010075 RTC_DCHECK(apm_data_dumper);
Alessio Bazzica980c4602021-04-14 19:09:17 +020076 RTC_DCHECK(noise_level_estimator_);
77 RTC_DCHECK(saturation_protector_);
Alessio Bazzica61982a72021-04-14 16:17:09 +020078 if (!config.use_saturation_protector) {
Alessio Bazzica59f1d1e2020-09-30 22:54:00 +020079 RTC_LOG(LS_WARNING) << "The saturation protector cannot be disabled.";
80 }
Alex Loiko5e784612018-11-01 14:51:56 +010081}
82
Alex Loiko2bac8962018-03-27 13:38:36 +020083AdaptiveAgc::~AdaptiveAgc() = default;
84
Alessio Bazzicad66a6052021-04-29 16:13:25 +020085void AdaptiveAgc::Initialize(int sample_rate_hz, int num_channels) {
86 gain_controller_.Initialize(sample_rate_hz, num_channels);
87}
88
Alessio Bazzicad5e6f412020-09-30 13:07:57 +020089void AdaptiveAgc::Process(AudioFrameView<float> frame, float limiter_envelope) {
90 AdaptiveDigitalGainApplier::FrameInfo info;
Alessio Bazzica980c4602021-04-14 19:09:17 +020091
92 VadLevelAnalyzer::Result vad_result = vad_.AnalyzeFrame(frame);
93 info.speech_probability = vad_result.speech_probability;
94 apm_data_dumper_->DumpRaw("agc2_speech_probability",
95 vad_result.speech_probability);
96 apm_data_dumper_->DumpRaw("agc2_input_rms_dbfs", vad_result.rms_dbfs);
97 apm_data_dumper_->DumpRaw("agc2_input_peak_dbfs", vad_result.peak_dbfs);
98
99 speech_level_estimator_.Update(vad_result);
100 info.speech_level_dbfs = speech_level_estimator_.level_dbfs();
101 info.speech_level_reliable = speech_level_estimator_.IsConfident();
102 apm_data_dumper_->DumpRaw("agc2_speech_level_dbfs", info.speech_level_dbfs);
103 apm_data_dumper_->DumpRaw("agc2_speech_level_reliable",
104 info.speech_level_reliable);
105
106 info.noise_rms_dbfs = noise_level_estimator_->Analyze(frame);
107 apm_data_dumper_->DumpRaw("agc2_noise_rms_dbfs", info.noise_rms_dbfs);
108
109 saturation_protector_->Analyze(info.speech_probability, vad_result.peak_dbfs,
110 info.speech_level_dbfs);
111 info.headroom_db = saturation_protector_->HeadroomDb();
112 apm_data_dumper_->DumpRaw("agc2_headroom_db", info.headroom_db);
113
114 info.limiter_envelope_dbfs = FloatS16ToDbfs(limiter_envelope);
115 apm_data_dumper_->DumpRaw("agc2_limiter_envelope_dbfs",
116 info.limiter_envelope_dbfs);
117
118 gain_controller_.Process(info, frame);
Alex Loiko2bac8962018-03-27 13:38:36 +0200119}
120
Alessio Bazzica980c4602021-04-14 19:09:17 +0200121void AdaptiveAgc::HandleInputGainChange() {
Alex Loikoa837dd72018-08-06 16:32:12 +0200122 speech_level_estimator_.Reset();
Alessio Bazzica980c4602021-04-14 19:09:17 +0200123 saturation_protector_->Reset();
Alex Loikoa837dd72018-08-06 16:32:12 +0200124}
125
Alex Loiko2bac8962018-03-27 13:38:36 +0200126} // namespace webrtc