blob: 3a9433b47684364f188da877275f548d928b7d80 [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
Alejandro Luebs18fcbcf2016-02-22 15:57:38 -080025// Return |current| changed towards |target|, with the relative change being at
26// most |limit|.
ekm35b72fb2015-07-10 14:11:52 -070027float UpdateFactor(float target, float current, float limit) {
Alejandro Luebs18fcbcf2016-02-22 15:57:38 -080028 float gain = target / (current + std::numeric_limits<float>::epsilon());
29 if (gain < 1.f - limit) {
30 gain = 1.f - limit;
31 } else if (gain > 1.f + limit) {
32 gain = 1.f + limit;
33 }
34 return current * gain + std::numeric_limits<float>::epsilon();
ekm030249d2015-06-15 13:02:24 -070035}
36
Alejandro Luebs32348192016-02-17 20:04:19 -080037} // namespace
ekm030249d2015-06-15 13:02:24 -070038
Alejandro Luebs18fcbcf2016-02-22 15:57:38 -080039template<typename T>
40PowerEstimator<T>::PowerEstimator(size_t num_freqs, float decay)
41 : power_(num_freqs, 0.f), decay_(decay) {}
ekm030249d2015-06-15 13:02:24 -070042
Alejandro Luebs18fcbcf2016-02-22 15:57:38 -080043template<typename T>
44void PowerEstimator<T>::Step(const T* data) {
45 for (size_t i = 0; i < power_.size(); ++i) {
46 power_[i] = decay_ * power_[i] +
47 (1.f - decay_) * std::abs(data[i]) * std::abs(data[i]);
ekm030249d2015-06-15 13:02:24 -070048 }
49}
50
Alejandro Luebs18fcbcf2016-02-22 15:57:38 -080051template class PowerEstimator<float>;
52template class PowerEstimator<std::complex<float>>;
ekm030249d2015-06-15 13:02:24 -070053
Alejandro Luebs18fcbcf2016-02-22 15:57:38 -080054GainApplier::GainApplier(size_t freqs, float relative_change_limit)
ekmeyerson60d9b332015-08-14 10:35:55 -070055 : num_freqs_(freqs),
Alejandro Luebs18fcbcf2016-02-22 15:57:38 -080056 relative_change_limit_(relative_change_limit),
aluebs0a007592016-02-26 17:17:38 -080057 target_(freqs, 1.f),
58 current_(freqs, 1.f) {}
ekm030249d2015-06-15 13:02:24 -070059
Alejandro Luebs32348192016-02-17 20:04:19 -080060void GainApplier::Apply(const std::complex<float>* in_block,
61 std::complex<float>* out_block) {
Peter Kastingdce40cf2015-08-24 14:52:23 -070062 for (size_t i = 0; i < num_freqs_; ++i) {
Alejandro Luebs18fcbcf2016-02-22 15:57:38 -080063 current_[i] = UpdateFactor(target_[i], current_[i], relative_change_limit_);
64 out_block[i] = sqrtf(fabsf(current_[i])) * in_block[i];
ekm030249d2015-06-15 13:02:24 -070065 }
66}
67
68} // namespace intelligibility
69
70} // namespace webrtc