/*
 * 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 <module_common_types.h>
#include <audio_processing.h>
#include "speex/speex_resampler.h"

// undefine to perform multi channels API functional tests
//#define DUAL_MIC_TEST

//------------------------------------------------------------------------------
// 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, uint32_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
    uint32_t type;                  // subtype of effect
#ifdef DUAL_MIC_TEST
    bool aux_channels_on;           // support auxiliary channels
    size_t cur_channel_config;      // current auciliary channel configuration
#endif
};

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

#ifdef DUAL_MIC_TEST
enum {
    PREPROC_CMD_DUAL_MIC_ENABLE = EFFECT_CMD_FIRST_PROPRIETARY, // enable dual mic mode
    PREPROC_CMD_DUAL_MIC_PCM_DUMP_START,                        // start pcm capture
    PREPROC_CMD_DUAL_MIC_PCM_DUMP_STOP                          // stop pcm capture
};

enum {
    CHANNEL_CFG_MONO,
    CHANNEL_CFG_STEREO,
    CHANNEL_CFG_MONO_AUX,
    CHANNEL_CFG_STEREO_AUX,
    CHANNEL_CFG_CNT,
    CHANNEL_CFG_FIRST_AUX = CHANNEL_CFG_MONO_AUX,
};

const channel_config_t sDualMicConfigs[CHANNEL_CFG_CNT] = {
        {AUDIO_CHANNEL_IN_MONO , 0},
        {AUDIO_CHANNEL_IN_STEREO , 0},
        {AUDIO_CHANNEL_IN_FRONT , AUDIO_CHANNEL_IN_BACK},
        {AUDIO_CHANNEL_IN_STEREO , AUDIO_CHANNEL_IN_RIGHT}
};

bool sHasAuxChannels[PREPROC_NUM_EFFECTS] = {
        false,   // PREPROC_AGC
        true,   // PREPROC_AEC
        true,   // PREPROC_NS
};

bool gDualMicEnabled;
FILE *gPcmDumpFh;
static pthread_mutex_t gPcmDumpLock = PTHREAD_MUTEX_INITIALIZER;
#endif


//------------------------------------------------------------------------------
// 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 = 3;
static const int kAgcDefaultCompGain = 9;
static const bool kAgcDefaultLimiter = true;

int  AgcInit (preproc_effect_t *effect)
{
    ALOGV("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();
    ALOGV("AgcCreate got agc %p", agc);
    if (agc == NULL) {
        ALOGW("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,
                    uint32_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:
        ALOGW("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);
        ALOGV("AgcGetParameter() target level %d milliBels", *(int16_t *) pValue);
        break;
    case AGC_PARAM_COMP_GAIN:
        *(int16_t *) pValue = (int16_t)(agc->compression_gain_db() * 100);
        ALOGV("AgcGetParameter() comp gain %d milliBels", *(int16_t *) pValue);
        break;
    case AGC_PARAM_LIMITER_ENA:
        *(bool *) pValue = (bool)agc->is_limiter_enabled();
        ALOGV("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:
        ALOGW("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:
        ALOGV("AgcSetParameter() target level %d milliBels", *(int16_t *)pValue);
        status = agc->set_target_level_dbfs(-(*(int16_t *)pValue / 100));
        break;
    case AGC_PARAM_COMP_GAIN:
        ALOGV("AgcSetParameter() comp gain %d milliBels", *(int16_t *)pValue);
        status = agc->set_compression_gain_db(*(int16_t *)pValue / 100);
        break;
    case AGC_PARAM_LIMITER_ENA:
        ALOGV("AgcSetParameter() limiter enabled %s", *(bool *)pValue ? "true" : "false");
        status = agc->enable_limiter(*(bool *)pValue);
        break;
    case AGC_PARAM_PROPERTIES:
        ALOGV("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:
        ALOGW("AgcSetParameter() unknown param %08x value %08x", param, *(uint32_t *)pValue);
        status = -EINVAL;
        break;
    }

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

    return status;
}

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

void AgcDisable(preproc_effect_t *effect)
{
    ALOGV("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)
{
    ALOGV("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();
    ALOGV("AecCreate got aec %p", aec);
    if (aec == NULL) {
        ALOGW("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,
                    uint32_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();
        ALOGV("AecGetParameter() echo delay %d us", *(uint32_t *)pValue);
        break;
    default:
        ALOGW("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);
        ALOGV("AecSetParameter() echo delay %d us, status %d", value, status);
        break;
    default:
        ALOGW("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);
    ALOGV("AecEnable aec %p", aec);
    aec->Enable(true);
}

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

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

    if (audio_is_input_device(device)) {
        return 0;
    }

    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)
{
    ALOGV("NsInit");
    webrtc::NoiseSuppression *ns = static_cast<webrtc::NoiseSuppression *>(effect->engine);
    ns->set_level(kNsDefaultLevel);
    webrtc::Config config;
    std::vector<webrtc::Point> geometry;
    // TODO(aluebs): Make the geometry settable.
    geometry.push_back(webrtc::Point(-0.03f, 0.f, 0.f));
    geometry.push_back(webrtc::Point(-0.01f, 0.f, 0.f));
    geometry.push_back(webrtc::Point(0.01f, 0.f, 0.f));
    geometry.push_back(webrtc::Point(0.03f, 0.f, 0.f));
    // The geometry needs to be set with Beamforming enabled.
    config.Set<webrtc::Beamforming>(
            new webrtc::Beamforming(true, geometry));
    effect->session->apm->SetExtraOptions(config);
    config.Set<webrtc::Beamforming>(
            new webrtc::Beamforming(false, geometry));
    effect->session->apm->SetExtraOptions(config);
    effect->type = NS_TYPE_SINGLE_CHANNEL;
    return 0;
}

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

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

int NsSetParameter (preproc_effect_t *effect, void *pParam, void *pValue)
{
    int status = 0;
    webrtc::NoiseSuppression *ns = static_cast<webrtc::NoiseSuppression *>(effect->engine);
    uint32_t param = *(uint32_t *)pParam;
    uint32_t value = *(uint32_t *)pValue;
    switch(param) {
        case NS_PARAM_LEVEL:
            ns->set_level((webrtc::NoiseSuppression::Level)value);
            ALOGV("NsSetParameter() level %d", value);
            break;
        case NS_PARAM_TYPE:
        {
            webrtc::Config config;
            std::vector<webrtc::Point> geometry;
            bool is_beamforming_enabled =
                    value == NS_TYPE_MULTI_CHANNEL && ns->is_enabled();
            config.Set<webrtc::Beamforming>(
                    new webrtc::Beamforming(is_beamforming_enabled, geometry));
            effect->session->apm->SetExtraOptions(config);
            effect->type = value;
            ALOGV("NsSetParameter() type %d", value);
            break;
        }
        default:
            ALOGW("NsSetParameter() unknown param %08x value %08x", param, value);
            status = -EINVAL;
    }

    return status;
}

void NsEnable(preproc_effect_t *effect)
{
    webrtc::NoiseSuppression *ns = static_cast<webrtc::NoiseSuppression *>(effect->engine);
    ALOGV("NsEnable ns %p", ns);
    ns->Enable(true);
    if (effect->type == NS_TYPE_MULTI_CHANNEL) {
        webrtc::Config config;
        std::vector<webrtc::Point> geometry;
        config.Set<webrtc::Beamforming>(new webrtc::Beamforming(true, geometry));
        effect->session->apm->SetExtraOptions(config);
    }
}

void NsDisable(preproc_effect_t *effect)
{
    ALOGV("NsDisable");
    webrtc::NoiseSuppression *ns = static_cast<webrtc::NoiseSuppression *>(effect->engine);
    ns->Enable(false);
    webrtc::Config config;
    std::vector<webrtc::Point> geometry;
    config.Set<webrtc::Beamforming>(new webrtc::Beamforming(false, geometry));
    effect->session->apm->SetExtraOptions(config);
}

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;
    ALOGV("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:
            ALOGE("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:
            ALOGE("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:
            ALOGE("Effect_SetState invalid transition");
            status = -ENOSYS;
            break;
        case PREPROC_EFFECT_STATE_ACTIVE:
            // enabling an already enabled effect is just ignored
            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;

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

    if (session->createdMsk == 0) {
        session->apm = webrtc::AudioProcessing::Create();
        if (session->apm == NULL) {
            ALOGW("Session_CreateEffect could not get apm engine");
            goto error;
        }
        const webrtc::ProcessingConfig processing_config = {
            {{kPreprocDefaultSr, kPreProcDefaultCnl},
             {kPreprocDefaultSr, kPreProcDefaultCnl},
             {kPreprocDefaultSr, kPreProcDefaultCnl},
             {kPreprocDefaultSr, kPreProcDefaultCnl}}};
        session->apm->Initialize(processing_config);
        session->procFrame = new webrtc::AudioFrame();
        if (session->procFrame == NULL) {
            ALOGW("Session_CreateEffect could not allocate audio frame");
            goto error;
        }
        session->revFrame = new webrtc::AudioFrame();
        if (session->revFrame == NULL) {
            ALOGW("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->sample_rate_hz_ = kPreprocDefaultSr;
        session->procFrame->num_channels_ = kPreProcDefaultCnl;
        session->revChannelCount = kPreProcDefaultCnl;
        session->revFrame->sample_rate_hz_ = kPreprocDefaultSr;
        session->revFrame->num_channels_ = 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;
    }
    ALOGV("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;
        delete session->apm;
        session->apm = NULL;
    }
    return status;
}

int Session_ReleaseEffect(preproc_session_t *session,
                          preproc_effect_t *fx)
{
    ALOGW_IF(Effect_Release(fx) != 0, " Effect_Release() failed for proc ID %d", fx->procId);
    session->createdMsk &= ~(1<<fx->procId);
    if (session->createdMsk == 0) {
        delete 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 = audio_channel_count_from_in_mask(config->inputCfg.channels);
    uint32_t outCnl = audio_channel_count_from_in_mask(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;
    }

    ALOGV("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;
    }

    const webrtc::ProcessingConfig processing_config = {
      {{static_cast<int>(session->apmSamplingRate), inCnl},
       {static_cast<int>(session->apmSamplingRate), outCnl},
       {static_cast<int>(session->apmSamplingRate), inCnl},
       {static_cast<int>(session->apmSamplingRate), inCnl}}};
    status = session->apm->Initialize(processing_config);
    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->num_channels_ = inCnl;
    session->procFrame->sample_rate_hz_ = session->apmSamplingRate;

    session->revChannelCount = inCnl;
    session->revFrame->num_channels_ = inCnl;
    session->revFrame->sample_rate_hz_ = session->apmSamplingRate;

    // force process buffer reallocation
    session->inBufSize = 0;
    session->outBufSize = 0;
    session->framesIn = 0;
    session->framesOut = 0;


    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) {
            ALOGW("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) {
            ALOGW("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) {
            ALOGW("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;
}

void Session_GetConfig(preproc_session_t *session, effect_config_t *config)
{
    memset(config, 0, sizeof(effect_config_t));
    config->inputCfg.samplingRate = config->outputCfg.samplingRate = session->samplingRate;
    config->inputCfg.format = config->outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
    config->inputCfg.channels = audio_channel_in_mask_from_count(session->inChannelCount);
    // "out" doesn't mean output device, so this is the correct API to convert channel count to mask
    config->outputCfg.channels = audio_channel_in_mask_from_count(session->outChannelCount);
    config->inputCfg.mask = config->outputCfg.mask =
            (EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT);
}

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;
    }

    ALOGV("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 = audio_channel_count_from_out_mask(config->inputCfg.channels);
    const webrtc::ProcessingConfig processing_config = {
       {{static_cast<int>(session->apmSamplingRate), session->inChannelCount},
        {static_cast<int>(session->apmSamplingRate), session->outChannelCount},
        {static_cast<int>(session->apmSamplingRate), inCnl},
        {static_cast<int>(session->apmSamplingRate), inCnl}}};
    int status = session->apm->Initialize(processing_config);
    if (status < 0) {
        return -EINVAL;
    }
    session->revChannelCount = inCnl;
    session->revFrame->num_channels_ = inCnl;
    session->revFrame->sample_rate_hz_ = session->apmSamplingRate;
    // force process buffer reallocation
    session->revBufSize = 0;
    session->framesRev = 0;

    return 0;
}

void Session_GetReverseConfig(preproc_session_t *session, effect_config_t *config)
{
    memset(config, 0, sizeof(effect_config_t));
    config->inputCfg.samplingRate = config->outputCfg.samplingRate = session->samplingRate;
    config->inputCfg.format = config->outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
    config->inputCfg.channels = config->outputCfg.channels =
            audio_channel_in_mask_from_count(session->revChannelCount);
    config->inputCfg.mask = config->outputCfg.mask =
            (EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT);
}

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);
        }
    }
    ALOGV("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(const 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){
        ALOGV("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){
        ALOGW("PreProcessingFx_Process() ERROR bad pointer");
        return -EINVAL;
    }

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

//    ALOGV("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) {
                int16_t *buf;
                session->inBufSize = session->framesIn + fr;
                buf = (int16_t *)realloc(session->inBuf,
                                 session->inBufSize * session->inChannelCount * sizeof(int16_t));
                if (buf == NULL) {
                    session->framesIn = 0;
                    free(session->inBuf);
                    session->inBuf = NULL;
                    return -ENOMEM;
                }
                session->inBuf = buf;
            }
            memcpy(session->inBuf + session->framesIn * session->inChannelCount,
                   inBuffer->s16,
                   fr * session->inChannelCount * sizeof(int16_t));
#ifdef DUAL_MIC_TEST
            pthread_mutex_lock(&gPcmDumpLock);
            if (gPcmDumpFh != NULL) {
                fwrite(inBuffer->raw,
                       fr * session->inChannelCount * sizeof(int16_t), 1, gPcmDumpFh);
            }
            pthread_mutex_unlock(&gPcmDumpLock);
#endif

            session->framesIn += fr;
            inBuffer->frameCount = fr;
            if (session->framesIn < session->frameCount) {
                return 0;
            }
            spx_uint32_t frIn = session->framesIn;
            spx_uint32_t frOut = session->apmFrameCount;
            if (session->inChannelCount == 1) {
                speex_resampler_process_int(session->inResampler,
                                            0,
                                            session->inBuf,
                                            &frIn,
                                            session->procFrame->data_,
                                            &frOut);
            } else {
                speex_resampler_process_interleaved_int(session->inResampler,
                                                        session->inBuf,
                                                        &frIn,
                                                        session->procFrame->data_,
                                                        &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->data_ + session->framesIn * session->inChannelCount,
                   inBuffer->s16,
                   fr * session->inChannelCount * sizeof(int16_t));

#ifdef DUAL_MIC_TEST
            pthread_mutex_lock(&gPcmDumpLock);
            if (gPcmDumpFh != NULL) {
                fwrite(inBuffer->raw,
                       fr * session->inChannelCount * sizeof(int16_t), 1, gPcmDumpFh);
            }
            pthread_mutex_unlock(&gPcmDumpLock);
#endif

            session->framesIn += fr;
            inBuffer->frameCount = fr;
            if (session->framesIn < session->frameCount) {
                return 0;
            }
            session->framesIn = 0;
        }
        session->procFrame->samples_per_channel_ = session->apmFrameCount;

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

        if (session->outBufSize < session->framesOut + session->frameCount) {
            int16_t *buf;
            session->outBufSize = session->framesOut + session->frameCount;
            buf = (int16_t *)realloc(session->outBuf,
                             session->outBufSize * session->outChannelCount * sizeof(int16_t));
            if (buf == NULL) {
                session->framesOut = 0;
                free(session->outBuf);
                session->outBuf = NULL;
                return -ENOMEM;
            }
            session->outBuf = buf;
        }

        if (session->outResampler != NULL) {
            spx_uint32_t frIn = session->apmFrameCount;
            spx_uint32_t frOut = session->frameCount;
            if (session->inChannelCount == 1) {
                speex_resampler_process_int(session->outResampler,
                                    0,
                                    session->procFrame->data_,
                                    &frIn,
                                    session->outBuf + session->framesOut * session->outChannelCount,
                                    &frOut);
            } else {
                speex_resampler_process_interleaved_int(session->outResampler,
                                    session->procFrame->data_,
                                    &frIn,
                                    session->outBuf + session->framesOut * session->outChannelCount,
                                    &frOut);
            }
            session->framesOut += frOut;
        } else {
            memcpy(session->outBuf + session->framesOut * session->outChannelCount,
                   session->procFrame->data_,
                   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;
    }

    //ALOGV("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_SET_CONFIG: {
            if (pCmdData    == NULL||
                cmdSize     != sizeof(effect_config_t)||
                pReplyData  == NULL||
                *replySize  != sizeof(int)){
                ALOGV("PreProcessingFx_Command cmdCode Case: "
                        "EFFECT_CMD_SET_CONFIG: ERROR");
                return -EINVAL;
            }
#ifdef DUAL_MIC_TEST
            // make sure that the config command is accepted by making as if all effects were
            // disabled: this is OK for functional tests
            uint32_t enabledMsk = effect->session->enabledMsk;
            if (gDualMicEnabled) {
                effect->session->enabledMsk = 0;
            }
#endif
            *(int *)pReplyData = Session_SetConfig(effect->session, (effect_config_t *)pCmdData);
#ifdef DUAL_MIC_TEST
            if (gDualMicEnabled) {
                effect->session->enabledMsk = enabledMsk;
            }
#endif
            if (*(int *)pReplyData != 0) {
                break;
            }
            if (effect->state != PREPROC_EFFECT_STATE_ACTIVE) {
                *(int *)pReplyData = Effect_SetState(effect, PREPROC_EFFECT_STATE_CONFIG);
            }
            } break;

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

            Session_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("PreProcessingFx_Command cmdCode Case: "
                        "EFFECT_CMD_SET_CONFIG_REVERSE: ERROR");
                return -EINVAL;
            }
            *(int *)pReplyData = Session_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("PreProcessingFx_Command cmdCode Case: "
                        "EFFECT_CMD_GET_CONFIG_REVERSE: ERROR");
                return -EINVAL;
            }
            Session_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: {
            effect_param_t *p = (effect_param_t *)pCmdData;

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

            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,
                                                       &p->vsize,
                                                       p->data + voffset);
                *replySize = sizeof(effect_param_t) + voffset + p->vsize;
            }
        } break;

        case EFFECT_CMD_SET_PARAM:{
            if (pCmdData == NULL||
                    cmdSize < sizeof(effect_param_t) ||
                    pReplyData == NULL || replySize == NULL ||
                    *replySize != sizeof(int32_t)){
                ALOGV("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)){
                ALOGV("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 == NULL || *replySize != sizeof(int)){
                ALOGV("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 == NULL || *replySize != sizeof(int)){
                ALOGV("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)) {
                ALOGV("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;

#ifdef DUAL_MIC_TEST
        ///// test commands start
        case PREPROC_CMD_DUAL_MIC_ENABLE: {
            if (pCmdData == NULL|| cmdSize != sizeof(uint32_t) ||
                    pReplyData == NULL || replySize == NULL) {
                ALOGE("PreProcessingFx_Command cmdCode Case: "
                        "PREPROC_CMD_DUAL_MIC_ENABLE: ERROR");
                *replySize = 0;
                return -EINVAL;
            }
            gDualMicEnabled = *(bool *)pCmdData;
            if (gDualMicEnabled) {
                effect->aux_channels_on = sHasAuxChannels[effect->procId];
            } else {
                effect->aux_channels_on = false;
            }
            effect->cur_channel_config = (effect->session->inChannelCount == 1) ?
                    CHANNEL_CFG_MONO : CHANNEL_CFG_STEREO;

            ALOGV("PREPROC_CMD_DUAL_MIC_ENABLE: %s", gDualMicEnabled ? "enabled" : "disabled");
            *replySize = sizeof(int);
            *(int *)pReplyData = 0;
            } break;
        case PREPROC_CMD_DUAL_MIC_PCM_DUMP_START: {
            if (pCmdData == NULL|| pReplyData == NULL || replySize == NULL) {
                ALOGE("PreProcessingFx_Command cmdCode Case: "
                        "PREPROC_CMD_DUAL_MIC_PCM_DUMP_START: ERROR");
                *replySize = 0;
                return -EINVAL;
            }
            pthread_mutex_lock(&gPcmDumpLock);
            if (gPcmDumpFh != NULL) {
                fclose(gPcmDumpFh);
                gPcmDumpFh = NULL;
            }
            char *path = strndup((char *)pCmdData, cmdSize);
            gPcmDumpFh = fopen((char *)path, "wb");
            pthread_mutex_unlock(&gPcmDumpLock);
            ALOGV("PREPROC_CMD_DUAL_MIC_PCM_DUMP_START: path %s gPcmDumpFh %p",
                  path, gPcmDumpFh);
            ALOGE_IF(gPcmDumpFh <= 0, "gPcmDumpFh open error %d %s", errno, strerror(errno));
            free(path);
            *replySize = sizeof(int);
            *(int *)pReplyData = 0;
            } break;
        case PREPROC_CMD_DUAL_MIC_PCM_DUMP_STOP: {
            if (pReplyData == NULL || replySize == NULL) {
                ALOGE("PreProcessingFx_Command cmdCode Case: "
                        "PREPROC_CMD_DUAL_MIC_PCM_DUMP_STOP: ERROR");
                *replySize = 0;
                return -EINVAL;
            }
            pthread_mutex_lock(&gPcmDumpLock);
            if (gPcmDumpFh != NULL) {
                fclose(gPcmDumpFh);
                gPcmDumpFh = NULL;
            }
            pthread_mutex_unlock(&gPcmDumpLock);
            ALOGV("PREPROC_CMD_DUAL_MIC_PCM_DUMP_STOP");
            *replySize = sizeof(int);
            *(int *)pReplyData = 0;
            } break;
        ///// test commands end

        case EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS: {
            if(!gDualMicEnabled) {
                return -EINVAL;
            }
            if (pCmdData == NULL|| cmdSize != 2 * sizeof(uint32_t) ||
                    pReplyData == NULL || replySize == NULL) {
                ALOGE("PreProcessingFx_Command cmdCode Case: "
                        "EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS: ERROR");
                *replySize = 0;
                return -EINVAL;
            }
            if (*(uint32_t *)pCmdData != EFFECT_FEATURE_AUX_CHANNELS ||
                  !effect->aux_channels_on) {
                ALOGV("PreProcessingFx_Command feature EFFECT_FEATURE_AUX_CHANNELS not supported by"
                        " fx %d", effect->procId);
                *(uint32_t *)pReplyData = -ENOSYS;
                *replySize = sizeof(uint32_t);
                break;
            }
            size_t num_configs = *((uint32_t *)pCmdData + 1);
            if (*replySize < (2 * sizeof(uint32_t) +
                              num_configs * sizeof(channel_config_t))) {
                *replySize = 0;
                return -EINVAL;
            }

            *((uint32_t *)pReplyData + 1) = CHANNEL_CFG_CNT;
            if (num_configs < CHANNEL_CFG_CNT ||
                    *replySize < (2 * sizeof(uint32_t) +
                                     CHANNEL_CFG_CNT * sizeof(channel_config_t))) {
                *(uint32_t *)pReplyData = -ENOMEM;
            } else {
                num_configs = CHANNEL_CFG_CNT;
                *(uint32_t *)pReplyData = 0;
            }
            ALOGV("PreProcessingFx_Command EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS num config %d",
                  num_configs);

            *replySize = 2 * sizeof(uint32_t) + num_configs * sizeof(channel_config_t);
            *((uint32_t *)pReplyData + 1) = num_configs;
            memcpy((uint32_t *)pReplyData + 2, &sDualMicConfigs, num_configs * sizeof(channel_config_t));
            } break;
        case EFFECT_CMD_GET_FEATURE_CONFIG:
            if(!gDualMicEnabled) {
                return -EINVAL;
            }
            if (pCmdData == NULL|| cmdSize != sizeof(uint32_t) ||
                    pReplyData == NULL || replySize == NULL ||
                    *replySize < sizeof(uint32_t) + sizeof(channel_config_t)) {
                ALOGE("PreProcessingFx_Command cmdCode Case: "
                        "EFFECT_CMD_GET_FEATURE_CONFIG: ERROR");
                return -EINVAL;
            }
            if (*(uint32_t *)pCmdData != EFFECT_FEATURE_AUX_CHANNELS || !effect->aux_channels_on) {
                *(uint32_t *)pReplyData = -ENOSYS;
                *replySize = sizeof(uint32_t);
                break;
            }
            ALOGV("PreProcessingFx_Command EFFECT_CMD_GET_FEATURE_CONFIG");
            *(uint32_t *)pReplyData = 0;
            *replySize = sizeof(uint32_t) + sizeof(channel_config_t);
            memcpy((uint32_t *)pReplyData + 1,
                   &sDualMicConfigs[effect->cur_channel_config],
                   sizeof(channel_config_t));
            break;
        case EFFECT_CMD_SET_FEATURE_CONFIG: {
            ALOGV("PreProcessingFx_Command EFFECT_CMD_SET_FEATURE_CONFIG: "
                    "gDualMicEnabled %d effect->aux_channels_on %d",
                  gDualMicEnabled, effect->aux_channels_on);
            if(!gDualMicEnabled) {
                return -EINVAL;
            }
            if (pCmdData == NULL|| cmdSize != (sizeof(uint32_t) + sizeof(channel_config_t)) ||
                    pReplyData == NULL || replySize == NULL ||
                    *replySize < sizeof(uint32_t)) {
                ALOGE("PreProcessingFx_Command cmdCode Case: "
                        "EFFECT_CMD_SET_FEATURE_CONFIG: ERROR\n"
                        "pCmdData %p cmdSize %d pReplyData %p replySize %p *replySize %d",
                        pCmdData, cmdSize, pReplyData, replySize, replySize ? *replySize : -1);
                return -EINVAL;
            }
            *replySize = sizeof(uint32_t);
            if (*(uint32_t *)pCmdData != EFFECT_FEATURE_AUX_CHANNELS || !effect->aux_channels_on) {
                *(uint32_t *)pReplyData = -ENOSYS;
                ALOGV("PreProcessingFx_Command cmdCode Case: "
                                        "EFFECT_CMD_SET_FEATURE_CONFIG: ERROR\n"
                                        "CmdData %d effect->aux_channels_on %d",
                                        *(uint32_t *)pCmdData, effect->aux_channels_on);
                break;
            }
            size_t i;
            for (i = 0; i < CHANNEL_CFG_CNT;i++) {
                if (memcmp((uint32_t *)pCmdData + 1,
                           &sDualMicConfigs[i], sizeof(channel_config_t)) == 0) {
                    break;
                }
            }
            if (i == CHANNEL_CFG_CNT) {
                *(uint32_t *)pReplyData = -EINVAL;
                ALOGW("PreProcessingFx_Command EFFECT_CMD_SET_FEATURE_CONFIG invalid config"
                        "[%08x].[%08x]", *((uint32_t *)pCmdData + 1), *((uint32_t *)pCmdData + 2));
            } else {
                effect->cur_channel_config = i;
                *(uint32_t *)pReplyData = 0;
                ALOGV("PreProcessingFx_Command EFFECT_CMD_SET_FEATURE_CONFIG New config"
                        "[%08x].[%08x]", sDualMicConfigs[i].main_channels, sDualMicConfigs[i].aux_channels);
            }
            } break;
#endif
        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;
    }

    *pDescriptor = *sDescriptors[effect->procId];

    return 0;
}

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

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

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

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

//    ALOGV("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) {
                int16_t *buf;
                session->revBufSize = session->framesRev + fr;
                buf = (int16_t *)realloc(session->revBuf,
                                 session->revBufSize * session->inChannelCount * sizeof(int16_t));
                if (buf == NULL) {
                    session->framesRev = 0;
                    free(session->revBuf);
                    session->revBuf = NULL;
                    return -ENOMEM;
                }
                session->revBuf = buf;
            }
            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;
            }
            spx_uint32_t frIn = session->framesRev;
            spx_uint32_t frOut = session->apmFrameCount;
            if (session->inChannelCount == 1) {
                speex_resampler_process_int(session->revResampler,
                                            0,
                                            session->revBuf,
                                            &frIn,
                                            session->revFrame->data_,
                                            &frOut);
            } else {
                speex_resampler_process_interleaved_int(session->revResampler,
                                                        session->revBuf,
                                                        &frIn,
                                                        session->revFrame->data_,
                                                        &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->data_ + 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->samples_per_channel_ = session->apmFrameCount;
        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_Create(const effect_uuid_t *uuid,
                            int32_t             sessionId,
                            int32_t             ioId,
                            effect_handle_t  *pInterface)
{
    ALOGV("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) {
        ALOGW("EffectCreate: fx not found uuid: %08x", uuid->timeLow);
        return -EINVAL;
    }
    procId = UuidToProcId(&desc->type);

    session = PreProc_GetSession(procId, sessionId, ioId);
    if (session == NULL) {
        ALOGW("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;
    ALOGV("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(const 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) {
        ALOGV("PreProcessingLib_GetDescriptor() not found");
        return  -EINVAL;
    }

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

    *pDescriptor = *desc;
    return 0;
}

// This is the only symbol that needs to be exported
__attribute__ ((visibility ("default")))
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",
    .create_effect = PreProcessingLib_Create,
    .release_effect = PreProcessingLib_Release,
    .get_descriptor = PreProcessingLib_GetDescriptor
};

}; // extern "C"
