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

Commit ff0a51f9 authored by rago's avatar rago
Browse files

Frequency Domain implementation of Dynamics Processing Effect

Ported the frequency domain implementation of the effect from the
development sandbox.

Bug: 64161702
Bug: 38266419

Test: manual with Triton app. Cts tests. Listening tests.
Change-Id: I9417beba2f98f2a677f0857c7976bf76a0e0d8e0
parent 9f011fed
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -18,9 +18,14 @@ LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_VENDOR_MODULE := true

EIGEN_PATH := external/eigen
LOCAL_C_INCLUDES += $(EIGEN_PATH)

LOCAL_SRC_FILES:= \
    EffectDynamicsProcessing.cpp \
    dsp/DPBase.cpp
    dsp/DPBase.cpp \
    dsp/DPFrequency.cpp

LOCAL_CFLAGS+= -O2 -fvisibility=hidden
LOCAL_CFLAGS += -Wall -Werror
+55 −11
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@

#include <audio_effects/effect_dynamicsprocessing.h>
#include <dsp/DPBase.h>
#include <dsp/DPFrequency.h>

//#define VERY_VERY_VERBOSE_LOGGING
#ifdef VERY_VERY_VERBOSE_LOGGING
@@ -186,7 +187,7 @@ int DP_init(DynamicsProcessingContext *pContext)
    pContext->mConfig.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
    pContext->mConfig.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
    pContext->mConfig.inputCfg.format = AUDIO_FORMAT_PCM_FLOAT;
    pContext->mConfig.inputCfg.samplingRate = 44100;
    pContext->mConfig.inputCfg.samplingRate = 48000;
    pContext->mConfig.inputCfg.bufferProvider.getBuffer = NULL;
    pContext->mConfig.inputCfg.bufferProvider.releaseBuffer = NULL;
    pContext->mConfig.inputCfg.bufferProvider.cookie = NULL;
@@ -194,7 +195,7 @@ int DP_init(DynamicsProcessingContext *pContext)
    pContext->mConfig.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE;
    pContext->mConfig.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
    pContext->mConfig.outputCfg.format = AUDIO_FORMAT_PCM_FLOAT;
    pContext->mConfig.outputCfg.samplingRate = 44100;
    pContext->mConfig.outputCfg.samplingRate = 48000;
    pContext->mConfig.outputCfg.bufferProvider.getBuffer = NULL;
    pContext->mConfig.outputCfg.bufferProvider.releaseBuffer = NULL;
    pContext->mConfig.outputCfg.bufferProvider.cookie = NULL;
@@ -209,18 +210,53 @@ int DP_init(DynamicsProcessingContext *pContext)
}

