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

Commit e2bd0d49 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

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

parents 7d08bf4e ff0a51f9
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