/*
 * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
 * Not a Contribution.
 *
 * Copyright (C) 2013 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.
 */

#define LOG_TAG "audio_hw_ssr"
/*#define LOG_NDEBUG 0*/
#define LOG_NDDEBUG 0

#include <errno.h>
#include <cutils/properties.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <cutils/str_parms.h>
#include <cutils/log.h>
#include <pthread.h>
#include <cutils/sched_policy.h>
#include <sys/resource.h>
#include <system/thread_defs.h>

#include "audio_hw.h"
#include "audio_extn.h"
#include "platform.h"
#include "platform_api.h"
#include "surround_rec_interface.h"

#ifdef DYNAMIC_LOG_ENABLED
#include <log_xml_parser.h>
#define LOG_MASK HAL_MOD_FILE_SSR
#include <log_utils.h>
#endif

#ifdef SSR_ENABLED
#define COEFF_ARRAY_SIZE            4
#define FILT_SIZE                   ((512+1)* 6)  /* # ((FFT bins)/2+1)*numOutputs */
#define SSR_CHANNEL_OUTPUT_NUM      6
#define SSR_PERIOD_SIZE             240

#define NUM_IN_BUFS                 4
#define NUM_OUT_BUFS                4
#define NUM_IN_CHANNELS             3

#define LIB_SURROUND_3MIC_PROC  "libsurround_3mic_proc.so"
#define LIB_DRC                 "libdrc.so"

#define AUDIO_PARAMETER_SSRMODE_ON        "ssrOn"


typedef short Word16;
typedef const get_param_data_t* (*surround_rec_get_get_param_data_t)(void);
typedef const set_param_data_t* (*surround_rec_get_set_param_data_t)(void);
typedef int (*surround_rec_init_t)(void **, int, int, int, int, const char *);
typedef void (*surround_rec_deinit_t)(void *);
typedef void (*surround_rec_process_t)(void *, const int16_t *, int16_t *);

typedef int (*drc_init_t)(void **, int, int, const char *);
typedef void (*drc_deinit_t)(void *);
typedef int (*drc_process_t)(void *, const int16_t *, int16_t *);

struct pcm_buffer {
    void *data;
    int length;
};

struct pcm_buffer_queue {
    struct pcm_buffer_queue *next;
    struct pcm_buffer buffer;
};

struct ssr_module {
    int                 ssr_3mic;
    int                 num_out_chan;
    FILE                *fp_input;
    FILE                *fp_output;
    void                *surround_obj;
    Word16              *surround_raw_buffer;
    int                  surround_raw_buffer_size;
    bool                 is_ssr_enabled;
    struct stream_in    *in;
    void                *drc_obj;


    void *surround_rec_handle;
    surround_rec_get_get_param_data_t surround_rec_get_get_param_data;
    surround_rec_get_set_param_data_t surround_rec_get_set_param_data;
    surround_rec_init_t surround_rec_init;
    surround_rec_deinit_t surround_rec_deinit;
    surround_rec_process_t surround_rec_process;

    void *drc_handle;
    drc_init_t drc_init;
    drc_deinit_t drc_deinit;
    drc_process_t drc_process;

    pthread_t ssr_process_thread;
    bool ssr_process_thread_started;
    bool ssr_process_thread_stop;
    struct pcm_buffer_queue in_buf_nodes[NUM_IN_BUFS];
    struct pcm_buffer_queue out_buf_nodes[NUM_OUT_BUFS];
    void *in_buf_data;
    void *out_buf_data;
    struct pcm_buffer_queue *out_buf_free;
    struct pcm_buffer_queue *out_buf;
    struct pcm_buffer_queue *in_buf_free;
    struct pcm_buffer_queue *in_buf;
    pthread_mutex_t ssr_process_lock;
    pthread_cond_t cond_process;
    pthread_cond_t cond_read;
    bool is_ssr_mode_on;
};

