/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <errno.h>
#include <fcntl.h>

#define LOG_TAG "eS305VoiceProcessing"
//#define LOG_NDEBUG 0
#include <cutils/log.h>

#include "eS305VoiceProcessing.h"
#include <audio_effects/effect_aec.h>
#include <audio_effects/effect_ns.h>
#include <audio_effects/effect_agc.h>

extern "C" {

//------------------------------------------------------------------------------
// local definitions
//------------------------------------------------------------------------------

// number of sessions this effect bundle can be used for
#define ADNC_PFX_NUM_SESSION 8

// types of pre processing modules
enum adnc_pfx_id
{
    PFX_ID_AEC = 0,  // Acoustic Echo Cancellation
    PFX_ID_NS,       // Noise Suppression
    PFX_ID_AGC,      // Automatic Gain Control
    PFX_ID_CNT
};

// Session state
enum adnc_pfx_session_state {
    PFX_SESSION_STATE_INIT,        // initialized
    PFX_SESSION_STATE_CONFIG       // configuration received
};

// Effect/Preprocessor state
enum adnc_pfx_effect_state {
    PFX_EFFECT_STATE_INIT,         // initialized
    PFX_EFFECT_STATE_CREATED,      // effect created
    PFX_EFFECT_STATE_CONFIG,       // configuration received/disabled
    PFX_EFFECT_STATE_ACTIVE        // active/enabled
};

typedef struct adnc_pfx_session_s adnc_pfx_session_t;
typedef struct adnc_pfx_effect_s  adnc_pfx_effect_t;
typedef struct adnc_pfx_ops_s     adnc_pfx_ops_t;

// Effect operation table. Functions for all pre processors are declared in sPreProcOps[] table.
// Function pointer can be null if no action required.
struct adnc_pfx_ops_s {
    int (* create)(adnc_pfx_effect_t *fx);
    int (* init)(adnc_pfx_effect_t *fx);
    int (* reset)(adnc_pfx_effect_t *fx);
    void (* enable)(adnc_pfx_effect_t *fx);
    void (* disable)(adnc_pfx_effect_t *fx);
    int (* set_parameter)(adnc_pfx_effect_t *fx, void *param, void *value);
    int (* get_parameter)(adnc_pfx_effect_t *fx, void *param, size_t *size, void *value);
    int (* set_device)(adnc_pfx_effect_t *fx, uint32_t device);
};

// Effect context
struct adnc_pfx_effect_s {
    const struct effect_interface_s *itfe;
    uint32_t procId;                // type of pre processor (enum adnc_pfx_id)
    uint32_t state;                 // current state (enum adnc_pfx_effect_state)
    adnc_pfx_session_t *session;     // session the effect is on
    const adnc_pfx_ops_t *ops;       // effect ops table
};

// Session context
struct adnc_pfx_session_s {
    uint32_t state;                     // current state (enum adnc_pfx_session_state)
    audio_source_t audioSource;
    // FIXME not used, delete?
    //int audioSessionId;             // audio session ID
    int ioHandle;                     // handle of input stream this session is on
    uint32_t createdMsk;              // bit field containing IDs of created pre processors
    uint32_t activeMsk;               // bit field containing IDs of pre processors currently active
    struct adnc_pfx_effect_s effects[PFX_ID_CNT]; // effects in this session

    // effect settings
    //   none controllable from public API here
};

//-----------------------------------------
// forward declarations
//-----------------------------------------
int Adnc_SetNoiseSuppressionInt_l(bool);
int Adnc_SetAutomaticGainControlInt_l(bool);
int Adnc_SetEchoCancellationInt_l(bool);
int Adnc_ReevaluateUsageInt_l(audio_io_handle_t);
int Adnc_SleepInt_l();

//------------------------------------------------------------------------------
// eS305 control
//------------------------------------------------------------------------------
#define ES305_SYSFS_PATH "/sys/class/i2c-dev/i2c-4/device/4-003e/"
#define ES305_VOICE_PROCESSING_PATH ES305_SYSFS_PATH "voice_processing"
#define ES305_PRESET_PATH           ES305_SYSFS_PATH "preset"
#define ES305_TX_NS_LEVEL_PATH      ES305_SYSFS_PATH "tx_ns_level"
#define ES305_TX_AGC_ENABLE_PATH    ES305_SYSFS_PATH "tx_agc_enable"
#define ES305_AEC_ENABLE_PATH       ES305_SYSFS_PATH "aec_enable"
#define ES305_SLEEP_PATH            ES305_SYSFS_PATH "sleep"

enum eS305_controls {
    ES305_CTRL_VOICE_PROCESSING = 0,
    ES305_CTRL_PRESET,
    ES305_CTRL_TX_NS_LEVEL,
    ES305_CTRL_TX_AGC_ENABLE,
    ES305_CTRL_AEC_ENABLE,
    ES305_CTRL_SLEEP,
    ES305_NUM_CTRL
};

struct eS305_ctrl_s {
    int fd[ES305_NUM_CTRL];
    int current_preset;
    int requested_preset;
    int ioHandle;
};
typedef struct eS305_ctrl_s eS305_ctrl_t;

static eS305_ctrl_t eS305_ctrl = {
        { -1/*vp*/, -1/*preset*/, -1/*ns*/, -1/*agc*/, -1/*aec*/, -1/*sleep*/},
        ES305_PRESET_OFF  /*current_preset*/,
        ES305_PRESET_INIT /*requested_preset, an invalid preset, different from current_preset*/,
        ES305_IO_HANDLE_NONE
};

//------------------------------------------------------------------------------
// Effect descriptors
//------------------------------------------------------------------------------

// UUIDs for effect types have been generated from http://www.itu.int/ITU-T/asn1/uuid.html
// as the pre processing effects are not defined by OpenSL ES

// Acoustic Echo Cancellation
static const effect_descriptor_t aec_descriptor = {
        FX_IID_AEC_, // type
        { 0xfd90ff00, 0x0b55, 0x11e2, 0x892e, { 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66 } }, // uuid
        EFFECT_CONTROL_API_VERSION,
        (EFFECT_FLAG_TYPE_PRE_PROC|EFFECT_FLAG_DEVICE_IND),
        0, //FIXME indicate CPU load
        0, //FIXME indicate memory usage
        "Acoustic Echo Canceler",
        "Audience"
};

// Noise suppression
static const effect_descriptor_t ns_descriptor = {
        FX_IID_NS_, // type
        { 0x08fa98b0, 0x0b56, 0x11e2, 0x892e, { 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66 } }, // uuid
        EFFECT_CONTROL_API_VERSION,
        (EFFECT_FLAG_TYPE_PRE_PROC|EFFECT_FLAG_DEVICE_IND),
        0, //FIXME indicate CPU load
        0, //FIXME indicate memory usage
        "Noise Suppression",
        "Audience"
};

// Automatic Gain Control
static const effect_descriptor_t agc_descriptor = {
        FX_IID_AGC_, // type
        { 0xe9e87eb0, 0x0b55, 0x11e2, 0x892e, { 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66 } }, // uuid
        EFFECT_CONTROL_API_VERSION,
        (EFFECT_FLAG_TYPE_PRE_PROC|EFFECT_FLAG_DEVICE_IND),
        0, //FIXME indicate CPU load
        0, //FIXME indicate memory usage
        "Automatic Gain Control",
        "Audience"
};

static const effect_descriptor_t *adnc_pfx_descriptors[PFX_ID_CNT] = {
        &aec_descriptor,
        &ns_descriptor,
        &agc_descriptor
};


//------------------------------------------------------------------------------
// Helper functions
//------------------------------------------------------------------------------
static const effect_uuid_t * const sAdncUuidTable[PFX_ID_CNT] = {
        FX_IID_AEC,
        FX_IID_NS,
        FX_IID_AGC
};

const effect_uuid_t * Adnc_ProcIdToUuid(int procId)
{
    if (procId >= PFX_ID_CNT) {
        return EFFECT_UUID_NULL;
    }
    return sAdncUuidTable[procId];
}

uint32_t Adnc_UuidToProcId(const effect_uuid_t * uuid)
{
    size_t i;
    for (i = 0; i < PFX_ID_CNT; i++) {
        if (memcmp(uuid, sAdncUuidTable[i], sizeof(*uuid)) == 0) {
            break;
        }
    }
    return i;
}


//------------------------------------------------------------------------------
// Acoustic Echo Canceler (AEC)
//------------------------------------------------------------------------------
int aec_init (adnc_pfx_effect_t *effect)
{
    ALOGV("aec_init [noop]");
    return 0;
}

int aec_create(adnc_pfx_effect_t *effect)
{
    ALOGV("aec_create [noop]");
    return aec_init (effect);
}

int aec_reset(adnc_pfx_effect_t *effect)
{
    ALOGV("aec_reset [noop]");
    return 0;
}

int aec_get_parameter(adnc_pfx_effect_t     *effect,
                    void              *pParam,
                    size_t            *pValueSize,
                    void              *pValue)
{
    int status = 0;
    uint32_t param = *(uint32_t *)pParam;

    if (*pValueSize < sizeof(uint32_t)) {
        return -EINVAL;
    }
    /* NOT SUPPORTED
    switch (param) {
    case AEC_PARAM_ECHO_DELAY:
    case AEC_PARAM_PROPERTIES:
        break;
    default:
        ALOGW("aec_get_parameter() unknown param %08x value %08x", param, *(uint32_t *)pValue);
        status = -EINVAL;
        break;
    }
    return status;
    */
    return -EINVAL;
}

int aec_set_parameter (adnc_pfx_effect_t *effect, void *pParam, void *pValue)
{
    int status = 0;
    uint32_t param = *(uint32_t *)pParam;
    uint32_t value = *(uint32_t *)pValue;

    /* NOT SUPPORTED
    switch (param) {
    case AEC_PARAM_ECHO_DELAY:
    case AEC_PARAM_PROPERTIES:
        ALOGV("aec_setParameter() echo delay %d us, status %d", value, status);
        break;
    default:
        ALOGW("aec_setParameter() unknown param %08x value %08x", param, *(uint32_t *)pValue);
        status = -EINVAL;
        break;
    }
    */
    return status;
}

void aec_enable(adnc_pfx_effect_t *effect)
{
    ALOGV("aec_enable [noop]");
}

void aec_disable(adnc_pfx_effect_t *effect)
{
    ALOGV("aec_disable [noop]");
}

int aec_set_device(adnc_pfx_effect_t *effect, uint32_t device)
{
    ALOGV("aec_set_device(device=%08x) [noop]", device);

    /*
    switch(device) {
    case AUDIO_DEVICE_OUT_EARPIECE:
        break;
    case AUDIO_DEVICE_OUT_SPEAKER:
        break;
    case AUDIO_DEVICE_OUT_WIRED_HEADSET:
    case AUDIO_DEVICE_OUT_WIRED_HEADPHONE:
    default:
        break;
    }
    */

    return 0;
}

static const adnc_pfx_ops_t aec_ops = {
        aec_create,
        aec_init,
        aec_reset,
        aec_enable,
        aec_disable,
        aec_set_parameter,
        aec_get_parameter,
        aec_set_device,
};


//------------------------------------------------------------------------------
// Noise Suppression (NS)
//------------------------------------------------------------------------------
int ns_init (adnc_pfx_effect_t *effect)
{
    ALOGV("ns_init [noop]");

    return 0;
}

int ns_create(adnc_pfx_effect_t *effect)
{
    ALOGV("ns_create %p", effect);

    return ns_init (effect);
}

int ns_get_parameter(adnc_pfx_effect_t     *effect,
                   void              *pParam,
                   size_t            *pValueSize,
                   void              *pValue)
{
    int status = 0;
    return status;
}

int ns_set_parameter(adnc_pfx_effect_t *effect, void *pParam, void *pValue)
{
    int status = 0;
    return status;
}

void ns_enable(adnc_pfx_effect_t *effect)
{
    ALOGV("ns_enable [noop]");
}

void ns_disable(adnc_pfx_effect_t *effect)
{
    ALOGV("ns_disable [noop]");
}

static const adnc_pfx_ops_t ns_ops = {
        ns_create,
        ns_init,
        NULL,
        ns_enable,
        ns_disable,
        ns_set_parameter,
        ns_get_parameter,
        NULL,
};


//------------------------------------------------------------------------------
// Automatic Gain Control (AGC)
//------------------------------------------------------------------------------
int agc_init (adnc_pfx_effect_t *effect)
{
    ALOGV("agc_init  [noop]");

    return 0;
}

int agc_create(adnc_pfx_effect_t *effect)
{
    ALOGV("agc_create %p", effect);

    return agc_init (effect);
}

int agc_get_parameter(adnc_pfx_effect_t     *effect,
                   void              *pParam,
                   size_t            *pValueSize,
                   void              *pValue)
{
    int status = 0;
    return status;
}

int agc_set_parameter(adnc_pfx_effect_t *effect, void *pParam, void *pValue)
{
    int status = 0;
    return status;
}

void agc_enable(adnc_pfx_effect_t *effect)
{
    ALOGV("agc_enable [noop]");
}

void agc_disable(adnc_pfx_effect_t *effect)
{
    ALOGV("agc_disable [noop]");
}

static const adnc_pfx_ops_t agc_ops = {
        agc_create,
        agc_init,
        NULL,
        agc_enable,
        agc_disable,
        agc_set_parameter,
        agc_get_parameter,
        NULL,
};

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
static const adnc_pfx_ops_t *sPreProcOps[PFX_ID_CNT] = {
        &aec_ops,
        &ns_ops,
        &agc_ops
};

//------------------------------------------------------------------------------
// Pre-processing effect functions
//------------------------------------------------------------------------------
extern const struct effect_interface_s sEffectInterface;

#define BAD_STATE_ABORT(from, to) \
        LOG_ALWAYS_FATAL("Bad state transition from %d to %d", from, to);

void AdncSession_SetProcEnabled(adnc_pfx_session_t *session, uint32_t procId, bool enabled);

int AdncPreProFx_SetState(adnc_pfx_effect_t *effect, uint32_t state)
{
    int status = 0;
    ALOGV("AdncPreProFx_SetState procId %d, new %d old %d", effect->procId, state, effect->state);
    switch(state) {
    case PFX_EFFECT_STATE_INIT:
        switch(effect->state) {
        case PFX_EFFECT_STATE_ACTIVE:
            effect->ops->disable(effect);
            AdncSession_SetProcEnabled(effect->session, effect->procId, false);
        case PFX_EFFECT_STATE_CONFIG:
        case PFX_EFFECT_STATE_CREATED:
        case PFX_EFFECT_STATE_INIT:
            break;
        default:
            BAD_STATE_ABORT(effect->state, state);
        }
        break;
    case PFX_EFFECT_STATE_CREATED:
        switch(effect->state) {
        case PFX_EFFECT_STATE_INIT:
            status = effect->ops->create(effect);
            break;
        case PFX_EFFECT_STATE_CREATED:
        case PFX_EFFECT_STATE_ACTIVE:
        case PFX_EFFECT_STATE_CONFIG:
            ALOGE("Effect_SetState invalid transition");
            status = -ENOSYS;
            break;
        default:
            BAD_STATE_ABORT(effect->state, state);
        }
        break;
    case PFX_EFFECT_STATE_CONFIG:
        switch(effect->state) {
        case PFX_EFFECT_STATE_INIT:
            ALOGE("Effect_SetState invalid transition");
            status = -ENOSYS;
            break;
        case PFX_EFFECT_STATE_ACTIVE:
            effect->ops->disable(effect);
            AdncSession_SetProcEnabled(effect->session, effect->procId, false);
            break;
        case PFX_EFFECT_STATE_CREATED:
        case PFX_EFFECT_STATE_CONFIG:
            break;
        default:
            BAD_STATE_ABORT(effect->state, state);
        }
        break;
    case PFX_EFFECT_STATE_ACTIVE:
        switch(effect->state) {
        case PFX_EFFECT_STATE_INIT:
        case PFX_EFFECT_STATE_CREATED:
            ALOGE("Effect_SetState invalid transition");
            status = -ENOSYS;
            break;
        case PFX_EFFECT_STATE_ACTIVE:
            // enabling an already enabled effect is just ignored
            break;
        case PFX_EFFECT_STATE_CONFIG:
            effect->ops->enable(effect);
            AdncSession_SetProcEnabled(effect->session, effect->procId, true);
            break;
        default:
            BAD_STATE_ABORT(effect->state, state);
        }
        break;
    default:
        BAD_STATE_ABORT(effect->state, state);
    }
    if (status == 0) {
        effect->state = state;
    }
    return status;
}

int AdncPreProFx_Init(adnc_pfx_effect_t *effect, uint32_t procId)
{
    ALOGV(" AdncPreProFx_Init(procId=%d)", procId);
    effect->itfe = &sEffectInterface;
    effect->ops = sPreProcOps[procId];
    effect->procId = procId;
    effect->state = PFX_EFFECT_STATE_INIT;
    return 0;
}

int AdncPreProFx_Create(adnc_pfx_effect_t *effect,
               adnc_pfx_session_t *session,
               effect_handle_t  *interface)
{
    ALOGV(" AdncPreProFx_Create(effect=%p)", effect);
    effect->session = session;
    *interface = (effect_handle_t)&effect->itfe;
    return AdncPreProFx_SetState(effect, PFX_EFFECT_STATE_CREATED);
}

int AdncPreProFx_Release(adnc_pfx_effect_t *effect)
{
    return AdncPreProFx_SetState(effect, PFX_EFFECT_STATE_INIT);
}


//------------------------------------------------------------------------------
// Session functions
//------------------------------------------------------------------------------
/*
 *  Initialize a session context.
 *  Must be called with a lock on sAdncBundleLock.
 */
int AdncSession_Init_l(adnc_pfx_session_t *session)
{
    ALOGV("AdncSession_Init()");
    size_t i;
    int status = 0;

    session->state = PFX_SESSION_STATE_INIT;
    session->audioSource = AUDIO_SOURCE_DEFAULT;
    //session->audioSessionId = ES305_SESSION_ID_NONE;  // FIXME not used delete?
    session->ioHandle = ES305_IO_HANDLE_NONE;
    session->createdMsk = 0;
    session->activeMsk  = 0;
    // initialize each effect for this session context
    for (i = 0; i < PFX_ID_CNT && status == 0; i++) {
        status = AdncPreProFx_Init(&session->effects[i], i);
    }
    return status;
}

/*
 * Must be called with a lock on sAdncBundleLock.
 */
int AdncSession_CreateEffect_l(adnc_pfx_session_t *session,
                             int32_t procId,
                             effect_handle_t  *interface)
{
    int status = -ENOMEM;
    ALOGV("AdncSession_CreateEffect handle=%d procId %d, old createdMsk %08x",
            session->ioHandle, procId, session->createdMsk);

    status = AdncPreProFx_Create(&session->effects[procId], session, interface);
    if (status >= 0) {
        ALOGV("  AdncSession_CreateEffect OK");
        session->createdMsk |= (1 << procId);
    }
    return status;
}

int AdncSession_SetConfig(adnc_pfx_session_t *session, effect_config_t *config)
{
    ALOGV("AdncSession_SetConfig [noop]");
    return 0;
}

void AdncSession_GetConfig(adnc_pfx_session_t *session, effect_config_t *config)
{
    ALOGV("AdncSession_GetConfig [noop]");
}

int AdncSession_SetReverseConfig(adnc_pfx_session_t *session, effect_config_t *config)
{
    ALOGV("AdncSession_SetReverseConfig [noop]");
    return 0;
}

void AdncSession_GetReverseConfig(adnc_pfx_session_t *session, effect_config_t *config)
{
    ALOGV("AdncSession_GetReverseConfig [noop]");
}

void AdncSession_SetProcEnabled(adnc_pfx_session_t *session, uint32_t procId, bool enabled)
{
    ALOGV("AdncSession_SetProcEnabled [noop] proc %d, enabled %d", procId, enabled);
    //no need to reevaluate session settings, if recording is currently ongoing, we'll reevaluate
    //  through eS305_AddEffect()
}

int AdncSession_SetSource(adnc_pfx_session_t *session, audio_source_t source)
{
    session->audioSource = source;
    return 0;
}

//------------------------------------------------------------------------------
// Bundle functions
//------------------------------------------------------------------------------
#define ADNC_BUNDLE_NO_INIT 1
static int sAdncBundleInitStatus = ADNC_BUNDLE_NO_INIT;
static adnc_pfx_session_t sAdncSessions[ADNC_PFX_NUM_SESSION];
static pthread_mutex_t sAdncBundleLock;

/* Returns a session context for the given IO handle
 * Returns an existing session context if the IO handle matches, initializes a new one otherwise.
 * Returns NULL if no more session contexts are available
 * Must be called with a lock on sAdncBundleLock
 */
adnc_pfx_session_t *AdncBundle_GetSession_l(int32_t procId, int32_t sessionId, int32_t ioId)
{
    size_t i;
    for (i = 0; i < ADNC_PFX_NUM_SESSION; i++) {
        if (sAdncSessions[i].ioHandle == ioId) {
            return &sAdncSessions[i];
        }
    }
    for (i = 0; i < ADNC_PFX_NUM_SESSION; i++) {
        if (sAdncSessions[i].ioHandle == ES305_IO_HANDLE_NONE) {
            //sAdncSessions[i].audioSessionId = sessionId; // FIXME not used delete?
            sAdncSessions[i].ioHandle = ioId;
            return &sAdncSessions[i];
        }
    }
    ALOGV("AdncBundle_GetSession_l");
    return NULL;
}

/*
 * Must be called with a lock on sAdncBundleLock.
 */
int AdncBundle_Init_l() {
    size_t i;
    int status = 0;

    if (sAdncBundleInitStatus <= 0) {
        return sAdncBundleInitStatus;
    }
    // initialize all the session contexts that this bundle supports
    for (i = 0; i < ADNC_PFX_NUM_SESSION && status == 0; i++) {
        status = AdncSession_Init_l(&sAdncSessions[i]);
    }
    sAdncBundleInitStatus = status;
    return sAdncBundleInitStatus;
}

/*
 * Must be called with a lock on sAdncBundleLock.
 */
int AdncBundle_Release_l() {
    ALOGV("AdncBundle_Release_l()");

    Adnc_SleepInt_l();

    for (int i = 0 ; i < ES305_NUM_CTRL ; i++) {
        if (eS305_ctrl.fd[i] >= 0) {
            close(eS305_ctrl.fd[i]);
        }
        eS305_ctrl.fd[i] = -1;
    }
    return 0;
}

const effect_descriptor_t *AdncBundle_GetDescriptor(const effect_uuid_t *uuid)
{
    size_t i;
    for (i = 0; i < PFX_ID_CNT; i++) {
        if (memcmp(&adnc_pfx_descriptors[i]->uuid, uuid, sizeof(effect_uuid_t)) == 0) {
            return adnc_pfx_descriptors[i];
        }
    }
    return NULL;
}

/*
 * Debug only: display session contexts
 */
void AdncBundle_logv_dumpSessions() {
    ALOGV("Sessions:");
    for (int i=0 ; i<ADNC_PFX_NUM_SESSION ; i++) {
        ALOGV(" session %d handle=%d cre=%2x act=%2x",
           i, sAdncSessions[i].ioHandle, sAdncSessions[i].createdMsk, sAdncSessions[i].activeMsk);
    }
}

//------------------------------------------------------------------------------
// Effect Control Interface Implementation
//------------------------------------------------------------------------------
int AdncVoiceProcessingFx_Command(effect_handle_t  self,
                            uint32_t            cmdCode,
                            uint32_t            cmdSize,
                            void                *pCmdData,
                            uint32_t            *replySize,
                            void                *pReplyData)
{
    adnc_pfx_effect_t * effect = (adnc_pfx_effect_t *) self;
    int retsize;
    int status;

    if (effect == NULL){
        return -EINVAL;
    }

    ALOGV("AdncVoiceProcessingFx_Command: command %d cmdSize %d",cmdCode, cmdSize);

    switch (cmdCode){
        case EFFECT_CMD_INIT:
            if (pReplyData == NULL || *replySize != sizeof(int)){
                return -EINVAL;
            }
            if (effect->ops->init) {
                effect->ops->init(effect);
            }
            *(int *)pReplyData = 0;
            break;

        case EFFECT_CMD_SET_CONFIG: {
            if (pCmdData    == NULL||
                cmdSize     != sizeof(effect_config_t)||
                pReplyData  == NULL||
                *replySize  != sizeof(int)){
                ALOGV("AdncVoiceProcessingFx_Command cmdCode Case: "
                        "EFFECT_CMD_SET_CONFIG: ERROR");
                return -EINVAL;
            }

            *(int *)pReplyData = AdncSession_SetConfig(effect->session, (effect_config_t *)pCmdData);

            if (*(int *)pReplyData != 0) {
                break;
            }
            if (effect->state != PFX_EFFECT_STATE_ACTIVE) {
                *(int *)pReplyData = AdncPreProFx_SetState(effect, PFX_EFFECT_STATE_CONFIG);
            }
            } break;

        case EFFECT_CMD_GET_CONFIG:
            if (pReplyData == NULL ||
                *replySize != sizeof(effect_config_t)) {
                ALOGV("\tLVM_ERROR : AdncVoiceProcessingFx_Command cmdCode Case: "
                        "EFFECT_CMD_GET_CONFIG: ERROR");
                return -EINVAL;
            }

            AdncSession_GetConfig(effect->session, (effect_config_t *)pReplyData);
            break;

        case EFFECT_CMD_SET_CONFIG_REVERSE:
            if (pCmdData == NULL ||
                cmdSize != sizeof(effect_config_t) ||
                pReplyData == NULL ||
                *replySize != sizeof(int)) {
                ALOGV("AdncVoiceProcessingFx_Command cmdCode Case: "
                        "EFFECT_CMD_SET_CONFIG_REVERSE: ERROR");
                return -EINVAL;
            }
            *(int *)pReplyData = AdncSession_SetReverseConfig(effect->session,
                                                          (effect_config_t *)pCmdData);
            if (*(int *)pReplyData != 0) {
                break;
            }
            break;

        case EFFECT_CMD_GET_CONFIG_REVERSE:
            if (pReplyData == NULL ||
                *replySize != sizeof(effect_config_t)){
                ALOGV("AdncVoiceProcessingFx_Command cmdCode Case: "
                        "EFFECT_CMD_GET_CONFIG_REVERSE: ERROR");
                return -EINVAL;
            }
            AdncSession_GetReverseConfig(effect->session, (effect_config_t *)pCmdData);
            break;

        case EFFECT_CMD_RESET:
            if (effect->ops->reset) {
                effect->ops->reset(effect);
            }
            break;

        case EFFECT_CMD_GET_PARAM:{
            if (pCmdData == NULL ||
                    cmdSize < (int)sizeof(effect_param_t) ||
                    pReplyData == NULL ||
                    *replySize < (int)sizeof(effect_param_t)){
                ALOGV("AdncVoiceProcessingFx_Command cmdCode Case: "
                        "EFFECT_CMD_GET_PARAM: ERROR");
                return -EINVAL;
            }
            effect_param_t *p = (effect_param_t *)pCmdData;

            memcpy(pReplyData, pCmdData, sizeof(effect_param_t) + p->psize);

            p = (effect_param_t *)pReplyData;

            int voffset = ((p->psize - 1) / sizeof(int32_t) + 1) * sizeof(int32_t);

            if (effect->ops->get_parameter) {
                p->status = effect->ops->get_parameter(effect, p->data,
                                                       (size_t  *)&p->vsize,
                                                       p->data + voffset);
                *replySize = sizeof(effect_param_t) + voffset + p->vsize;
            }
        } break;

        case EFFECT_CMD_SET_PARAM:{
            if (pCmdData == NULL||
                    cmdSize < (int)sizeof(effect_param_t) ||
                    pReplyData == NULL ||
                    *replySize != sizeof(int32_t)){
                ALOGV("AdncVoiceProcessingFx_Command cmdCode Case: "
                        "EFFECT_CMD_SET_PARAM: ERROR");
                return -EINVAL;
            }
            effect_param_t *p = (effect_param_t *) pCmdData;

            if (p->psize != sizeof(int32_t)){
                ALOGV("AdncVoiceProcessingFx_Command cmdCode Case: "
                        "EFFECT_CMD_SET_PARAM: ERROR, psize is not sizeof(int32_t)");
                return -EINVAL;
            }
            if (effect->ops->set_parameter) {
                *(int *)pReplyData = effect->ops->set_parameter(effect,
                                                                (void *)p->data,
                                                                p->data + p->psize);
            }
        } break;

        case EFFECT_CMD_ENABLE:
            if (pReplyData == NULL || *replySize != sizeof(int)){
                ALOGV("AdncVoiceProcessingFx_Command cmdCode Case: EFFECT_CMD_ENABLE: ERROR");
                return -EINVAL;
            }
            *(int *)pReplyData = AdncPreProFx_SetState(effect, PFX_EFFECT_STATE_ACTIVE);
            break;

        case EFFECT_CMD_DISABLE:
            if (pReplyData == NULL || *replySize != sizeof(int)){
                ALOGV("AdncVoiceProcessingFx_Command cmdCode Case: EFFECT_CMD_DISABLE: ERROR");
                return -EINVAL;
            }
            *(int *)pReplyData  = AdncPreProFx_SetState(effect, PFX_EFFECT_STATE_CONFIG);
            break;

        case EFFECT_CMD_SET_DEVICE:
        case EFFECT_CMD_SET_INPUT_DEVICE:
            if (pCmdData == NULL ||
                cmdSize != sizeof(uint32_t)) {
                ALOGV("AdncVoiceProcessingFx_Command cmdCode Case: EFFECT_CMD_SET_DEVICE: ERROR");
                return -EINVAL;
            }

            if (effect->ops->set_device) {
                effect->ops->set_device(effect, *(uint32_t *)pCmdData);
            }
            break;

        case EFFECT_CMD_SET_VOLUME:
        case EFFECT_CMD_SET_AUDIO_MODE:
        case EFFECT_CMD_SET_FEATURE_CONFIG:
            break;

        case EFFECT_CMD_SET_AUDIO_SOURCE:
            if (pCmdData == NULL ||
                    cmdSize != sizeof(uint32_t)) {
                ALOGV("AdncVoiceProcessingFx_Command cmdCode Case: EFFECT_CMD_SET_AUDIO_SOURCE: ERROR");
                return -EINVAL;
            }
            return AdncSession_SetSource(effect->session, (audio_source_t) *(uint32_t *)pCmdData);
            break;

        default:
            return -EINVAL;
    }
    return 0;
}


int AdncVoiceProcessingFx_GetDescriptor(effect_handle_t   self,
                                  effect_descriptor_t *pDescriptor)
{
    adnc_pfx_effect_t * effect = (adnc_pfx_effect_t *) self;

    if (effect == NULL || pDescriptor == NULL) {
        return -EINVAL;
    }

    memcpy(pDescriptor, adnc_pfx_descriptors[effect->procId], sizeof(effect_descriptor_t));

    return 0;
}


// effect_handle_t interface implementation for effect
const struct effect_interface_s sEffectInterface = {
        NULL, /* Process */
        AdncVoiceProcessingFx_Command,
        AdncVoiceProcessingFx_GetDescriptor,
        NULL
};
//------------------------------------------------------------------------------
// Effect Library Interface Implementation
//------------------------------------------------------------------------------

int adnc_create(const effect_uuid_t *uuid,
            int32_t         sessionId,
            int32_t         ioId,
            effect_handle_t *pInterface)
{
    ALOGV("adnc_create: uuid: %08x session %d IO: %d", uuid->timeLow, sessionId, ioId);

    int status = 0;
    const effect_descriptor_t *desc;
    adnc_pfx_session_t *session;
    uint32_t procId;

    pthread_mutex_lock(&sAdncBundleLock);

    if (AdncBundle_Init_l() != 0) {
        status = sAdncBundleInitStatus;
        goto exit;
    }

    desc =  AdncBundle_GetDescriptor(uuid);
    if (desc == NULL) {
        ALOGW("  adnc_create: fx not found uuid: %08x", uuid->timeLow);
        status = -EINVAL;
        goto exit;
    }
    procId = Adnc_UuidToProcId(&desc->type);

    session = AdncBundle_GetSession_l(procId, sessionId, ioId);
    if (session == NULL) {
        ALOGW("  adnc_create: no more session available");
        status = -EINVAL;
        goto exit;
    }

    status = AdncSession_CreateEffect_l(session, procId, pInterface);

    if (status < 0 && session->createdMsk == 0) {
        session->ioHandle = ES305_IO_HANDLE_NONE;
    }

exit:
    pthread_mutex_unlock(&sAdncBundleLock);
    return status;
}

int adnc_release(effect_handle_t interface)
{
    int i, status = 0;
    ALOGV("adnc_release %p", interface);

    // the effect handle comes from the effect framework, ok to cast
    const adnc_pfx_effect_t * fx = (adnc_pfx_effect_t *) interface;

    const uint32_t removalMsk = ~(1 << fx->procId);

    pthread_mutex_lock(&sAdncBundleLock);

    if (AdncBundle_Init_l() != 0) {
        status = sAdncBundleInitStatus;
        goto exit;
    }

    if (fx->session->ioHandle == 0) {
        status = -EINVAL;
        goto exit;
    }

    // effect is released, flag it as inactive and not created
    fx->session->createdMsk &= removalMsk;
    fx->session->activeMsk  &= removalMsk;

    // configuration has changed, reevaluate
    status = Adnc_ReevaluateUsageInt_l(fx->session->ioHandle);
    // not checking the return status here: if there was an error,
    //    we still need to free the session and wouldn't exit here

    // free session if it has no more effects
    if (fx->session->createdMsk == 0) {
        ALOGV(" resetting session on handle %d after effect release", fx->session->ioHandle);
        const int statusInit = AdncSession_Init_l(fx->session);
        if (status == 0) {
            status = statusInit;
        }
    }

exit:
    pthread_mutex_unlock(&sAdncBundleLock);
    return status;
}

int adnc_get_descriptor(const effect_uuid_t *uuid, effect_descriptor_t *pDescriptor) {
    if (pDescriptor == NULL || uuid == NULL){
        ALOGV("adnc_get_descriptor() invalid params");
        return -EINVAL;
    }

    const effect_descriptor_t *desc = AdncBundle_GetDescriptor(uuid);
    if (desc == NULL) {
        ALOGV("adnc_get_descriptor() not found");
        return -EINVAL;
    }

    ALOGV("adnc_get_descriptor() got fx %s", desc->name);

    memcpy(pDescriptor, desc, sizeof(effect_descriptor_t));
    return 0;
}

audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
    tag : AUDIO_EFFECT_LIBRARY_TAG,
    version : EFFECT_LIBRARY_API_VERSION,
    name : "Audience Voice Preprocessing Library",
    implementor : "The Android Open Source Project",
    create_effect : adnc_create,
    release_effect : adnc_release,
    get_descriptor : adnc_get_descriptor
};

