From cd0c4683947231a7d3dc7811bedb75c5a965103c Mon Sep 17 00:00:00 2001 From: Jean-Michel Trivi Date: Wed, 25 Sep 2013 18:43:55 -0700 Subject: LoudnessEnhancer compatible with stereo imaging Use a single compressor for both channels. Envelope of signal is determined by looking at both channels. Bug 8413913 Change-Id: Ia9b6f34923d2977c60a3352500b858dfa1fab33c --- .../dsp/core/dynamic_range_compression-inl.h | 2 +- .../dsp/core/dynamic_range_compression.cpp | 35 ++++++++++++++++++++++ .../loudness/dsp/core/dynamic_range_compression.h | 3 ++ 3 files changed, 39 insertions(+), 1 deletion(-) (limited to 'media/libeffects/loudness/dsp') diff --git a/media/libeffects/loudness/dsp/core/dynamic_range_compression-inl.h b/media/libeffects/loudness/dsp/core/dynamic_range_compression-inl.h index fed8c2a..da75ceb 100644 --- a/media/libeffects/loudness/dsp/core/dynamic_range_compression-inl.h +++ b/media/libeffects/loudness/dsp/core/dynamic_range_compression-inl.h @@ -35,7 +35,7 @@ inline void AdaptiveDynamicRangeCompression::set_knee_threshold_via_target_gain( float target_gain) { const float decibel = target_gain_to_knee_threshold_.Interpolate( target_gain); - ALOGE("set_knee_threshold_via_target_gain: decibel =%.3f", decibel); + ALOGV("set_knee_threshold_via_target_gain: decibel =%.3fdB", decibel); set_knee_threshold(decibel); } diff --git a/media/libeffects/loudness/dsp/core/dynamic_range_compression.cpp b/media/libeffects/loudness/dsp/core/dynamic_range_compression.cpp index 2bbd043..7bd068e 100644 --- a/media/libeffects/loudness/dsp/core/dynamic_range_compression.cpp +++ b/media/libeffects/loudness/dsp/core/dynamic_range_compression.cpp @@ -102,5 +102,40 @@ float AdaptiveDynamicRangeCompression::Compress(float x) { return x; } +void AdaptiveDynamicRangeCompression::Compress(float *x1, float *x2) { + // Taking the maximum amplitude of both channels + const float max_abs_x = std::max(std::fabs(*x1), + std::max(std::fabs(*x2), kMinLogAbsValue)); + const float max_abs_x_dB = math::fast_log(max_abs_x); + // Subtract Threshold from log-encoded input to get the amount of overshoot + const float overshoot = max_abs_x_dB - knee_threshold_; + // Hard half-wave rectifier + const float rect = std::max(overshoot, 0.0f); + // Multiply rectified overshoot with slope + const float cv = rect * slope_; + const float prev_state = state_; + if (cv <= state_) { + state_ = alpha_attack_ * state_ + (1.0f - alpha_attack_) * cv; + } else { + state_ = alpha_release_ * state_ + (1.0f - alpha_release_) * cv; + } + compressor_gain_ *= + math::ExpApproximationViaTaylorExpansionOrder5(state_ - prev_state); + *x1 *= compressor_gain_; + if (*x1 > kFixedPointLimit) { + *x1 = kFixedPointLimit; + } + if (*x1 < -kFixedPointLimit) { + *x1 = -kFixedPointLimit; + } + *x2 *= compressor_gain_; + if (*x2 > kFixedPointLimit) { + *x2 = kFixedPointLimit; + } + if (*x2 < -kFixedPointLimit) { + *x2 = -kFixedPointLimit; + } +} + } // namespace le_fx diff --git a/media/libeffects/loudness/dsp/core/dynamic_range_compression.h b/media/libeffects/loudness/dsp/core/dynamic_range_compression.h index 4c015df..2821a78 100644 --- a/media/libeffects/loudness/dsp/core/dynamic_range_compression.h +++ b/media/libeffects/loudness/dsp/core/dynamic_range_compression.h @@ -55,6 +55,9 @@ class AdaptiveDynamicRangeCompression { // log(.) and exp(.). float Compress(float x); + // Stereo channel version of the compressor + void Compress(float *x1, float *x2); + // This version is slower than Compress(.) but faster than CompressSlow(.) float CompressNormalSpeed(float x); -- cgit v1.1