static struct ssr_module ssrmod = {
    .fp_input = NULL,
    .fp_output = NULL,
    .surround_obj = NULL,
    .surround_raw_buffer = NULL,
    .surround_raw_buffer_size = 0,
    .is_ssr_enabled = 0,
    .in = NULL,
    .drc_obj = NULL,

    .surround_rec_handle = NULL,
    .surround_rec_get_get_param_data = NULL,
    .surround_rec_get_set_param_data = NULL,
    .surround_rec_init = NULL,
    .surround_rec_deinit = NULL,
    .surround_rec_process = NULL,

    .drc_handle = NULL,
    .drc_init = NULL,
    .drc_deinit = NULL,
    .drc_process = NULL,

    .ssr_process_thread_stop = 0,
    .ssr_process_thread_started = 0,
    .in_buf_data = NULL,
    .out_buf_data = NULL,
    .out_buf_free = NULL,
    .out_buf = NULL,
    .in_buf_free = NULL,
    .in_buf = NULL,
    .cond_process = PTHREAD_COND_INITIALIZER,
    .cond_read = PTHREAD_COND_INITIALIZER,
    .ssr_process_lock = PTHREAD_MUTEX_INITIALIZER,
    .is_ssr_mode_on = false,
};

static void *ssr_process_thread(void *context);

static int32_t drc_init_lib(int num_chan, int sample_rate __unused)
{
    int ret = 0;
    const char *cfgFileName = "";

    if (ssrmod.drc_obj) {
        ALOGE("%s: DRC library is already initialized", __func__);
        return 0;
    }

    ssrmod.drc_handle = dlopen(LIB_DRC, RTLD_NOW);
    if (ssrmod.drc_handle == NULL) {
        ALOGE("%s: DLOPEN failed for %s", __func__, LIB_DRC);
        ret = -ENOSYS;
        goto init_fail;
    }

    ALOGV("%s: DLOPEN successful for %s", __func__, LIB_DRC);
    ssrmod.drc_init = (drc_init_t)
        dlsym(ssrmod.drc_handle, "DRC_init");
    ssrmod.drc_deinit = (drc_deinit_t)
        dlsym(ssrmod.drc_handle, "DRC_deinit");
    ssrmod.drc_process = (drc_process_t)
        dlsym(ssrmod.drc_handle, "DRC_process");

    if (!ssrmod.drc_init ||
        !ssrmod.drc_deinit ||
        !ssrmod.drc_process){
        ALOGW("%s: Could not find one of the symbols from %s",
              __func__, LIB_DRC);
        ret = -ENOSYS;
        goto init_fail;
    }

    /* TO DO: different config files for different sample rates */
    if (num_chan == 6) {
        cfgFileName = "/vendor/etc/drc/drc_cfg_5.1.txt";
    } else if (num_chan == 2) {
        cfgFileName = "/vendor/etc/drc/drc_cfg_AZ.txt";
    }

    ALOGV("%s: Calling drc_init: num ch: %d, period: %d, cfg file: %s", __func__, num_chan, SSR_PERIOD_SIZE, cfgFileName);
    ret = ssrmod.drc_init(&ssrmod.drc_obj, num_chan, SSR_PERIOD_SIZE, cfgFileName);
    if (ret) {
        ALOGE("drc_init failed with ret:%d",ret);
        ret = -EINVAL;
        goto init_fail;
    }

    return 0;

init_fail:
    if (ssrmod.drc_obj) {
        ssrmod.drc_obj = NULL;
    }
    if(ssrmod.drc_handle) {
        dlclose(ssrmod.drc_handle);
        ssrmod.drc_handle = NULL;
    }
    return ret;
}

