Loading media/libeffects/loudness/EffectLoudnessEnhancer.cpp +17 −25 Original line number Diff line number Diff line Loading @@ -56,8 +56,7 @@ struct LoudnessEnhancerContext { int32_t mTargetGainmB;// target gain in mB // in this implementation, there is no coupling between the compression on the left and right // channels le_fx::AdaptiveDynamicRangeCompression* mCompressorL; le_fx::AdaptiveDynamicRangeCompression* mCompressorR; le_fx::AdaptiveDynamicRangeCompression* mCompressor; }; // Loading @@ -68,11 +67,10 @@ void LE_reset(LoudnessEnhancerContext *pContext) { ALOGV(" > LE_reset(%p)", pContext); if ((pContext->mCompressorL != NULL) && (pContext->mCompressorR != NULL)) { if (pContext->mCompressor != NULL) { float targetAmp = pow(10, pContext->mTargetGainmB/2000.0f); // mB to linear amplification ALOGV("LE_reset(): Target gain=%dmB <=> factor=%.2fX", pContext->mTargetGainmB, targetAmp); pContext->mCompressorL->Initialize(targetAmp, pContext->mConfig.inputCfg.samplingRate); pContext->mCompressorR->Initialize(targetAmp, pContext->mConfig.inputCfg.samplingRate); pContext->mCompressor->Initialize(targetAmp, pContext->mConfig.inputCfg.samplingRate); } else { ALOGE("LE_reset(%p): null compressors, can't apply target gain", pContext); } Loading Loading @@ -176,13 +174,9 @@ int LE_init(LoudnessEnhancerContext *pContext) float targetAmp = pow(10, pContext->mTargetGainmB/2000.0f); // mB to linear amplification ALOGV("LE_init(): Target gain=%dmB <=> factor=%.2fX", pContext->mTargetGainmB, targetAmp); if (pContext->mCompressorL == NULL) { pContext->mCompressorL = new le_fx::AdaptiveDynamicRangeCompression(); pContext->mCompressorL->Initialize(targetAmp, pContext->mConfig.inputCfg.samplingRate); } if (pContext->mCompressorR == NULL) { pContext->mCompressorR = new le_fx::AdaptiveDynamicRangeCompression(); pContext->mCompressorR->Initialize(targetAmp, pContext->mConfig.inputCfg.samplingRate); if (pContext->mCompressor == NULL) { pContext->mCompressor = new le_fx::AdaptiveDynamicRangeCompression(); pContext->mCompressor->Initialize(targetAmp, pContext->mConfig.inputCfg.samplingRate); } LE_setConfig(pContext, &pContext->mConfig); Loading Loading @@ -215,8 +209,7 @@ int LELib_Create(const effect_uuid_t *uuid, pContext->mItfe = &gLEInterface; pContext->mState = LOUDNESS_ENHANCER_STATE_UNINITIALIZED; pContext->mCompressorL = NULL; pContext->mCompressorR = NULL; pContext->mCompressor = NULL; ret = LE_init(pContext); if (ret < 0) { ALOGW("LELib_Create() init failed"); Loading @@ -242,13 +235,9 @@ int LELib_Release(effect_handle_t handle) { return -EINVAL; } pContext->mState = LOUDNESS_ENHANCER_STATE_UNINITIALIZED; if (pContext->mCompressorL != NULL) { delete pContext->mCompressorL; pContext->mCompressorL = NULL; } if (pContext->mCompressorR != NULL) { delete pContext->mCompressorR; pContext->mCompressorR = NULL; if (pContext->mCompressor != NULL) { delete pContext->mCompressor; pContext->mCompressor = NULL; } delete pContext; Loading Loading @@ -293,11 +282,14 @@ int LE_process( //ALOGV("LE about to process %d samples", inBuffer->frameCount); uint16_t inIdx; float inputAmp = pow(10, pContext->mTargetGainmB/2000.0f); float leftSample, rightSample; for (inIdx = 0 ; inIdx < inBuffer->frameCount ; inIdx++) { inBuffer->s16[2*inIdx] = pContext->mCompressorL->Compress( inputAmp * (float)inBuffer->s16[2*inIdx]); inBuffer->s16[2*inIdx +1] = pContext->mCompressorR->Compress( inputAmp * (float)inBuffer->s16[2*inIdx +1]); // makeup gain is applied on the input of the compressor leftSample = inputAmp * (float)inBuffer->s16[2*inIdx]; rightSample = inputAmp * (float)inBuffer->s16[2*inIdx +1]; pContext->mCompressor->Compress(&leftSample, &rightSample); inBuffer->s16[2*inIdx] = (int16_t) leftSample; inBuffer->s16[2*inIdx +1] = (int16_t) rightSample; } if (inBuffer->raw != outBuffer->raw) { Loading media/libeffects/loudness/dsp/core/dynamic_range_compression-inl.h +1 −1 Original line number Diff line number Diff line Loading @@ -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); } Loading media/libeffects/loudness/dsp/core/dynamic_range_compression.cpp +35 −0 Original line number Diff line number Diff line Loading @@ -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 media/libeffects/loudness/dsp/core/dynamic_range_compression.h +3 −0 Original line number Diff line number Diff line Loading @@ -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); Loading Loading
media/libeffects/loudness/EffectLoudnessEnhancer.cpp +17 −25 Original line number Diff line number Diff line Loading @@ -56,8 +56,7 @@ struct LoudnessEnhancerContext { int32_t mTargetGainmB;// target gain in mB // in this implementation, there is no coupling between the compression on the left and right // channels le_fx::AdaptiveDynamicRangeCompression* mCompressorL; le_fx::AdaptiveDynamicRangeCompression* mCompressorR; le_fx::AdaptiveDynamicRangeCompression* mCompressor; }; // Loading @@ -68,11 +67,10 @@ void LE_reset(LoudnessEnhancerContext *pContext) { ALOGV(" > LE_reset(%p)", pContext); if ((pContext->mCompressorL != NULL) && (pContext->mCompressorR != NULL)) { if (pContext->mCompressor != NULL) { float targetAmp = pow(10, pContext->mTargetGainmB/2000.0f); // mB to linear amplification ALOGV("LE_reset(): Target gain=%dmB <=> factor=%.2fX", pContext->mTargetGainmB, targetAmp); pContext->mCompressorL->Initialize(targetAmp, pContext->mConfig.inputCfg.samplingRate); pContext->mCompressorR->Initialize(targetAmp, pContext->mConfig.inputCfg.samplingRate); pContext->mCompressor->Initialize(targetAmp, pContext->mConfig.inputCfg.samplingRate); } else { ALOGE("LE_reset(%p): null compressors, can't apply target gain", pContext); } Loading Loading @@ -176,13 +174,9 @@ int LE_init(LoudnessEnhancerContext *pContext) float targetAmp = pow(10, pContext->mTargetGainmB/2000.0f); // mB to linear amplification ALOGV("LE_init(): Target gain=%dmB <=> factor=%.2fX", pContext->mTargetGainmB, targetAmp); if (pContext->mCompressorL == NULL) { pContext->mCompressorL = new le_fx::AdaptiveDynamicRangeCompression(); pContext->mCompressorL->Initialize(targetAmp, pContext->mConfig.inputCfg.samplingRate); } if (pContext->mCompressorR == NULL) { pContext->mCompressorR = new le_fx::AdaptiveDynamicRangeCompression(); pContext->mCompressorR->Initialize(targetAmp, pContext->mConfig.inputCfg.samplingRate); if (pContext->mCompressor == NULL) { pContext->mCompressor = new le_fx::AdaptiveDynamicRangeCompression(); pContext->mCompressor->Initialize(targetAmp, pContext->mConfig.inputCfg.samplingRate); } LE_setConfig(pContext, &pContext->mConfig); Loading Loading @@ -215,8 +209,7 @@ int LELib_Create(const effect_uuid_t *uuid, pContext->mItfe = &gLEInterface; pContext->mState = LOUDNESS_ENHANCER_STATE_UNINITIALIZED; pContext->mCompressorL = NULL; pContext->mCompressorR = NULL; pContext->mCompressor = NULL; ret = LE_init(pContext); if (ret < 0) { ALOGW("LELib_Create() init failed"); Loading @@ -242,13 +235,9 @@ int LELib_Release(effect_handle_t handle) { return -EINVAL; } pContext->mState = LOUDNESS_ENHANCER_STATE_UNINITIALIZED; if (pContext->mCompressorL != NULL) { delete pContext->mCompressorL; pContext->mCompressorL = NULL; } if (pContext->mCompressorR != NULL) { delete pContext->mCompressorR; pContext->mCompressorR = NULL; if (pContext->mCompressor != NULL) { delete pContext->mCompressor; pContext->mCompressor = NULL; } delete pContext; Loading Loading @@ -293,11 +282,14 @@ int LE_process( //ALOGV("LE about to process %d samples", inBuffer->frameCount); uint16_t inIdx; float inputAmp = pow(10, pContext->mTargetGainmB/2000.0f); float leftSample, rightSample; for (inIdx = 0 ; inIdx < inBuffer->frameCount ; inIdx++) { inBuffer->s16[2*inIdx] = pContext->mCompressorL->Compress( inputAmp * (float)inBuffer->s16[2*inIdx]); inBuffer->s16[2*inIdx +1] = pContext->mCompressorR->Compress( inputAmp * (float)inBuffer->s16[2*inIdx +1]); // makeup gain is applied on the input of the compressor leftSample = inputAmp * (float)inBuffer->s16[2*inIdx]; rightSample = inputAmp * (float)inBuffer->s16[2*inIdx +1]; pContext->mCompressor->Compress(&leftSample, &rightSample); inBuffer->s16[2*inIdx] = (int16_t) leftSample; inBuffer->s16[2*inIdx +1] = (int16_t) rightSample; } if (inBuffer->raw != outBuffer->raw) { Loading
media/libeffects/loudness/dsp/core/dynamic_range_compression-inl.h +1 −1 Original line number Diff line number Diff line Loading @@ -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); } Loading
media/libeffects/loudness/dsp/core/dynamic_range_compression.cpp +35 −0 Original line number Diff line number Diff line Loading @@ -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
media/libeffects/loudness/dsp/core/dynamic_range_compression.h +3 −0 Original line number Diff line number Diff line Loading @@ -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); Loading