blob: 6c44415130027aa736e2384cfd9557a10bc74347 [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>
ekm030249d2015-06-15 13:02:24 -070017
ekm35b72fb2015-07-10 14:11:52 -070018namespace webrtc {
ekm030249d2015-06-15 13:02:24 -070019
ekm35b72fb2015-07-10 14:11:52 -070020namespace intelligibility {
21
Alejandro Luebs32348192016-02-17 20:04:19 -080022namespace {
23
24// Return |current| changed towards |target|, with the change being at most
25// |limit|.
ekm35b72fb2015-07-10 14:11:52 -070026float UpdateFactor(float target, float current, float limit) {
ekm030249d2015-06-15 13:02:24 -070027 float delta = fabsf(target - current);
Alejandro Luebs32348192016-02-17 20:04:19 -080028 float sign = copysign(1.f, target - current);
ekm030249d2015-06-15 13:02:24 -070029 return current + sign * fminf(delta, limit);
30}
31
Alejandro Luebs32348192016-02-17 20:04:19 -080032} // namespace
ekm030249d2015-06-15 13:02:24 -070033
Alejandro Luebs32348192016-02-17 20:04:19 -080034PowerEstimator::PowerEstimator(size_t num_freqs,
35 float decay)
36 : magnitude_(new float[num_freqs]()),
37 power_(new float[num_freqs]()),
ekmeyerson60d9b332015-08-14 10:35:55 -070038 num_freqs_(num_freqs),
Alejandro Luebs32348192016-02-17 20:04:19 -080039 decay_(decay) {
40 memset(magnitude_.get(), 0, sizeof(*magnitude_.get()) * num_freqs_);
41 memset(power_.get(), 0, sizeof(*power_.get()) * num_freqs_);
ekm030249d2015-06-15 13:02:24 -070042}
43
Alejandro Luebs32348192016-02-17 20:04:19 -080044// Compute the magnitude from the beginning, with exponential decaying of the
ekm030249d2015-06-15 13:02:24 -070045// series data.
Alejandro Luebs32348192016-02-17 20:04:19 -080046void PowerEstimator::Step(const std::complex<float>* data) {
Peter Kastingdce40cf2015-08-24 14:52:23 -070047 for (size_t i = 0; i < num_freqs_; ++i) {
Alejandro Luebs32348192016-02-17 20:04:19 -080048 magnitude_[i] = decay_ * magnitude_[i] +
49 (1.f - decay_) * std::abs(data[i]);
ekm030249d2015-06-15 13:02:24 -070050 }
51}
52
Alejandro Luebs32348192016-02-17 20:04:19 -080053const float* PowerEstimator::Power() {
Peter Kastingdce40cf2015-08-24 14:52:23 -070054 for (size_t i = 0; i < num_freqs_; ++i) {
Alejandro Luebs32348192016-02-17 20:04:19 -080055 power_[i] = magnitude_[i] * magnitude_[i];
ekm030249d2015-06-15 13:02:24 -070056 }
Alejandro Luebs32348192016-02-17 20:04:19 -080057 return &power_[0];
ekm030249d2015-06-15 13:02:24 -070058}
59
Peter Kastingdce40cf2015-08-24 14:52:23 -070060GainApplier::GainApplier(size_t freqs, float change_limit)
ekmeyerson60d9b332015-08-14 10:35:55 -070061 : num_freqs_(freqs),
ekm030249d2015-06-15 13:02:24 -070062 change_limit_(change_limit),
63 target_(new float[freqs]()),
64 current_(new float[freqs]()) {
Peter Kastingdce40cf2015-08-24 14:52:23 -070065 for (size_t i = 0; i < freqs; ++i) {
Alejandro Luebs32348192016-02-17 20:04:19 -080066 target_[i] = 1.f;
67 current_[i] = 1.f;
ekm030249d2015-06-15 13:02:24 -070068 }
69}
70
Alejandro Luebs32348192016-02-17 20:04:19 -080071void GainApplier::Apply(const std::complex<float>* in_block,
72 std::complex<float>* out_block) {
Peter Kastingdce40cf2015-08-24 14:52:23 -070073 for (size_t i = 0; i < num_freqs_; ++i) {
ekm030249d2015-06-15 13:02:24 -070074 float factor = sqrtf(fabsf(current_[i]));
75 if (!std::isnormal(factor)) {
Alejandro Luebs32348192016-02-17 20:04:19 -080076 factor = 1.f;
ekm030249d2015-06-15 13:02:24 -070077 }
78 out_block[i] = factor * in_block[i];
79 current_[i] = UpdateFactor(target_[i], current_[i], change_limit_);
80 }
81}
82
83} // namespace intelligibility
84
85} // namespace webrtc