static int32_t ssr_init_surround_sound_3mic_lib(unsigned long buffersize, int num_in_chan, int num_out_chan, int sample_rate)
{
    int ret = 0;
    const char *cfgFileName = NULL;

    if ( ssrmod.surround_obj ) {
        ALOGE("%s: surround sound library is already initialized", __func__);
        return 0;
    }

    ssrmod.surround_rec_handle = dlopen(LIB_SURROUND_3MIC_PROC, RTLD_NOW);
    if (ssrmod.surround_rec_handle == NULL) {
        ALOGE("%s: DLOPEN failed for %s", __func__, LIB_SURROUND_3MIC_PROC);
        goto init_fail;
    } else {
        ALOGV("%s: DLOPEN successful for %s", __func__, LIB_SURROUND_3MIC_PROC);
        ssrmod.surround_rec_get_get_param_data = (surround_rec_get_get_param_data_t)
        dlsym(ssrmod.surround_rec_handle, "surround_rec_get_get_param_data");

        ssrmod.surround_rec_get_set_param_data = (surround_rec_get_set_param_data_t)
        dlsym(ssrmod.surround_rec_handle, "surround_rec_get_set_param_data");
        ssrmod.surround_rec_init = (surround_rec_init_t)
        dlsym(ssrmod.surround_rec_handle, "surround_rec_init");
        ssrmod.surround_rec_deinit = (surround_rec_deinit_t)
        dlsym(ssrmod.surround_rec_handle, "surround_rec_deinit");
        ssrmod.surround_rec_process = (surround_rec_process_t)
        dlsym(ssrmod.surround_rec_handle, "surround_rec_process");

        if (!ssrmod.surround_rec_get_get_param_data ||
            !ssrmod.surround_rec_get_set_param_data ||
            !ssrmod.surround_rec_init ||
            !ssrmod.surround_rec_deinit ||
            !ssrmod.surround_rec_process){
            ALOGW("%s: Could not find the one of the symbols from %s",
                  __func__, LIB_SURROUND_3MIC_PROC);
            ret = -ENOSYS;
            goto init_fail;
        }
    }

    /* Allocate memory for input buffer */
    ssrmod.surround_raw_buffer = (Word16 *) calloc(buffersize,
                                              sizeof(Word16));
    if (!ssrmod.surround_raw_buffer) {
       ALOGE("%s: Memory allocation failure. Not able to allocate "
             "memory for surroundInputBuffer", __func__);
       ret = -ENOMEM;
       goto init_fail;
    }

    ssrmod.surround_raw_buffer_size = buffersize;

    ssrmod.num_out_chan = num_out_chan;

    if (num_out_chan == 6) {
        cfgFileName = "/vendor/etc/surround_sound_3mic/surround_sound_rec_5.1.cfg";
    } else if (num_out_chan == 2) {
        cfgFileName = "/vendor/etc/surround_sound_3mic/surround_sound_rec_AZ.cfg";
    } else {
        ALOGE("%s: No cfg file for num_out_chan: %d", __func__, num_out_chan);
    }

    ALOGV("%s: Calling surround_rec_init: in ch: %d, out ch: %d, period: %d, sample rate: %d, cfg file: %s",
          __func__, num_in_chan, num_out_chan, SSR_PERIOD_SIZE, sample_rate, cfgFileName);
     ret = ssrmod.surround_rec_init(&ssrmod.surround_obj,
        num_in_chan, num_out_chan, SSR_PERIOD_SIZE, sample_rate, cfgFileName);
    if (ret) {
        ALOGE("surround_rec_init failed with ret:%d",ret);
        ret = -EINVAL;
        goto init_fail;
    }

    return 0;

init_fail:
    if (ssrmod.surround_obj) {
        ssrmod.surround_obj = NULL;
    }
    if (ssrmod.surround_raw_buffer) {
        free(ssrmod.surround_raw_buffer);
        ssrmod.surround_raw_buffer = NULL;
        ssrmod.surround_raw_buffer_size = 0;
    }
    if(ssrmod.surround_rec_handle) {
        dlclose(ssrmod.surround_rec_handle);
        ssrmod.surround_rec_handle = NULL;
    }
    return ret;
}

