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

Commit f5bdb971 authored by Eric Laurent's avatar Eric Laurent Committed by Android Git Automerger
Browse files

am 8e886be4: Merge "Modifications in audio effect engine state management." into gingerbread

Merge commit '8e886be413570fab6c623930a5775dd36a6d11e1' into gingerbread-plus-aosp

* commit '8e886be413570fab6c623930a5775dd36a6d11e1':
  Modifications in audio effect engine state management.
parents 659b0a97 cbf35c04
Loading
Loading
Loading
Loading
+63 −39
Original line number Diff line number Diff line
@@ -17,8 +17,7 @@


#define LOG_TAG "AudioFlinger"
//
#define LOG_NDEBUG 0
//#define LOG_NDEBUG 0

#include <math.h>
#include <signal.h>
@@ -5085,49 +5084,69 @@ void AudioFlinger::EffectModule::disconnect(const wp<EffectHandle>& handle)
    }
}

void AudioFlinger::EffectModule::process()
{
void AudioFlinger::EffectModule::updateState() {
    Mutex::Autolock _l(mLock);

    if (mEffectInterface == NULL || mConfig.inputCfg.buffer.raw == NULL || mConfig.outputCfg.buffer.raw == NULL) {
        return;
    }

    if (mState != IDLE) {
        // do 32 bit to 16 bit conversion for auxiliary effect input buffer
        if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
            AudioMixer::ditherAndClamp(mConfig.inputCfg.buffer.s32,
                                        mConfig.inputCfg.buffer.s32,
                                        mConfig.inputCfg.buffer.frameCount);
        }

        // TODO: handle effects with buffer provider
        if (mState != ACTIVE) {
    switch (mState) {
            case RESET:
    case RESTART:
        reset_l();
                mState = STARTING;
        // FALL THROUGH

    case STARTING:
        // clear auxiliary effect input buffer for next accumulation
        if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
                    memset(mConfig.inputCfg.buffer.raw, 0, mConfig.inputCfg.buffer.frameCount*sizeof(int32_t));
            memset(mConfig.inputCfg.buffer.raw,
                   0,
                   mConfig.inputCfg.buffer.frameCount*sizeof(int32_t));
        }
                return;
            case STARTING:
        start_l();
        mState = ACTIVE;
        break;
    case STOPPING:
        stop_l();
        mDisableWaitCnt = mMaxDisableWaitCnt;
        mState = STOPPED;
        break;
    case STOPPED:
                stop_l();
        // mDisableWaitCnt is forced to 1 by process() when the engine indicates the end of the
        // turn off sequence.
        if (--mDisableWaitCnt == 0) {
            reset_l();
            mState = IDLE;
        }
        break;
    default: //IDLE , ACTIVE
        break;
    }
}

void AudioFlinger::EffectModule::process()
{
    Mutex::Autolock _l(mLock);

    if (mEffectInterface == NULL ||
            mConfig.inputCfg.buffer.raw == NULL ||
            mConfig.outputCfg.buffer.raw == NULL) {
        return;
    }

    if (mState == ACTIVE || mState == STOPPING || mState == STOPPED) {
        // do 32 bit to 16 bit conversion for auxiliary effect input buffer
        if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
            AudioMixer::ditherAndClamp(mConfig.inputCfg.buffer.s32,
                                        mConfig.inputCfg.buffer.s32,
                                        mConfig.inputCfg.buffer.frameCount);
        }

        // do the actual processing in the effect engine
        (*mEffectInterface)->process(mEffectInterface, &mConfig.inputCfg.buffer, &mConfig.outputCfg.buffer);
        int ret = (*mEffectInterface)->process(mEffectInterface,
                                               &mConfig.inputCfg.buffer,
                                               &mConfig.outputCfg.buffer);

        // force transition to IDLE state when engine is ready
        if (mState == STOPPED && ret == -ENODATA) {
            mDisableWaitCnt = 1;
        }

        // clear auxiliary effect input buffer for next accumulation
        if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
@@ -5216,6 +5235,10 @@ status_t AudioFlinger::EffectModule::configure()
    if (status == 0) {
        status = cmdStatus;
    }

    mMaxDisableWaitCnt = (MAX_DISABLE_TIME_MS * mConfig.outputCfg.samplingRate) /
            (1000 * mConfig.outputCfg.buffer.frameCount);

    return status;
}

@@ -5292,21 +5315,19 @@ status_t AudioFlinger::EffectModule::setEnabled(bool enabled)
        switch (mState) {
        // going from disabled to enabled
        case IDLE:
            mState = RESET;
            mState = STARTING;
            break;
        case STOPPED:
            mState = RESTART;
            break;
        case STOPPING:
            mState = ACTIVE;
            break;
        case STOPPED:
            mState = STARTING;
            break;

        // going from enabled to disabled
        case RESET:
            mState = IDLE;
            break;
        case RESTART:
        case STARTING:
            mState = STOPPED;
            mState = IDLE;
            break;
        case ACTIVE:
            mState = STOPPING;
@@ -5325,7 +5346,7 @@ status_t AudioFlinger::EffectModule::setEnabled(bool enabled)
bool AudioFlinger::EffectModule::isEnabled()
{
    switch (mState) {
    case RESET:
    case RESTART:
    case STARTING:
    case ACTIVE:
        return true;
@@ -5772,6 +5793,9 @@ void AudioFlinger::EffectChain::process_l()
    for (size_t i = 0; i < size; i++) {
        mEffects[i]->process();
    }
    for (size_t i = 0; i < size; i++) {
        mEffects[i]->updateState();
    }
    // if no track is active, input buffer must be cleared here as the mixer process
    // will not do it
    if (mSessionId > 0 && activeTracks() == 0) {
+8 −1
Original line number Diff line number Diff line
@@ -905,7 +905,7 @@ private:

        enum effect_state {
            IDLE,
            RESET,
            RESTART,
            STARTING,
            ACTIVE,
            STOPPING,
@@ -914,6 +914,7 @@ private:

        int         id() { return mId; }
        void process();
        void updateState();
        status_t command(int cmdCode, int cmdSize, void *pCmdData, int *replySize, void *pReplyData);

        void reset_l();
@@ -948,6 +949,9 @@ private:

    protected:

        // Maximum time allocated to effect engines to complete the turn off sequence
        static const uint32_t MAX_DISABLE_TIME_MS = 10000;

        EffectModule(const EffectModule&);
        EffectModule& operator = (const EffectModule&);

@@ -973,6 +977,9 @@ private:
        status_t mStatus;               // initialization status
        uint32_t mState;                // current activation state (effect_state)
        Vector< wp<EffectHandle> > mHandles;    // list of client handles
        uint32_t mMaxDisableWaitCnt;    // maximum grace period before forcing an effect off after
                                        // sending disable command.
        uint32_t mDisableWaitCnt;       // current process() calls count during disable period.
    };

    // The EffectHandle class implements the IEffect interface. It provides resources