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

Commit 04feef63 authored by Eric Laurent's avatar Eric Laurent Committed by Gerrit Code Review
Browse files

Merge "[AudioPolicyService] Add creation of DeviceEffects"

parents 5bebb2df 0618298c
Loading
Loading
Loading
Loading
+47 −1
Original line number Diff line number Diff line
@@ -42,7 +42,10 @@ namespace android {
AudioPolicyEffects::AudioPolicyEffects()
{
    status_t loadResult = loadAudioEffectXmlConfig();
    if (loadResult < 0) {
    if (loadResult == NO_ERROR) {
        mDefaultDeviceEffectFuture = std::async(
                    std::launch::async, &AudioPolicyEffects::initDefaultDeviceEffects, this);
    } else if (loadResult < 0) {
        ALOGW("Failed to load XML effect configuration, fallback to .conf");
        // load automatic audio effect modules
        if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE, R_OK) == 0) {
@@ -908,8 +911,24 @@ status_t AudioPolicyEffects::loadAudioEffectXmlConfig() {
            streams.add(stream.type, effectDescs.release());
        }
    };

    auto loadDeviceProcessingChain = [](auto &processingChain, auto& devicesEffects) {
        for (auto& deviceProcess : processingChain) {

            auto effectDescs = std::make_unique<EffectDescVector>();
            for (auto& effect : deviceProcess.effects) {
                effectDescs->mEffects.add(
                        new EffectDesc{effect.get().name.c_str(), effect.get().uuid});
            }
            auto deviceEffects = std::make_unique<DeviceEffects>(
                        std::move(effectDescs), deviceProcess.type, deviceProcess.address);
            devicesEffects.emplace(deviceProcess.address, std::move(deviceEffects));
        }
    };

    loadProcessingChain(result.parsedConfig->preprocess, mInputSources);
    loadProcessingChain(result.parsedConfig->postprocess, mOutputStreams);
    loadDeviceProcessingChain(result.parsedConfig->deviceprocess, mDeviceEffects);
    // Casting from ssize_t to status_t is probably safe, there should not be more than 2^31 errors
    return result.nbSkippedElement;
}
@@ -942,5 +961,32 @@ status_t AudioPolicyEffects::loadAudioEffectConfig(const char *path)
    return NO_ERROR;
}

void AudioPolicyEffects::initDefaultDeviceEffects()
{
    Mutex::Autolock _l(mLock);
    for (const auto& deviceEffectsIter : mDeviceEffects) {
        const auto& deviceEffects =  deviceEffectsIter.second;
        for (const auto& effectDesc : deviceEffects->mEffectDescriptors->mEffects) {
            auto fx = std::make_unique<AudioEffect>(
                        EFFECT_UUID_NULL, String16("android"), &effectDesc->mUuid, 0, nullptr,
                        nullptr, AUDIO_SESSION_DEVICE, AUDIO_IO_HANDLE_NONE,
                        AudioDeviceTypeAddr{deviceEffects->getDeviceType(),
                                            deviceEffects->getDeviceAddress()});
            status_t status = fx->initCheck();
            if (status != NO_ERROR && status != ALREADY_EXISTS) {
                ALOGE("%s(): failed to create Fx %s on port type=%d address=%s", __func__,
                      effectDesc->mName, deviceEffects->getDeviceType(),
                      deviceEffects->getDeviceAddress().c_str());
                // fx goes out of scope and strong ref on AudioEffect is released
                continue;
            }
            fx->setEnabled(true);
            ALOGV("%s(): create Fx %s added on port type=%d address=%s", __func__,
                  effectDesc->mName, deviceEffects->getDeviceType(),
                  deviceEffects->getDeviceAddress().c_str());
            deviceEffects->mEffects.push_back(std::move(fx));
        }
    }
}

} // namespace android
+39 −0
Original line number Diff line number Diff line
@@ -25,6 +25,9 @@
#include <system/audio.h>
#include <utils/Vector.h>
#include <utils/SortedVector.h>
#include <android-base/thread_annotations.h>

#include <future>

namespace android {

@@ -104,6 +107,7 @@ public:
    status_t removeStreamDefaultEffect(audio_unique_id_t id);

private:
    void initDefaultDeviceEffects();

    // class to store the description of an effects and its parameters
    // as defined in audio_effects.conf
@@ -192,6 +196,28 @@ private:
        Vector< sp<AudioEffect> >mEffects;
    };

    /**
     * @brief The DeviceEffects class stores the effects associated to a given Device Port.
     */
    class DeviceEffects {
    public:
        explicit DeviceEffects(std::unique_ptr<EffectDescVector> effectDescriptors,
                               audio_devices_t device, const std::string& address) :
            mEffectDescriptors(std::move(effectDescriptors)),
            mDeviceType(device), mDeviceAddress(address) {}
        /*virtual*/ ~DeviceEffects() = default;

        std::vector<std::unique_ptr<AudioEffect>> mEffects;
        audio_devices_t getDeviceType() const { return mDeviceType; }
        std::string getDeviceAddress() const { return mDeviceAddress; }
        const std::unique_ptr<EffectDescVector> mEffectDescriptors;

    private:
        const audio_devices_t mDeviceType;
        const std::string mDeviceAddress;

    };


    static const char * const kInputSourceNames[AUDIO_SOURCE_CNT -1];
    static audio_source_t inputSourceNameToEnum(const char *name);
@@ -237,6 +263,19 @@ private:
    KeyedVector< audio_stream_type_t, EffectDescVector* > mOutputStreams;
    // Automatic output effects are unique for audiosession ID
    KeyedVector< audio_session_t, EffectVector* > mOutputSessions;

    /**
     * @brief mDeviceEffects map of device effects indexed by the device address
     */
    std::map<std::string, std::unique_ptr<DeviceEffects>> mDeviceEffects GUARDED_BY(mLock);

    /**
     * Device Effect initialization must be asynchronous: the audio_policy service parses and init
     * effect on first reference. AudioFlinger will handle effect creation and register these
     * effect on audio_policy service.
     * We must store the reference of the furture garantee real asynchronous operation.
     */
    std::future<void> mDefaultDeviceEffectFuture;
};

} // namespace android