void audio_extn_ssr_update_enabled()
{
    char ssr_enabled[PROPERTY_VALUE_MAX] = "false";

    property_get("ro.vendor.audio.sdk.ssr",ssr_enabled,"0");
    if (!strncmp("true", ssr_enabled, 4)) {
        ALOGD("%s: surround sound recording is supported", __func__);
        ssrmod.is_ssr_enabled = true;
    } else {
        ALOGD("%s: surround sound recording is not supported", __func__);
        ssrmod.is_ssr_enabled = false;
    }
}

bool audio_extn_ssr_get_enabled()
{
    ALOGV("%s: is_ssr_enabled:%d is_ssr_mode_on:%d ", __func__, ssrmod.is_ssr_enabled, ssrmod.is_ssr_mode_on);

    if(ssrmod.is_ssr_enabled && ssrmod.is_ssr_mode_on)
        return true;

    return false;
}

bool  audio_extn_ssr_check_usecase(struct stream_in *in) {
    int ret = false;
    int channel_count = audio_channel_count_from_in_mask(in->channel_mask);
    audio_devices_t devices = in->device;
    audio_source_t source = in->source;

    if ((audio_extn_ssr_get_enabled()) &&
            ((channel_count == 2) || (channel_count == 6)) &&
            ((AUDIO_SOURCE_MIC == source) || (AUDIO_SOURCE_CAMCORDER == source)) &&
            ((AUDIO_DEVICE_IN_BUILTIN_MIC == devices) || (AUDIO_DEVICE_IN_BACK_MIC == devices)) &&
            (in->format == AUDIO_FORMAT_PCM_16_BIT)) {
        ALOGD("%s: SSR enabled with channel_count :%d",
                      __func__, channel_count);
        ret = true;
    }
    return ret;
}

int audio_extn_ssr_set_usecase(struct stream_in *in,
                               struct audio_config *config,
                               bool *update_params)
{
    int ret = -EINVAL;
    int channel_count = audio_channel_count_from_in_mask(in->channel_mask);
    audio_channel_representation_t representation =
                  audio_channel_mask_get_representation(in->channel_mask);
    *update_params = false;

    if (audio_extn_ssr_check_usecase(in)) {

        if (representation == AUDIO_CHANNEL_REPRESENTATION_INDEX) {
            /* update params in case channel representation index.
             * on returning error, flinger will retry with supported representation passed
             */
            ALOGD("%s: SSR supports only channel representation position, channel_mask(%#x)"
                              ,__func__, config->channel_mask);
            config->channel_mask = AUDIO_CHANNEL_IN_6;
            ret = 0;
            *update_params = true;
        } else {
            if (!audio_extn_ssr_init(in, channel_count)) {
                ALOGD("%s: Created SSR session succesfully", __func__);
                ret = 0;
            } else {
                ALOGE("%s: Unable to start SSR record session", __func__);
            }
        }
    }
    return ret;
}

static void pcm_buffer_queue_push(struct pcm_buffer_queue **queue,
                                  struct pcm_buffer_queue *node)
{
    struct pcm_buffer_queue *iter;

    node->next = NULL;
    if ((*queue) == NULL) {
        *queue = node;
    } else {
        iter = *queue;
        while (iter->next) {
            iter = iter->next;
        }
        iter->next = node;
    }
}

static struct pcm_buffer_queue *pcm_buffer_queue_pop(struct pcm_buffer_queue **queue)
{
    struct pcm_buffer_queue *node = (*queue);
    if (node != NULL) {
        *queue = node->next;
        node->next = NULL;
    }
    return node;
}

