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

/****************************************************************************************/
/*                                                                                      */
/*    Includes                                                                          */
/*                                                                                      */
/****************************************************************************************/

#include "LVDBE.h"
#include "LVDBE_Private.h"

/****************************************************************************************/
/*                                                                                      */
/* FUNCTION:                 LVDBE_Memory                                               */
/*                                                                                      */
/* DESCRIPTION:                                                                         */
/*    This function is used for memory allocation and free. It can be called in         */
/*    two ways:                                                                         */
/*                                                                                      */
/*        hInstance = NULL                Returns the memory requirements               */
/*        hInstance = Instance handle        Returns the memory requirements and        */
/*                                        allocated base addresses for the instance     */
/*                                                                                      */
/*    When this function is called for memory allocation (hInstance=NULL) the memory    */
/*  base address pointers are NULL on return.                                           */
/*                                                                                      */
/*    When the function is called for free (hInstance = Instance Handle) the memory     */
/*  table returns the allocated memory and base addresses used during initialisation.   */
/*                                                                                      */
/* PARAMETERS:                                                                          */
/*  hInstance                Instance Handle                                            */
/*  pMemoryTable             Pointer to an empty memory definition table                */
/*    pCapabilities           Pointer to the instance capabilities                      */
/*                                                                                      */
/* RETURNS:                                                                             */
/*  LVDBE_SUCCESS            Succeeded                                                  */
/*                                                                                      */
/* NOTES:                                                                               */
/*    1.    This function may be interrupted by the LVDBE_Process function              */
/*                                                                                      */
/****************************************************************************************/

LVDBE_ReturnStatus_en LVDBE_Memory(LVDBE_Handle_t            hInstance,
                                   LVDBE_MemTab_t            *pMemoryTable,
                                   LVDBE_Capabilities_t      *pCapabilities)
{

    LVM_UINT32          ScratchSize;
    LVDBE_Instance_t    *pInstance = (LVDBE_Instance_t *)hInstance;


    /*
     * Fill in the memory table
     */
    if (hInstance == LVM_NULL)
    {
        /*
         * Instance memory
         */
        pMemoryTable->Region[LVDBE_MEMREGION_INSTANCE].Size         = sizeof(LVDBE_Instance_t);
        pMemoryTable->Region[LVDBE_MEMREGION_INSTANCE].Alignment    = LVDBE_INSTANCE_ALIGN;
        pMemoryTable->Region[LVDBE_MEMREGION_INSTANCE].Type         = LVDBE_PERSISTENT;
        pMemoryTable->Region[LVDBE_MEMREGION_INSTANCE].pBaseAddress = LVM_NULL;

        /*
         * Data memory
         */
        pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_DATA].Size         = sizeof(LVDBE_Data_t);
        pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_DATA].Alignment    = LVDBE_PERSISTENT_DATA_ALIGN;
        pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_DATA].Type         = LVDBE_PERSISTENT_DATA;
        pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_DATA].pBaseAddress = LVM_NULL;

        /*
         * Coef memory
         */
        pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].Size         = sizeof(LVDBE_Coef_t);
        pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].Alignment    = LVDBE_PERSISTENT_COEF_ALIGN;
        pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].Type         = LVDBE_PERSISTENT_COEF;
        pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].pBaseAddress = LVM_NULL;

        /*
         * Scratch memory
         */
        ScratchSize = (LVM_UINT32)(LVDBE_SCRATCHBUFFERS_INPLACE*sizeof(LVM_INT16)*pCapabilities->MaxBlockSize);
        pMemoryTable->Region[LVDBE_MEMREGION_SCRATCH].Size         = ScratchSize;
        pMemoryTable->Region[LVDBE_MEMREGION_SCRATCH].Alignment    = LVDBE_SCRATCH_ALIGN;
        pMemoryTable->Region[LVDBE_MEMREGION_SCRATCH].Type         = LVDBE_SCRATCH;
        pMemoryTable->Region[LVDBE_MEMREGION_SCRATCH].pBaseAddress = LVM_NULL;
    }
    else
    {
        /* Read back memory allocation table */
        *pMemoryTable = pInstance->MemoryTable;
    }

    return(LVDBE_SUCCESS);
}


/****************************************************************************************/
/*                                                                                      */
/* FUNCTION:                 LVDBE_Init                                                 */
/*                                                                                      */
/* DESCRIPTION:                                                                         */
/*    Create and initialisation function for the Dynamic Bass Enhancement module        */
/*                                                                                      */
/*    This function can be used to create an algorithm instance by calling with         */
/*    hInstance set to NULL. In this case the algorithm returns the new instance        */
/*    handle.                                                                           */
/*                                                                                      */
/*    This function can be used to force a full re-initialisation of the algorithm      */
/*    by calling with hInstance = Instance Handle. In this case the memory table        */
/*    should be correct for the instance, this can be ensured by calling the function   */
/*    DBE_Memory before calling this function.                                          */
/*                                                                                      */
/* PARAMETERS:                                                                          */
/*  hInstance                  Instance handle                                          */
/*  pMemoryTable             Pointer to the memory definition table                     */
/*  pCapabilities              Pointer to the instance capabilities                     */
/*                                                                                      */
/* RETURNS:                                                                             */
/*  LVDBE_SUCCESS            Initialisation succeeded                                   */
/*  LVDBE_ALIGNMENTERROR    Instance or scratch memory on incorrect alignment           */
/*    LVDBE_NULLADDRESS        Instance or scratch memory has a NULL pointer            */
/*                                                                                      */
/* NOTES:                                                                               */
/*  1.     The instance handle is the pointer to the base address of the first memory   */
/*        region.                                                                       */
/*    2.    This function must not be interrupted by the LVDBE_Process function         */
/*                                                                                      */
/****************************************************************************************/

