/*
 * Copyright (C) 2011 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 <stdlib.h>
#include <string.h>
#define LOG_TAG "PreProcessing"
//#define LOG_NDEBUG 0
#include <utils/Log.h>
#include <utils/Timers.h>
#include <hardware/audio_effect.h>
#include <audio_effects/effect_aec.h>
#include <audio_effects/effect_agc.h>
#include <audio_effects/effect_ns.h>
#include "modules/interface/module_common_types.h"
#include "modules/audio_processing/main/interface/audio_processing.h"
#include "speex/speex_resampler.h"


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

// maximum number of sessions
#define PREPROC_NUM_SESSIONS 8

// types of pre processing modules
enum preproc_id
{
    PREPROC_AGC,        // Automatic Gain Control
    PREPROC_AEC,        // Acoustic Echo Canceler
    PREPROC_NS,         // Noise Suppressor
    PREPROC_NUM_EFFECTS
};

// Session state
enum preproc_session_state {
    PREPROC_SESSION_STATE_INIT,        // initialized
    PREPROC_SESSION_STATE_CONFIG       // configuration received
};

// Effect/Preprocessor state
enum preproc_effect_state {
    PREPROC_EFFECT_STATE_INIT,         // initialized
    PREPROC_EFFECT_STATE_CREATED,      // webRTC engine created
    PREPROC_EFFECT_STATE_CONFIG,       // configuration received/disabled
    PREPROC_EFFECT_STATE_ACTIVE        // active/enabled
};

// handle on webRTC engine
typedef void* preproc_fx_handle_t;

typedef struct preproc_session_s preproc_session_t;
typedef struct preproc_effect_s preproc_effect_t;
typedef struct preproc_ops_s preproc_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 preproc_ops_s {
    int (* create)(preproc_effect_t *fx);
    int (* init)(preproc_effect_t *fx);
    int (* reset)(preproc_effect_t *fx);
    void (* enable)(preproc_effect_t *fx);
    void (* disable)(preproc_effect_t *fx);
    int (* set_parameter)(preproc_effect_t *fx, void *param, void *value);
    int (* get_parameter)(preproc_effect_t *fx, void *param, size_t *size, void *value);
    int (* set_device)(preproc_effect_t *fx, uint32_t device);
};

// Effect context
struct preproc_effect_s {
    const struct effect_interface_s *itfe;
    uint32_t procId;                // type of pre processor (enum preproc_id)
    uint32_t state;                 // current state (enum preproc_effect_state)
    preproc_session_t *session;     // session the effect is on
    const preproc_ops_t *ops;       // effect ops table
    preproc_fx_handle_t engine;     // handle on webRTC engine
};

// Session context
struct preproc_session_s {
    struct preproc_effect_s effects[PREPROC_NUM_EFFECTS]; // effects in this session
    uint32_t state;                     // current state (enum preproc_session_state)
    int id;                             // audio session ID
    int io;                             // handle of input stream this session is on
    webrtc::AudioProcessing* apm;       // handle on webRTC audio processing module (APM)
    size_t apmFrameCount;               // buffer size for webRTC process (10 ms)
    uint32_t apmSamplingRate;           // webRTC APM sampling rate (8/16 or 32 kHz)
    size_t frameCount;                  // buffer size before input resampler ( <=> apmFrameCount)
    uint32_t samplingRate;              // sampling rate at effect process interface
    uint32_t inChannelCount;            // input channel count
    uint32_t outChannelCount;           // output channel count
    uint32_t createdMsk;                // bit field containing IDs of crested pre processors
    uint32_t enabledMsk;                // bit field containing IDs of enabled pre processors
    uint32_t processedMsk;              // bit field containing IDs of pre processors already
                                        // processed in current round
    webrtc::AudioFrame *procFrame;      // audio frame passed to webRTC AMP ProcessStream()
    int16_t *inBuf;                     // input buffer used when resampling
    size_t inBufSize;                   // input buffer size in frames
    size_t framesIn;                    // number of frames in input buffer
    SpeexResamplerState *inResampler;   // handle on input speex resampler
    int16_t *outBuf;                    // output buffer used when resampling
    size_t outBufSize;                  // output buffer size in frames
    size_t framesOut;                   // number of frames in output buffer
    SpeexResamplerState *outResampler;  // handle on output speex resampler
    uint32_t revChannelCount;           // number of channels on reverse stream
    uint32_t revEnabledMsk;             // bit field containing IDs of enabled pre processors
                                        // with reverse channel
    uint32_t revProcessedMsk;           // bit field containing IDs of pre processors with reverse
                                        // channel already processed in current round
    webrtc::AudioFrame *revFrame;       // audio frame passed to webRTC AMP AnalyzeReverseStream()
    int16_t *revBuf;                    // reverse channel input buffer
    size_t revBufSize;                  // reverse channel input buffer size
    size_t framesRev;                   // number of frames in reverse channel input buffer
    SpeexResamplerState *revResampler;  // handle on reverse channel input speex resampler
};

//------------------------------------------------------------------------------
// 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

// Automatic Gain Control
static const effect_descriptor_t sAgcDescriptor = {
        { 0x0a8abfe0, 0x654c, 0x11e0, 0xba26, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }, // type
        { 0xaa8130e0, 0x66fc, 0x11e0, 0xbad0, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }, // 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",
        "The Android Open Source Project"
};

// Acoustic Echo Cancellation
static const effect_descriptor_t sAecDescriptor = {
        { 0x7b491460, 0x8d4d, 0x11e0, 0xbd61, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }, // type
        { 0xbb392ec0, 0x8d4d, 0x11e0, 0xa896, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }, // 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",
        "The Android Open Source Project"
};

// Noise suppression
static const effect_descriptor_t sNsDescriptor = {
        { 0x58b4b260, 0x8e06, 0x11e0, 0xaa8e, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }, // type
        { 0xc06c8400, 0x8e06, 0x11e0, 0x9cb6, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }, // 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",
        "The Android Open Source Project"
};


static const effect_descriptor_t *sDescriptors[PREPROC_NUM_EFFECTS] = {
        &sAgcDescriptor,
        &sAecDescriptor,
        &sNsDescriptor
};

//------------------------------------------------------------------------------
// Helper functions
//------------------------------------------------------------------------------

const effect_uuid_t * const sUuidToPreProcTable[PREPROC_NUM_EFFECTS] = {
        FX_IID_AGC,
        FX_IID_AEC,
        FX_IID_NS
};


const effect_uuid_t * ProcIdToUuid(int procId)
{
    if (procId >= PREPROC_NUM_EFFECTS) {
        return EFFECT_UUID_NULL;
    }
    return sUuidToPreProcTable[procId];
}

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

bool HasReverseStream(uint32_t procId)
{
    if (procId == PREPROC_AEC) {
        return true;
    }
    return false;
}


//------------------------------------------------------------------------------
// Automatic Gain Control (AGC)
//------------------------------------------------------------------------------

static const int kAgcDefaultTargetLevel = 0;
static const int kAgcDefaultCompGain = 90;
static const bool kAgcDefaultLimiter = true;

int  AgcInit (preproc_effect_t *effect)
{
    LOGV("AgcInit");
    webrtc::GainControl *agc = static_cast<webrtc::GainControl *>(effect->engine);
    agc->set_mode(webrtc::GainControl::kFixedDigital);
    agc->set_target_level_dbfs(kAgcDefaultTargetLevel);
    agc->set_compression_gain_db(kAgcDefaultCompGain);
    agc->enable_limiter(kAgcDefaultLimiter);
    return 0;
}

int  AgcCreate(preproc_effect_t *effect)
{
    webrtc::GainControl *agc = effect->session->apm->gain_control();
    LOGV("AgcCreate got agc %p", agc);
    if (agc == NULL) {
        LOGW("AgcCreate Error");
        return -ENOMEM;
    }
    effect->engine = static_cast<preproc_fx_handle_t>(agc);
    AgcInit(effect);
    return 0;
}

int AgcGetParameter(preproc_effect_t *effect,
                    void *pParam,
                    size_t *pValueSize,
                    void *pValue)
{
    int status = 0;
    uint32_t param = *(uint32_t *)pParam;
    t_agc_settings *pProperties = (t_agc_settings *)pValue;
    webrtc::GainControl *agc = static_cast<webrtc::GainControl *>(effect->engine);

    switch (param) {
    case AGC_PARAM_TARGET_LEVEL:
    case AGC_PARAM_COMP_GAIN:
        if (*pValueSize < sizeof(int16_t)) {
            *pValueSize = 0;
            return -EINVAL;
        }
        break;
    case AGC_PARAM_LIMITER_ENA:
        if (*pValueSize < sizeof(bool)) {
            *pValueSize = 0;
            return -EINVAL;
        }
        break;
    case AGC_PARAM_PROPERTIES:
        if (*pValueSize < sizeof(t_agc_settings)) {
            *pValueSize = 0;
            return -EINVAL;
        }
        break;

    default:
        LOGW("AgcGetParameter() unknown param %08x", param);
        status = -EINVAL;
        break;
    }

    switch (param) {
    case AGC_PARAM_TARGET_LEVEL:
        *(int16_t *) pValue = (int16_t)(agc->target_level_dbfs() * -100);
        LOGV("AgcGetParameter() target level %d milliBels", *(int16_t *) pValue);
        break;
    case AGC_PARAM_COMP_GAIN:
        *(int16_t *) pValue = (int16_t)(agc->compression_gain_db() * 100);
        LOGV("AgcGetParameter() comp gain %d milliBels", *(int16_t *) pValue);
        break;
    case AGC_PARAM_LIMITER_ENA:
        *(bool *) pValue = (bool)agc->is_limiter_enabled();
        LOGV("AgcGetParameter() limiter enabled %s",
             (*(int16_t *) pValue != 0) ? "true" : "false");
        break;
    case AGC_PARAM_PROPERTIES:
        pProperties->targetLevel = (int16_t)(agc->target_level_dbfs() * -100);
        pProperties->compGain = (int16_t)(agc->compression_gain_db() * 100);
        pProperties->limiterEnabled = (bool)agc->is_limiter_enabled();
        break;
    default:
        LOGW("AgcGetParameter() unknown param %d", param);
        status = -EINVAL;
        break;
    }
    return status;
}

int AgcSetParameter (preproc_effect_t *effect, void *pParam, void *pValue)
{
    int status = 0;
    uint32_t param = *(uint32_t *)pParam;
    t_agc_settings *pProperties = (t_agc_settings *)pValue;
    webrtc::GainControl *agc = static_cast<webrtc::GainControl *>(effect->engine);

    switch (param) {
    case AGC_PARAM_TARGET_LEVEL:
        LOGV("AgcSetParameter() target level %d milliBels", *(int16_t *)pValue);
        status = agc->set_target_level_dbfs(-(*(int16_t *)pValue / 100));
        break;
    case AGC_PARAM_COMP_GAIN:
        LOGV("AgcSetParameter() comp gain %d milliBels", *(int16_t *)pValue);
        status = agc->set_compression_gain_db(*(int16_t *)pValue / 100);
        break;
    case AGC_PARAM_LIMITER_ENA:
        LOGV("AgcSetParameter() limiter enabled %s", *(bool *)pValue ? "true" : "false");
        status = agc->enable_limiter(*(bool *)pValue);
        break;
    case AGC_PARAM_PROPERTIES:
        LOGV("AgcSetParameter() properties level %d, gain %d limiter %d",
             pProperties->targetLevel,
             pProperties->compGain,
             pProperties->limiterEnabled);
        status = agc->set_target_level_dbfs(-(pProperties->targetLevel / 100));
        if (status != 0) break;
        status = agc->set_compression_gain_db(pProperties->compGain / 100);
        if (status != 0) break;
        status = agc->enable_limiter(pProperties->limiterEnabled);
        break;
    default:
        LOGW("AgcSetParameter() unknown param %08x value %08x", param, *(uint32_t *)pValue);
        status = -EINVAL;
        break;
    }

    LOGV("AgcSetParameter() done status %d", status);

    return status;
}

void AgcEnable(preproc_effect_t *effect)
{
    webrtc::GainControl *agc = static_cast<webrtc::GainControl *>(effect->engine);
    LOGV("AgcEnable agc %p", agc);
    agc->Enable(true);
}

void AgcDisable(preproc_effect_t *effect)
{
    LOGV("AgcDisable");
    webrtc::GainControl *agc = static_cast<webrtc::GainControl *>(effect->engine);
    agc->Enable(false);
}


static const preproc_ops_t sAgcOps = {
        AgcCreate,
        AgcInit,
        NULL,
        AgcEnable,
        AgcDisable,
        AgcSetParameter,
        AgcGetParameter,
        NULL
};


//------------------------------------------------------------------------------
// Acoustic Echo Canceler (AEC)
//------------------------------------------------------------------------------

static const webrtc::EchoControlMobile::RoutingMode kAecDefaultMode =
        webrtc::EchoControlMobile::kEarpiece;
static const bool kAecDefaultComfortNoise = true;

int  AecInit (preproc_effect_t *effect)
{
    LOGV("AecInit");
    webrtc::EchoControlMobile *aec = static_cast<webrtc::EchoControlMobile *>(effect->engine);
    aec->set_routing_mode(kAecDefaultMode);
    aec->enable_comfort_noise(kAecDefaultComfortNoise);
    return 0;
}

int  AecCreate(preproc_effect_t *effect)
{
    webrtc::EchoControlMobile *aec = effect->session->apm->echo_control_mobile();
    LOGV("AecCreate got aec %p", aec);
    if (aec == NULL) {
        LOGW("AgcCreate Error");
        return -ENOMEM;
    }
    effect->engine = static_cast<preproc_fx_handle_t>(aec);
    AecInit (effect);
    return 0;
}

int AecGetParameter(preproc_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;
    }
    switch (param) {
    case AEC_PARAM_ECHO_DELAY:
    case AEC_PARAM_PROPERTIES:
        *(uint32_t *)pValue = 1000 * effect->session->apm->stream_delay_ms();
        LOGV("AecGetParameter() echo delay %d us", *(uint32_t *)pValue);
        break;
    default:
        LOGW("AecGetParameter() unknown param %08x value %08x", param, *(uint32_t *)pValue);
        status = -EINVAL;
        break;
    }
    return status;
}

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

    switch (param) {
    case AEC_PARAM_ECHO_DELAY:
    case AEC_PARAM_PROPERTIES:
        status = effect->session->apm->set_stream_delay_ms(value/1000);
        LOGV("AecSetParameter() echo delay %d us, status %d", value, status);
        break;
    default:
        LOGW("AecSetParameter() unknown param %08x value %08x", param, *(uint32_t *)pValue);
        status = -EINVAL;
        break;
    }
    return status;
}

void AecEnable(preproc_effect_t *effect)
{
    webrtc::EchoControlMobile *aec = static_cast<webrtc::EchoControlMobile *>(effect->engine);
    LOGV("AecEnable aec %p", aec);
    aec->Enable(true);
}

void AecDisable(preproc_effect_t *effect)
{
    LOGV("AecDisable");
    webrtc::EchoControlMobile *aec = static_cast<webrtc::EchoControlMobile *>(effect->engine);
    aec->Enable(false);
}

int AecSetDevice(preproc_effect_t *effect, uint32_t device)
{
    LOGV("AecSetDevice %08x", device);
    webrtc::EchoControlMobile *aec = static_cast<webrtc::EchoControlMobile *>(effect->engine);
    webrtc::EchoControlMobile::RoutingMode mode = webrtc::EchoControlMobile::kQuietEarpieceOrHeadset;

    switch(device) {
    case AUDIO_DEVICE_OUT_EARPIECE:
        mode = webrtc::EchoControlMobile::kEarpiece;
        break;
    case AUDIO_DEVICE_OUT_SPEAKER:
        mode = webrtc::EchoControlMobile::kSpeakerphone;
        break;
    case AUDIO_DEVICE_OUT_WIRED_HEADSET:
    case AUDIO_DEVICE_OUT_WIRED_HEADPHONE:
    default:
        break;
    }
    aec->set_routing_mode(mode);
    return 0;
}

static const preproc_ops_t sAecOps = {
        AecCreate,
        AecInit,
        NULL,
        AecEnable,
        AecDisable,
        AecSetParameter,
        AecGetParameter,
        AecSetDevice
};

//------------------------------------------------------------------------------
// Noise Suppression (NS)
//------------------------------------------------------------------------------

static const webrtc::NoiseSuppression::Level kNsDefaultLevel = webrtc::NoiseSuppression::kModerate;

int  NsInit (preproc_effect_t *effect)
{
    LOGV("NsInit");
    webrtc::NoiseSuppression *ns = static_cast<webrtc::NoiseSuppression *>(effect->engine);
    ns->set_level(kNsDefaultLevel);
    return 0;
}

int  NsCreate(preproc_effect_t *effect)
{
    webrtc::NoiseSuppression *ns = effect->session->apm->noise_suppression();
    LOGV("NsCreate got ns %p", ns);
    if (ns == NULL) {
        LOGW("AgcCreate Error");
        return -ENOMEM;
    }
    effect->engine = static_cast<preproc_fx_handle_t>(ns);
    NsInit (effect);
    return 0;
}

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

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

void NsEnable(preproc_effect_t *effect)
{
    webrtc::NoiseSuppression *ns = static_cast<webrtc::NoiseSuppression *>(effect->engine);
    LOGV("NsEnable ns %p", ns);
    ns->Enable(true);
}

void NsDisable(preproc_effect_t *effect)
{
    LOGV("NsDisable");
    webrtc::NoiseSuppression *ns = static_cast<webrtc::NoiseSuppression *>(effect->engine);
    ns->Enable(false);
}

static const preproc_ops_t sNsOps = {
        NsCreate,
        NsInit,
        NULL,
        NsEnable,
        NsDisable,
        NsSetParameter,
        NsGetParameter,
        NULL
};


static const preproc_ops_t *sPreProcOps[PREPROC_NUM_EFFECTS] = {
        &sAgcOps,
        &sAecOps,
        &sNsOps
};


//------------------------------------------------------------------------------
// Effect functions
//------------------------------------------------------------------------------

void Session_SetProcEnabled(preproc_session_t *session, uint32_t procId, bool enabled);

extern "C" const struct effect_interface_s sEffectInterface;
extern "C" const struct effect_interface_s sEffectInterfaceReverse;

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

int Effect_SetState(preproc_effect_t *effect, uint32_t state)
{
    int status = 0;
    LOGV("Effect_SetState proc %d, new %d old %d", effect->procId, state, effect->state);
    switch(state) {
    case PREPROC_EFFECT_STATE_INIT:
        switch(effect->state) {
        case PREPROC_EFFECT_STATE_ACTIVE:
            effect->ops->disable(effect);
            Session_SetProcEnabled(effect->session, effect->procId, false);
        case PREPROC_EFFECT_STATE_CONFIG:
        case PREPROC_EFFECT_STATE_CREATED:
        case PREPROC_EFFECT_STATE_INIT:
            break;
        default:
            BAD_STATE_ABORT(effect->state, state);
        }
        break;
    case PREPROC_EFFECT_STATE_CREATED:
        switch(effect->state) {
        case PREPROC_EFFECT_STATE_INIT:
            status = effect->ops->create(effect);
            break;
        case PREPROC_EFFECT_STATE_CREATED:
        case PREPROC_EFFECT_STATE_ACTIVE:
        case PREPROC_EFFECT_STATE_CONFIG:
            LOGE("Effect_SetState invalid transition");
            status = -ENOSYS;
            break;
        default:
            BAD_STATE_ABORT(effect->state, state);
        }
        break;
    case PREPROC_EFFECT_STATE_CONFIG:
        switch(effect->state) {
        case PREPROC_EFFECT_STATE_INIT:
            LOGE("Effect_SetState invalid transition");
            status = -ENOSYS;
            break;
        case PREPROC_EFFECT_STATE_ACTIVE:
            effect->ops->disable(effect);
            Session_SetProcEnabled(effect->session, effect->procId, false);
            break;
        case PREPROC_EFFECT_STATE_CREATED:
        case PREPROC_EFFECT_STATE_CONFIG:
            break;
        default:
            BAD_STATE_ABORT(effect->state, state);
        }
        break;
    case PREPROC_EFFECT_STATE_ACTIVE:
        switch(effect->state) {
        case PREPROC_EFFECT_STATE_INIT:
        case PREPROC_EFFECT_STATE_CREATED:
        case PREPROC_EFFECT_STATE_ACTIVE:
            LOGE("Effect_SetState invalid transition");
            status = -ENOSYS;
            break;
        case PREPROC_EFFECT_STATE_CONFIG:
            effect->ops->enable(effect);
            Session_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 Effect_Init(preproc_effect_t *effect, uint32_t procId)
{
    if (HasReverseStream(procId)) {
        effect->itfe = &sEffectInterfaceReverse;
    } else {
        effect->itfe = &sEffectInterface;
    }
    effect->ops = sPreProcOps[procId];
    effect->procId = procId;
    effect->state = PREPROC_EFFECT_STATE_INIT;
    return 0;
}

int Effect_Create(preproc_effect_t *effect,
               preproc_session_t *session,
               effect_handle_t  *interface)
{
    effect->session = session;
    *interface = (effect_handle_t)&effect->itfe;
    return Effect_SetState(effect, PREPROC_EFFECT_STATE_CREATED);
}

int Effect_Release(preproc_effect_t *effect)
{
    return Effect_SetState(effect, PREPROC_EFFECT_STATE_INIT);
}


//------------------------------------------------------------------------------
// Session functions
//------------------------------------------------------------------------------

#define RESAMPLER_QUALITY SPEEX_RESAMPLER_QUALITY_VOIP

static const int kPreprocDefaultSr = 16000;
static const int kPreProcDefaultCnl = 1;

int Session_Init(preproc_session_t *session)
{
    size_t i;
    int status = 0;

    session->state = PREPROC_SESSION_STATE_INIT;
    session->id = 0;
    session->io = 0;
    session->createdMsk = 0;
    session->apm = NULL;
    for (i = 0; i < PREPROC_NUM_EFFECTS && status == 0; i++) {
        status = Effect_Init(&session->effects[i], i);
    }
    return status;
}


extern "C" int Session_CreateEffect(preproc_session_t *session,
                                    int32_t procId,
                                    effect_handle_t  *interface)
{
    int status = -ENOMEM;

    LOGV("Session_CreateEffect procId %d, createdMsk %08x", procId, session->createdMsk);

    if (session->createdMsk == 0) {
        session->apm = webrtc::AudioProcessing::Create(session->io);
        if (session->apm == NULL) {
            LOGW("Session_CreateEffect could not get apm engine");
            goto error;
        }
        session->apm->set_sample_rate_hz(kPreprocDefaultSr);
        session->apm->set_num_channels(kPreProcDefaultCnl, kPreProcDefaultCnl);
        session->apm->set_num_reverse_channels(kPreProcDefaultCnl);
        session->procFrame = new webrtc::AudioFrame();
        if (session->procFrame == NULL) {
            LOGW("Session_CreateEffect could not allocate audio frame");
            goto error;
        }
        session->revFrame = new webrtc::AudioFrame();
        if (session->revFrame == NULL) {
            LOGW("Session_CreateEffect could not allocate reverse audio frame");
            goto error;
        }
        session->apmSamplingRate = kPreprocDefaultSr;
        session->apmFrameCount = (kPreprocDefaultSr) / 100;
        session->frameCount = session->apmFrameCount;
        session->samplingRate = kPreprocDefaultSr;
        session->inChannelCount = kPreProcDefaultCnl;
        session->outChannelCount = kPreProcDefaultCnl;
        session->procFrame->_frequencyInHz = kPreprocDefaultSr;
        session->procFrame->_audioChannel = kPreProcDefaultCnl;
        session->revChannelCount = kPreProcDefaultCnl;
        session->revFrame->_frequencyInHz = kPreprocDefaultSr;
        session->revFrame->_audioChannel = kPreProcDefaultCnl;
        session->enabledMsk = 0;
        session->processedMsk = 0;
        session->revEnabledMsk = 0;
        session->revProcessedMsk = 0;
        session->inResampler = NULL;
        session->inBuf = NULL;
        session->inBufSize = 0;
        session->outResampler = NULL;
        session->outBuf = NULL;
        session->outBufSize = 0;
        session->revResampler = NULL;
        session->revBuf = NULL;
        session->revBufSize = 0;
    }
    status = Effect_Create(&session->effects[procId], session, interface);
    if (status < 0) {
        goto error;
    }
    LOGV("Session_CreateEffect OK");
    session->createdMsk |= (1<<procId);
    return status;

error:
    if (session->createdMsk == 0) {
        delete session->revFrame;
        session->revFrame = NULL;
        delete session->procFrame;
        session->procFrame = NULL;
        webrtc::AudioProcessing::Destroy(session->apm);
        session->apm = NULL;
    }
    return status;
}

int Session_ReleaseEffect(preproc_session_t *session,
                          preproc_effect_t *fx)
{
    LOGW_IF(Effect_Release(fx) != 0, " Effect_Release() failed for proc ID %d", fx->procId);
    session->createdMsk &= ~(1<<fx->procId);
    if (session->createdMsk == 0) {
        webrtc::AudioProcessing::Destroy(session->apm);
        session->apm = NULL;
        delete session->procFrame;
        session->procFrame = NULL;
        delete session->revFrame;
        session->revFrame = NULL;
        if (session->inResampler != NULL) {
            speex_resampler_destroy(session->inResampler);
            session->inResampler = NULL;
        }
        if (session->outResampler != NULL) {
            speex_resampler_destroy(session->outResampler);
            session->outResampler = NULL;
        }
        if (session->revResampler != NULL) {
            speex_resampler_destroy(session->revResampler);
            session->revResampler = NULL;
        }
        delete session->inBuf;
        session->inBuf = NULL;
        delete session->outBuf;
        session->outBuf = NULL;
        delete session->revBuf;
        session->revBuf = NULL;

        session->io = 0;
    }

    return 0;
}


int Session_SetConfig(preproc_session_t *session, effect_config_t *config)
{
    uint32_t sr;
    uint32_t inCnl = popcount(config->inputCfg.channels);
    uint32_t outCnl = popcount(config->outputCfg.channels);

    if (config->inputCfg.samplingRate != config->outputCfg.samplingRate ||
        config->inputCfg.format != config->outputCfg.format ||
        config->inputCfg.format != AUDIO_FORMAT_PCM_16_BIT) {
        return -EINVAL;
    }

    LOGV("Session_SetConfig sr %d cnl %08x",
         config->inputCfg.samplingRate, config->inputCfg.channels);
    int status;

    // AEC implementation is limited to 16kHz
    if (config->inputCfg.samplingRate >= 32000 && !(session->createdMsk & (1 << PREPROC_AEC))) {
        session->apmSamplingRate = 32000;
    } else
    if (config->inputCfg.samplingRate >= 16000) {
        session->apmSamplingRate = 16000;
    } else if (config->inputCfg.samplingRate >= 8000) {
        session->apmSamplingRate = 8000;
    }
    status = session->apm->set_sample_rate_hz(session->apmSamplingRate);
    if (status < 0) {
        return -EINVAL;
    }
    status = session->apm->set_num_channels(inCnl, outCnl);
    if (status < 0) {
        return -EINVAL;
    }
    status = session->apm->set_num_reverse_channels(inCnl);
    if (status < 0) {
        return -EINVAL;
    }

    session->samplingRate = config->inputCfg.samplingRate;
    session->apmFrameCount = session->apmSamplingRate / 100;
    if (session->samplingRate == session->apmSamplingRate) {
        session->frameCount = session->apmFrameCount;
    } else {
        session->frameCount = (session->apmFrameCount * session->samplingRate) /
                session->apmSamplingRate  + 1;
    }
    session->inChannelCount = inCnl;
    session->outChannelCount = outCnl;
    session->procFrame->_audioChannel = inCnl;
    session->procFrame->_frequencyInHz = session->apmSamplingRate;

    session->revChannelCount = inCnl;
    session->revFrame->_audioChannel = inCnl;
    session->revFrame->_frequencyInHz = session->apmSamplingRate;

    if (session->inResampler != NULL) {
        speex_resampler_destroy(session->inResampler);
        session->inResampler = NULL;
    }
    if (session->outResampler != NULL) {
        speex_resampler_destroy(session->outResampler);
        session->outResampler = NULL;
    }
    if (session->revResampler != NULL) {
        speex_resampler_destroy(session->revResampler);
        session->revResampler = NULL;
    }
    if (session->samplingRate != session->apmSamplingRate) {
        int error;
        session->inResampler = speex_resampler_init(session->inChannelCount,
                                                    session->samplingRate,
                                                    session->apmSamplingRate,
                                                    RESAMPLER_QUALITY,
                                                    &error);
        if (session->inResampler == NULL) {
            LOGW("Session_SetConfig Cannot create speex resampler: %s",
                 speex_resampler_strerror(error));
            return -EINVAL;
        }
        session->outResampler = speex_resampler_init(session->outChannelCount,
                                                    session->apmSamplingRate,
                                                    session->samplingRate,
                                                    RESAMPLER_QUALITY,
                                                    &error);
        if (session->outResampler == NULL) {
            LOGW("Session_SetConfig Cannot create speex resampler: %s",
                 speex_resampler_strerror(error));
            speex_resampler_destroy(session->inResampler);
            session->inResampler = NULL;
            return -EINVAL;
        }
        session->revResampler = speex_resampler_init(session->inChannelCount,
                                                    session->samplingRate,
                                                    session->apmSamplingRate,
                                                    RESAMPLER_QUALITY,
                                                    &error);
        if (session->revResampler == NULL) {
            LOGW("Session_SetConfig Cannot create speex resampler: %s",
                 speex_resampler_strerror(error));
            speex_resampler_destroy(session->inResampler);
            session->inResampler = NULL;
            speex_resampler_destroy(session->outResampler);
            session->outResampler = NULL;
            return -EINVAL;
        }
    }

    session->state = PREPROC_SESSION_STATE_CONFIG;
    return 0;
}

int Session_SetReverseConfig(preproc_session_t *session, effect_config_t *config)
{
    if (config->inputCfg.samplingRate != config->outputCfg.samplingRate ||
            config->inputCfg.format != config->outputCfg.format ||
            config->inputCfg.format != AUDIO_FORMAT_PCM_16_BIT) {
        return -EINVAL;
    }

    LOGV("Session_SetReverseConfig sr %d cnl %08x",
         config->inputCfg.samplingRate, config->inputCfg.channels);

    if (session->state < PREPROC_SESSION_STATE_CONFIG) {
        return -ENOSYS;
    }
    if (config->inputCfg.samplingRate != session->samplingRate ||
            config->inputCfg.format != AUDIO_FORMAT_PCM_16_BIT) {
        return -EINVAL;
    }
    uint32_t inCnl = popcount(config->inputCfg.channels);
    int status = session->apm->set_num_reverse_channels(inCnl);
    if (status < 0) {
        return -EINVAL;
    }
    session->revChannelCount = inCnl;
    session->revFrame->_audioChannel = inCnl;
    session->revFrame->_frequencyInHz = session->apmSamplingRate;
    return 0;
}

void Session_SetProcEnabled(preproc_session_t *session, uint32_t procId, bool enabled)
{
    if (enabled) {
        if(session->enabledMsk == 0) {
            session->framesIn = 0;
            if (session->inResampler != NULL) {
                speex_resampler_reset_mem(session->inResampler);
            }
            session->framesOut = 0;
            if (session->outResampler != NULL) {
                speex_resampler_reset_mem(session->outResampler);
            }
        }
        session->enabledMsk |= (1 << procId);
        if (HasReverseStream(procId)) {
            session->framesRev = 0;
            if (session->revResampler != NULL) {
                speex_resampler_reset_mem(session->revResampler);
            }
            session->revEnabledMsk |= (1 << procId);
        }
    } else {
        session->enabledMsk &= ~(1 << procId);
        if (HasReverseStream(procId)) {
            session->revEnabledMsk &= ~(1 << procId);
        }
    }
    LOGV("Session_SetProcEnabled proc %d, enabled %d enabledMsk %08x revEnabledMsk %08x",
         procId, enabled, session->enabledMsk, session->revEnabledMsk);
    session->processedMsk = 0;
    if (HasReverseStream(procId)) {
        session->revProcessedMsk = 0;
    }
}

//------------------------------------------------------------------------------
// Bundle functions
//------------------------------------------------------------------------------

static int sInitStatus = 1;
static preproc_session_t sSessions[PREPROC_NUM_SESSIONS];

preproc_session_t *PreProc_GetSession(int32_t procId, int32_t  sessionId, int32_t  ioId)
{
    size_t i;
    int free = -1;
    for (i = 0; i < PREPROC_NUM_SESSIONS; i++) {
        if (sSessions[i].io == ioId) {
            if (sSessions[i].createdMsk & (1 << procId)) {
                return NULL;
            }
            return &sSessions[i];
        }
    }
    for (i = 0; i < PREPROC_NUM_SESSIONS; i++) {
        if (sSessions[i].io == 0) {
            sSessions[i].id = sessionId;
            sSessions[i].io = ioId;
            return &sSessions[i];
        }
    }
    return NULL;
}


int PreProc_Init() {
    size_t i;
    int status = 0;

    if (sInitStatus <= 0) {
        return sInitStatus;
    }
    for (i = 0; i < PREPROC_NUM_SESSIONS && status == 0; i++) {
        status = Session_Init(&sSessions[i]);
    }
    sInitStatus = status;
    return sInitStatus;
}

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


extern "C" {

//------------------------------------------------------------------------------
// Effect Control Interface Implementation
//------------------------------------------------------------------------------

int PreProcessingFx_Process(effect_handle_t     self,
                            audio_buffer_t    *inBuffer,
                            audio_buffer_t    *outBuffer)
{
    preproc_effect_t * effect = (preproc_effect_t *)self;
    int    status = 0;

    if (effect == NULL){
        LOGV("PreProcessingFx_Process() ERROR effect == NULL");
        return -EINVAL;
    }
    preproc_session_t * session = (preproc_session_t *)effect->session;

    if (inBuffer == NULL  || inBuffer->raw == NULL  ||
            outBuffer == NULL || outBuffer->raw == NULL){
        LOGW("PreProcessingFx_Process() ERROR bad pointer");
        return -EINVAL;
    }

    session->processedMsk |= (1<<effect->procId);

//    LOGV("PreProcessingFx_Process In %d frames enabledMsk %08x processedMsk %08x",
//         inBuffer->frameCount, session->enabledMsk, session->processedMsk);

    if ((session->processedMsk & session->enabledMsk) == session->enabledMsk) {
        effect->session->processedMsk = 0;
        size_t framesRq = outBuffer->frameCount;
        size_t framesWr = 0;
        if (session->framesOut) {
            size_t fr = session->framesOut;
            if (outBuffer->frameCount < fr) {
                fr = outBuffer->frameCount;
            }
            memcpy(outBuffer->s16,
                  session->outBuf,
                  fr * session->outChannelCount * sizeof(int16_t));
            memcpy(session->outBuf,
                  session->outBuf + fr * session->outChannelCount,
                  (session->framesOut - fr) * session->outChannelCount * sizeof(int16_t));
            session->framesOut -= fr;
            framesWr += fr;
        }
        outBuffer->frameCount = framesWr;
        if (framesWr == framesRq) {
            inBuffer->frameCount = 0;
            return 0;
        }

        if (session->inResampler != NULL) {
            size_t fr = session->frameCount - session->framesIn;
            if (inBuffer->frameCount < fr) {
                fr = inBuffer->frameCount;
            }
            if (session->inBufSize < session->framesIn + fr) {
                session->inBufSize = session->framesIn + fr;
                session->inBuf = (int16_t *)realloc(session->inBuf,
                                 session->inBufSize * session->inChannelCount * sizeof(int16_t));
            }
            memcpy(session->inBuf + session->framesIn * session->inChannelCount,
                   inBuffer->s16,
                   fr * session->inChannelCount * sizeof(int16_t));

            session->framesIn += fr;
            inBuffer->frameCount = fr;
            if (session->framesIn < session->frameCount) {
                return 0;
            }
            size_t frIn = session->framesIn;
            size_t frOut = session->apmFrameCount;
            if (session->inChannelCount == 1) {
                speex_resampler_process_int(session->inResampler,
                                            0,
                                            session->inBuf,
                                            &frIn,
                                            session->procFrame->_payloadData,
                                            &frOut);
            } else {
                speex_resampler_process_interleaved_int(session->inResampler,
                                                        session->inBuf,
                                                        &frIn,
                                                        session->procFrame->_payloadData,
                                                        &frOut);
            }
            memcpy(session->inBuf,
                   session->inBuf + frIn * session->inChannelCount,
                   (session->framesIn - frIn) * session->inChannelCount * sizeof(int16_t));
            session->framesIn -= frIn;
        } else {
            size_t fr = session->frameCount - session->framesIn;
            if (inBuffer->frameCount < fr) {
                fr = inBuffer->frameCount;
            }
            memcpy(session->procFrame->_payloadData + session->framesIn * session->inChannelCount,
                   inBuffer->s16,
                   fr * session->inChannelCount * sizeof(int16_t));
            session->framesIn += fr;
            inBuffer->frameCount = fr;
            if (session->framesIn < session->frameCount) {
                return 0;
            }
            session->framesIn = 0;
        }
        session->procFrame->_payloadDataLengthInSamples =
                session->apmFrameCount * session->inChannelCount;

        effect->session->apm->ProcessStream(session->procFrame);

        if (session->outBufSize < session->framesOut + session->frameCount) {
            session->outBufSize = session->framesOut + session->frameCount;
            session->outBuf = (int16_t *)realloc(session->outBuf,
                              session->outBufSize * session->outChannelCount * sizeof(int16_t));
        }

        if (session->outResampler != NULL) {
            size_t frIn = session->apmFrameCount;
            size_t frOut = session->frameCount;
            if (session->inChannelCount == 1) {
                speex_resampler_process_int(session->outResampler,
                                    0,
                                    session->procFrame->_payloadData,
                                    &frIn,
                                    session->outBuf + session->framesOut * session->outChannelCount,
                                    &frOut);
            } else {
                speex_resampler_process_interleaved_int(session->outResampler,
                                    session->procFrame->_payloadData,
                                    &frIn,
                                    session->outBuf + session->framesOut * session->outChannelCount,
                                    &frOut);
            }
            session->framesOut += frOut;
        } else {
            memcpy(session->outBuf + session->framesOut * session->outChannelCount,
                   session->procFrame->_payloadData,
                   session->frameCount * session->outChannelCount * sizeof(int16_t));
            session->framesOut += session->frameCount;
        }
        size_t fr = session->framesOut;
        if (framesRq - framesWr < fr) {
            fr = framesRq - framesWr;
        }
        memcpy(outBuffer->s16 + framesWr * session->outChannelCount,
              session->outBuf,
              fr * session->outChannelCount * sizeof(int16_t));
        memcpy(session->outBuf,
              session->outBuf + fr * session->outChannelCount,
              (session->framesOut - fr) * session->outChannelCount * sizeof(int16_t));
        session->framesOut -= fr;
        outBuffer->frameCount += fr;

        return 0;
    } else {
        return -ENODATA;
    }
}

int PreProcessingFx_Command(effect_handle_t  self,
                            uint32_t            cmdCode,
                            uint32_t            cmdSize,
                            void                *pCmdData,
                            uint32_t            *replySize,
                            void                *pReplyData)
{
    preproc_effect_t * effect = (preproc_effect_t *) self;
    int retsize;
    int status;

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

    //LOGV("PreProcessingFx_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_CONFIGURE:
            if (pCmdData    == NULL||
                cmdSize     != sizeof(effect_config_t)||
                pReplyData  == NULL||
                *replySize  != sizeof(int)){
                LOGV("PreProcessingFx_Command cmdCode Case: "
                        "EFFECT_CMD_CONFIGURE: ERROR");
                return -EINVAL;
            }
            *(int *)pReplyData = Session_SetConfig(effect->session, (effect_config_t *)pCmdData);
            if (*(int *)pReplyData != 0) {
                break;
            }
            *(int *)pReplyData = Effect_SetState(effect, PREPROC_EFFECT_STATE_CONFIG);
            break;

        case EFFECT_CMD_CONFIGURE_REVERSE:
            if (pCmdData    == NULL||
                cmdSize     != sizeof(effect_config_t)||
                pReplyData  == NULL||
                *replySize  != sizeof(int)){
                LOGV("PreProcessingFx_Command cmdCode Case: "
                        "EFFECT_CMD_CONFIGURE_REVERSE: ERROR");
                return -EINVAL;
            }
            *(int *)pReplyData = Session_SetReverseConfig(effect->session,
                                                          (effect_config_t *)pCmdData);
            if (*(int *)pReplyData != 0) {
                break;
            }
            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)){
                LOGV("PreProcessingFx_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)){
                LOGV("PreProcessingFx_Command cmdCode Case: "
                        "EFFECT_CMD_SET_PARAM: ERROR");
                return -EINVAL;
            }
            effect_param_t *p = (effect_param_t *) pCmdData;

            if (p->psize != sizeof(int32_t)){
                LOGV("PreProcessingFx_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)){
                LOGV("PreProcessingFx_Command cmdCode Case: EFFECT_CMD_ENABLE: ERROR");
                return -EINVAL;
            }
            *(int *)pReplyData = Effect_SetState(effect, PREPROC_EFFECT_STATE_ACTIVE);
            break;

        case EFFECT_CMD_DISABLE:
            if (pReplyData == NULL || *replySize != sizeof(int)){
                LOGV("PreProcessingFx_Command cmdCode Case: EFFECT_CMD_DISABLE: ERROR");
                return -EINVAL;
            }
            *(int *)pReplyData  = Effect_SetState(effect, PREPROC_EFFECT_STATE_CONFIG);
            break;

        case EFFECT_CMD_SET_DEVICE:
        case EFFECT_CMD_SET_INPUT_DEVICE:
            if (pCmdData == NULL ||
                cmdSize != sizeof(uint32_t)) {
                LOGV("PreProcessingFx_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:
            break;

        default:
            return -EINVAL;
    }
    return 0;
}


int PreProcessingFx_GetDescriptor(effect_handle_t   self,
                                  effect_descriptor_t *pDescriptor)
{
    preproc_effect_t * effect = (preproc_effect_t *) self;

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

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

    return 0;
}

int PreProcessingFx_ProcessReverse(effect_handle_t     self,
                                   audio_buffer_t    *inBuffer,
                                   audio_buffer_t    *outBuffer)
{
    preproc_effect_t * effect = (preproc_effect_t *)self;
    int    status = 0;

    if (effect == NULL){
        LOGW("PreProcessingFx_ProcessReverse() ERROR effect == NULL");
        return -EINVAL;
    }
    preproc_session_t * session = (preproc_session_t *)effect->session;

    if (inBuffer == NULL  || inBuffer->raw == NULL){
        LOGW("PreProcessingFx_ProcessReverse() ERROR bad pointer");
        return -EINVAL;
    }

    session->revProcessedMsk |= (1<<effect->procId);

//    LOGV("PreProcessingFx_ProcessReverse In %d frames revEnabledMsk %08x revProcessedMsk %08x",
//         inBuffer->frameCount, session->revEnabledMsk, session->revProcessedMsk);


    if ((session->revProcessedMsk & session->revEnabledMsk) == session->revEnabledMsk) {
        effect->session->revProcessedMsk = 0;
        if (session->revResampler != NULL) {
            size_t fr = session->frameCount - session->framesRev;
            if (inBuffer->frameCount < fr) {
                fr = inBuffer->frameCount;
            }
            if (session->revBufSize < session->framesRev + fr) {
                session->revBufSize = session->framesRev + fr;
                session->revBuf = (int16_t *)realloc(session->revBuf,
                                  session->revBufSize * session->inChannelCount * sizeof(int16_t));
            }
            memcpy(session->revBuf + session->framesRev * session->inChannelCount,
                   inBuffer->s16,
                   fr * session->inChannelCount * sizeof(int16_t));

            session->framesRev += fr;
            inBuffer->frameCount = fr;
            if (session->framesRev < session->frameCount) {
                return 0;
            }
            size_t frIn = session->framesRev;
            size_t frOut = session->apmFrameCount;
            if (session->inChannelCount == 1) {
                speex_resampler_process_int(session->revResampler,
                                            0,
                                            session->revBuf,
                                            &frIn,
                                            session->revFrame->_payloadData,
                                            &frOut);
            } else {
                speex_resampler_process_interleaved_int(session->revResampler,
                                                        session->revBuf,
                                                        &frIn,
                                                        session->revFrame->_payloadData,
                                                        &frOut);
            }
            memcpy(session->revBuf,
                   session->revBuf + frIn * session->inChannelCount,
                   (session->framesRev - frIn) * session->inChannelCount * sizeof(int16_t));
            session->framesRev -= frIn;
        } else {
            size_t fr = session->frameCount - session->framesRev;
            if (inBuffer->frameCount < fr) {
                fr = inBuffer->frameCount;
            }
            memcpy(session->revFrame->_payloadData + session->framesRev * session->inChannelCount,
                   inBuffer->s16,
                   fr * session->inChannelCount * sizeof(int16_t));
            session->framesRev += fr;
            inBuffer->frameCount = fr;
            if (session->framesRev < session->frameCount) {
                return 0;
            }
            session->framesRev = 0;
        }
        session->revFrame->_payloadDataLengthInSamples =
                session->apmFrameCount * session->inChannelCount;
        effect->session->apm->AnalyzeReverseStream(session->revFrame);
        return 0;
    } else {
        return -ENODATA;
    }
}


// effect_handle_t interface implementation for effect
const struct effect_interface_s sEffectInterface = {
    PreProcessingFx_Process,
    PreProcessingFx_Command,
    PreProcessingFx_GetDescriptor,
    NULL
};

const struct effect_interface_s sEffectInterfaceReverse = {
    PreProcessingFx_Process,
    PreProcessingFx_Command,
    PreProcessingFx_GetDescriptor,
    PreProcessingFx_ProcessReverse
};

//------------------------------------------------------------------------------
// Effect Library Interface Implementation
//------------------------------------------------------------------------------

int PreProcessingLib_QueryNumberEffects(uint32_t *pNumEffects)
{
    if (PreProc_Init() != 0) {
        return sInitStatus;
    }
    if (pNumEffects == NULL) {
        return -EINVAL;
    }
    *pNumEffects = PREPROC_NUM_EFFECTS;
    return sInitStatus;
}

int PreProcessingLib_QueryEffect(uint32_t index, effect_descriptor_t *pDescriptor)
{
    if (PreProc_Init() != 0) {
        return sInitStatus;
    }
    if (index >= PREPROC_NUM_EFFECTS) {
        return -EINVAL;
    }
    memcpy(pDescriptor, sDescriptors[index], sizeof(effect_descriptor_t));
    return 0;
}

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

    int status;
    const effect_descriptor_t *desc;
    preproc_session_t *session;
    uint32_t procId;

    if (PreProc_Init() != 0) {
        return sInitStatus;
    }
    desc =  PreProc_GetDescriptor(uuid);
    if (desc == NULL) {
        LOGW("EffectCreate: fx not found uuid: %08x", uuid->timeLow);
        return -EINVAL;
    }
    procId = UuidToProcId(&desc->type);

    session = PreProc_GetSession(procId, sessionId, ioId);
    if (session == NULL) {
        LOGW("EffectCreate: no more session available");
        return -EINVAL;
    }

    status = Session_CreateEffect(session, procId, pInterface);

    if (status < 0 && session->createdMsk == 0) {
        session->io = 0;
    }
    return status;
}

int PreProcessingLib_Release(effect_handle_t interface)
{
    int status;
    LOGV("EffectRelease start %p", interface);
    if (PreProc_Init() != 0) {
        return sInitStatus;
    }

    preproc_effect_t *fx = (preproc_effect_t *)interface;

    if (fx->session->io == 0) {
        return -EINVAL;
    }
    return Session_ReleaseEffect(fx->session, fx);
}

int PreProcessingLib_GetDescriptor(effect_uuid_t       *uuid,
                                   effect_descriptor_t *pDescriptor) {

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

    const effect_descriptor_t *desc = PreProc_GetDescriptor(uuid);
    if (desc == NULL) {
        LOGV("PreProcessingLib_GetDescriptor() not found");
        return  -EINVAL;
    }

    LOGV("PreProcessingLib_GetDescriptor() 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 : "Audio Preprocessing Library",
    implementor : "The Android Open Source Project",
    query_num_effects : PreProcessingLib_QueryNumberEffects,
    query_effect : PreProcessingLib_QueryEffect,
    create_effect : PreProcessingLib_Create,
    release_effect : PreProcessingLib_Release,
    get_descriptor : PreProcessingLib_GetDescriptor
};

}; // extern "C"
