Alex Loiko | 2bac896 | 2018-03-27 13:38:36 +0200 | [diff] [blame] | 1 | /* |
| 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 Loiko | 2bac896 | 2018-03-27 13:38:36 +0200 | [diff] [blame] | 13 | #include "common_audio/include/audio_util.h" |
Alessio Bazzica | 253f836 | 2020-11-27 16:02:38 +0100 | [diff] [blame] | 14 | #include "modules/audio_processing/agc2/cpu_features.h" |
Alex Loiko | db6af36 | 2018-06-20 14:14:18 +0200 | [diff] [blame] | 15 | #include "modules/audio_processing/agc2/vad_with_level.h" |
Alex Loiko | 2bac896 | 2018-03-27 13:38:36 +0200 | [diff] [blame] | 16 | #include "modules/audio_processing/logging/apm_data_dumper.h" |
Yves Gerey | 988cc08 | 2018-10-23 12:03:01 +0200 | [diff] [blame] | 17 | #include "rtc_base/checks.h" |
Alessio Bazzica | 59f1d1e | 2020-09-30 22:54:00 +0200 | [diff] [blame] | 18 | #include "rtc_base/logging.h" |
Alex Loiko | 2bac896 | 2018-03-27 13:38:36 +0200 | [diff] [blame] | 19 | |
| 20 | namespace webrtc { |
Alessio Bazzica | d5e6f41 | 2020-09-30 13:07:57 +0200 | [diff] [blame] | 21 | namespace { |
| 22 | |
Alessio Bazzica | 61982a7 | 2021-04-14 16:17:09 +0200 | [diff] [blame] | 23 | using AdaptiveDigitalConfig = |
| 24 | AudioProcessing::Config::GainController2::AdaptiveDigital; |
| 25 | using NoiseEstimatorType = |
| 26 | AudioProcessing::Config::GainController2::NoiseEstimator; |
| 27 | |
Alessio Bazzica | 524f682 | 2021-01-05 10:28:24 +0100 | [diff] [blame] | 28 | // Detects the available CPU features and applies any kill-switches. |
| 29 | AvailableCpuFeatures GetAllowedCpuFeatures( |
Alessio Bazzica | 61982a7 | 2021-04-14 16:17:09 +0200 | [diff] [blame] | 30 | const AdaptiveDigitalConfig& config) { |
Alessio Bazzica | 253f836 | 2020-11-27 16:02:38 +0100 | [diff] [blame] | 31 | AvailableCpuFeatures features = GetAvailableCpuFeatures(); |
Alessio Bazzica | 524f682 | 2021-01-05 10:28:24 +0100 | [diff] [blame] | 32 | if (!config.sse2_allowed) { |
| 33 | features.sse2 = false; |
| 34 | } |
| 35 | if (!config.avx2_allowed) { |
Alessio Bazzica | 253f836 | 2020-11-27 16:02:38 +0100 | [diff] [blame] | 36 | features.avx2 = false; |
| 37 | } |
Alessio Bazzica | 524f682 | 2021-01-05 10:28:24 +0100 | [diff] [blame] | 38 | if (!config.neon_allowed) { |
| 39 | features.neon = false; |
| 40 | } |
Alessio Bazzica | 253f836 | 2020-11-27 16:02:38 +0100 | [diff] [blame] | 41 | return features; |
| 42 | } |
| 43 | |
Alessio Bazzica | 61982a7 | 2021-04-14 16:17:09 +0200 | [diff] [blame] | 44 | std::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 Bazzica | d5e6f41 | 2020-09-30 13:07:57 +0200 | [diff] [blame] | 55 | } // namespace |
Alex Loiko | 2bac896 | 2018-03-27 13:38:36 +0200 | [diff] [blame] | 56 | |
Alex Loiko | 5e78461 | 2018-11-01 14:51:56 +0100 | [diff] [blame] | 57 | AdaptiveAgc::AdaptiveAgc(ApmDataDumper* apm_data_dumper, |
Alessio Bazzica | 61982a7 | 2021-04-14 16:17:09 +0200 | [diff] [blame] | 58 | const AdaptiveDigitalConfig& config) |
Alessio Bazzica | 980c460 | 2021-04-14 19:09:17 +0200 | [diff] [blame] | 59 | : 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 Bazzica | d66a605 | 2021-04-29 16:13:25 +0200 | [diff] [blame] | 65 | config.max_output_noise_level_dbfs, |
| 66 | config.dry_run), |
Alex Loiko | 5e78461 | 2018-11-01 14:51:56 +0100 | [diff] [blame] | 67 | apm_data_dumper_(apm_data_dumper), |
Alessio Bazzica | 61982a7 | 2021-04-14 16:17:09 +0200 | [diff] [blame] | 68 | noise_level_estimator_( |
Alessio Bazzica | 980c460 | 2021-04-14 19:09:17 +0200 | [diff] [blame] | 69 | 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 Loiko | 5e78461 | 2018-11-01 14:51:56 +0100 | [diff] [blame] | 75 | RTC_DCHECK(apm_data_dumper); |
Alessio Bazzica | 980c460 | 2021-04-14 19:09:17 +0200 | [diff] [blame] | 76 | RTC_DCHECK(noise_level_estimator_); |
| 77 | RTC_DCHECK(saturation_protector_); |
Alessio Bazzica | 61982a7 | 2021-04-14 16:17:09 +0200 | [diff] [blame] | 78 | if (!config.use_saturation_protector) { |
Alessio Bazzica | 59f1d1e | 2020-09-30 22:54:00 +0200 | [diff] [blame] | 79 | RTC_LOG(LS_WARNING) << "The saturation protector cannot be disabled."; |
| 80 | } |
Alex Loiko | 5e78461 | 2018-11-01 14:51:56 +0100 | [diff] [blame] | 81 | } |
| 82 | |
Alex Loiko | 2bac896 | 2018-03-27 13:38:36 +0200 | [diff] [blame] | 83 | AdaptiveAgc::~AdaptiveAgc() = default; |
| 84 | |
Alessio Bazzica | d66a605 | 2021-04-29 16:13:25 +0200 | [diff] [blame] | 85 | void AdaptiveAgc::Initialize(int sample_rate_hz, int num_channels) { |
| 86 | gain_controller_.Initialize(sample_rate_hz, num_channels); |
| 87 | } |
| 88 | |
Alessio Bazzica | d5e6f41 | 2020-09-30 13:07:57 +0200 | [diff] [blame] | 89 | void AdaptiveAgc::Process(AudioFrameView<float> frame, float limiter_envelope) { |
| 90 | AdaptiveDigitalGainApplier::FrameInfo info; |
Alessio Bazzica | 980c460 | 2021-04-14 19:09:17 +0200 | [diff] [blame] | 91 | |
| 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 Loiko | 2bac896 | 2018-03-27 13:38:36 +0200 | [diff] [blame] | 119 | } |
| 120 | |
Alessio Bazzica | 980c460 | 2021-04-14 19:09:17 +0200 | [diff] [blame] | 121 | void AdaptiveAgc::HandleInputGainChange() { |
Alex Loiko | a837dd7 | 2018-08-06 16:32:12 +0200 | [diff] [blame] | 122 | speech_level_estimator_.Reset(); |
Alessio Bazzica | 980c460 | 2021-04-14 19:09:17 +0200 | [diff] [blame] | 123 | saturation_protector_->Reset(); |
Alex Loiko | a837dd7 | 2018-08-06 16:32:12 +0200 | [diff] [blame] | 124 | } |
| 125 | |
Alex Loiko | 2bac896 | 2018-03-27 13:38:36 +0200 | [diff] [blame] | 126 | } // namespace webrtc |