LVDBE_ReturnStatus_en LVDBE_Init(LVDBE_Handle_t         *phInstance,
                                   LVDBE_MemTab_t       *pMemoryTable,
                                   LVDBE_Capabilities_t *pCapabilities)
{

    LVDBE_Instance_t      *pInstance;
    LVMixer3_1St_st       *pMixer_Instance;
    LVMixer3_2St_st       *pBypassMixer_Instance;
    LVM_INT16             i;
    LVM_INT32             MixGain;


    /*
     * Set the instance handle if not already initialised
     */
    if (*phInstance == LVM_NULL)
    {
        *phInstance = (LVDBE_Handle_t)pMemoryTable->Region[LVDBE_MEMREGION_INSTANCE].pBaseAddress;
    }
    pInstance =(LVDBE_Instance_t  *)*phInstance;


    /*
     * Check the memory table for NULL pointers and incorrectly aligned data
     */
    for (i=0; i<LVDBE_NR_MEMORY_REGIONS; i++)
    {
        if (pMemoryTable->Region[i].Size!=0)
        {
            if (pMemoryTable->Region[i].pBaseAddress==LVM_NULL)
            {
                return(LVDBE_NULLADDRESS);
            }
            if (((uintptr_t)pMemoryTable->Region[i].pBaseAddress % pMemoryTable->Region[i].Alignment)!=0){
                return(LVDBE_ALIGNMENTERROR);
            }
        }
    }


    /*
     * Save the memory table in the instance structure
     */
    pInstance->Capabilities = *pCapabilities;


    /*
     * Save the memory table in the instance structure
     */
    pInstance->MemoryTable = *pMemoryTable;


    /*
     * Set the default instance parameters
     */
    pInstance->Params.CentreFrequency   =    LVDBE_CENTRE_55HZ;
    pInstance->Params.EffectLevel       =    0;
    pInstance->Params.HeadroomdB        =    0;
    pInstance->Params.HPFSelect         =    LVDBE_HPF_OFF;
    pInstance->Params.OperatingMode     =    LVDBE_OFF;
    pInstance->Params.SampleRate        =    LVDBE_FS_8000;
    pInstance->Params.VolumeControl     =    LVDBE_VOLUME_OFF;
    pInstance->Params.VolumedB          =    0;


    /*
     * Set pointer to data and coef memory
     */
    pInstance->pData = pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_DATA].pBaseAddress;
    pInstance->pCoef = pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].pBaseAddress;


    /*
     * Initialise the filters
     */
    LVDBE_SetFilters(pInstance,                 /* Set the filter taps and coefficients */
                     &pInstance->Params);


    /*
     * Initialise the AGC
     */
    LVDBE_SetAGC(pInstance,                                     /* Set the AGC gain */
                 &pInstance->Params);
    pInstance->pData->AGCInstance.AGC_Gain = pInstance->pData->AGCInstance.AGC_MaxGain;
                                                /* Default to the bass boost setting */

    // initialize the mixer with some fixes values since otherwise LVDBE_SetVolume ends up
    // reading uninitialized data
    pMixer_Instance = &pInstance->pData->BypassVolume;
    LVC_Mixer_Init(&pMixer_Instance->MixerStream[0],0x00007FFF,0x00007FFF);

    /*
     * Initialise the volume
     */
    LVDBE_SetVolume(pInstance,                                         /* Set the Volume */
                    &pInstance->Params);

    pInstance->pData->AGCInstance.Volume = pInstance->pData->AGCInstance.Target;
                                                /* Initialise as the target */

    MixGain = LVC_Mixer_GetTarget(&pMixer_Instance->MixerStream[0]);
    LVC_Mixer_Init(&pMixer_Instance->MixerStream[0],MixGain,MixGain);

    /* Configure the mixer process path */
    pMixer_Instance->MixerStream[0].CallbackParam = 0;
    pMixer_Instance->MixerStream[0].pCallbackHandle = LVM_NULL;
    pMixer_Instance->MixerStream[0].pCallBack = LVM_NULL;
    pMixer_Instance->MixerStream[0].CallbackSet = 0;

    /*
     * Initialise the clicks minimisation BypassMixer
     */

    pBypassMixer_Instance = &pInstance->pData->BypassMixer;

    /*
     * Setup the mixer gain for the processed path
     */
    pBypassMixer_Instance->MixerStream[0].CallbackParam = 0;
    pBypassMixer_Instance->MixerStream[0].pCallbackHandle = LVM_NULL;
    pBypassMixer_Instance->MixerStream[0].pCallBack = LVM_NULL;
    pBypassMixer_Instance->MixerStream[0].CallbackSet=0;
    LVC_Mixer_Init(&pBypassMixer_Instance->MixerStream[0],0,0);
    LVC_Mixer_SetTimeConstant(&pBypassMixer_Instance->MixerStream[0],
        LVDBE_BYPASS_MIXER_TC,pInstance->Params.SampleRate,2);
    /*
     * Setup the mixer gain for the unprocessed path
     */
    pBypassMixer_Instance->MixerStream[1].CallbackParam = 0;
    pBypassMixer_Instance->MixerStream[1].pCallbackHandle = LVM_NULL;
    pBypassMixer_Instance->MixerStream[1].pCallBack = LVM_NULL;
    pBypassMixer_Instance->MixerStream[1].CallbackSet=0;
    LVC_Mixer_Init(&pBypassMixer_Instance->MixerStream[1],0x00007FFF,0x00007FFF);
    LVC_Mixer_SetTimeConstant(&pBypassMixer_Instance->MixerStream[1],
        LVDBE_BYPASS_MIXER_TC,pInstance->Params.SampleRate,2);

    return(LVDBE_SUCCESS);
}

