Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0b74d2b4 authored by Jean-Michel Trivi's avatar Jean-Michel Trivi Committed by Android (Google) Code Review
Browse files

Merge "LoudnessEnhancer compatible with stereo imaging" into klp-dev

parents a2340b30 cd0c4683
Loading
Loading
Loading
Loading
+17 −25
Original line number Diff line number Diff line
@@ -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;
};

//
@@ -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);
    }
@@ -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);
@@ -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");
@@ -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;

@@ -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) {
+1 −1
Original line number Diff line number Diff line
@@ -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);
}

+35 −0
Original line number Diff line number Diff line
@@ -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
+3 −0
Original line number Diff line number Diff line
@@ -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);