static void deinit_ssr_process_thread()
{
    pthread_mutex_lock(&ssrmod.ssr_process_lock);
    ssrmod.ssr_process_thread_stop = 1;

    if(ssrmod.in_buf_data != NULL)
       free(ssrmod.in_buf_data);
    ssrmod.in_buf_data = NULL;
    ssrmod.in_buf = NULL;
    ssrmod.in_buf_free = NULL;

    if(ssrmod.out_buf_data != NULL)
       free(ssrmod.out_buf_data);
    ssrmod.out_buf_data = NULL;
    ssrmod.out_buf = NULL;
    ssrmod.out_buf_free = NULL;
    pthread_cond_broadcast(&ssrmod.cond_process);
    pthread_cond_broadcast(&ssrmod.cond_read);
    pthread_mutex_unlock(&ssrmod.ssr_process_lock);
    if (ssrmod.ssr_process_thread_started) {
        pthread_join(ssrmod.ssr_process_thread, (void **)NULL);
        ssrmod.ssr_process_thread_started = 0;
    }
}

struct stream_in *audio_extn_ssr_get_stream()
{
    return ssrmod.in;
}

int32_t audio_extn_ssr_init(struct stream_in *in, int num_out_chan)
{
    uint32_t ret = -1;
    char c_multi_ch_dump[128] = {0};
    uint32_t buffer_size;

    ALOGD("%s: ssr case, sample rate %d", __func__, in->config.rate);

    if (ssrmod.surround_obj != NULL) {
        ALOGV("%s: reinitializing surround sound library", __func__);
        audio_extn_ssr_deinit();
    }

    if (audio_extn_ssr_get_enabled()) {
        ssrmod.ssr_3mic = 1;
    } else {
        ALOGE(" Rejecting SSR -- init is called without enabling SSR");
        goto fail;
    }

    /* buffer size equals to  period_size * period_count */     
    buffer_size = SSR_PERIOD_SIZE * NUM_IN_CHANNELS * sizeof(int16_t);
    ALOGV("%s: buffer_size: %d", __func__, buffer_size);

    if (ssrmod.ssr_3mic != 0) {
        ret = ssr_init_surround_sound_3mic_lib(buffer_size, NUM_IN_CHANNELS, num_out_chan, in->config.rate);
        if (0 != ret) {
            ALOGE("%s: ssr_init_surround_sound_3mic_lib failed: %d  "
                  "buffer_size:%d", __func__, ret, buffer_size);
            goto fail;
        }
    }

    /* Initialize DRC if available */
    ret = drc_init_lib(num_out_chan, in->config.rate);
    if (0 != ret) {
        ALOGE("%s: drc_init_lib failed, ret %d", __func__, ret);
    }

    pthread_mutex_lock(&ssrmod.ssr_process_lock);
    if (!ssrmod.ssr_process_thread_started) {
        int i;
        int output_buf_size = SSR_PERIOD_SIZE * sizeof(int16_t) * num_out_chan;

        ssrmod.in_buf_data = (void *)calloc(buffer_size, NUM_IN_BUFS);
        if (ssrmod.in_buf_data == NULL) {
            ALOGE("%s: failed to allocate input buffer", __func__);
            pthread_mutex_unlock(&ssrmod.ssr_process_lock);
            ret = -ENOMEM;
            goto fail;
        }
        ssrmod.out_buf_data = (void *)calloc(output_buf_size, NUM_OUT_BUFS);
        if (ssrmod.out_buf_data == NULL) {
            ALOGE("%s: failed to allocate output buffer", __func__);
            pthread_mutex_unlock(&ssrmod.ssr_process_lock);
            ret = -ENOMEM;
            // ssrmod.in_buf_data will be freed in deinit_ssr_process_thread()
            goto fail;
        }

        ssrmod.in_buf = NULL;
        ssrmod.in_buf_free = NULL;
        ssrmod.out_buf = NULL;
        ssrmod.out_buf_free = NULL;

        for (i=0; i < NUM_IN_BUFS; i++) {
            struct pcm_buffer_queue *buf = &ssrmod.in_buf_nodes[i];
            buf->buffer.data = &(((char *)ssrmod.in_buf_data)[i*buffer_size]);
            buf->buffer.length = buffer_size;
            pcm_buffer_queue_push(&ssrmod.in_buf_free, buf);
        }

        for (i=0; i < NUM_OUT_BUFS; i++) {
            struct pcm_buffer_queue *buf = &ssrmod.out_buf_nodes[i];
            buf->buffer.data = &(((char *)ssrmod.out_buf_data)[i*output_buf_size]);
            buf->buffer.length = output_buf_size;
            pcm_buffer_queue_push(&ssrmod.out_buf, buf);
        }

        ssrmod.ssr_process_thread_stop = 0;
        ALOGV("%s: creating thread", __func__);
        ret = pthread_create(&ssrmod.ssr_process_thread,
                             (const pthread_attr_t *) NULL,
                             ssr_process_thread, NULL);
        if (ret != 0) {
            ALOGE("%s: failed to create thread for surround sound recording.",
                  __func__);
            pthread_mutex_unlock(&ssrmod.ssr_process_lock);
            goto fail;
        }

        ssrmod.ssr_process_thread_started = 1;
        ALOGV("%s: done creating thread", __func__);
    }

    in->config.channels = NUM_IN_CHANNELS;
    in->config.period_size = SSR_PERIOD_SIZE;
    in->config.period_count = in->config.channels * sizeof(int16_t);

    pthread_mutex_unlock(&ssrmod.ssr_process_lock);

    property_get("vendor.audio.ssr.pcmdump",c_multi_ch_dump,"0");
    if (0 == strncmp("true", c_multi_ch_dump, sizeof("ssr.dump-pcm"))) {
        /* Remember to change file system permission of data(e.g. chmod 777 data/),
          otherwise, fopen may fail */
        if ( !ssrmod.fp_input) {
            ALOGD("%s: Opening ssr input dump file \n", __func__);
            ssrmod.fp_input = fopen("/data/vendor/misc/audio/ssr_input_3ch.pcm", "wb");
        }

        if ( !ssrmod.fp_output) {
            if(ssrmod.num_out_chan == 6) {
                ALOGD("%s: Opening ssr input dump file for 6 channel\n", __func__);
                ssrmod.fp_output = fopen("/data/vendor/misc/audio/ssr_output_6ch.pcm", "wb");
            } else {
                ALOGD("%s: Opening ssr input dump file for 2 channel\n", __func__);
                ssrmod.fp_output = fopen("/data/vendor/misc/audio/ssr_output_2ch.pcm", "wb");
            }
        }

        if ((!ssrmod.fp_input) || (!ssrmod.fp_output)) {
            ALOGE("%s: input dump or ouput dump open failed: mfp_4ch:%p mfp_6ch:%p",
                  __func__, ssrmod.fp_input, ssrmod.fp_output);
        }
    }

    ssrmod.in = in;

    ALOGV("%s: exit", __func__);
    return 0;

fail:
    (void) audio_extn_ssr_deinit();
    return ret;
}

