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

Commit d24e983e authored by rago's avatar rago
Browse files

Setting EFFECT_FLAG_VOLUME_CTRL for DynamicsProcessing effect

Fixing level handling in DynamicsProcessing effect.

Bug: 79712497
Test: manual testing and sound amplifier test
Change-Id: Ie263ab570ad55e10e1ee80795357977a24a920fd
parent d55d0f32
Loading
Loading
Loading
Loading
+113 −72
Original line number Diff line number Diff line
@@ -51,7 +51,7 @@ const effect_descriptor_t gDPDescriptor = {
        {0x7261676f, 0x6d75, 0x7369, 0x6364, {0x28, 0xe2, 0xfd, 0x3a, 0xc3, 0x9e}}, // type
        {0xe0e6539b, 0x1781, 0x7261, 0x676f, {0x6d, 0x75, 0x73, 0x69, 0x63, 0x40}}, // uuid
        EFFECT_CONTROL_API_VERSION,
        (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_FIRST),
        (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_LAST | EFFECT_FLAG_VOLUME_CTRL),
        0, // TODO
        1,
        "Dynamics Processing",
@@ -367,6 +367,76 @@ int DP_process(effect_handle_t self, audio_buffer_t *inBuffer,
    return 0;
}

//helper function
bool DP_checkSizesInt(uint32_t paramSize, uint32_t valueSize, uint32_t expectedParams,
        uint32_t expectedValues) {
    if (paramSize < expectedParams * sizeof(int32_t)) {
        ALOGE("Invalid paramSize: %u expected %u", paramSize,
                (uint32_t)(expectedParams * sizeof(int32_t)));
        return false;
    }
    if (valueSize < expectedValues * sizeof(int32_t)) {
        ALOGE("Invalid valueSize %u expected %u", valueSize,
                (uint32_t)(expectedValues * sizeof(int32_t)));
        return false;
    }
    return true;
}

static dp_fx::DPChannel* DP_getChannel(DynamicsProcessingContext *pContext,
        int32_t channel) {
    if (pContext->mPDynamics == NULL) {
        return NULL;
    }
    dp_fx::DPChannel *pChannel = pContext->mPDynamics->getChannel(channel);
    ALOGE_IF(pChannel == NULL, "DPChannel NULL. invalid channel %d", channel);
    return pChannel;
}

static dp_fx::DPEq* DP_getEq(DynamicsProcessingContext *pContext, int32_t channel,
        int32_t eqType) {
    dp_fx::DPChannel *pChannel = DP_getChannel(pContext, channel);
    if (pChannel == NULL) {
        return NULL;
    }
    dp_fx::DPEq *pEq = (eqType == DP_PARAM_PRE_EQ ? pChannel->getPreEq() :
            (eqType == DP_PARAM_POST_EQ ? pChannel->getPostEq() : NULL));
    ALOGE_IF(pEq == NULL,"DPEq NULL invalid eq");
    return pEq;
}

static dp_fx::DPEqBand* DP_getEqBand(DynamicsProcessingContext *pContext, int32_t channel,
        int32_t eqType, int32_t band) {
    dp_fx::DPEq *pEq = DP_getEq(pContext, channel, eqType);
    if (pEq == NULL) {
        return NULL;
    }
    dp_fx::DPEqBand *pEqBand = pEq->getBand(band);
    ALOGE_IF(pEqBand == NULL, "DPEqBand NULL. invalid band %d", band);
    return pEqBand;
}

static dp_fx::DPMbc* DP_getMbc(DynamicsProcessingContext *pContext, int32_t channel) {
    dp_fx::DPChannel * pChannel = DP_getChannel(pContext, channel);
    if (pChannel == NULL) {
        return NULL;
    }
    dp_fx::DPMbc *pMbc = pChannel->getMbc();
    ALOGE_IF(pMbc == NULL, "DPMbc NULL invalid MBC");
    return pMbc;
}

static dp_fx::DPMbcBand* DP_getMbcBand(DynamicsProcessingContext *pContext, int32_t channel,
        int32_t band) {
    dp_fx::DPMbc *pMbc = DP_getMbc(pContext, channel);
    if (pMbc == NULL) {
        return NULL;
    }
    dp_fx::DPMbcBand *pMbcBand = pMbc->getBand(band);
    ALOGE_IF(pMbcBand == NULL, "pMbcBand NULL. invalid band %d", band);
    return pMbcBand;
}

int DP_command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize,
        void *pCmdData, uint32_t *replySize, void *pReplyData) {

@@ -483,8 +553,49 @@ int DP_command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize,
                p->data + voffset);
        break;
    }
    case EFFECT_CMD_SET_VOLUME: {
        ALOGV("EFFECT_CMD_SET_VOLUME");
        // if pReplyData is NULL, VOL_CTRL is delegated to another effect
        if (pReplyData == NULL || replySize == NULL || *replySize < ((int)sizeof(int32_t) * 2)) {
            ALOGV("no VOLUME data to return");
            break;
        }
        if (pCmdData == NULL || cmdSize < ((int)sizeof(uint32_t) * 2)) {
            ALOGE("\tLVM_ERROR : DynamicsProcessing EFFECT_CMD_SET_VOLUME ERROR");
            return -EINVAL;
        }

        const int32_t unityGain = 1 << 24;
        //channel count
        int32_t channelCount = (int32_t)audio_channel_count_from_out_mask(
                pContext->mConfig.inputCfg.channels);
        for (int32_t ch = 0; ch < channelCount; ch++) {

            dp_fx::DPChannel * pChannel = DP_getChannel(pContext, ch);
            if (pChannel == NULL) {
                ALOGE("%s EFFECT_CMD_SET_VOLUME invalid channel %d", __func__, ch);
                return -EINVAL;
                break;
            }

            int32_t offset = ch;
            if (ch > 1) {
                // FIXME: limited to 2 unique channels. If more channels present, use value for
                // first channel
                offset = 0;
            }
            const float gain = (float)*((uint32_t *)pCmdData + offset) / unityGain;
            const float gainDb = linearToDb(gain);
            ALOGVV("%s EFFECT_CMD_SET_VOLUME channel %d, engine outputlevel %f (%0.2f dB)",
                    __func__, ch, gain, gainDb);
            pChannel->setOutputGain(gainDb);
        }

        const int32_t  volRet[2] = {unityGain, unityGain}; // Apply no volume before effect.
        memcpy(pReplyData, volRet, sizeof(volRet));
        break;
    }
    case EFFECT_CMD_SET_DEVICE:
    case EFFECT_CMD_SET_VOLUME:
    case EFFECT_CMD_SET_AUDIO_MODE:
        break;