//-------------------------------------------------------
// eS305 control interface
//-------------------------------------------------------
int Adnc_SetAutomaticGainControlInt_l(bool agc_on)
{
    ALOGV("Adnc_SetAutomaticGainControlInt_l(%d)", agc_on);

    if (eS305_ctrl.fd[ES305_CTRL_TX_AGC_ENABLE] < 0) {
        ALOGV("  opening eS305 path for agc");
        eS305_ctrl.fd[ES305_CTRL_TX_AGC_ENABLE] = open(ES305_TX_AGC_ENABLE_PATH, O_RDWR);
        if (eS305_ctrl.fd[ES305_CTRL_TX_AGC_ENABLE] < 0) {
            ALOGE("  Cannot open eS305 path for agc: %s", strerror(errno));
            return -ENODEV;
        }
    }

    if (agc_on) {
        write(eS305_ctrl.fd[ES305_CTRL_TX_AGC_ENABLE], ES305_AGC_ON, strlen(ES305_AGC_ON));
    } else {
        write(eS305_ctrl.fd[ES305_CTRL_TX_AGC_ENABLE], ES305_AEC_OFF, strlen(ES305_AGC_OFF));
    }
    return 0;
}

int Adnc_SetEchoCancellationInt_l(bool aec_on)
{
    ALOGV("Adnc_SetEchoCancellationInt_l(%d)", aec_on);

    if (eS305_ctrl.fd[ES305_CTRL_AEC_ENABLE] < 0) {
        ALOGV("  opening eS305 path for aec");
        eS305_ctrl.fd[ES305_CTRL_AEC_ENABLE] = open(ES305_AEC_ENABLE_PATH, O_RDWR);
        if (eS305_ctrl.fd[ES305_CTRL_AEC_ENABLE] < 0) {
            ALOGE("  Cannot open eS305 path for aec: %s", strerror(errno));
            return -ENODEV;
        }
    }

    if (aec_on) {
        write(eS305_ctrl.fd[ES305_CTRL_AEC_ENABLE], ES305_AEC_ON, strlen(ES305_AEC_ON));
    } else {
        write(eS305_ctrl.fd[ES305_CTRL_AEC_ENABLE], ES305_AEC_OFF, strlen(ES305_AEC_OFF));
    }
    return 0;
}