int32_t audio_extn_ssr_deinit()
{
    ALOGV("%s: entry", __func__);
    deinit_ssr_process_thread();

    if (ssrmod.drc_obj) {
        ssrmod.drc_deinit(ssrmod.drc_obj);
        ssrmod.drc_obj = NULL;
    }

    if (ssrmod.surround_obj) {

        if (ssrmod.ssr_3mic) {
            ssrmod.surround_rec_deinit(ssrmod.surround_obj);
            ssrmod.surround_obj = NULL;
        }
        if (ssrmod.surround_raw_buffer) {
            free(ssrmod.surround_raw_buffer);
            ssrmod.surround_raw_buffer = NULL;
        }
        if (ssrmod.fp_input)
            fclose(ssrmod.fp_input);
        if (ssrmod.fp_output)
            fclose(ssrmod.fp_output);
    }

    if(ssrmod.drc_handle) {
        dlclose(ssrmod.drc_handle);
        ssrmod.drc_handle = NULL;
    }

    if(ssrmod.surround_rec_handle) {
        dlclose(ssrmod.surround_rec_handle);
        ssrmod.surround_rec_handle = NULL;
    }

    ssrmod.in = NULL;
    //SSR session can be closed due to device switch
    //Do not force reset ssr mode

    //ssrmod.is_ssr_mode_on = false;
    ALOGV("%s: exit", __func__);

    return 0;
}

