Audio笔记之EffectChain::process_l

来源:互联网 发布:java错误无法加载主类 编辑:程序博客网 时间:2024/06/03 17:30
// Must be called with EffectChain::mLock lockedvoid AudioFlinger::EffectChain::process_l(){    sp<ThreadBase> thread = mThread.promote();    if (thread == 0) {        ALOGW("process_l(): cannot promote mixer thread");        return;    }    bool isGlobalSession = (mSessionId == AUDIO_SESSION_OUTPUT_MIX) ||            (mSessionId == AUDIO_SESSION_OUTPUT_STAGE);    // never process effects when:    // - on an OFFLOAD thread    // - no more tracks are on the session and the effect tail has been rendered    bool doProcess = (thread->type() != ThreadBase::OFFLOAD);    //1、对于非全局effect,如果没有关联的track且tailBuffCount为0,则不使用音效    //  每次新增激活track,都会将tailBuffCount置为MaxCount,所以当激活track    //  数量不为0时,tailBuffCount肯定大于0,因此当有激活track存在时,一定会    //  执行音效处理,如果没有激活track存在时,如果有关联的track,虽然调用了音效    //  处理,但实际上输入已经经过清理了,所以不影响输出    //2、对于全局effect,无需关系track状态,直接对MixBuff中的数据进行处理    if (!isGlobalSession) {        bool tracksOnSession = (trackCnt() != 0);        if (!tracksOnSession && mTailBufferCount == 0) {            doProcess = false;        }        // 如果与effect关联的track都没有激活        if (activeTrackCnt() == 0) {            // if no track is active and the effect tail has not been rendered,            // the input buffer must be cleared here as the mixer process will not do it            if (tracksOnSession || mTailBufferCount > 0) {                clearInputBuffer_l(thread);                if (mTailBufferCount > 0) {                    mTailBufferCount--;                }            }        }    }    size_t size = mEffects.size();    if (doProcess) {        for (size_t i = 0; i < size; i++) {            mEffects[i]->process();        }    }    for (size_t i = 0; i < size; i++) {        mEffects[i]->updateState();    }}void AudioFlinger::EffectModule::process(){    Mutex::Autolock _l(mLock);    if (mState == DESTROYED || mEffectInterface == NULL ||            mConfig.inputCfg.buffer.raw == NULL ||            mConfig.outputCfg.buffer.raw == NULL) {        return;    }    // 1、如果该effect可用,则调用effect engine进行数据处理,并将其写入输出    // 2、如果该effect不可用,且属于insert类型并处于Chain的尾端,则需要    //    将其输入填充到其输出,否则该Chain的数据无法送到mMixBuff中,如果    //    effect不是在尾端,则其输入和输出相同,无需进行额外的填充    if (isProcessEnabled()) {        // do 32 bit to 16 bit conversion for auxiliary effect input buffer        if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {            ditherAndClamp(mConfig.inputCfg.buffer.s32,                                        mConfig.inputCfg.buffer.s32,                                        mConfig.inputCfg.buffer.frameCount/2);        }        // do the actual processing in the effect engine        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) {            memset(mConfig.inputCfg.buffer.raw, 0,                   mConfig.inputCfg.buffer.frameCount*sizeof(int32_t));        }    } else if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_INSERT &&                mConfig.inputCfg.buffer.raw != mConfig.outputCfg.buffer.raw) {        // If an insert effect is idle and input buffer is different from output buffer,        // accumulate input onto output        sp<EffectChain> chain = mChain.promote();        if (chain != 0 && chain->activeTrackCnt() != 0) {            size_t frameCnt = mConfig.inputCfg.buffer.frameCount * 2;  //always stereo here            int16_t *in = mConfig.inputCfg.buffer.s16;            int16_t *out = mConfig.outputCfg.buffer.s16;            for (size_t i = 0; i < frameCnt; i++) {                out[i] = clamp16((int32_t)out[i] + (int32_t)in[i]);            }        }    }}bool AudioFlinger::EffectModule::isProcessEnabled() const{    if (mStatus != NO_ERROR) {        return false;    }    switch (mState) {    case RESTART:    case ACTIVE:    case STOPPING:    case STOPPED:        return true;    case IDLE:    case STARTING:    case DESTROYED:    default:        return false;    }}static inline int16_t clamp16(int32_t sample){    if ((sample>>15) ^ (sample>>31))        sample = 0x7FFF ^ (sample>>31);    return sample;}void AudioFlinger::EffectModule::updateState() {    Mutex::Autolock _l(mLock);    switch (mState) {    case RESTART:        reset_l();        // 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));        }        if (start_l() == NO_ERROR) {            mState = ACTIVE;        } else {            mState = IDLE;        }        break;    case STOPPING:        if (stop_l() == NO_ERROR) {            mDisableWaitCnt = mMaxDisableWaitCnt;        } else {            mDisableWaitCnt = 1; // will cause immediate transition to IDLE        }        mState = STOPPED;        break;    case STOPPED:        // 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, DESTROYED        break;    }} 

0 0
原创粉丝点击