/*
 * Copyright (C) 2010 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.
 */

/* Equalizer implementation */

#include "sles_allinclusive.h"
#ifdef ANDROID
#include <audio_effects/effect_equalizer.h>
#endif

#define MAX_EQ_PRESETS 3

#if !defined(ANDROID)
static const struct EqualizerBand EqualizerBands[MAX_EQ_BANDS] = {
    {1000, 1500, 2000},
    {2000, 3000, 4000},
    {4000, 5500, 7000},
    {7000, 8000, 9000}
};

static const struct EqualizerPreset {
    const char *mName;
    SLmillibel mLevels[MAX_EQ_BANDS];
} EqualizerPresets[MAX_EQ_PRESETS] = {
    {"Default", {0, 0, 0, 0}},
    {"Bass", {500, 200, 100, 0}},
    {"Treble", {0, 100, 200, 500}}
};
#endif


#if defined(ANDROID)
/**
 * returns true if this interface is not associated with an initialized Equalizer effect
 */
static inline bool NO_EQ(IEqualizer* v) {
    return (v->mEqEffect == 0);
}
#endif


static SLresult IEqualizer_SetEnabled(SLEqualizerItf self, SLboolean enabled)
{
    SL_ENTER_INTERFACE

    IEqualizer *thiz = (IEqualizer *) self;
    interface_lock_exclusive(thiz);
    thiz->mEnabled = (SLboolean) enabled;
#if !defined(ANDROID)
    result = SL_RESULT_SUCCESS;
#else
    if (NO_EQ(thiz)) {
        result = SL_RESULT_CONTROL_LOST;
    } else {
        android::status_t status =
                thiz->mEqEffect->setEnabled((bool) thiz->mEnabled);
        result = android_fx_statusToResult(status);
    }
#endif
    interface_unlock_exclusive(thiz);

    SL_LEAVE_INTERFACE
}


static SLresult IEqualizer_IsEnabled(SLEqualizerItf self, SLboolean *pEnabled)
{
    SL_ENTER_INTERFACE

      if (NULL == pEnabled) {
          result = SL_RESULT_PARAMETER_INVALID;
      } else {
          IEqualizer *thiz = (IEqualizer *) self;
          interface_lock_exclusive(thiz);
          SLboolean enabled = thiz->mEnabled;
 #if !defined(ANDROID)
          *pEnabled = enabled;
          result = SL_RESULT_SUCCESS;
 #else
          if (NO_EQ(thiz)) {
              result = SL_RESULT_CONTROL_LOST;
          } else {
              *pEnabled = (SLboolean) thiz->mEqEffect->getEnabled();
              result = SL_RESULT_SUCCESS;
          }
 #endif
          interface_unlock_exclusive(thiz);
      }

      SL_LEAVE_INTERFACE
}


static SLresult IEqualizer_GetNumberOfBands(SLEqualizerItf self, SLuint16 *pNumBands)
{
    SL_ENTER_INTERFACE

    if (NULL == pNumBands) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        IEqualizer *thiz = (IEqualizer *) self;
        // Note: no lock, but OK because it is const
        *pNumBands = thiz->mNumBands;
        result = SL_RESULT_SUCCESS;
    }

    SL_LEAVE_INTERFACE
}


static SLresult IEqualizer_GetBandLevelRange(SLEqualizerItf self, SLmillibel *pMin,
    SLmillibel *pMax)
{
    SL_ENTER_INTERFACE

    if (NULL == pMin && NULL == pMax) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        IEqualizer *thiz = (IEqualizer *) self;
        // Note: no lock, but OK because it is const
        if (NULL != pMin)
            *pMin = thiz->mBandLevelRangeMin;
        if (NULL != pMax)
            *pMax = thiz->mBandLevelRangeMax;
        result = SL_RESULT_SUCCESS;
    }

    SL_LEAVE_INTERFACE
}