@@ -523,76 +634,6 @@ int DP_getParameterCmdSize(uint32_t paramSize,
    return 0;
}

//helper function
bool DP_checkSizesInt(uint32_t paramSize, uint32_t valueSize, uint32_t expectedParams,
        uint32_t expectedValues) {
    if (paramSize < expectedParams * sizeof(int32_t)) {
        ALOGE("Invalid paramSize: %u expected %u", paramSize,
                (uint32_t) (expectedParams * sizeof(int32_t)));
        return false;
    }
    if (valueSize < expectedValues * sizeof(int32_t)) {
        ALOGE("Invalid valueSize %u expected %u", valueSize,
                (uint32_t)(expectedValues * sizeof(int32_t)));
        return false;
    }
    return true;
}

static dp_fx::DPChannel* DP_getChannel(DynamicsProcessingContext *pContext,
        int32_t channel) {
    if (pContext->mPDynamics == NULL) {
        return NULL;
    }
    dp_fx::DPChannel *pChannel = pContext->mPDynamics->getChannel(channel);
    ALOGE_IF(pChannel == NULL, "DPChannel NULL. invalid channel %d", channel);
    return pChannel;
}

static dp_fx::DPEq* DP_getEq(DynamicsProcessingContext *pContext, int32_t channel,
        int32_t eqType) {
    dp_fx::DPChannel * pChannel = DP_getChannel(pContext, channel);
    if (pChannel == NULL) {
        return NULL;
    }
    dp_fx::DPEq *pEq = (eqType == DP_PARAM_PRE_EQ ? pChannel->getPreEq() :
            (eqType == DP_PARAM_POST_EQ ? pChannel->getPostEq() : NULL));
    ALOGE_IF(pEq == NULL,"DPEq NULL invalid eq");
    return pEq;
}

static dp_fx::DPEqBand* DP_getEqBand(DynamicsProcessingContext *pContext, int32_t channel,
        int32_t eqType, int32_t band) {
    dp_fx::DPEq *pEq = DP_getEq(pContext, channel, eqType);
    if (pEq == NULL) {
        return NULL;
    }
    dp_fx::DPEqBand *pEqBand = pEq->getBand(band);
    ALOGE_IF(pEqBand == NULL, "DPEqBand NULL. invalid band %d", band);
    return pEqBand;
}

