/*
 * Copyright (C) 2014 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 "offload_effect_equalizer"
//#define LOG_NDEBUG 0

#include <cutils/list.h>
#include <cutils/log.h>
#include <tinyalsa/asoundlib.h>
#include <sound/audio_effects.h>
#include <audio_effects/effect_equalizer.h>

#include "effect_api.h"
#include "equalizer.h"

/* Offload equalizer UUID: a0dac280-401c-11e3-9379-0002a5d5c51b */
const effect_descriptor_t equalizer_descriptor = {
        {0x0bed4300, 0xddd6, 0x11db, 0x8f34, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // type
        {0xa0dac280, 0x401c, 0x11e3, 0x9379, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // uuid
        EFFECT_CONTROL_API_VERSION,
        (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_HW_ACC_TUNNEL),
        0, /* TODO */
        1,
        "MSM offload equalizer",
        "The Android Open Source Project",
};

static const char *equalizer_preset_names[] = {
                                        "Normal",
                                        "Classical",
                                        "Dance",
                                        "Flat",
                                        "Folk",
                                        "Heavy Metal",
                                        "Hip Hop",
                                        "Jazz",
                                        "Pop",
                                        "Rock"
					};

static const uint32_t equalizer_band_freq_range[NUM_EQ_BANDS][2] = {
                                       {30000, 120000},
                                       {120001, 460000},
                                       {460001, 1800000},
                                       {1800001, 7000000},
                                       {7000001, 20000000}};

static const int16_t equalizer_band_presets_level[] = {
                                        3, 0, 0, 0, 3,      /* Normal Preset */
                                        5, 3, -2, 4, 4,     /* Classical Preset */
                                        6, 0, 2, 4, 1,      /* Dance Preset */
                                        0, 0, 0, 0, 0,      /* Flat Preset */
                                        3, 0, 0, 2, -1,     /* Folk Preset */
                                        4, 1, 9, 3, 0,      /* Heavy Metal Preset */
                                        5, 3, 0, 1, 3,      /* Hip Hop Preset */
                                        4, 2, -2, 2, 5,     /* Jazz Preset */
                                       -1, 2, 5, 1, -2,     /* Pop Preset */
                                        5, 3, -1, 3, 5};    /* Rock Preset */

const uint16_t equalizer_band_presets_freq[NUM_EQ_BANDS] = {
                                        60,      /* Frequencies in Hz */
                                        230,
                                        910,
                                        3600,
                                        14000
};

/*
 * Equalizer operations
 */

int equalizer_get_band_level(equalizer_context_t *context, int32_t band)
{
    ALOGV("%s: band: %d level: %d", __func__, band,
           context->band_levels[band] * 100);
    return context->band_levels[band] * 100;
}

int equalizer_set_band_level(equalizer_context_t *context, int32_t band,
                             int32_t level)
{
    ALOGV("%s: band: %d, level: %d", __func__, band, level);
    if (level > 0) {
        level = (int)((level+50)/100);
    } else {
        level = (int)((level-50)/100);
    }
    context->band_levels[band] = level;
    context->preset = PRESET_CUSTOM;

    offload_eq_set_preset(&(context->offload_eq), PRESET_CUSTOM);
    offload_eq_set_bands_level(&(context->offload_eq),
                               NUM_EQ_BANDS,
                               equalizer_band_presets_freq,
                               context->band_levels);
    if (context->ctl)
        offload_eq_send_params(context->ctl, &context->offload_eq,
                               OFFLOAD_SEND_EQ_ENABLE_FLAG |
                               OFFLOAD_SEND_EQ_BANDS_LEVEL);
    return 0;
}

int equalizer_get_center_frequency(equalizer_context_t *context __unused, int32_t band)
{
    ALOGV("%s: band: %d", __func__, band);
    return (equalizer_band_freq_range[band][0] +
            equalizer_band_freq_range[band][1]) / 2;
}

int equalizer_get_band_freq_range(equalizer_context_t *context __unused, int32_t band,
                                  uint32_t *low, uint32_t *high)
{
    ALOGV("%s: band: %d", __func__, band);
    *low = equalizer_band_freq_range[band][0];
    *high = equalizer_band_freq_range[band][1];
   return 0;
}

int equalizer_get_band(equalizer_context_t *context __unused, uint32_t freq)
{
    int i;

    ALOGV("%s: freq: %d", __func__, freq);
    for (i = 0; i < NUM_EQ_BANDS; i++) {
        if (freq <= equalizer_band_freq_range[i][1]) {
            return i;
        }
    }
    return NUM_EQ_BANDS - 1;
}

int equalizer_get_preset(equalizer_context_t *context)
{
    ALOGV("%s: preset: %d", __func__, context->preset);
    return context->preset;
}

int equalizer_set_preset(equalizer_context_t *context, int preset)
{
    int i;

    ALOGV("%s: preset: %d", __func__, preset);
    context->preset = preset;
    for (i=0; i<NUM_EQ_BANDS; i++)
        context->band_levels[i] =
                 equalizer_band_presets_level[i + preset * NUM_EQ_BANDS];

    offload_eq_set_preset(&(context->offload_eq), preset);
    offload_eq_set_bands_level(&(context->offload_eq),
                               NUM_EQ_BANDS,
                               equalizer_band_presets_freq,
                               context->band_levels);
    if(context->ctl)
        offload_eq_send_params(context->ctl, &context->offload_eq,
                               OFFLOAD_SEND_EQ_ENABLE_FLAG |
                               OFFLOAD_SEND_EQ_PRESET);
    return 0;
}

const char * equalizer_get_preset_name(equalizer_context_t *context __unused,
                                       int32_t preset)
{
    ALOGV("%s: preset: %s", __func__, equalizer_preset_names[preset]);
    if (preset == PRESET_CUSTOM) {
        return "Custom";
    } else {
        return equalizer_preset_names[preset];
    }
}

int equalizer_get_num_presets(equalizer_context_t *context __unused)
{
    ALOGV("%s: presets_num: %d", __func__,
           sizeof(equalizer_preset_names)/sizeof(char *));
    return sizeof(equalizer_preset_names)/sizeof(char *);
}

int equalizer_get_parameter(effect_context_t *context, effect_param_t *p,
                            uint32_t *size)
{
    equalizer_context_t *eq_ctxt = (equalizer_context_t *)context;
    int voffset = ((p->psize - 1) / sizeof(int32_t) + 1) * sizeof(int32_t);
    int32_t *param_tmp = (int32_t *)p->data;
    int32_t param = *param_tmp++;
    int32_t param2;
    char *name;
    void *value = p->data + voffset;
    int i;

    ALOGV("%s", __func__);

    p->status = 0;

    switch (param) {
    case EQ_PARAM_NUM_BANDS:
    case EQ_PARAM_CUR_PRESET:
    case EQ_PARAM_GET_NUM_OF_PRESETS:
    case EQ_PARAM_BAND_LEVEL:
    case EQ_PARAM_GET_BAND:
        if (p->vsize < sizeof(int16_t))
           p->status = -EINVAL;
        p->vsize = sizeof(int16_t);
        break;

    case EQ_PARAM_LEVEL_RANGE:
        if (p->vsize < 2 * sizeof(int16_t))
            p->status = -EINVAL;
        p->vsize = 2 * sizeof(int16_t);
        break;
    case EQ_PARAM_BAND_FREQ_RANGE:
       if (p->vsize < 2 * sizeof(int32_t))
            p->status = -EINVAL;
        p->vsize = 2 * sizeof(int32_t);
        break;

   case EQ_PARAM_CENTER_FREQ:
        if (p->vsize < sizeof(int32_t))
            p->status = -EINVAL;
        p->vsize = sizeof(int32_t);
        break;

    case EQ_PARAM_GET_PRESET_NAME:
        break;

    case EQ_PARAM_PROPERTIES:
        if (p->vsize < (2 + NUM_EQ_BANDS) * sizeof(uint16_t))
            p->status = -EINVAL;
        p->vsize = (2 + NUM_EQ_BANDS) * sizeof(uint16_t);
        break;

    default:
        p->status = -EINVAL;
    }

    *size = sizeof(effect_param_t) + voffset + p->vsize;

    if (p->status != 0)
        return 0;

    switch (param) {
    case EQ_PARAM_NUM_BANDS:
	ALOGV("%s: EQ_PARAM_NUM_BANDS", __func__);
        *(uint16_t *)value = (uint16_t)NUM_EQ_BANDS;
        break;

    case EQ_PARAM_LEVEL_RANGE:
	ALOGV("%s: EQ_PARAM_LEVEL_RANGE", __func__);
        *(int16_t *)value = -1500;
        *((int16_t *)value + 1) = 1500;
        break;

    case EQ_PARAM_BAND_LEVEL:
	ALOGV("%s: EQ_PARAM_BAND_LEVEL", __func__);
        param2 = *param_tmp;
        if (param2 >= NUM_EQ_BANDS) {
            p->status = -EINVAL;
            break;
        }
        *(int16_t *)value = (int16_t)equalizer_get_band_level(eq_ctxt, param2);
        break;

    case EQ_PARAM_CENTER_FREQ:
	ALOGV("%s: EQ_PARAM_CENTER_FREQ", __func__);
        param2 = *param_tmp;
        if (param2 >= NUM_EQ_BANDS) {
           p->status = -EINVAL;
            break;
        }
        *(int32_t *)value = equalizer_get_center_frequency(eq_ctxt, param2);
        break;

    case EQ_PARAM_BAND_FREQ_RANGE:
	ALOGV("%s: EQ_PARAM_BAND_FREQ_RANGE", __func__);
        param2 = *param_tmp;
        if (param2 >= NUM_EQ_BANDS) {
            p->status = -EINVAL;
           break;
        }
       equalizer_get_band_freq_range(eq_ctxt, param2, (uint32_t *)value,
                                     ((uint32_t *)value + 1));
        break;

    case EQ_PARAM_GET_BAND:
	ALOGV("%s: EQ_PARAM_GET_BAND", __func__);
        param2 = *param_tmp;
        *(uint16_t *)value = (uint16_t)equalizer_get_band(eq_ctxt, param2);
        break;

    case EQ_PARAM_CUR_PRESET:
	ALOGV("%s: EQ_PARAM_CUR_PRESET", __func__);
        *(uint16_t *)value = (uint16_t)equalizer_get_preset(eq_ctxt);
        break;

    case EQ_PARAM_GET_NUM_OF_PRESETS:
	ALOGV("%s: EQ_PARAM_GET_NUM_OF_PRESETS", __func__);
        *(uint16_t *)value = (uint16_t)equalizer_get_num_presets(eq_ctxt);
        break;

    case EQ_PARAM_GET_PRESET_NAME:
	ALOGV("%s: EQ_PARAM_GET_PRESET_NAME", __func__);
        param2 = *param_tmp;
	ALOGV("param2: %d", param2);
        if (param2 >= equalizer_get_num_presets(eq_ctxt)) {
            p->status = -EINVAL;
            break;
        }
        name = (char *)value;
        strlcpy(name, equalizer_get_preset_name(eq_ctxt, param2), p->vsize - 1);
        name[p->vsize - 1] = 0;
        p->vsize = strlen(name) + 1;
        break;

    case EQ_PARAM_PROPERTIES: {
	ALOGV("%s: EQ_PARAM_PROPERTIES", __func__);
        int16_t *prop = (int16_t *)value;
        prop[0] = (int16_t)equalizer_get_preset(eq_ctxt);
        prop[1] = (int16_t)NUM_EQ_BANDS;
        for (i = 0; i < NUM_EQ_BANDS; i++) {
            prop[2 + i] = (int16_t)equalizer_get_band_level(eq_ctxt, i);
        }
    } break;

    default:
        p->status = -EINVAL;
        break;
    }

    return 0;
}

int equalizer_set_parameter(effect_context_t *context, effect_param_t *p,
                            uint32_t size __unused)
{
    equalizer_context_t *eq_ctxt = (equalizer_context_t *)context;
    int voffset = ((p->psize - 1) / sizeof(int32_t) + 1) * sizeof(int32_t);
    void *value = p->data + voffset;
    int32_t *param_tmp = (int32_t *)p->data;
    int32_t param = *param_tmp++;
    int32_t preset;
    int32_t band;
    int32_t level;
    int i;

    ALOGV("%s", __func__);

    p->status = 0;

    switch (param) {
    case EQ_PARAM_CUR_PRESET:
	ALOGV("EQ_PARAM_CUR_PRESET");
        preset = (int32_t)(*(uint16_t *)value);

        if ((preset >= equalizer_get_num_presets(eq_ctxt)) || (preset < 0)) {
           p->status = -EINVAL;
            break;
        }
        equalizer_set_preset(eq_ctxt, preset);
        break;
    case EQ_PARAM_BAND_LEVEL:
	ALOGV("EQ_PARAM_BAND_LEVEL");
        band =  *param_tmp;
        level = (int32_t)(*(int16_t *)value);
        if (band >= NUM_EQ_BANDS) {
           p->status = -EINVAL;
            break;
        }
        equalizer_set_band_level(eq_ctxt, band, level);
        break;
    case EQ_PARAM_PROPERTIES: {
	ALOGV("EQ_PARAM_PROPERTIES");
        int16_t *prop = (int16_t *)value;
        if ((int)prop[0] >= equalizer_get_num_presets(eq_ctxt)) {
            p->status = -EINVAL;
            break;
        }
        if (prop[0] >= 0) {
            equalizer_set_preset(eq_ctxt, (int)prop[0]);
        } else {
            if ((int)prop[1] != NUM_EQ_BANDS) {
                p->status = -EINVAL;
                break;
            }
            for (i = 0; i < NUM_EQ_BANDS; i++) {
               equalizer_set_band_level(eq_ctxt, i, (int)prop[2 + i]);
            }
        }
    } break;
    default:
        p->status = -EINVAL;
        break;
    }

    return 0;
}

int equalizer_set_device(effect_context_t *context,  uint32_t device)
{
    ALOGV("%s: device: %d", __func__, device);
    equalizer_context_t *eq_ctxt = (equalizer_context_t *)context;
    eq_ctxt->device = device;
    offload_eq_set_device(&(eq_ctxt->offload_eq), device);
    return 0;
}

int equalizer_reset(effect_context_t *context)
{
    equalizer_context_t *eq_ctxt = (equalizer_context_t *)context;

    return 0;
}

int equalizer_init(effect_context_t *context)
{
    ALOGV("%s", __func__);
    equalizer_context_t *eq_ctxt = (equalizer_context_t *)context;

    context->config.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
    context->config.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
    context->config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
    context->config.inputCfg.samplingRate = 44100;
    context->config.inputCfg.bufferProvider.getBuffer = NULL;
    context->config.inputCfg.bufferProvider.releaseBuffer = NULL;
    context->config.inputCfg.bufferProvider.cookie = NULL;
    context->config.inputCfg.mask = EFFECT_CONFIG_ALL;
    context->config.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE;
    context->config.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
    context->config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
    context->config.outputCfg.samplingRate = 44100;
    context->config.outputCfg.bufferProvider.getBuffer = NULL;
    context->config.outputCfg.bufferProvider.releaseBuffer = NULL;
    context->config.outputCfg.bufferProvider.cookie = NULL;
    context->config.outputCfg.mask = EFFECT_CONFIG_ALL;

    set_config(context, &context->config);

    memset(&(eq_ctxt->offload_eq), 0, sizeof(struct eq_params));
    offload_eq_set_preset(&(eq_ctxt->offload_eq), INVALID_PRESET);

    return 0;
}

int equalizer_enable(effect_context_t *context)
{
    equalizer_context_t *eq_ctxt = (equalizer_context_t *)context;

    ALOGV("%s", __func__);

    if (!offload_eq_get_enable_flag(&(eq_ctxt->offload_eq))) {
        offload_eq_set_enable_flag(&(eq_ctxt->offload_eq), true);
        if (eq_ctxt->ctl)
            offload_eq_send_params(eq_ctxt->ctl, &eq_ctxt->offload_eq,
                                   OFFLOAD_SEND_EQ_ENABLE_FLAG |
                                   OFFLOAD_SEND_EQ_BANDS_LEVEL);
    }
    return 0;
}

int equalizer_disable(effect_context_t *context)
{
    equalizer_context_t *eq_ctxt = (equalizer_context_t *)context;

    ALOGV("%s", __func__);
    if (offload_eq_get_enable_flag(&(eq_ctxt->offload_eq))) {
        offload_eq_set_enable_flag(&(eq_ctxt->offload_eq), false);
        if (eq_ctxt->ctl)
            offload_eq_send_params(eq_ctxt->ctl, &eq_ctxt->offload_eq,
                                   OFFLOAD_SEND_EQ_ENABLE_FLAG);
    }
    return 0;
}

int equalizer_start(effect_context_t *context, output_context_t *output)
{
    equalizer_context_t *eq_ctxt = (equalizer_context_t *)context;

    ALOGV("%s: %p", __func__, output->ctl);
    eq_ctxt->ctl = output->ctl;
    if (offload_eq_get_enable_flag(&(eq_ctxt->offload_eq)))
        if (eq_ctxt->ctl)
            offload_eq_send_params(eq_ctxt->ctl, &eq_ctxt->offload_eq,
                                   OFFLOAD_SEND_EQ_ENABLE_FLAG |
                                   OFFLOAD_SEND_EQ_BANDS_LEVEL);
    return 0;
}

int equalizer_stop(effect_context_t *context, output_context_t *output __unused)
{
    equalizer_context_t *eq_ctxt = (equalizer_context_t *)context;

    ALOGV("%s", __func__);
    eq_ctxt->ctl = NULL;
    return 0;
}