int Adnc_SetNoiseSuppressionInt_l(bool ns_on)
{
    ALOGV("Adnc_SetNoiseSuppressionInt(%d)", ns_on);

    if (eS305_ctrl.fd[ES305_CTRL_TX_NS_LEVEL] < 0) {
        ALOGV("  opening eS305 path for ns");
        eS305_ctrl.fd[ES305_CTRL_TX_NS_LEVEL] = open(ES305_TX_NS_LEVEL_PATH, O_RDWR);
        if (eS305_ctrl.fd[ES305_CTRL_TX_NS_LEVEL] < 0) {
            ALOGE("  Cannot open eS305 path for ns: %s", strerror(errno));
            return -ENODEV;
        }
    }

    if (ns_on) {
        if (eS305_ctrl.requested_preset == ES305_PRESET_ASRA_HANDHELD) {
            ALOGV("  setting ns to %s", ES305_NS_VOICE_REC_HANDHELD_ON);
            write(eS305_ctrl.fd[ES305_CTRL_TX_NS_LEVEL],
                    ES305_NS_VOICE_REC_HANDHELD_ON, strlen(ES305_NS_VOICE_REC_HANDHELD_ON));
        } else if ((eS305_ctrl.requested_preset == ES305_PRESET_ASRA_DESKTOP)
                || (eS305_ctrl.requested_preset == ES305_PRESET_ASRA_HEADSET)) {
            ALOGV("  setting ns to %s", ES305_NS_VOICE_REC_SINGLE_MIC_ON);
            write(eS305_ctrl.fd[ES305_CTRL_TX_NS_LEVEL],
                    ES305_NS_VOICE_REC_SINGLE_MIC_ON, strlen(ES305_NS_VOICE_REC_SINGLE_MIC_ON));
        } else {
            ALOGV("  setting ns to %s", ES305_NS_DEFAULT_ON);
            write(eS305_ctrl.fd[ES305_CTRL_TX_NS_LEVEL],
                    ES305_NS_DEFAULT_ON, strlen(ES305_NS_DEFAULT_ON));
        }
    } else {
        ALOGV("  setting ns to %s", ES305_NS_OFF);
        write(eS305_ctrl.fd[ES305_CTRL_TX_NS_LEVEL], ES305_NS_OFF, strlen(ES305_NS_OFF));
    }
    return 0;
}

