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

Commit 8c0d4456 authored by rago's avatar rago Committed by android-build-merger
Browse files

Merge "Frequency Domain implementation of Dynamics Processing Effect" into pi-dev

am: e2bd0d49

Change-Id: I852959903a75a5c976e79aee7083a8de67584fba
parents 74b17876 e2bd0d49
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