/*
 * 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 "LVEQNB.h"
#include "LVEQNB_Private.h"
#include "VectorArithmetic.h"
#include "BIQUAD.h"


/****************************************************************************************/
/*                                                                                      */
/*  Defines                                                                             */
/*                                                                                      */
/****************************************************************************************/

#define SHIFT       13

/****************************************************************************************/
/*                                                                                      */
/* FUNCTION:                LVEQNB_Process                                              */
/*                                                                                      */
/* DESCRIPTION:                                                                         */
/*  Process function for the N-Band Equaliser module.                                   */
/*                                                                                      */
/* PARAMETERS:                                                                          */
/*  hInstance               Instance handle                                             */
/*  pInData                 Pointer to the input data                                   */
/*  pOutData                Pointer to the output data                                  */
/*  NumSamples              Number of samples in the input buffer                       */
/*                                                                                      */
/* RETURNS:                                                                             */
/*  LVEQNB_SUCCESS          Succeeded                                                   */
/*  LVEQNB_NULLADDRESS      When hInstance, pInData or pOutData are NULL                */
/*  LVEQNB_ALIGNMENTERROR   When pInData or pOutData are not 32-bit aligned             */
/*  LVEQNB_TOOMANYSAMPLES   NumSamples was larger than the maximum block size           */
/*                                                                                      */
/* NOTES:                                                                               */
/*                                                                                      */
/****************************************************************************************/

LVEQNB_ReturnStatus_en LVEQNB_Process(LVEQNB_Handle_t       hInstance,
                                      const LVM_INT16       *pInData,
                                      LVM_INT16             *pOutData,
                                      LVM_UINT16            NumSamples)
{

    LVM_UINT16          i;
    Biquad_Instance_t   *pBiquad;
    LVEQNB_Instance_t   *pInstance = (LVEQNB_Instance_t  *)hInstance;
    LVM_INT32           *pScratch;


     /* Check for NULL pointers */
    if((hInstance == LVM_NULL) || (pInData == LVM_NULL) || (pOutData == LVM_NULL))
    {
        return LVEQNB_NULLADDRESS;
    }

    /* Check if the input and output data buffers are 32-bit aligned */
    if ((((uintptr_t)pInData % 4) != 0) || (((uintptr_t)pOutData % 4) != 0))
    {
        return LVEQNB_ALIGNMENTERROR;
    }

    pScratch  = (LVM_INT32 *)pInstance->pFastTemporary;

    /*
    * Check the number of samples is not too large
    */
    if (NumSamples > pInstance->Capabilities.MaxBlockSize)
    {
        return(LVEQNB_TOOMANYSAMPLES);
    }

    if (pInstance->Params.OperatingMode == LVEQNB_ON)
    {
        /*
         * Convert from 16-bit to 32-bit
         */
        Int16LShiftToInt32_16x32((LVM_INT16 *)pInData,      /* Source */
                                 pScratch,                  /* Destination */
                                 (LVM_INT16)(2*NumSamples), /* Left and Right */
                                 SHIFT);                    /* Scaling shift */

        /*
         * For each section execte the filter unless the gain is 0dB
         */
        if (pInstance->NBands != 0)
        {
            for (i=0; i<pInstance->NBands; i++)
            {
                /*
                 * Check if band is non-zero dB gain
                 */
                if (pInstance->pBandDefinitions[i].Gain != 0)
                {
                    /*
                     * Get the address of the biquad instance
                     */
                    pBiquad = &pInstance->pEQNB_FilterState[i];


                    /*
                     * Select single or double precision as required
                     */
                    switch (pInstance->pBiquadType[i])
                    {
                        case LVEQNB_SinglePrecision:
                        {
                            PK_2I_D32F32C14G11_TRC_WRA_01(pBiquad,
                                                          (LVM_INT32 *)pScratch,
                                                          (LVM_INT32 *)pScratch,
                                                          (LVM_INT16)NumSamples);
                            break;
                        }

                        case LVEQNB_DoublePrecision:
                        {
                            PK_2I_D32F32C30G11_TRC_WRA_01(pBiquad,
                                                          (LVM_INT32 *)pScratch,
                                                          (LVM_INT32 *)pScratch,
                                                          (LVM_INT16)NumSamples);
                            break;
                        }
                        default:
                            break;
                    }
                }
            }
        }


        if(pInstance->bInOperatingModeTransition == LVM_TRUE){
                /*
                 * Convert from 32-bit to 16- bit and saturate
                 */
                Int32RShiftToInt16_Sat_32x16(pScratch,                      /* Source */
                                             (LVM_INT16 *)pScratch,         /* Destination */
                                             (LVM_INT16)(2*NumSamples),     /* Left and Right */
                                             SHIFT);                        /* Scaling shift */

                LVC_MixSoft_2St_D16C31_SAT(&pInstance->BypassMixer,
                                                (LVM_INT16 *)pScratch,
                                                (LVM_INT16 *)pInData,
                                                (LVM_INT16 *)pScratch,
                                                (LVM_INT16)(2*NumSamples));

                Copy_16((LVM_INT16*)pScratch,                           /* Source */
                        pOutData,                                       /* Destination */
                        (LVM_INT16)(2*NumSamples));                     /* Left and Right samples */
        }
        else{

            /*
             * Convert from 32-bit to 16- bit and saturate
             */
            Int32RShiftToInt16_Sat_32x16(pScratch,              /* Source */
                                         pOutData,              /* Destination */
                                         (LVM_INT16 )(2*NumSamples), /* Left and Right */
                                         SHIFT);                /* Scaling shift */
        }
    }
    else
    {
        /*
         * Mode is OFF so copy the data if necessary
         */
        if (pInData != pOutData)
        {
            Copy_16(pInData,                                    /* Source */
                    pOutData,                                   /* Destination */
                    (LVM_INT16)(2*NumSamples));                 /* Left and Right samples */
        }
    }



    return(LVEQNB_SUCCESS);

}