static SLresult IEqualizer_SetBandLevel(SLEqualizerItf self, SLuint16 band, SLmillibel level)
{
    SL_ENTER_INTERFACE

    IEqualizer *thiz = (IEqualizer *) self;
    if (!(thiz->mBandLevelRangeMin <= level && level <= thiz->mBandLevelRangeMax) ||
            (band >= thiz->mNumBands)) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        interface_lock_exclusive(thiz);
#if !defined(ANDROID)
        thiz->mLevels[band] = level;
        thiz->mPreset = SL_EQUALIZER_UNDEFINED;
        result = SL_RESULT_SUCCESS;
#else
        if (NO_EQ(thiz)) {
            result = SL_RESULT_CONTROL_LOST;
        } else {
            android::status_t status =
                android_eq_setParam(thiz->mEqEffect, EQ_PARAM_BAND_LEVEL, band, &level);
            result = android_fx_statusToResult(status);
        }
#endif
        interface_unlock_exclusive(thiz);
    }

    SL_LEAVE_INTERFACE
}


static SLresult IEqualizer_GetBandLevel(SLEqualizerItf self, SLuint16 band, SLmillibel *pLevel)
{
    SL_ENTER_INTERFACE

    if (NULL == pLevel) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        IEqualizer *thiz = (IEqualizer *) self;
        // const, no lock needed
        if (band >= thiz->mNumBands) {
            result = SL_RESULT_PARAMETER_INVALID;
        } else {
            SLmillibel level = 0;
            interface_lock_shared(thiz);
#if !defined(ANDROID)
            level = thiz->mLevels[band];
            result = SL_RESULT_SUCCESS;
#else
            if (NO_EQ(thiz)) {
                result = SL_RESULT_CONTROL_LOST;
            } else {
                android::status_t status =
                    android_eq_getParam(thiz->mEqEffect, EQ_PARAM_BAND_LEVEL, band, &level);
                result = android_fx_statusToResult(status);
            }
#endif
            interface_unlock_shared(thiz);
            *pLevel = level;
        }
    }

    SL_LEAVE_INTERFACE
}


static SLresult IEqualizer_GetCenterFreq(SLEqualizerItf self, SLuint16 band, SLmilliHertz *pCenter)
{
    SL_ENTER_INTERFACE

    if (NULL == pCenter) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        IEqualizer *thiz = (IEqualizer *) self;
        if (band >= thiz->mNumBands) {
            result = SL_RESULT_PARAMETER_INVALID;
        } else {
#if !defined(ANDROID)
            // Note: no lock, but OK because it is const
            *pCenter = thiz->mBands[band].mCenter;
            result = SL_RESULT_SUCCESS;
#else
            SLmilliHertz center = 0;
            interface_lock_shared(thiz);
            if (NO_EQ(thiz)) {
                result = SL_RESULT_CONTROL_LOST;
            } else {
                android::status_t status =
                    android_eq_getParam(thiz->mEqEffect, EQ_PARAM_CENTER_FREQ, band, &center);
                result = android_fx_statusToResult(status);
            }
            interface_unlock_shared(thiz);
            *pCenter = center;
#endif
        }
    }

    SL_LEAVE_INTERFACE
}


static SLresult IEqualizer_GetBandFreqRange(SLEqualizerItf self, SLuint16 band,
    SLmilliHertz *pMin, SLmilliHertz *pMax)
{
    SL_ENTER_INTERFACE

    if (NULL == pMin && NULL == pMax) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        IEqualizer *thiz = (IEqualizer *) self;
        if (band >= thiz->mNumBands) {
            result = SL_RESULT_PARAMETER_INVALID;
        } else {
#if !defined(ANDROID)
            // Note: no lock, but OK because it is const
            if (NULL != pMin)
                *pMin = thiz->mBands[band].mMin;
            if (NULL != pMax)
                *pMax = thiz->mBands[band].mMax;
            result = SL_RESULT_SUCCESS;
#else
            SLmilliHertz range[2] = {0, 0}; // SLmilliHertz is SLuint32
            interface_lock_shared(thiz);
            if (NO_EQ(thiz)) {
                result = SL_RESULT_CONTROL_LOST;
            } else {
                android::status_t status =
                    android_eq_getParam(thiz->mEqEffect, EQ_PARAM_BAND_FREQ_RANGE, band, range);
                result = android_fx_statusToResult(status);
            }
            interface_unlock_shared(thiz);
            if (NULL != pMin) {
                *pMin = range[0];
            }
            if (NULL != pMax) {
                *pMax = range[1];
            }
#endif
        }
    }

    SL_LEAVE_INTERFACE
}