static void *ssr_process_thread(void *context __unused)
{
    int32_t ret;

    ALOGV("%s: enter", __func__);

    setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_URGENT_AUDIO);
    set_sched_policy(0, SP_FOREGROUND);

    pthread_mutex_lock(&ssrmod.ssr_process_lock);
    while (!ssrmod.ssr_process_thread_stop) {
        struct pcm_buffer_queue *out_buf;
        struct pcm_buffer_queue *in_buf;

        while ((!ssrmod.ssr_process_thread_stop) &&
               ((ssrmod.out_buf_free == NULL) ||
                (ssrmod.in_buf == NULL))) {
            ALOGV("%s: waiting for buffers", __func__);
            pthread_cond_wait(&ssrmod.cond_process, &ssrmod.ssr_process_lock);
        }
        if (ssrmod.ssr_process_thread_stop) {
            break;
        }
        ALOGV("%s: got buffers", __func__);

        out_buf = pcm_buffer_queue_pop(&ssrmod.out_buf_free);
        in_buf = pcm_buffer_queue_pop(&ssrmod.in_buf);

        pthread_mutex_unlock(&ssrmod.ssr_process_lock);

        /* apply ssr libs to convert 4ch to 6ch */
        if (ssrmod.ssr_3mic) {
            ssrmod.surround_rec_process(ssrmod.surround_obj,
                (int16_t *) in_buf->buffer.data,
                (int16_t *) out_buf->buffer.data);
        }

        /* Run DRC if initialized */
        if (ssrmod.drc_obj != NULL) {
            ALOGV("%s: Running DRC", __func__);
            ret = ssrmod.drc_process(ssrmod.drc_obj, out_buf->buffer.data, out_buf->buffer.data);
            if (ret != 0) {
                ALOGE("%s: drc_process returned %d", __func__, ret);
            }
        }

        /*dump for raw pcm data*/
        if (ssrmod.fp_input)
            fwrite(in_buf->buffer.data, 1, in_buf->buffer.length, ssrmod.fp_input);
        if (ssrmod.fp_output)
            fwrite(out_buf->buffer.data, 1, out_buf->buffer.length, ssrmod.fp_output);

        pthread_mutex_lock(&ssrmod.ssr_process_lock);

        pcm_buffer_queue_push(&ssrmod.out_buf, out_buf);
        pcm_buffer_queue_push(&ssrmod.in_buf_free, in_buf);

        /* Read thread should go on without waiting for condition
         * variable. If it has to wait (due to this thread not keeping
         * up with the read requests), let this thread use the remainder
         * of its buffers before waking up the read thread. */
        if (ssrmod.in_buf == NULL) {
            pthread_cond_signal(&ssrmod.cond_read);
        }
    }
    pthread_mutex_unlock(&ssrmod.ssr_process_lock);

    ALOGV("%s: exit", __func__);

    pthread_exit(NULL);
}

