ekm | 030249d | 2015-06-15 13:02:24 -0700 | [diff] [blame] | 1 | /* |
| 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 | |
Mirko Bonadei | 92ea95e | 2017-09-15 06:47:31 +0200 | [diff] [blame] | 11 | #include "modules/audio_processing/intelligibility/intelligibility_utils.h" |
ekm | 030249d | 2015-06-15 13:02:24 -0700 | [diff] [blame] | 12 | |
ekm | 35b72fb | 2015-07-10 14:11:52 -0700 | [diff] [blame] | 13 | #include <math.h> |
ekmeyerson | 3ab2f14 | 2015-07-23 12:15:24 -0700 | [diff] [blame] | 14 | #include <stdlib.h> |
ekm | 35b72fb | 2015-07-10 14:11:52 -0700 | [diff] [blame] | 15 | #include <string.h> |
ekm | 030249d | 2015-06-15 13:02:24 -0700 | [diff] [blame] | 16 | #include <algorithm> |
Alejandro Luebs | 18fcbcf | 2016-02-22 15:57:38 -0800 | [diff] [blame] | 17 | #include <limits> |
ekm | 030249d | 2015-06-15 13:02:24 -0700 | [diff] [blame] | 18 | |
Karl Wiberg | e40468b | 2017-11-22 10:42:26 +0100 | [diff] [blame] | 19 | #include "rtc_base/numerics/safe_minmax.h" |
kwiberg | 0703856 | 2017-06-12 11:40:47 -0700 | [diff] [blame] | 20 | |
ekm | 35b72fb | 2015-07-10 14:11:52 -0700 | [diff] [blame] | 21 | namespace webrtc { |
ekm | 030249d | 2015-06-15 13:02:24 -0700 | [diff] [blame] | 22 | |
ekm | 35b72fb | 2015-07-10 14:11:52 -0700 | [diff] [blame] | 23 | namespace intelligibility { |
| 24 | |
Alejandro Luebs | 3234819 | 2016-02-17 20:04:19 -0800 | [diff] [blame] | 25 | namespace { |
| 26 | |
aluebs | 4896aaa | 2016-04-28 16:08:59 -0700 | [diff] [blame] | 27 | const float kMinFactor = 0.01f; |
aluebs | 7bd5f25 | 2016-06-21 11:30:25 -0700 | [diff] [blame] | 28 | const float kMaxFactor = 100.f; |
aluebs | 4896aaa | 2016-04-28 16:08:59 -0700 | [diff] [blame] | 29 | |
Alejandro Luebs | 18fcbcf | 2016-02-22 15:57:38 -0800 | [diff] [blame] | 30 | // Return |current| changed towards |target|, with the relative change being at |
| 31 | // most |limit|. |
ekm | 35b72fb | 2015-07-10 14:11:52 -0700 | [diff] [blame] | 32 | float UpdateFactor(float target, float current, float limit) { |
kwiberg | 0703856 | 2017-06-12 11:40:47 -0700 | [diff] [blame] | 33 | const float gain = target / (current + std::numeric_limits<float>::epsilon()); |
| 34 | const float clamped_gain = rtc::SafeClamp(gain, 1 - limit, 1 + limit); |
| 35 | return rtc::SafeClamp(current * clamped_gain, kMinFactor, kMaxFactor); |
ekm | 030249d | 2015-06-15 13:02:24 -0700 | [diff] [blame] | 36 | } |
| 37 | |
Alejandro Luebs | 3234819 | 2016-02-17 20:04:19 -0800 | [diff] [blame] | 38 | } // namespace |
ekm | 030249d | 2015-06-15 13:02:24 -0700 | [diff] [blame] | 39 | |
Alejandro Luebs | 18fcbcf | 2016-02-22 15:57:38 -0800 | [diff] [blame] | 40 | template<typename T> |
| 41 | PowerEstimator<T>::PowerEstimator(size_t num_freqs, float decay) |
| 42 | : power_(num_freqs, 0.f), decay_(decay) {} |
ekm | 030249d | 2015-06-15 13:02:24 -0700 | [diff] [blame] | 43 | |
Alejandro Luebs | 18fcbcf | 2016-02-22 15:57:38 -0800 | [diff] [blame] | 44 | template<typename T> |
| 45 | void PowerEstimator<T>::Step(const T* data) { |
| 46 | for (size_t i = 0; i < power_.size(); ++i) { |
| 47 | power_[i] = decay_ * power_[i] + |
| 48 | (1.f - decay_) * std::abs(data[i]) * std::abs(data[i]); |
ekm | 030249d | 2015-06-15 13:02:24 -0700 | [diff] [blame] | 49 | } |
| 50 | } |
| 51 | |
Alejandro Luebs | 18fcbcf | 2016-02-22 15:57:38 -0800 | [diff] [blame] | 52 | template class PowerEstimator<float>; |
| 53 | template class PowerEstimator<std::complex<float>>; |
ekm | 030249d | 2015-06-15 13:02:24 -0700 | [diff] [blame] | 54 | |
Alejandro Luebs | 18fcbcf | 2016-02-22 15:57:38 -0800 | [diff] [blame] | 55 | GainApplier::GainApplier(size_t freqs, float relative_change_limit) |
ekmeyerson | 60d9b33 | 2015-08-14 10:35:55 -0700 | [diff] [blame] | 56 | : num_freqs_(freqs), |
Alejandro Luebs | 18fcbcf | 2016-02-22 15:57:38 -0800 | [diff] [blame] | 57 | relative_change_limit_(relative_change_limit), |
aluebs | 0a00759 | 2016-02-26 17:17:38 -0800 | [diff] [blame] | 58 | target_(freqs, 1.f), |
| 59 | current_(freqs, 1.f) {} |
ekm | 030249d | 2015-06-15 13:02:24 -0700 | [diff] [blame] | 60 | |
Alejandro Luebs | 37062ed | 2016-09-06 11:25:40 -0700 | [diff] [blame] | 61 | GainApplier::~GainApplier() {} |
| 62 | |
Alejandro Luebs | 3234819 | 2016-02-17 20:04:19 -0800 | [diff] [blame] | 63 | void GainApplier::Apply(const std::complex<float>* in_block, |
| 64 | std::complex<float>* out_block) { |
Peter Kasting | dce40cf | 2015-08-24 14:52:23 -0700 | [diff] [blame] | 65 | for (size_t i = 0; i < num_freqs_; ++i) { |
Alejandro Luebs | 18fcbcf | 2016-02-22 15:57:38 -0800 | [diff] [blame] | 66 | current_[i] = UpdateFactor(target_[i], current_[i], relative_change_limit_); |
| 67 | out_block[i] = sqrtf(fabsf(current_[i])) * in_block[i]; |
ekm | 030249d | 2015-06-15 13:02:24 -0700 | [diff] [blame] | 68 | } |
| 69 | } |
| 70 | |
Alejandro Luebs | ef00925 | 2016-09-20 14:51:56 -0700 | [diff] [blame] | 71 | DelayBuffer::DelayBuffer(size_t delay, size_t num_channels) |
| 72 | : buffer_(num_channels, std::vector<float>(delay, 0.f)), read_index_(0u) {} |
| 73 | |
| 74 | DelayBuffer::~DelayBuffer() {} |
| 75 | |
| 76 | void DelayBuffer::Delay(float* const* data, size_t length) { |
| 77 | size_t sample_index = read_index_; |
| 78 | for (size_t i = 0u; i < buffer_.size(); ++i) { |
| 79 | sample_index = read_index_; |
| 80 | for (size_t j = 0u; j < length; ++j) { |
| 81 | float swap = data[i][j]; |
| 82 | data[i][j] = buffer_[i][sample_index]; |
| 83 | buffer_[i][sample_index] = swap; |
| 84 | if (++sample_index == buffer_.size()) { |
| 85 | sample_index = 0u; |
| 86 | } |
| 87 | } |
| 88 | } |
| 89 | read_index_ = sample_index; |
| 90 | } |
| 91 | |
ekm | 030249d | 2015-06-15 13:02:24 -0700 | [diff] [blame] | 92 | } // namespace intelligibility |
| 93 | |
| 94 | } // namespace webrtc |