int Adnc_SetVoiceProcessingInt_l(bool vp_on)
{
    if (eS305_ctrl.fd[ES305_CTRL_VOICE_PROCESSING] < 0) {
        ALOGV("  opening eS305 path for VP");
        eS305_ctrl.fd[ES305_CTRL_VOICE_PROCESSING] = open(ES305_VOICE_PROCESSING_PATH, O_RDWR);
        if (eS305_ctrl.fd[ES305_CTRL_VOICE_PROCESSING] < 0) {
            ALOGE("    cannot open eS305 path for VP: %s", strerror(errno));
            return -ENODEV;
        }
    }
    if (vp_on) {
        write(eS305_ctrl.fd[ES305_CTRL_VOICE_PROCESSING], ES305_ON, strlen(ES305_ON));
    } else {
        write(eS305_ctrl.fd[ES305_CTRL_VOICE_PROCESSING], ES305_OFF, strlen(ES305_OFF));
    }
    return 0;
}

/*
 * Put the eS305 to sleep
 * Post condition when no error: eS305_ctrl.current_preset == ES305_PRESET_OFF
 */
int Adnc_SleepInt_l()
{
    if (eS305_ctrl.current_preset == ES305_PRESET_OFF) {
        return 0;
    }

    ALOGV(" Adnc_SleepInt()_l setting VP off + sleep 1");

    Adnc_SetVoiceProcessingInt_l(false /*vp_on*/);

    ALOGV("  Adnc_SetSleepInt_l");
    if (eS305_ctrl.fd[ES305_CTRL_SLEEP] < 0) {
        ALOGV("  opening eS305 path for sleep");
        eS305_ctrl.fd[ES305_CTRL_SLEEP] = open(ES305_SLEEP_PATH, O_RDWR);
        if (eS305_ctrl.fd[ES305_CTRL_SLEEP] < 0) {
            ALOGE("    cannot open eS305 path for sleep: %s", strerror(errno));
            return -ENODEV;
        }
    }

    write(eS305_ctrl.fd[ES305_CTRL_SLEEP], ES305_ON, strlen(ES305_ON));

    eS305_ctrl.current_preset = ES305_PRESET_OFF;

    return 0;
}

