OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
174 << "Last frame peak level: " << frame_peak_level_dbfs | 174 << "Last frame peak level: " << frame_peak_level_dbfs |
175 << " dBFS"; | 175 << " dBFS"; |
176 | 176 |
177 Reset(); | 177 Reset(); |
178 } | 178 } |
179 } | 179 } |
180 | 180 |
181 LevelController::LevelController() | 181 LevelController::LevelController() |
182 : data_dumper_(new ApmDataDumper(instance_count_)), | 182 : data_dumper_(new ApmDataDumper(instance_count_)), |
183 gain_applier_(data_dumper_.get()), | 183 gain_applier_(data_dumper_.get()), |
184 signal_classifier_(data_dumper_.get()) { | 184 signal_classifier_(data_dumper_.get()), |
| 185 peak_level_estimator_(kTargetLcPeakLeveldBFS) { |
185 Initialize(AudioProcessing::kSampleRate48kHz); | 186 Initialize(AudioProcessing::kSampleRate48kHz); |
186 ++instance_count_; | 187 ++instance_count_; |
187 } | 188 } |
188 | 189 |
189 LevelController::~LevelController() {} | 190 LevelController::~LevelController() {} |
190 | 191 |
191 void LevelController::Initialize(int sample_rate_hz) { | 192 void LevelController::Initialize(int sample_rate_hz) { |
192 RTC_DCHECK(sample_rate_hz == AudioProcessing::kSampleRate8kHz || | 193 RTC_DCHECK(sample_rate_hz == AudioProcessing::kSampleRate8kHz || |
193 sample_rate_hz == AudioProcessing::kSampleRate16kHz || | 194 sample_rate_hz == AudioProcessing::kSampleRate16kHz || |
194 sample_rate_hz == AudioProcessing::kSampleRate32kHz || | 195 sample_rate_hz == AudioProcessing::kSampleRate32kHz || |
195 sample_rate_hz == AudioProcessing::kSampleRate48kHz); | 196 sample_rate_hz == AudioProcessing::kSampleRate48kHz); |
196 data_dumper_->InitiateNewSetOfRecordings(); | 197 data_dumper_->InitiateNewSetOfRecordings(); |
197 gain_selector_.Initialize(sample_rate_hz); | 198 gain_selector_.Initialize(sample_rate_hz); |
198 gain_applier_.Initialize(sample_rate_hz); | 199 gain_applier_.Initialize(sample_rate_hz); |
199 signal_classifier_.Initialize(sample_rate_hz); | 200 signal_classifier_.Initialize(sample_rate_hz); |
200 noise_level_estimator_.Initialize(sample_rate_hz); | 201 noise_level_estimator_.Initialize(sample_rate_hz); |
201 peak_level_estimator_.Initialize(); | 202 peak_level_estimator_.Initialize(config_.initial_peak_level_dbfs); |
202 saturating_gain_estimator_.Initialize(); | 203 saturating_gain_estimator_.Initialize(); |
203 metrics_.Initialize(sample_rate_hz); | 204 metrics_.Initialize(sample_rate_hz); |
204 | 205 |
205 last_gain_ = 1.0f; | 206 last_gain_ = 1.0f; |
206 sample_rate_hz_ = rtc::Optional<int>(sample_rate_hz); | 207 sample_rate_hz_ = rtc::Optional<int>(sample_rate_hz); |
207 dc_forgetting_factor_ = 0.01f * sample_rate_hz / 48000.f; | 208 dc_forgetting_factor_ = 0.01f * sample_rate_hz / 48000.f; |
208 std::fill(dc_level_, dc_level_ + arraysize(dc_level_), 0.f); | 209 std::fill(dc_level_, dc_level_ + arraysize(dc_level_), 0.f); |
209 } | 210 } |
210 | 211 |
211 void LevelController::Process(AudioBuffer* audio) { | 212 void LevelController::Process(AudioBuffer* audio) { |
(...skipping 21 matching lines...) Expand all Loading... |
233 noise_level_estimator_.Analyze(signal_type, FrameEnergy(*audio)); | 234 noise_level_estimator_.Analyze(signal_type, FrameEnergy(*audio)); |
234 | 235 |
235 // Estimate the overall signal peak level. | 236 // Estimate the overall signal peak level. |
236 const float frame_peak_level = PeakLevel(*audio); | 237 const float frame_peak_level = PeakLevel(*audio); |
237 const float long_term_peak_level = | 238 const float long_term_peak_level = |
238 peak_level_estimator_.Analyze(signal_type, frame_peak_level); | 239 peak_level_estimator_.Analyze(signal_type, frame_peak_level); |
239 | 240 |
240 float saturating_gain = saturating_gain_estimator_.GetGain(); | 241 float saturating_gain = saturating_gain_estimator_.GetGain(); |
241 | 242 |
242 // Compute the new gain to apply. | 243 // Compute the new gain to apply. |
243 last_gain_ = gain_selector_.GetNewGain(long_term_peak_level, noise_energy, | 244 last_gain_ = |
244 saturating_gain, signal_type); | 245 gain_selector_.GetNewGain(long_term_peak_level, noise_energy, |
| 246 saturating_gain, gain_jumpstart_, signal_type); |
| 247 |
| 248 // Unflag the jumpstart of the gain as it should only happen once. |
| 249 gain_jumpstart_ = false; |
245 | 250 |
246 // Apply the gain to the signal. | 251 // Apply the gain to the signal. |
247 int num_saturations = gain_applier_.Process(last_gain_, audio); | 252 int num_saturations = gain_applier_.Process(last_gain_, audio); |
248 | 253 |
249 // Estimate the gain that saturates the overall signal. | 254 // Estimate the gain that saturates the overall signal. |
250 saturating_gain_estimator_.Update(last_gain_, num_saturations); | 255 saturating_gain_estimator_.Update(last_gain_, num_saturations); |
251 | 256 |
252 // Update the metrics. | 257 // Update the metrics. |
253 metrics_.Update(long_term_peak_level, noise_energy, last_gain_, | 258 metrics_.Update(long_term_peak_level, noise_energy, last_gain_, |
254 frame_peak_level); | 259 frame_peak_level); |
255 | 260 |
256 data_dumper_->DumpRaw("lc_selected_gain", 1, &last_gain_); | 261 data_dumper_->DumpRaw("lc_selected_gain", 1, &last_gain_); |
257 data_dumper_->DumpRaw("lc_noise_energy", 1, &noise_energy); | 262 data_dumper_->DumpRaw("lc_noise_energy", 1, &noise_energy); |
258 data_dumper_->DumpRaw("lc_peak_level", 1, &long_term_peak_level); | 263 data_dumper_->DumpRaw("lc_peak_level", 1, &long_term_peak_level); |
259 data_dumper_->DumpRaw("lc_saturating_gain", 1, &saturating_gain); | 264 data_dumper_->DumpRaw("lc_saturating_gain", 1, &saturating_gain); |
260 | 265 |
261 data_dumper_->DumpWav("lc_output", audio->num_frames(), | 266 data_dumper_->DumpWav("lc_output", audio->num_frames(), |
262 audio->channels_f()[0], *sample_rate_hz_, 1); | 267 audio->channels_f()[0], *sample_rate_hz_, 1); |
263 } | 268 } |
264 | 269 |
| 270 void LevelController::ApplyConfig( |
| 271 const AudioProcessing::Config::LevelController& config) { |
| 272 RTC_DCHECK(Validate(config)); |
| 273 config_ = config; |
| 274 peak_level_estimator_.Initialize(config_.initial_peak_level_dbfs); |
| 275 gain_jumpstart_ = true; |
| 276 } |
| 277 |
265 std::string LevelController::ToString( | 278 std::string LevelController::ToString( |
266 const AudioProcessing::Config::LevelController& config) { | 279 const AudioProcessing::Config::LevelController& config) { |
267 std::stringstream ss; | 280 std::stringstream ss; |
268 ss << "{" | 281 ss << "{" |
269 << "enabled: " << (config.enabled ? "true" : "false") << "}"; | 282 << "enabled: " << (config.enabled ? "true" : "false") << ", " |
| 283 << "initial_peak_level_dbfs: " << config.initial_peak_level_dbfs << "}"; |
270 return ss.str(); | 284 return ss.str(); |
271 } | 285 } |
272 | 286 |
273 bool LevelController::Validate( | 287 bool LevelController::Validate( |
274 const AudioProcessing::Config::LevelController& config) { | 288 const AudioProcessing::Config::LevelController& config) { |
275 return true; | 289 return (config.initial_peak_level_dbfs < |
| 290 std::numeric_limits<float>::epsilon() && |
| 291 config.initial_peak_level_dbfs > |
| 292 -(100.f + std::numeric_limits<float>::epsilon())); |
276 } | 293 } |
277 | 294 |
278 } // namespace webrtc | 295 } // namespace webrtc |
OLD | NEW |