static dp_fx::DPMbc* DP_getMbc(DynamicsProcessingContext *pContext, int32_t channel) {
    dp_fx::DPChannel * pChannel = DP_getChannel(pContext, channel);
    if (pChannel == NULL) {
        return NULL;
    }
    dp_fx::DPMbc *pMbc = pChannel->getMbc();
    ALOGE_IF(pMbc == NULL, "DPMbc NULL invalid MBC");
    return pMbc;
}

static dp_fx::DPMbcBand* DP_getMbcBand(DynamicsProcessingContext *pContext, int32_t channel,
        int32_t band) {
    dp_fx::DPMbc *pMbc = DP_getMbc(pContext, channel);
    if (pMbc == NULL) {
        return NULL;
    }
    dp_fx::DPMbcBand *pMbcBand = pMbc->getBand(band);
    ALOGE_IF(pMbcBand == NULL, "pMbcBand NULL. invalid band %d", band);
    return pMbcBand;
}

int DP_getParameter(DynamicsProcessingContext *pContext,
                           uint32_t paramSize,
                           void *pParam,
+2 −2
Original line number Diff line number Diff line
@@ -174,8 +174,8 @@ void DPLimiter::init(bool inUse, bool enabled, uint32_t linkGroup, float attackT
}

//----
DPChannel::DPChannel() : mInitialized(false), mInputGainDb(0), mPreEqInUse(false), mMbcInUse(false),
        mPostEqInUse(false), mLimiterInUse(false) {
DPChannel::DPChannel() : mInitialized(false), mInputGainDb(0), mOutputGainDb(0),
        mPreEqInUse(false), mMbcInUse(false), mPostEqInUse(false), mLimiterInUse(false) {
}

void DPChannel::init(float inputGain, bool preEqInUse, uint32_t preEqBandCount,
+11 −0
Original line number Diff line number Diff line
@@ -272,6 +272,16 @@ public:
        mInputGainDb = gain;
    }

    float getOutputGain() const {
        if (!mInitialized) {
            return 0;
        }
        return mOutputGainDb;
    }
    void setOutputGain(float gain) {
        mOutputGainDb = gain;
    }

    DPEq* getPreEq();
    DPMbc* getMbc();
    DPEq* getPostEq();
@@ -281,6 +291,7 @@ public:
private:
    bool mInitialized;
    float mInputGainDb;
    float mOutputGainDb;

    DPEq mPreEq;
    DPMbc mMbc;
+12 −12
Original line number Diff line number Diff line
@@ -53,14 +53,6 @@ template <> bool compareEquality<float>(float a, float b) {
#define IS_CHANGED(c, a, b) { c |= !compareEquality(a,b); \
    (a) = (b); }

float dBtoLinear(float valueDb) {
    return pow (10, valueDb / 20.0);
}

float linearToDb(float value) {
    return 20 * log10(value);
}

//ChannelBuffers helper
void ChannelBuffer::initBuffers(unsigned int blockSize, unsigned int overlapSize,
        unsigned int halfFftSize, unsigned int samplingRate, DPBase &dpBase) {
@@ -376,6 +368,9 @@ void DPFrequency::updateParameters(ChannelBuffer &cb, int channelIndex) {
            mLinkedLimiters.update(cb.mLimiterParams.linkGroup, channelIndex);
        }
    }

    //=== Output Gain
    cb.outputGainDb = pChannel->getOutputGain();
}

size_t DPFrequency::processSamples(const float *in, float *out, size_t samples) {
@@ -651,16 +646,21 @@ void DPFrequency::processLinkedLimiters(CBufferVector &channelBuffers) {
}

size_t DPFrequency::processLastStages(ChannelBuffer &cb) {

    float outputGainFactor = dBtoLinear(cb.outputGainDb);
    //== Limiter. last Pass
    if (cb.mLimiterInUse && cb.mLimiterEnabled) {
        const size_t cSize = cb.complexTemp.size();
        const size_t maxBin = std::min(cSize/2, mHalfFFTSize);
        //compute factor, with post-gain
        float factor = cb.mLimiterParams.linkFactor * dBtoLinear(cb.mLimiterParams.postGainDb);
        outputGainFactor *= factor;
    }

        //apply to all
    //apply to all if != 1.0
    if (!compareEquality(outputGainFactor, 1.0f)) {
        size_t cSize = cb.complexTemp.size();
        size_t maxBin = std::min(cSize/2, mHalfFFTSize);
        for (size_t k = 0; k < maxBin; k++) {
            cb.complexTemp[k] *= factor;
            cb.complexTemp[k] *= outputGainFactor;
        }
    }

+1 −0
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ public:

    //Current parameters
    float inputGainDb;
    float outputGainDb;
    struct BandParams {
        bool enabled;
        float freqCutoffHz;
Loading