/*
 * Apply the eS305_ctrl.requested_preset preset after turning VP on
 * Post condition when no error: eS305_ctrl.current_preset == eS305_ctrl.requested_preset
 */
int Adnc_ApplyPresetInt_l()
{
    ALOGV("Adnc_ApplyPresetInt() current_preset=%d, requested_preset=%d",
            eS305_ctrl.current_preset, eS305_ctrl.requested_preset);

    if (eS305_ctrl.requested_preset == eS305_ctrl.current_preset) {
        ALOGV("  nothing to do, preset %d is current", eS305_ctrl.requested_preset);
        return 0;
    }

    // preset off implies going to sleep
    if (eS305_ctrl.requested_preset == ES305_PRESET_OFF) {
        return Adnc_SleepInt_l();
    }

    // voice processing must be on before setting the preset
    if ((eS305_ctrl.current_preset == ES305_PRESET_OFF)
            || (eS305_ctrl.current_preset == ES305_PRESET_INIT)) {
        const int status = Adnc_SetVoiceProcessingInt_l(true /*vp_on*/);
        if (status != 0) {
            return status;
        }
    }

    if (eS305_ctrl.fd[ES305_CTRL_PRESET] < 0) {
        ALOGV("  opening eS305 path for PRESET");
        eS305_ctrl.fd[ES305_CTRL_PRESET] = open(ES305_PRESET_PATH, O_RDWR);
    }
    if (eS305_ctrl.fd[ES305_CTRL_PRESET] < 0) {
        ALOGE("  Cannot open eS305 path for PRESET: %s", strerror(errno));
        return -ENODEV;
    }

    char str[8];
    sprintf(str, "%d", eS305_ctrl.requested_preset);
    write(eS305_ctrl.fd[ES305_CTRL_PRESET], str, strlen(str));

    eS305_ctrl.current_preset = eS305_ctrl.requested_preset;

    return 0;
}


