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

Commit 4a3d5c23 authored by Mikhail Naganov's avatar Mikhail Naganov
Browse files

Abstract away access to audio effects HAL and factory

In this CL all direct calls to functions from EffectsFactoryApi.h
and hardware/audio_effect.h are encapsulated within two new
classes: EffectsFactoryHalLocal and EffectHalLocal. AudioFlinger
uses interface classes EffectsFactoryHalInterface and
EffectHalInterface to access these functions.

Bug: 30222631
Change-Id: Id64b9c5529319077f6f968921489a13f60daa977
parent ecb00813
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -28,6 +28,8 @@ LOCAL_SRC_FILES:= \
    AudioHwDevice.cpp           \
    AudioStreamOut.cpp          \
    SpdifStreamOut.cpp          \
    EffectHalLocal.cpp          \
    EffectsFactoryHalLocal.cpp	\
    Effects.cpp                 \
    AudioMixer.cpp.arm          \
    BufferProviders.cpp         \
+40 −12
Original line number Diff line number Diff line
@@ -44,11 +44,11 @@

#include "AudioMixer.h"
#include "AudioFlinger.h"
#include "EffectsFactoryHalInterface.h"
#include "ServiceUtilities.h"

#include <media/AudioResamplerPublic.h>

#include <media/EffectsFactoryApi.h>
#include <audio_effects/effect_visualizer.h>
#include <audio_effects/effect_ns.h>
#include <audio_effects/effect_aec.h>
@@ -85,6 +85,7 @@ namespace android {
static const char kDeadlockedString[] = "AudioFlinger may be deadlocked\n";
static const char kHardwareLockedString[] = "Hardware lock is taken\n";
static const char kClientLockedString[] = "Client lock is taken\n";
static const char kNoEffectsFactory[] = "Effects Factory is absent\n";


nsecs_t AudioFlinger::mStandbyTimeInNsecs = kDefaultStandbyTimeInNsecs;
@@ -205,6 +206,8 @@ AudioFlinger::AudioFlinger()
    // in bad state, reset the state upon service start.
    BatteryNotifier::getInstance().noteResetAudio();

    mEffectsFactoryHal = EffectsFactoryHalInterface::create();

#ifdef TEE_SINK
    char value[PROPERTY_VALUE_MAX];
    (void) property_get("ro.debuggable", value, "0");
@@ -422,7 +425,12 @@ status_t AudioFlinger::dump(int fd, const Vector<String16>& args)
            write(fd, result.string(), result.size());
        }

        EffectDumpEffects(fd);
        if (mEffectsFactoryHal.get() != NULL) {
            mEffectsFactoryHal->dumpEffects(fd);
        } else {
            String8 result(kNoEffectsFactory);
            write(fd, result.string(), result.size());
        }

        dumpClients(fd, args);
        if (clientLocked) {
@@ -2593,24 +2601,39 @@ sp<AudioFlinger::SyncEvent> AudioFlinger::createSyncEvent(AudioSystem::sync_even
//  Effect management
// ----------------------------------------------------------------------------

sp<EffectsFactoryHalInterface> AudioFlinger::getEffectsFactory() {
    return mEffectsFactoryHal;
}

status_t AudioFlinger::queryNumberEffects(uint32_t *numEffects) const
{
    Mutex::Autolock _l(mLock);
    return EffectQueryNumberEffects(numEffects);
    if (mEffectsFactoryHal.get()) {
        return mEffectsFactoryHal->queryNumberEffects(numEffects);
    } else {
        return -ENODEV;
    }
}

status_t AudioFlinger::queryEffect(uint32_t index, effect_descriptor_t *descriptor) const
{
    Mutex::Autolock _l(mLock);
    return EffectQueryEffect(index, descriptor);
    if (mEffectsFactoryHal.get()) {
        return mEffectsFactoryHal->getDescriptor(index, descriptor);
    } else {
        return -ENODEV;
    }
}

status_t AudioFlinger::getEffectDescriptor(const effect_uuid_t *pUuid,
        effect_descriptor_t *descriptor) const
{
    Mutex::Autolock _l(mLock);
    return EffectGetDescriptor(pUuid, descriptor);
    if (mEffectsFactoryHal.get()) {
        return mEffectsFactoryHal->getDescriptor(pUuid, descriptor);
    } else {
        return -ENODEV;
    }
}


@@ -2630,8 +2653,8 @@ sp<IEffect> AudioFlinger::createEffect(
    effect_descriptor_t desc;

    pid_t pid = IPCThreadState::self()->getCallingPid();
    ALOGV("createEffect pid %d, effectClient %p, priority %d, sessionId %d, io %d",
            pid, effectClient.get(), priority, sessionId, io);
    ALOGV("createEffect pid %d, effectClient %p, priority %d, sessionId %d, io %d, factory %p",
            pid, effectClient.get(), priority, sessionId, io, mEffectsFactoryHal.get());

    if (pDesc == NULL) {
        lStatus = BAD_VALUE;
@@ -2651,10 +2674,15 @@ sp<IEffect> AudioFlinger::createEffect(
        goto Exit;
    }

    if (mEffectsFactoryHal.get() == NULL) {
        lStatus = NO_INIT;
        goto Exit;
    }

    {
        if (!EffectIsNullUuid(&pDesc->uuid)) {
        if (!EffectsFactoryHalInterface::isNullUuid(&pDesc->uuid)) {
            // if uuid is specified, request effect descriptor
            lStatus = EffectGetDescriptor(&pDesc->uuid, &desc);
            lStatus = mEffectsFactoryHal->getDescriptor(&pDesc->uuid, &desc);
            if (lStatus < 0) {
                ALOGW("createEffect() error %d from EffectGetDescriptor", lStatus);
                goto Exit;
@@ -2662,7 +2690,7 @@ sp<IEffect> AudioFlinger::createEffect(
        } else {
            // if uuid is not specified, look for an available implementation
            // of the required type in effect factory
            if (EffectIsNullUuid(&pDesc->type)) {
            if (EffectsFactoryHalInterface::isNullUuid(&pDesc->type)) {
                ALOGW("createEffect() no effect type");
                lStatus = BAD_VALUE;
                goto Exit;
@@ -2672,13 +2700,13 @@ sp<IEffect> AudioFlinger::createEffect(
            d.flags = 0; // prevent compiler warning
            bool found = false;

            lStatus = EffectQueryNumberEffects(&numEffects);
            lStatus = mEffectsFactoryHal->queryNumberEffects(&numEffects);
            if (lStatus < 0) {
                ALOGW("createEffect() error %d from EffectQueryNumberEffects", lStatus);
                goto Exit;
            }
            for (uint32_t i = 0; i < numEffects; i++) {
                lStatus = EffectQueryEffect(i, &desc);
                lStatus = mEffectsFactoryHal->getDescriptor(i, &desc);
                if (lStatus < 0) {
                    ALOGW("createEffect() error %d from EffectQueryEffect", lStatus);
                    continue;
+3 −0
Original line number Diff line number Diff line
@@ -72,6 +72,7 @@ struct effect_param_cblk_t;
class AudioMixer;
class AudioBuffer;
class AudioResampler;
class EffectsFactoryHalInterface;
class FastMixer;
class PassthruBufferProvider;
class ServerProxy;
@@ -272,6 +273,7 @@ public:

    sp<NBLog::Writer>   newWriter_l(size_t size, const char *name);
    void                unregisterWriter(const sp<NBLog::Writer>& writer);
    sp<EffectsFactoryHalInterface> getEffectsFactory();
private:
    static const size_t kLogMemorySize = 40 * 1024;
    sp<MemoryDealer>    mLogMemoryDealer;   // == 0 when NBLog is disabled
@@ -762,6 +764,7 @@ private:
    nsecs_t mGlobalEffectEnableTime;  // when a global effect was last enabled

    sp<PatchPanel> mPatchPanel;
    sp<EffectsFactoryHalInterface> mEffectsFactoryHal;

    bool        mSystemReady;
};
+34 −21
Original line number Diff line number Diff line
@@ -21,12 +21,13 @@
#include <audio_utils/primitives.h>
#include <audio_utils/format.h>
#include <media/AudioResamplerPublic.h>
#include <media/EffectsFactoryApi.h>

#include <utils/Log.h>

#include "Configuration.h"
#include "BufferProviders.h"
#include "EffectHalInterface.h"
#include "EffectsFactoryHalInterface.h"

#ifndef ARRAY_SIZE
#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
@@ -145,13 +146,22 @@ DownmixerBufferProvider::DownmixerBufferProvider(
    ALOGV("DownmixerBufferProvider(%p)(%#x, %#x, %#x %u %d)",
            this, inputChannelMask, outputChannelMask, format,
            sampleRate, sessionId);
    if (!sIsMultichannelCapable
            || EffectCreate(&sDwnmFxDesc.uuid,
    if (!sIsMultichannelCapable) {
        ALOGE("DownmixerBufferProvider() error: not multichannel capable");
        return;
    }
    mEffectsFactory = EffectsFactoryHalInterface::create();
    if (mEffectsFactory.get() == NULL) {
        ALOGE("DownmixerBufferProvider() error: could not obtain the effects factory");
        return;
    }
    if (mEffectsFactory->createEffect(&sDwnmFxDesc.uuid,
                                      sessionId,
                                      SESSION_ID_INVALID_AND_IGNORED,
                    &mDownmixHandle) != 0) {
                                      &mDownmixInterface) != 0) {
         ALOGE("DownmixerBufferProvider() error creating downmixer effect");
         mDownmixHandle = NULL;
         mDownmixInterface.clear();
         mEffectsFactory.clear();
         return;
     }
     // channel input configuration will be overridden per-track
@@ -173,28 +183,28 @@ DownmixerBufferProvider::DownmixerBufferProvider(
     uint32_t replySize = sizeof(int);

     // Configure downmixer
     status_t status = (*mDownmixHandle)->command(mDownmixHandle,
     status_t status = mDownmixInterface->command(
             EFFECT_CMD_SET_CONFIG /*cmdCode*/, sizeof(effect_config_t) /*cmdSize*/,
             &mDownmixConfig /*pCmdData*/,
             &replySize, &cmdStatus /*pReplyData*/);
     if (status != 0 || cmdStatus != 0) {
         ALOGE("DownmixerBufferProvider() error %d cmdStatus %d while configuring downmixer",
                 status, cmdStatus);
         EffectRelease(mDownmixHandle);
         mDownmixHandle = NULL;
         mDownmixInterface.clear();
         mEffectsFactory.clear();
         return;
     }

     // Enable downmixer
     replySize = sizeof(int);
     status = (*mDownmixHandle)->command(mDownmixHandle,
     status = mDownmixInterface->command(
             EFFECT_CMD_ENABLE /*cmdCode*/, 0 /*cmdSize*/, NULL /*pCmdData*/,
             &replySize, &cmdStatus /*pReplyData*/);
     if (status != 0 || cmdStatus != 0) {
         ALOGE("DownmixerBufferProvider() error %d cmdStatus %d while enabling downmixer",
                 status, cmdStatus);
         EffectRelease(mDownmixHandle);
         mDownmixHandle = NULL;
         mDownmixInterface.clear();
         mEffectsFactory.clear();
         return;
     }

@@ -211,15 +221,15 @@ DownmixerBufferProvider::DownmixerBufferProvider(
     param->vsize = sizeof(downmix_type_t);
     memcpy(param->data + psizePadded, &downmixType, param->vsize);
     replySize = sizeof(int);
     status = (*mDownmixHandle)->command(mDownmixHandle,
     status = mDownmixInterface->command(
             EFFECT_CMD_SET_PARAM /* cmdCode */, downmixParamSize /* cmdSize */,
             param /*pCmdData*/, &replySize, &cmdStatus /*pReplyData*/);
     free(param);
     if (status != 0 || cmdStatus != 0) {
         ALOGE("DownmixerBufferProvider() error %d cmdStatus %d while setting downmix type",
                 status, cmdStatus);
         EffectRelease(mDownmixHandle);
         mDownmixHandle = NULL;
         mDownmixInterface.clear();
         mEffectsFactory.clear();
         return;
     }
     ALOGV("DownmixerBufferProvider() downmix type set to %d", (int) downmixType);
@@ -228,8 +238,6 @@ DownmixerBufferProvider::DownmixerBufferProvider(
DownmixerBufferProvider::~DownmixerBufferProvider()
{
    ALOGV("~DownmixerBufferProvider (%p)", this);
    EffectRelease(mDownmixHandle);
    mDownmixHandle = NULL;
}

void DownmixerBufferProvider::copyFrames(void *dst, const void *src, size_t frames)
@@ -239,7 +247,7 @@ void DownmixerBufferProvider::copyFrames(void *dst, const void *src, size_t fram
    mDownmixConfig.outputCfg.buffer.frameCount = frames;
    mDownmixConfig.outputCfg.buffer.raw = dst;
    // may be in-place if src == dst.
    status_t res = (*mDownmixHandle)->process(mDownmixHandle,
    status_t res = mDownmixInterface->process(
            &mDownmixConfig.inputCfg.buffer, &mDownmixConfig.outputCfg.buffer);
    ALOGE_IF(res != OK, "DownmixBufferProvider error %d", res);
}
@@ -248,8 +256,13 @@ void DownmixerBufferProvider::copyFrames(void *dst, const void *src, size_t fram
/*static*/ status_t DownmixerBufferProvider::init()
{
    // find multichannel downmix effect if we have to play multichannel content
    sp<EffectsFactoryHalInterface> effectsFactory = EffectsFactoryHalInterface::create();
    if (effectsFactory.get() == NULL) {
        ALOGE("AudioMixer() error: could not obtain the effects factory");
        return NO_INIT;
    }
    uint32_t numEffects = 0;
    int ret = EffectQueryNumberEffects(&numEffects);
    int ret = effectsFactory->queryNumberEffects(&numEffects);
    if (ret != 0) {
        ALOGE("AudioMixer() error %d querying number of effects", ret);
        return NO_INIT;
@@ -257,7 +270,7 @@ void DownmixerBufferProvider::copyFrames(void *dst, const void *src, size_t fram
    ALOGV("EffectQueryNumberEffects() numEffects=%d", numEffects);

    for (uint32_t i = 0 ; i < numEffects ; i++) {
        if (EffectQueryEffect(i, &sDwnmFxDesc) == 0) {
        if (effectsFactory->getDescriptor(i, &sDwnmFxDesc) == 0) {
            ALOGV("effect %d is called %s", i, sDwnmFxDesc.name);
            if (memcmp(&sDwnmFxDesc.type, EFFECT_UIID_DOWNMIX, sizeof(effect_uuid_t)) == 0) {
                ALOGI("found effect \"%s\" from %s",
+7 −2
Original line number Diff line number Diff line
@@ -24,9 +24,13 @@
#include <media/AudioBufferProvider.h>
#include <system/audio.h>
#include <sonic.h>
#include <utils/StrongPointer.h>

namespace android {

class EffectHalInterface;
class EffectsFactoryHalInterface;

// ----------------------------------------------------------------------------

class PassthruBufferProvider : public AudioBufferProvider {
@@ -97,12 +101,13 @@ public:
    //Overrides
    virtual void copyFrames(void *dst, const void *src, size_t frames);

    bool isValid() const { return mDownmixHandle != NULL; }
    bool isValid() const { return mDownmixInterface.get() != NULL; }
    static status_t init();
    static bool isMultichannelCapable() { return sIsMultichannelCapable; }

protected:
    effect_handle_t    mDownmixHandle;
    sp<EffectsFactoryHalInterface> mEffectsFactory;
    sp<EffectHalInterface> mDownmixInterface;
    effect_config_t    mDownmixConfig;

    // effect descriptor for the downmixer used by the mixer
Loading