static SLresult IEqualizer_GetBand(SLEqualizerItf self, SLmilliHertz frequency, SLuint16 *pBand)
{
    SL_ENTER_INTERFACE

    if (NULL == pBand) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        IEqualizer *thiz = (IEqualizer *) self;
#if !defined(ANDROID)
        // search for band whose center frequency has the closest ratio to 1.0
        // assumes bands are unsorted (a pessimistic assumption)
        // assumes bands can overlap (a pessimistic assumption)
        // assumes a small number of bands, so no need for a fancier algorithm
        const struct EqualizerBand *band;
        float floatFreq = (float) frequency;
        float bestRatio = 0.0;
        SLuint16 bestBand = SL_EQUALIZER_UNDEFINED;
        for (band = thiz->mBands; band < &thiz->mBands[thiz->mNumBands]; ++band) {
            if (!(band->mMin <= frequency && frequency <= band->mMax))
                continue;
            assert(band->mMin <= band->mCenter && band->mCenter <= band->mMax);
            assert(band->mCenter != 0);
            float ratio = frequency <= band->mCenter ?
                floatFreq / band->mCenter : band->mCenter / floatFreq;
            if (ratio > bestRatio) {
                bestRatio = ratio;
                bestBand = band - thiz->mBands;
            }
        }
        *pBand = bestBand;
        result = SL_RESULT_SUCCESS;
#else
        uint16_t band = 0;
        interface_lock_shared(thiz);
        if (NO_EQ(thiz)) {
            result = SL_RESULT_CONTROL_LOST;
        } else {
            android::status_t status =
                android_eq_getParam(thiz->mEqEffect, EQ_PARAM_GET_BAND, frequency, &band);
            result = android_fx_statusToResult(status);
        }
        interface_unlock_shared(thiz);
        *pBand = (SLuint16)band;
#endif
    }

    SL_LEAVE_INTERFACE
}


static SLresult IEqualizer_GetCurrentPreset(SLEqualizerItf self, SLuint16 *pPreset)
{
    SL_ENTER_INTERFACE

    if (NULL == pPreset) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        IEqualizer *thiz = (IEqualizer *) self;
        interface_lock_shared(thiz);
#if !defined(ANDROID)
        SLuint16 preset = thiz->mPreset;
        interface_unlock_shared(thiz);
        *pPreset = preset;
        result = SL_RESULT_SUCCESS;
#else
        uint16_t preset = 0;
        if (NO_EQ(thiz)) {
            result = SL_RESULT_CONTROL_LOST;
        } else {
            android::status_t status =
                    android_eq_getParam(thiz->mEqEffect, EQ_PARAM_CUR_PRESET, 0, &preset);
            result = android_fx_statusToResult(status);
        }
        interface_unlock_shared(thiz);

        if (preset < 0) {
            *pPreset = SL_EQUALIZER_UNDEFINED;
        } else {
            *pPreset = (SLuint16) preset;
        }
#endif

    }

    SL_LEAVE_INTERFACE
}


static SLresult IEqualizer_UsePreset(SLEqualizerItf self, SLuint16 index)
{
    SL_ENTER_INTERFACE
    SL_LOGV("Equalizer::UsePreset index=%u", index);

    IEqualizer *thiz = (IEqualizer *) self;
    if (index >= thiz->mNumPresets) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        interface_lock_exclusive(thiz);
#if !defined(ANDROID)
        SLuint16 band;
        for (band = 0; band < thiz->mNumBands; ++band)
            thiz->mLevels[band] = EqualizerPresets[index].mLevels[band];
        thiz->mPreset = index;
        interface_unlock_exclusive(thiz);
        result = SL_RESULT_SUCCESS;
#else
        if (NO_EQ(thiz)) {
            result = SL_RESULT_CONTROL_LOST;
        } else {
            android::status_t status =
                android_eq_setParam(thiz->mEqEffect, EQ_PARAM_CUR_PRESET, 0, &index);
            result = android_fx_statusToResult(status);
        }
        interface_unlock_shared(thiz);
#endif
    }

    SL_LEAVE_INTERFACE
}


