Index: webrtc/modules/audio_processing/intelligibility/intelligibility_utils.cc |
diff --git a/webrtc/modules/audio_processing/intelligibility/intelligibility_utils.cc b/webrtc/modules/audio_processing/intelligibility/intelligibility_utils.cc |
index 6c44415130027aa736e2384cfd9557a10bc74347..6d37199a2c179ffd88d3e01df6784aff2b9b68af 100644 |
--- a/webrtc/modules/audio_processing/intelligibility/intelligibility_utils.cc |
+++ b/webrtc/modules/audio_processing/intelligibility/intelligibility_utils.cc |
@@ -14,6 +14,7 @@ |
#include <stdlib.h> |
#include <string.h> |
#include <algorithm> |
+#include <limits> |
namespace webrtc { |
@@ -21,45 +22,38 @@ namespace intelligibility { |
namespace { |
-// Return |current| changed towards |target|, with the change being at most |
-// |limit|. |
+// Return |current| changed towards |target|, with the relative change being at |
+// most |limit|. |
float UpdateFactor(float target, float current, float limit) { |
- float delta = fabsf(target - current); |
- float sign = copysign(1.f, target - current); |
- return current + sign * fminf(delta, limit); |
+ float gain = target / (current + std::numeric_limits<float>::epsilon()); |
+ if (gain < 1.f - limit) { |
+ gain = 1.f - limit; |
+ } else if (gain > 1.f + limit) { |
+ gain = 1.f + limit; |
+ } |
+ return current * gain + std::numeric_limits<float>::epsilon(); |
} |
} // namespace |
-PowerEstimator::PowerEstimator(size_t num_freqs, |
- float decay) |
- : magnitude_(new float[num_freqs]()), |
- power_(new float[num_freqs]()), |
- num_freqs_(num_freqs), |
- decay_(decay) { |
- memset(magnitude_.get(), 0, sizeof(*magnitude_.get()) * num_freqs_); |
- memset(power_.get(), 0, sizeof(*power_.get()) * num_freqs_); |
-} |
+template<typename T> |
+PowerEstimator<T>::PowerEstimator(size_t num_freqs, float decay) |
+ : power_(num_freqs, 0.f), decay_(decay) {} |
-// Compute the magnitude from the beginning, with exponential decaying of the |
-// series data. |
-void PowerEstimator::Step(const std::complex<float>* data) { |
- for (size_t i = 0; i < num_freqs_; ++i) { |
- magnitude_[i] = decay_ * magnitude_[i] + |
- (1.f - decay_) * std::abs(data[i]); |
+template<typename T> |
+void PowerEstimator<T>::Step(const T* data) { |
+ for (size_t i = 0; i < power_.size(); ++i) { |
+ power_[i] = decay_ * power_[i] + |
+ (1.f - decay_) * std::abs(data[i]) * std::abs(data[i]); |
} |
} |
-const float* PowerEstimator::Power() { |
- for (size_t i = 0; i < num_freqs_; ++i) { |
- power_[i] = magnitude_[i] * magnitude_[i]; |
- } |
- return &power_[0]; |
-} |
+template class PowerEstimator<float>; |
+template class PowerEstimator<std::complex<float>>; |
-GainApplier::GainApplier(size_t freqs, float change_limit) |
+GainApplier::GainApplier(size_t freqs, float relative_change_limit) |
: num_freqs_(freqs), |
- change_limit_(change_limit), |
+ relative_change_limit_(relative_change_limit), |
target_(new float[freqs]()), |
current_(new float[freqs]()) { |
for (size_t i = 0; i < freqs; ++i) { |
@@ -71,12 +65,8 @@ GainApplier::GainApplier(size_t freqs, float change_limit) |
void GainApplier::Apply(const std::complex<float>* in_block, |
std::complex<float>* out_block) { |
for (size_t i = 0; i < num_freqs_; ++i) { |
- float factor = sqrtf(fabsf(current_[i])); |
- if (!std::isnormal(factor)) { |
- factor = 1.f; |
- } |
- out_block[i] = factor * in_block[i]; |
- current_[i] = UpdateFactor(target_[i], current_[i], change_limit_); |
+ current_[i] = UpdateFactor(target_[i], current_[i], relative_change_limit_); |
+ out_block[i] = sqrtf(fabsf(current_[i])) * in_block[i]; |
} |
} |