/*
 * Apply the settings of given the session context
 */
int Adnc_ApplySettingsFromSessionContextInt_l(adnc_pfx_session_t * session)
{
    ALOGV("Adnc_ApplySettingsFromSessionContextInt_l cre=%2x ac=%2x handle=%d",
                  session->createdMsk, session->activeMsk, session->ioHandle);
    int status = 0;

    if (session->ioHandle != eS305_ctrl.ioHandle) {
        return status;
    }

    // NS: special case of noise suppression, always reset according to effect state
    //     as default desirable value might differ from the preset
    const bool ns_on = ((session->activeMsk & (1 << PFX_ID_NS)) != 0);
    status = Adnc_SetNoiseSuppressionInt_l(ns_on /*ns_on*/);

    // AEC
    if ((session->createdMsk & (1 << PFX_ID_AEC))         /* the effect has been created */
            && (session->activeMsk  & (1 << PFX_ID_AEC))) /* the effect is active        */
    {
        Adnc_SetEchoCancellationInt_l(true /*aec_on*/);
    }

    // AGC
    if ((session->createdMsk & (1 << PFX_ID_AGC))         /* the effect has been created */
            && (session->activeMsk  & (1 << PFX_ID_AGC))) /* the effect is active        */
    {
        Adnc_SetAutomaticGainControlInt_l(true /*agc_on*/);
    }

    return status;
}