int32_t audio_extn_ssr_read(struct audio_stream_in *stream,
                       void *buffer, size_t bytes)
{
    struct stream_in *in = (struct stream_in *)stream;
    int32_t ret = 0;
    struct pcm_buffer_queue *in_buf;
    struct pcm_buffer_queue *out_buf;

    ALOGV("%s: entry", __func__);

    if (!ssrmod.surround_obj) {
        ALOGE("%s: surround_obj not initialized", __func__);
        return -ENOMEM;
    }

    ret = pcm_read(in->pcm, ssrmod.surround_raw_buffer, ssrmod.surround_raw_buffer_size);
    if (ret < 0) {
        ALOGE("%s: %s ret:%d", __func__, pcm_get_error(in->pcm),ret);
        return ret;
    }

    pthread_mutex_lock(&ssrmod.ssr_process_lock);

    if (!ssrmod.ssr_process_thread_started) {
        pthread_mutex_unlock(&ssrmod.ssr_process_lock);
        ALOGV("%s: ssr_process_thread not initialized", __func__);
        return -EINVAL;
    }

    if ((ssrmod.in_buf_free == NULL) || (ssrmod.out_buf == NULL)) {
        ALOGE("%s: waiting for buffers", __func__);
        pthread_cond_wait(&ssrmod.cond_read, &ssrmod.ssr_process_lock);
        if ((ssrmod.in_buf_free == NULL) || (ssrmod.out_buf == NULL)) {
            pthread_mutex_unlock(&ssrmod.ssr_process_lock);
            ALOGE("%s: failed to acquire buffers", __func__);
            return -EINVAL;
        }
    }

    in_buf = pcm_buffer_queue_pop(&ssrmod.in_buf_free);
    out_buf = pcm_buffer_queue_pop(&ssrmod.out_buf);

    memcpy(in_buf->buffer.data, ssrmod.surround_raw_buffer, in_buf->buffer.length);
    pcm_buffer_queue_push(&ssrmod.in_buf, in_buf);

    memcpy(buffer, out_buf->buffer.data, bytes);
    pcm_buffer_queue_push(&ssrmod.out_buf_free, out_buf);

    pthread_cond_signal(&ssrmod.cond_process);

    pthread_mutex_unlock(&ssrmod.ssr_process_lock);

    ALOGV("%s: exit", __func__);
    return ret;
}

void audio_extn_ssr_set_parameters(struct audio_device *adev __unused,
                                   struct str_parms *parms)
{
    int err;
    char value[4096] = {0};

    //Do not update SSR mode during recording
    if ( !ssrmod.surround_obj) {
        int ret = 0;
        ret = str_parms_get_str(parms, AUDIO_PARAMETER_SSRMODE_ON, value,
                                sizeof(value));
        if (ret >= 0) {
            if (strcmp(value, "true") == 0) {
                ALOGD("Received SSR session request..setting SSR mode to true");
                ssrmod.is_ssr_mode_on = true;
            } else {
                ALOGD("resetting SSR mode to false");
                ssrmod.is_ssr_mode_on = false;
            }
        }
    }
    if (ssrmod.ssr_3mic && ssrmod.surround_obj) {
        const set_param_data_t *set_params = ssrmod.surround_rec_get_set_param_data();
        if (set_params != NULL) {
            while (set_params->name != NULL && set_params->set_param_fn != NULL) {
                err = str_parms_get_str(parms, set_params->name, value, sizeof(value));
                if (err >= 0) {
                    ALOGV("Set %s to %s\n", set_params->name, value);
                    set_params->set_param_fn(ssrmod.surround_obj, value);
                }
                set_params++;
            }
        }
    }
}

void audio_extn_ssr_get_parameters(const struct audio_device *adev __unused,
                                   struct str_parms *parms,
                                   struct str_parms *reply)
{
    int err;
    char value[4096] = {0};

    if (ssrmod.ssr_3mic && ssrmod.surround_obj) {
        const get_param_data_t *get_params = ssrmod.surround_rec_get_get_param_data();
        int get_all = 0;
        err = str_parms_get_str(parms, "ssr.all", value, sizeof(value));
        if (err >= 0) {
            get_all = 1;
        }
        if (get_params != NULL) {
            while (get_params->name != NULL && get_params->get_param_fn != NULL) {
                err = str_parms_get_str(parms, get_params->name, value, sizeof(value));
                if (get_all || (err >= 0)) {
                    ALOGV("Getting parameter %s", get_params->name);
                    char *val = get_params->get_param_fn(ssrmod.surround_obj);
                    if (val != NULL) {
                        str_parms_add_str(reply, get_params->name, val);
                        free(val);
                    }
                }
                get_params++;
            }
        }
    }
}

#endif /* SSR_ENABLED */
