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

Commit b20cf7db authored by Eric Laurent's avatar Eric Laurent
Browse files

audio policy: concurrent capture effects

Add pre processing effect management for concurrent capture scenarii.
When several clients on the same input stream have enabled audio effects,
only the effects attached to the top priotity client are active.
Other effects are suspended.

Add AudioFlinger API to suspend/restore audio effects build on top
of exisiting internal effect suspend mechanism.

RecordThread now supports more than one effect chain.

AOSP pre processing implementation supports more than one effect session
per input.

Refactor AudioPolicyManager::closeAllInputs() to call closeInput() on
all inputs instead of partially duplicated code.

Bug: 128419018
Test: make
Change-Id: I685286da4c2905a8894a4354679f9787b1400621
parent aceea8bd
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
@@ -89,6 +89,7 @@ enum {
    GET_MICROPHONES,
    SET_MASTER_BALANCE,
    GET_MASTER_BALANCE,
    SET_EFFECT_SUSPENDED,
};

#define MAX_ITEMS_PER_LIST 1024
@@ -718,6 +719,18 @@ public:
        return reply.readInt32();
    }

    virtual void setEffectSuspended(int effectId,
                                    audio_session_t sessionId,
                                    bool suspended)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
        data.writeInt32(effectId);
        data.writeInt32(sessionId);
        data.writeInt32(suspended ? 1 : 0);
        remote()->transact(SET_EFFECT_SUSPENDED, data, &reply);
    }

    virtual audio_module_handle_t loadHwModule(const char *name)
    {
        Parcel data, reply;
@@ -913,6 +926,7 @@ status_t BnAudioFlinger::onTransact(
        case INVALIDATE_STREAM:
        case SET_VOICE_VOLUME:
        case MOVE_EFFECTS:
        case SET_EFFECT_SUSPENDED:
        case LOAD_HW_MODULE:
        case LIST_AUDIO_PORTS:
        case GET_AUDIO_PORT:
@@ -926,6 +940,7 @@ status_t BnAudioFlinger::onTransact(
            // return status only for non void methods
            switch (code) {
                case SET_RECORD_SILENCED:
                case SET_EFFECT_SUSPENDED:
                    break;
                default:
                    reply->writeInt32(static_cast<int32_t> (INVALID_OPERATION));
@@ -1371,6 +1386,14 @@ status_t BnAudioFlinger::onTransact(
            reply->writeInt32(moveEffects(session, srcOutput, dstOutput));
            return NO_ERROR;
        } break;
        case SET_EFFECT_SUSPENDED: {
            CHECK_INTERFACE(IAudioFlinger, data, reply);
            int effectId = data.readInt32();
            audio_session_t sessionId = (audio_session_t) data.readInt32();
            bool suspended = data.readInt32() == 1;
            setEffectSuspended(effectId, sessionId, suspended);
            return NO_ERROR;
        } break;
        case LOAD_HW_MODULE: {
            CHECK_INTERFACE(IAudioFlinger, data, reply);
            reply->writeInt32(loadHwModule(data.readCString()));
+4 −0
Original line number Diff line number Diff line
@@ -457,6 +457,10 @@ public:
    virtual status_t moveEffects(audio_session_t session, audio_io_handle_t srcOutput,
                                    audio_io_handle_t dstOutput) = 0;

    virtual void setEffectSuspended(int effectId,
                                    audio_session_t sessionId,
                                    bool suspended) = 0;

    virtual audio_module_handle_t loadHwModule(const char *name) = 0;

    // helpers for android.media.AudioManager.getProperty(), see description there for meaning
+5 −5
Original line number Diff line number Diff line
@@ -926,7 +926,7 @@ int Session_ReleaseEffect(preproc_session_t *session,
        delete session->revBuf;
        session->revBuf = NULL;

        session->io = 0;
        session->id = 0;
    }

    return 0;
@@ -1155,7 +1155,7 @@ preproc_session_t *PreProc_GetSession(int32_t procId, int32_t sessionId, int32_
{
    size_t i;
    for (i = 0; i < PREPROC_NUM_SESSIONS; i++) {
        if (sSessions[i].io == ioId) {
        if (sSessions[i].id == sessionId) {
            if (sSessions[i].createdMsk & (1 << procId)) {
                return NULL;
            }
@@ -1163,7 +1163,7 @@ preproc_session_t *PreProc_GetSession(int32_t procId, int32_t sessionId, int32_
        }
    }
    for (i = 0; i < PREPROC_NUM_SESSIONS; i++) {
        if (sSessions[i].io == 0) {
        if (sSessions[i].id == 0) {
            sSessions[i].id = sessionId;
            sSessions[i].io = ioId;
            return &sSessions[i];
@@ -1915,7 +1915,7 @@ int PreProcessingLib_Create(const effect_uuid_t *uuid,
    status = Session_CreateEffect(session, procId, pInterface);

    if (status < 0 && session->createdMsk == 0) {
        session->io = 0;
        session->id = 0;
    }
    return status;
}
@@ -1929,7 +1929,7 @@ int PreProcessingLib_Release(effect_handle_t interface)

    preproc_effect_t *fx = (preproc_effect_t *)interface;

    if (fx->session->io == 0) {
    if (fx->session->id == 0) {
        return -EINVAL;
    }
    return Session_ReleaseEffect(fx->session, fx);
+41 −6
Original line number Diff line number Diff line
@@ -1699,18 +1699,35 @@ void AudioFlinger::removeClient_l(pid_t pid)
}

// getEffectThread_l() must be called with AudioFlinger::mLock held
sp<AudioFlinger::PlaybackThread> AudioFlinger::getEffectThread_l(audio_session_t sessionId,
        int EffectId)
sp<AudioFlinger::ThreadBase> AudioFlinger::getEffectThread_l(audio_session_t sessionId,
        int effectId)
{
    sp<PlaybackThread> thread;
    sp<ThreadBase> thread;

    for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
        if (mPlaybackThreads.valueAt(i)->getEffect(sessionId, EffectId) != 0) {
        if (mPlaybackThreads.valueAt(i)->getEffect(sessionId, effectId) != 0) {
            ALOG_ASSERT(thread == 0);
            thread = mPlaybackThreads.valueAt(i);
        }
    }

    if (thread != nullptr) {
        return thread;
    }
    for (size_t i = 0; i < mRecordThreads.size(); i++) {
        if (mRecordThreads.valueAt(i)->getEffect(sessionId, effectId) != 0) {
            ALOG_ASSERT(thread == 0);
            thread = mRecordThreads.valueAt(i);
        }
    }
    if (thread != nullptr) {
        return thread;
    }
    for (size_t i = 0; i < mMmapThreads.size(); i++) {
        if (mMmapThreads.valueAt(i)->getEffect(sessionId, effectId) != 0) {
            ALOG_ASSERT(thread == 0);
            thread = mMmapThreads.valueAt(i);
        }
    }
    return thread;
}

@@ -3464,6 +3481,23 @@ status_t AudioFlinger::moveEffects(audio_session_t sessionId, audio_io_handle_t
    return moveEffectChain_l(sessionId, srcThread, dstThread);
}


void AudioFlinger::setEffectSuspended(int effectId,
                                audio_session_t sessionId,
                                bool suspended)
{
    Mutex::Autolock _l(mLock);

    sp<ThreadBase> thread = getEffectThread_l(sessionId, effectId);
    if (thread == nullptr) {
      return;
    }
    Mutex::Autolock _sl(thread->mLock);
    sp<EffectModule> effect = thread->getEffect_l(sessionId, effectId);
    thread->setEffectSuspended_l(&effect->desc().type, suspended, sessionId);
}


// moveEffectChain_l must be called with both srcThread and dstThread mLocks held
status_t AudioFlinger::moveEffectChain_l(audio_session_t sessionId,
                                   AudioFlinger::PlaybackThread *srcThread,
@@ -3541,7 +3575,8 @@ status_t AudioFlinger::moveAuxEffectToIo(int EffectId,
{
    status_t status = NO_ERROR;
    Mutex::Autolock _l(mLock);
    sp<PlaybackThread> thread = getEffectThread_l(AUDIO_SESSION_OUTPUT_MIX, EffectId);
    sp<PlaybackThread> thread =
        static_cast<PlaybackThread *>(getEffectThread_l(AUDIO_SESSION_OUTPUT_MIX, EffectId).get());

    if (EffectId != 0 && thread != 0 && dstThread != thread.get()) {
        Mutex::Autolock _dl(dstThread->mLock);
+5 −1
Original line number Diff line number Diff line
@@ -239,6 +239,10 @@ public:
    virtual status_t moveEffects(audio_session_t sessionId, audio_io_handle_t srcOutput,
                        audio_io_handle_t dstOutput);

            void setEffectSuspended(int effectId,
                                    audio_session_t sessionId,
                                    bool suspended) override;

    virtual audio_module_handle_t loadHwModule(const char *name);

    virtual uint32_t getPrimaryOutputSamplingRate();
@@ -708,7 +712,7 @@ using effect_buffer_t = int16_t;
              // return the playback thread with smallest HAL buffer size, and prefer fast
              PlaybackThread *fastPlaybackThread_l() const;

              sp<PlaybackThread> getEffectThread_l(audio_session_t sessionId, int EffectId);
              sp<ThreadBase> getEffectThread_l(audio_session_t sessionId, int effectId);


                void        removeClient_l(pid_t pid);
Loading