/*
 * Return a value between 0 and ADNC_PFX_NUM_SESSION-1 if a session context has the given handle,
 *        -1 if the handle isn't in handled by one of the sessions.
 * Must be called with a lock on sAdncBundleLock
 */
int Adnc_SessionNumberForHandle_l(audio_io_handle_t handle)
{
    for (int i = 0 ; i < ADNC_PFX_NUM_SESSION ; i++) {
        if (sAdncSessions[i].ioHandle == handle) {
            return i;
        }
    }
    return -1;
}


/*
 * Apply the settings of the session matching the given IO handle.
 * Must be called with a lock on sAdncBundleLock
 */
int Adnc_ApplySettingsForHandleInt_l(audio_io_handle_t handle)
{
    ALOGV(" Adnc_ApplySettingsForHandleInt_l(handle=%d)", handle);
    // indicates whether this effect bundle currently has a session context for this IO handle
    bool hasSession = false;
    int status = 0;
    int i;

    if (sAdncBundleInitStatus != 0) {
        // This assumes that the default config of the eS305 after setting a preset
        //    is the correct configuration.
        ALOGV(" no effect settings to apply for IO handle %d, no effect bundle", handle);
        return status;
    }

    const int sessionId = Adnc_SessionNumberForHandle_l(handle);
    if (sessionId >= 0) {
        ALOGV("  applying settings from session num %d", sessionId);
        status = Adnc_ApplySettingsFromSessionContextInt_l( &sAdncSessions[sessionId] );
    }
    else {
        ALOGV("  no session found for handle %d", handle);
    }

    return status;
}