static SLresult IEqualizer_GetNumberOfPresets(SLEqualizerItf self, SLuint16 *pNumPresets)
{
    SL_ENTER_INTERFACE

    if (NULL == pNumPresets) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        IEqualizer *thiz = (IEqualizer *) self;
        // Note: no lock, but OK because it is const
        *pNumPresets = thiz->mNumPresets;

        result = SL_RESULT_SUCCESS;
    }

    SL_LEAVE_INTERFACE
}


static SLresult IEqualizer_GetPresetName(SLEqualizerItf self, SLuint16 index, const SLchar **ppName)
{
    SL_ENTER_INTERFACE

    if (NULL == ppName) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        IEqualizer *thiz = (IEqualizer *) self;
#if !defined(ANDROID)
        if (index >= thiz->mNumPresets) {
            result = SL_RESULT_PARAMETER_INVALID;
        } else {
            *ppName = (SLchar *) thiz->mPresets[index].mName;
            result = SL_RESULT_SUCCESS;
        }
#else
        if (index >= thiz->mNumPresets) {
            result = SL_RESULT_PARAMETER_INVALID;
        } else {
            // FIXME query preset name rather than retrieve it from the engine.
            //       In SL ES 1.0.1, the strings must exist for the lifetime of the engine.
            //       Starting in 1.1, this will change and we don't need to hold onto the strings
            //       for so long as they will copied into application space.
            *ppName = (SLchar *) thiz->mThis->mEngine->mEqPresetNames[index];
            result = SL_RESULT_SUCCESS;
        }
#endif
    }

    SL_LEAVE_INTERFACE
}


static const struct SLEqualizerItf_ IEqualizer_Itf = {
    IEqualizer_SetEnabled,
    IEqualizer_IsEnabled,
    IEqualizer_GetNumberOfBands,
    IEqualizer_GetBandLevelRange,
    IEqualizer_SetBandLevel,
    IEqualizer_GetBandLevel,
    IEqualizer_GetCenterFreq,
    IEqualizer_GetBandFreqRange,
    IEqualizer_GetBand,
    IEqualizer_GetCurrentPreset,
    IEqualizer_UsePreset,
    IEqualizer_GetNumberOfPresets,
    IEqualizer_GetPresetName
};

void IEqualizer_init(void *self)
{
    IEqualizer *thiz = (IEqualizer *) self;
    thiz->mItf = &IEqualizer_Itf;
    thiz->mEnabled = SL_BOOLEAN_FALSE;
    thiz->mPreset = SL_EQUALIZER_UNDEFINED;
#if 0 < MAX_EQ_BANDS
    unsigned band;
    for (band = 0; band < MAX_EQ_BANDS; ++band)
        thiz->mLevels[band] = 0;
#endif
    // const fields
    thiz->mNumPresets = 0;
    thiz->mNumBands = 0;
#if !defined(ANDROID)
    thiz->mBands = EqualizerBands;
    thiz->mPresets = EqualizerPresets;
#endif
    thiz->mBandLevelRangeMin = 0;
    thiz->mBandLevelRangeMax = 0;
#if defined(ANDROID)
    memset(&thiz->mEqDescriptor, 0, sizeof(effect_descriptor_t));
    // placement new (explicit constructor)
    (void) new (&thiz->mEqEffect) android::sp<android::AudioEffect>();
#endif
}

void IEqualizer_deinit(void *self)
{
#if defined(ANDROID)
    IEqualizer *thiz = (IEqualizer *) self;
    // explicit destructor
    thiz->mEqEffect.~sp();
#endif
}

bool IEqualizer_Expose(void *self)
{
#if defined(ANDROID)
    IEqualizer *thiz = (IEqualizer *) self;
    if (!android_fx_initEffectDescriptor(SL_IID_EQUALIZER, &thiz->mEqDescriptor)) {
        SL_LOGE("Equalizer initialization failed");
        thiz->mNumPresets = 0;
        thiz->mNumBands = 0;
        thiz->mBandLevelRangeMin = 0;
        thiz->mBandLevelRangeMax = 0;
        return false;
    }
#endif
    return true;
}
