blob: 6e641a23325984bee6daab921a67c9acc959a489 [file] [log] [blame]
ekm030249d2015-06-15 13:02:24 -07001/*
2 * Copyright (c) 2014 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 "webrtc/modules/audio_processing/intelligibility/intelligibility_utils.h"
12
ekm35b72fb2015-07-10 14:11:52 -070013#include <math.h>
ekmeyerson3ab2f142015-07-23 12:15:24 -070014#include <stdlib.h>
ekm35b72fb2015-07-10 14:11:52 -070015#include <string.h>
ekm030249d2015-06-15 13:02:24 -070016#include <algorithm>
Alejandro Luebs18fcbcf2016-02-22 15:57:38 -080017#include <limits>
ekm030249d2015-06-15 13:02:24 -070018
ekm35b72fb2015-07-10 14:11:52 -070019namespace webrtc {
ekm030249d2015-06-15 13:02:24 -070020
ekm35b72fb2015-07-10 14:11:52 -070021namespace intelligibility {
22
Alejandro Luebs32348192016-02-17 20:04:19 -080023namespace {
24
aluebs4896aaa2016-04-28 16:08:59 -070025const float kMinFactor = 0.01f;
aluebs7bd5f252016-06-21 11:30:25 -070026const float kMaxFactor = 100.f;
aluebs4896aaa2016-04-28 16:08:59 -070027
Alejandro Luebs18fcbcf2016-02-22 15:57:38 -080028// Return |current| changed towards |target|, with the relative change being at
29// most |limit|.
ekm35b72fb2015-07-10 14:11:52 -070030float UpdateFactor(float target, float current, float limit) {
Alejandro Luebs18fcbcf2016-02-22 15:57:38 -080031 float gain = target / (current + std::numeric_limits<float>::epsilon());
aluebs4896aaa2016-04-28 16:08:59 -070032 gain = std::min(std::max(gain, 1.f - limit), 1.f + limit);
33 return std::min(std::max(current * gain, kMinFactor), kMaxFactor);;
ekm030249d2015-06-15 13:02:24 -070034}
35
Alejandro Luebs32348192016-02-17 20:04:19 -080036} // namespace
ekm030249d2015-06-15 13:02:24 -070037
Alejandro Luebs18fcbcf2016-02-22 15:57:38 -080038template<typename T>
39PowerEstimator<T>::PowerEstimator(size_t num_freqs, float decay)
40 : power_(num_freqs, 0.f), decay_(decay) {}
ekm030249d2015-06-15 13:02:24 -070041
Alejandro Luebs18fcbcf2016-02-22 15:57:38 -080042template<typename T>
43void PowerEstimator<T>::Step(const T* data) {
44 for (size_t i = 0; i < power_.size(); ++i) {
45 power_[i] = decay_ * power_[i] +
46 (1.f - decay_) * std::abs(data[i]) * std::abs(data[i]);
ekm030249d2015-06-15 13:02:24 -070047 }
48}
49
Alejandro Luebs18fcbcf2016-02-22 15:57:38 -080050template class PowerEstimator<float>;
51template class PowerEstimator<std::complex<float>>;
ekm030249d2015-06-15 13:02:24 -070052
Alejandro Luebs18fcbcf2016-02-22 15:57:38 -080053GainApplier::GainApplier(size_t freqs, float relative_change_limit)
ekmeyerson60d9b332015-08-14 10:35:55 -070054 : num_freqs_(freqs),
Alejandro Luebs18fcbcf2016-02-22 15:57:38 -080055 relative_change_limit_(relative_change_limit),
aluebs0a007592016-02-26 17:17:38 -080056 target_(freqs, 1.f),
57 current_(freqs, 1.f) {}
ekm030249d2015-06-15 13:02:24 -070058
Alejandro Luebs37062ed2016-09-06 11:25:40 -070059GainApplier::~GainApplier() {}
60
Alejandro Luebs32348192016-02-17 20:04:19 -080061void GainApplier::Apply(const std::complex<float>* in_block,
62 std::complex<float>* out_block) {
Peter Kastingdce40cf2015-08-24 14:52:23 -070063 for (size_t i = 0; i < num_freqs_; ++i) {
Alejandro Luebs18fcbcf2016-02-22 15:57:38 -080064 current_[i] = UpdateFactor(target_[i], current_[i], relative_change_limit_);
65 out_block[i] = sqrtf(fabsf(current_[i])) * in_block[i];
ekm030249d2015-06-15 13:02:24 -070066 }
67}
68
69} // namespace intelligibility
70
71} // namespace webrtc