/*
 * Reevaluate the usage of the eS305 based on the given IO handle.
 * Must be called with a lock on sAdncBundleLock
 */
int Adnc_ReevaluateUsageInt_l(audio_io_handle_t handle)
{
    ALOGV(" Adnc_ReevaluateUsageInt_l(handle=%d) current_preset=%d requested_preset=%d",
            handle, eS305_ctrl.current_preset, eS305_ctrl.requested_preset);
    int status = 0;
    if ((eS305_ctrl.requested_preset == ES305_PRESET_OFF) || (handle == ES305_IO_HANDLE_NONE)) {
        status = Adnc_SleepInt_l();
    } else {
        const int sessionId = Adnc_SessionNumberForHandle_l(handle);
        if (sessionId >= 0) {
            // recording active, use the preset only if there is an effect,
            //                   reset preset to off otherwise
            if (sAdncSessions[sessionId].activeMsk != 0) {
                status = Adnc_ApplyPresetInt_l();
                if (status == 0) {
                    //apply the settings of the session associated with the handle (if any)
                    status = Adnc_ApplySettingsForHandleInt_l(handle);
                }
            } else {
                status = Adnc_SleepInt_l();
            }
        }
    }
    return status;
}


//-------------------------------------------------------
// eS305 public control interface from HAL
//-------------------------------------------------------
int eS305_UsePreset(int preset)
{
    ALOGV("eS305_UsePreset(%d) current=%d handle=%d",
            preset, eS305_ctrl.current_preset, eS305_ctrl.ioHandle);

    int status = 0;

    pthread_mutex_lock(&sAdncBundleLock);

    //if (preset != -1) { AdncBundle_logv_dumpSessions(); }

    // allow preset transition from any preset to any other during recording,
    //    except from one ASRA preset to another
    if (eS305_ctrl.ioHandle != ES305_IO_HANDLE_NONE) {
        switch(eS305_ctrl.current_preset) {
        case ES305_PRESET_ASRA_HANDHELD:
        case ES305_PRESET_ASRA_DESKTOP:
        case ES305_PRESET_ASRA_HEADSET:
            switch(preset) {
            case ES305_PRESET_ASRA_HANDHELD:
            case ES305_PRESET_ASRA_DESKTOP:
            case ES305_PRESET_ASRA_HEADSET:
                ALOGV("  not switching from ASRA preset %d to %d during voice recognition",
                        eS305_ctrl.current_preset, preset);
                status = -EINVAL;
                goto exit;
            default:
                // transitioning from ASRA to non-ASRA: valid
                break;
            }
            break;
        default:
            // transitioning from non-ASRA: valid
            break;
        }
    }

    eS305_ctrl.requested_preset = preset;

    status = AdncBundle_Init_l();
    if (status != 0) {
        ALOGE(" error applying preset, bundle failed to initialize");
        goto exit;
    }

    status = Adnc_ReevaluateUsageInt_l(eS305_ctrl.ioHandle);

exit:
    pthread_mutex_unlock(&sAdncBundleLock);
    return status;
}


int eS305_SetActiveIoHandle(audio_io_handle_t handle)
{
    ALOGV("eS305_SetActiveIoHandle(%d)", handle);

    pthread_mutex_lock(&sAdncBundleLock);

    int status = AdncBundle_Init_l();
    if (status != 0) {
        ALOGE(" error setting active handle, bundle failed to initialize");
        pthread_mutex_unlock(&sAdncBundleLock);
        return status;
    }

    status = Adnc_ReevaluateUsageInt_l(handle);

    if (status == 0) {
        eS305_ctrl.ioHandle = handle;
    } else {
        ALOGE("  failed to update for new handle %d (current preset = %d)",
                handle, eS305_ctrl.current_preset);
    }

    pthread_mutex_unlock(&sAdncBundleLock);

    return status;
}


int eS305_AddEffect(effect_descriptor_t * descr, audio_io_handle_t handle)
{
    ALOGV("eS305_AddEffect(handle=%d)", handle);

    pthread_mutex_lock(&sAdncBundleLock);

    int status = AdncBundle_Init_l();
    if (status != 0) {
        ALOGE(" error setting adding effect, bundle failed to initialize");
        pthread_mutex_unlock(&sAdncBundleLock);
        return status;
    }

    if (descr == NULL){
        ALOGV(" eS305_AddEffect() ERROR effect descriptor is NULL");
        pthread_mutex_unlock(&sAdncBundleLock);
        return -EINVAL;
    }

    uint32_t procId = Adnc_UuidToProcId(&descr->type);

    adnc_pfx_session_t * session = AdncBundle_GetSession_l(
            procId, ES305_SESSION_ID_NONE, handle/*ioId*/);

    if (session != NULL) {
        // mark the effect as active
        session->activeMsk  |= (1 << procId);

        // update settings if necessary
        Adnc_ReevaluateUsageInt_l(session->ioHandle);
    }

    pthread_mutex_unlock(&sAdncBundleLock);

    return status;
}


int eS305_RemoveEffect(effect_descriptor_t * descr, audio_io_handle_t handle)
{
    ALOGV("eS305_RemoveEffect()");

    pthread_mutex_lock(&sAdncBundleLock);

    int status = AdncBundle_Init_l();
    if (status != 0) {
        ALOGE(" error setting removing effect, bundle failed to initialize");
        pthread_mutex_unlock(&sAdncBundleLock);
        return status;
    }

    if (descr == NULL){
        ALOGV(" eS305_AddEffect() ERROR effect descriptor is NULL");
        pthread_mutex_unlock(&sAdncBundleLock);
        return -EINVAL;
    }

    uint32_t procId = Adnc_UuidToProcId(&descr->type);

    adnc_pfx_session_t * session = AdncBundle_GetSession_l(
            procId, ES305_SESSION_ID_NONE, handle/*ioId*/);

    if (session != NULL) {
        // mark the effect as inactive
        session->activeMsk  &= ~(1 << procId);

        // update settings if necessary
        Adnc_ReevaluateUsageInt_l(session->ioHandle);
    }

    pthread_mutex_unlock(&sAdncBundleLock);

    return status;
}


int eS305_Release() {
    ALOGV("eS305_Release()");

    pthread_mutex_lock(&sAdncBundleLock);

    AdncBundle_Release_l();

    pthread_mutex_unlock(&sAdncBundleLock);

    return 0;
}

} // extern "C"