void DP_changeVariant(DynamicsProcessingContext *pContext, int newVariant) {
    if (pContext->mPDynamics != NULL) {
    ALOGV("DP_changeVariant from %d to %d", pContext->mCurrentVariant, newVariant);
    switch(newVariant) {
    case VARIANT_FAVOR_FREQUENCY_RESOLUTION: {
        pContext->mCurrentVariant = VARIANT_FAVOR_FREQUENCY_RESOLUTION;
        delete pContext->mPDynamics;
        pContext->mPDynamics = NULL;
        pContext->mPDynamics = new dp_fx::DPFrequency();
        break;
    }
    default: {
        ALOGW("DynamicsProcessing variant %d not available for creation", newVariant);
        break;
    }
    } //switch
}

static inline bool isPowerOf2(unsigned long n) {
    return (n & (n - 1)) == 0;
}

void DP_configureVariant(DynamicsProcessingContext *pContext, int newVariant) {
    ALOGV("DP_configureVariant %d", newVariant);
    switch(newVariant) {
    //TODO: actually instantiate one of the variants. For now all instantiate the base;
    default:
        pContext->mCurrentVariant = newVariant;
        pContext->mPDynamics = new dp_fx::DPBase();
    case VARIANT_FAVOR_FREQUENCY_RESOLUTION: {
        int32_t minBlockSize = (int32_t)dp_fx::DPFrequency::getMinBockSize();
        int32_t desiredBlock = pContext->mPreferredFrameDuration *
                pContext->mConfig.inputCfg.samplingRate / 1000.0f;
        int32_t currentBlock = desiredBlock;
        ALOGV(" sampling rate: %d, desiredBlock size %0.2f (%d) samples",
                pContext->mConfig.inputCfg.samplingRate, pContext->mPreferredFrameDuration,
                desiredBlock);
        if (desiredBlock < minBlockSize) {
            currentBlock = minBlockSize;
        } else if (!isPowerOf2(desiredBlock)) {
            //find next highest power of 2.
            currentBlock = 1 << (32 - __builtin_clz(desiredBlock));
        }
        ((dp_fx::DPFrequency*)pContext->mPDynamics)->configure(currentBlock,
                currentBlock/2,
                pContext->mConfig.inputCfg.samplingRate);
        break;
    }
    default: {
        ALOGE("DynamicsProcessing variant %d not available to configure", newVariant);
        break;
    }
    }
}

//
//--- Effect Library Interface Implementation
@@ -312,6 +348,7 @@ int DP_process(effect_handle_t self, audio_buffer_t *inBuffer,
                        pContext->mConfig.inputCfg.channels);
        pContext->mPDynamics->processSamples(inBuffer->f32, inBuffer->f32,
                inBuffer->frameCount * channelCount);

        if (inBuffer->raw != outBuffer->raw) {
            if (pContext->mConfig.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) {
                for (size_t i = 0; i < outBuffer->frameCount * channelCount; i++) {
@@ -518,7 +555,8 @@ static dp_fx::DPEq* DP_getEq(DynamicsProcessingContext *pContext, int32_t channe
    if (pChannel == NULL) {
        return NULL;
    }
    dp_fx::DPEq *pEq = eqType == DP_PARAM_PRE_EQ ? pChannel->getPreEq() : pChannel->getPostEq();
    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;
}
@@ -699,8 +737,10 @@ int DP_getParameter(DynamicsProcessingContext *pContext,
//              eqBand.getGain()};
        const int32_t channel = params[1];
        const int32_t band = params[2];
        int eqCommand = (command == DP_PARAM_PRE_EQ_BAND ? DP_PARAM_PRE_EQ :
                (command == DP_PARAM_POST_EQ_BAND ? DP_PARAM_POST_EQ : -1));

        dp_fx::DPEqBand *pEqBand = DP_getEqBand(pContext, channel, command, band);
        dp_fx::DPEqBand *pEqBand = DP_getEqBand(pContext, channel, eqCommand, band);
        if (pEqBand == NULL) {
            ALOGE("%s get PARAM_*_EQ_BAND invalid channel %d or band %d", __func__, channel, band);
            status = -EINVAL;
@@ -923,6 +963,8 @@ int DP_setParameter(DynamicsProcessingContext *pContext,
                mbcInUse != 0, (uint32_t)mbcBandCount,
                postEqInUse != 0, (uint32_t)postEqBandCount,
                limiterInUse != 0);

        DP_configureVariant(pContext, variant);
        break;
    }
    case DP_PARAM_INPUT_GAIN: {
@@ -1015,7 +1057,9 @@ int DP_setParameter(DynamicsProcessingContext *pContext,
                (command == DP_PARAM_PRE_EQ_BAND ? "preEqBand" : "postEqBand"), channel, band,
                enabled, cutoffFrequency, gain);

        dp_fx::DPEq *pEq = DP_getEq(pContext, channel, command);
        int eqCommand = (command == DP_PARAM_PRE_EQ_BAND ? DP_PARAM_PRE_EQ :
                (command == DP_PARAM_POST_EQ_BAND ? DP_PARAM_POST_EQ : -1));
        dp_fx::DPEq *pEq = DP_getEq(pContext, channel, eqCommand);
        if (pEq == NULL) {
            ALOGE("%s set PARAM_*_EQ_BAND invalid channel %d or command %d", __func__, channel,
                    command);
+6 −26
Original line number Diff line number Diff line
@@ -14,8 +14,12 @@
 * limitations under the License.
 */

#include <android/log.h>
#define LOG_TAG "DPBase"
//#define LOG_NDEBUG 0

#include <log/log.h>
#include "DPBase.h"
#include "DPFrequency.h"

namespace dp_fx {

@@ -234,6 +238,7 @@ DPBase::DPBase() : mInitialized(false), mChannelCount(0), mPreEqInUse(false), mP
void DPBase::init(uint32_t channelCount, bool preEqInUse, uint32_t preEqBandCount,
        bool mbcInUse, uint32_t mbcBandCount, bool postEqInUse, uint32_t postEqBandCount,
        bool limiterInUse) {
    ALOGV("DPBase::init");
    mChannelCount = channelCount;
    mPreEqInUse = preEqInUse;
    mPreEqBandCount = preEqBandCount;
@@ -250,31 +255,6 @@ void DPBase::init(uint32_t channelCount, bool preEqInUse, uint32_t preEqBandCoun
    mInitialized = true;
}

void DPBase::reset() {
    //perform reset operations with current architecture.
}

size_t DPBase::processSamples(float *in, float *out, size_t samples) {
    //actually do something with samples, for now, just apply level.
    uint32_t channelCount = getChannelCount();
    std::vector<float> level(channelCount);
    for (uint32_t ch = 0; ch < channelCount; ch++) {
        DPChannel *pChannel = getChannel(ch);
        if (pChannel != NULL) {
            level[ch] = pow(10, pChannel->getInputGain() / 20.0);
        }
    }
    size_t processedSamples = 0;
    float *pInput = in;
    float *pOutput = out;
    for (size_t k = 0; k < samples; k++) {
            float value = *pInput++;
            *pOutput++ = value * level[k % channelCount];
            processedSamples++;
    }
    return processedSamples;
}

DPChannel* DPBase::getChannel(uint32_t channelIndex) {
    if (!mInitialized || channelIndex < 0 || channelIndex >= mChannel.size()) {
        return NULL;
+9 −2
Original line number Diff line number Diff line
@@ -14,6 +14,10 @@
 * limitations under the License.
 */

#ifndef DPBASE_H_
#define DPBASE_H_


#include <stdint.h>
#include <cmath>
#include <vector>
@@ -297,8 +301,8 @@ public:
    void init(uint32_t channelCount, bool preEqInUse, uint32_t preEqBandCount,
            bool mbcInUse, uint32_t mbcBandCount, bool postEqInUse, uint32_t postEqBandCount,
            bool limiterInUse);
    virtual size_t processSamples(float *in, float *out, size_t samples);
    virtual void reset();
    virtual size_t processSamples(const float *in, float *out, size_t samples) = 0;
    virtual void reset() = 0;

    DPChannel* getChannel(uint32_t channelIndex);
    uint32_t getChannelCount() const {
@@ -342,3 +346,6 @@ private:
};

} //namespace dp_fx


#endif  // DPBASE_H_
+518 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading