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

/* Virtualizer implementation */

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

#define VIRTUALIZER_STRENGTH_MIN 0
#define VIRTUALIZER_STRENGTH_MAX 1000


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


static SLresult IVirtualizer_SetEnabled(SLVirtualizerItf self, SLboolean enabled)
{
    SL_ENTER_INTERFACE

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

    SL_LEAVE_INTERFACE

}


static SLresult IVirtualizer_IsEnabled(SLVirtualizerItf self, SLboolean *pEnabled)
{
    SL_ENTER_INTERFACE

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

    SL_LEAVE_INTERFACE
}


static SLresult IVirtualizer_SetStrength(SLVirtualizerItf self, SLpermille strength)
{
    SL_ENTER_INTERFACE

    if ((VIRTUALIZER_STRENGTH_MIN > strength) || (VIRTUALIZER_STRENGTH_MAX < strength)) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        IVirtualizer *thiz = (IVirtualizer *) self;
        interface_lock_exclusive(thiz);
#if !defined(ANDROID)
        thiz->mStrength = strength;
        result = SL_RESULT_SUCCESS;
#else
        if (NO_VIRTUALIZER(thiz)) {
            result = SL_RESULT_CONTROL_LOST;
        } else {
            android::status_t status = android_virt_setParam(thiz->mVirtualizerEffect,
                    VIRTUALIZER_PARAM_STRENGTH, &strength);
            result = android_fx_statusToResult(status);
        }
#endif
        interface_unlock_exclusive(thiz);
    }

    SL_LEAVE_INTERFACE
}


static SLresult IVirtualizer_GetRoundedStrength(SLVirtualizerItf self, SLpermille *pStrength)
{
    SL_ENTER_INTERFACE

    if (NULL == pStrength) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        IVirtualizer *thiz = (IVirtualizer *) self;
        interface_lock_exclusive(thiz);
        SLpermille strength = thiz->mStrength;;
#if !defined(ANDROID)
        result = SL_RESULT_SUCCESS;
#else
        if (NO_VIRTUALIZER(thiz)) {
            result = SL_RESULT_CONTROL_LOST;
        } else {
            android::status_t status = android_virt_getParam(thiz->mVirtualizerEffect,
                           VIRTUALIZER_PARAM_STRENGTH, &strength);
            result = android_fx_statusToResult(status);
        }
#endif
        interface_unlock_exclusive(thiz);
        *pStrength = strength;
    }

    SL_LEAVE_INTERFACE
}


static SLresult IVirtualizer_IsStrengthSupported(SLVirtualizerItf self, SLboolean *pSupported)
{
    SL_ENTER_INTERFACE

    if (NULL == pSupported) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
#if !defined(ANDROID)
        *pSupported = SL_BOOLEAN_TRUE;
        result = SL_RESULT_SUCCESS;
#else
        IVirtualizer *thiz = (IVirtualizer *) self;
        int32_t supported = 0;
        interface_lock_exclusive(thiz);
        if (NO_VIRTUALIZER(thiz)) {
            result = SL_RESULT_CONTROL_LOST;
        } else {
            android::status_t status =
                android_virt_getParam(thiz->mVirtualizerEffect,
                        VIRTUALIZER_PARAM_STRENGTH_SUPPORTED, &supported);
            result = android_fx_statusToResult(status);
        }
        interface_unlock_exclusive(thiz);
        *pSupported = (SLboolean) (supported != 0);
#endif
    }

    SL_LEAVE_INTERFACE
}


static const struct SLVirtualizerItf_ IVirtualizer_Itf = {
    IVirtualizer_SetEnabled,
    IVirtualizer_IsEnabled,
    IVirtualizer_SetStrength,
    IVirtualizer_GetRoundedStrength,
    IVirtualizer_IsStrengthSupported
};

void IVirtualizer_init(void *self)
{
    IVirtualizer *thiz = (IVirtualizer *) self;
    thiz->mItf = &IVirtualizer_Itf;
    thiz->mEnabled = SL_BOOLEAN_FALSE;
    thiz->mStrength = 0;
#if defined(ANDROID)
    memset(&thiz->mVirtualizerDescriptor, 0, sizeof(effect_descriptor_t));
    // placement new (explicit constructor)
    (void) new (&thiz->mVirtualizerEffect) android::sp<android::AudioEffect>();
#endif
}

void IVirtualizer_deinit(void *self)
{
#if defined(ANDROID)
    IVirtualizer *thiz = (IVirtualizer *) self;
    // explicit destructor
    thiz->mVirtualizerEffect.~sp();
#endif
}

bool IVirtualizer_Expose(void *self)
{
#if defined(ANDROID)
    IVirtualizer *thiz = (IVirtualizer *) self;
    if (!android_fx_initEffectDescriptor(SL_IID_VIRTUALIZER, &thiz->mVirtualizerDescriptor)) {
        SL_LOGE("Virtualizer initialization failed.");
        return false;
    }
#endif
    return true;
}
