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

Commit 0f66058e authored by François Gaffie's avatar François Gaffie Committed by Shunkai Yao
Browse files

audio effect: allow to manage chain of device effects (sw or hw)



Bug: 268441977
Test: m

Change-Id: I5351b5bd34488437a353b8a39a7d0a51e9a85a22
Signed-off-by: default avatarFrançois Gaffie <francois.gaffie@renault.com>
parent 899ae43a
Loading
Loading
Loading
Loading
+49 −17
Original line number Diff line number Diff line
@@ -40,18 +40,22 @@ void AudioFlinger::DeviceEffectManager::onCreateAudioPatch(audio_patch_handle_t
            __func__, handle, patch.mHalHandle,
            patch.mAudioPatch.num_sinks > 0 ? patch.mAudioPatch.sinks[0].ext.device.type : 0);
    Mutex::Autolock _l(mLock);
    for (auto& effect : mDeviceEffects) {
        status_t status = effect.second->onCreatePatch(handle, &patch); // TODO(b/288339104) void*
    for (auto& effectProxies : mDeviceEffects) {
        for (auto& effect : effectProxies.second) {
            status_t status = effect->onCreatePatch(handle, &patch); // TODO(b/288339104) void*
            ALOGV("%s Effect onCreatePatch status %d", __func__, status);
            ALOGW_IF(status == BAD_VALUE, "%s onCreatePatch error %d", __func__, status);
        }
    }
}

void AudioFlinger::DeviceEffectManager::onReleaseAudioPatch(audio_patch_handle_t handle) {
    ALOGV("%s", __func__);
    Mutex::Autolock _l(mLock);
    for (auto& effect : mDeviceEffects) {
        effect.second->onReleasePatch(handle);
    for (auto& effectProxies : mDeviceEffects) {
        for (auto& effect : effectProxies.second) {
            effect->onReleasePatch(handle);
        }
    }
}

@@ -61,12 +65,15 @@ void AudioFlinger::DeviceEffectManager::onUpdateAudioPatch(audio_patch_handle_t
            __func__, oldHandle, newHandle, patch.mHalHandle,
            patch.mAudioPatch.num_sinks > 0 ? patch.mAudioPatch.sinks[0].ext.device.type : 0);
    Mutex::Autolock _l(mLock);
    for (auto& effect : mDeviceEffects) {
    for (auto& effectProxies : mDeviceEffects) {
        for (auto& effect : effectProxies.second) {
            // TODO(b/288339104) void*
        status_t status = effect.second->onUpdatePatch(oldHandle, newHandle, &patch);
            status_t status = effect->onUpdatePatch(oldHandle, newHandle, &patch);
            ALOGV("%s Effect onUpdatePatch status %d", __func__, status);
            ALOGW_IF(status != NO_ERROR, "%s onUpdatePatch error %d", __func__, status);
        }
    }
}

// DeviceEffectManager::createEffect_l() must be called with AudioFlinger::mLock held
sp<IAfEffectHandle> AudioFlinger::DeviceEffectManager::createEffect_l(
@@ -80,6 +87,7 @@ sp<IAfEffectHandle> AudioFlinger::DeviceEffectManager::createEffect_l(
        bool probe,
        bool notifyFramesProcessed) {
    sp<IAfDeviceEffectProxy> effect;
    std::vector<sp<IAfDeviceEffectProxy>> effectsForDevice = {};
    sp<IAfEffectHandle> handle;
    status_t lStatus;

@@ -93,11 +101,20 @@ sp<IAfEffectHandle> AudioFlinger::DeviceEffectManager::createEffect_l(
        Mutex::Autolock _l(mLock);
        auto iter = mDeviceEffects.find(device);
        if (iter != mDeviceEffects.end()) {
            effect = iter->second;
        } else {
            effectsForDevice = iter->second;
            for (const auto& iterEffect : effectsForDevice) {
                if (memcmp(&iterEffect->desc().uuid, &descriptor->uuid, sizeof(effect_uuid_t)) ==
                    0) {
                    effect = iterEffect;
                    break;
                }
            }
        }
        if (effect == nullptr) {
            effect = IAfDeviceEffectProxy::create(device, mMyCallback,
                    descriptor, mAudioFlinger.nextUniqueId(AUDIO_UNIQUE_ID_USE_EFFECT),
                    notifyFramesProcessed);
            effectsForDevice.push_back(effect);
        }
        // create effect handle and connect it to effect module
        handle = IAfEffectHandle::create(
@@ -111,7 +128,8 @@ sp<IAfEffectHandle> AudioFlinger::DeviceEffectManager::createEffect_l(
                    lStatus = NO_ERROR;
                }
                if (lStatus == NO_ERROR || lStatus == ALREADY_EXISTS) {
                    mDeviceEffects.emplace(device, effect);
                    mDeviceEffects.erase(device);
                    mDeviceEffects.emplace(device, effectsForDevice);
                }
            }
        }
@@ -177,8 +195,10 @@ NO_THREAD_SAFETY_ANALYSIS // conditional try lock
        String8 outStr;
        outStr.appendFormat("%*sEffect for device %s address %s:\n", 2, "",
                ::android::toString(iter.first.mType).c_str(), iter.first.getAddress());
        for (const auto& effect : iter.second) {
            write(fd, outStr.string(), outStr.size());
        iter.second->dump2(fd, 4);
            effect->dump2(fd, 4);
        }
    }

    if (locked) {
@@ -186,11 +206,23 @@ NO_THREAD_SAFETY_ANALYSIS // conditional try lock
    }
}


size_t AudioFlinger::DeviceEffectManager::removeEffect(const sp<IAfDeviceEffectProxy>& effect)
{
    Mutex::Autolock _l(mLock);
    const auto& iter = mDeviceEffects.find(effect->device());
    if (iter != mDeviceEffects.end()) {
        const auto& iterEffect = std::find_if(
                iter->second.begin(), iter->second.end(), [&effect](const auto& effectProxy) {
                    return memcmp(&effectProxy->desc().uuid, &effect->desc().uuid,
                            sizeof(effect_uuid_t)) == 0;
                });
        if (iterEffect != iter->second.end()) {
            iter->second.erase(iterEffect);
            if (iter->second.empty()) {
                mDeviceEffects.erase(effect->device());
            }
        }
    }
    return mDeviceEffects.size();
}

+1 −1
Original line number Diff line number Diff line
@@ -72,7 +72,7 @@ private:
    Mutex mLock;
    AudioFlinger &mAudioFlinger;
    const sp<DeviceEffectManagerCallback> mMyCallback;
    std::map<AudioDeviceTypeAddr, sp<IAfDeviceEffectProxy>> mDeviceEffects;
    std::map<AudioDeviceTypeAddr, std::vector<sp<IAfDeviceEffectProxy>>> mDeviceEffects;
};

public: // TODO(b/288339104) extract inner class.