Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (C) 2004-2010 NXP Software
      3  * Copyright (C) 2010 The Android Open Source Project
      4  *
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at
      8  *
      9  *      http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 
     18 /****************************************************************************************/
     19 /*                                                                                      */
     20 /*  Includes                                                                            */
     21 /*                                                                                      */
     22 /****************************************************************************************/
     23 
     24 #include "LVEQNB.h"
     25 #include "LVEQNB_Private.h"
     26 #include "VectorArithmetic.h"
     27 #include "BIQUAD.h"
     28 
     29 
     30 /****************************************************************************************/
     31 /*                                                                                      */
     32 /*  Defines                                                                             */
     33 /*                                                                                      */
     34 /****************************************************************************************/
     35 
     36 #define SHIFT       13
     37 
     38 /****************************************************************************************/
     39 /*                                                                                      */
     40 /* FUNCTION:                LVEQNB_Process                                              */
     41 /*                                                                                      */
     42 /* DESCRIPTION:                                                                         */
     43 /*  Process function for the N-Band Equaliser module.                                   */
     44 /*                                                                                      */
     45 /* PARAMETERS:                                                                          */
     46 /*  hInstance               Instance handle                                             */
     47 /*  pInData                 Pointer to the input data                                   */
     48 /*  pOutData                Pointer to the output data                                  */
     49 /*  NumSamples              Number of samples in the input buffer                       */
     50 /*                                                                                      */
     51 /* RETURNS:                                                                             */
     52 /*  LVEQNB_SUCCESS          Succeeded                                                   */
     53 /*  LVEQNB_NULLADDRESS      When hInstance, pInData or pOutData are NULL                */
     54 /*  LVEQNB_ALIGNMENTERROR   When pInData or pOutData are not 32-bit aligned             */
     55 /*  LVEQNB_TOOMANYSAMPLES   NumSamples was larger than the maximum block size           */
     56 /*                                                                                      */
     57 /* NOTES:                                                                               */
     58 /*                                                                                      */
     59 /****************************************************************************************/
     60 
     61 LVEQNB_ReturnStatus_en LVEQNB_Process(LVEQNB_Handle_t       hInstance,
     62                                       const LVM_INT16       *pInData,
     63                                       LVM_INT16             *pOutData,
     64                                       LVM_UINT16            NumSamples)
     65 {
     66 
     67     LVM_UINT16          i;
     68     Biquad_Instance_t   *pBiquad;
     69     LVEQNB_Instance_t   *pInstance = (LVEQNB_Instance_t  *)hInstance;
     70     LVM_INT32           *pScratch;
     71 
     72 
     73      /* Check for NULL pointers */
     74     if((hInstance == LVM_NULL) || (pInData == LVM_NULL) || (pOutData == LVM_NULL))
     75     {
     76         return LVEQNB_NULLADDRESS;
     77     }
     78 
     79     /* Check if the input and output data buffers are 32-bit aligned */
     80     if ((((LVM_INT32)pInData % 4) != 0) || (((LVM_INT32)pOutData % 4) != 0))
     81     {
     82         return LVEQNB_ALIGNMENTERROR;
     83     }
     84 
     85     pScratch  = (LVM_INT32 *)pInstance->pFastTemporary;
     86 
     87     /*
     88     * Check the number of samples is not too large
     89     */
     90     if (NumSamples > pInstance->Capabilities.MaxBlockSize)
     91     {
     92         return(LVEQNB_TOOMANYSAMPLES);
     93     }
     94 
     95     if (pInstance->Params.OperatingMode == LVEQNB_ON)
     96     {
     97         /*
     98          * Convert from 16-bit to 32-bit
     99          */
    100         Int16LShiftToInt32_16x32((LVM_INT16 *)pInData,      /* Source */
    101                                  pScratch,                  /* Destination */
    102                                  (LVM_INT16)(2*NumSamples), /* Left and Right */
    103                                  SHIFT);                    /* Scaling shift */
    104 
    105         /*
    106          * For each section execte the filter unless the gain is 0dB
    107          */
    108         if (pInstance->NBands != 0)
    109         {
    110             for (i=0; i<pInstance->NBands; i++)
    111             {
    112                 /*
    113                  * Check if band is non-zero dB gain
    114                  */
    115                 if (pInstance->pBandDefinitions[i].Gain != 0)
    116                 {
    117                     /*
    118                      * Get the address of the biquad instance
    119                      */
    120                     pBiquad = &pInstance->pEQNB_FilterState[i];
    121 
    122 
    123                     /*
    124                      * Select single or double precision as required
    125                      */
    126                     switch (pInstance->pBiquadType[i])
    127                     {
    128                         case LVEQNB_SinglePrecision:
    129                         {
    130                             PK_2I_D32F32C14G11_TRC_WRA_01(pBiquad,
    131                                                           (LVM_INT32 *)pScratch,
    132                                                           (LVM_INT32 *)pScratch,
    133                                                           (LVM_INT16)NumSamples);
    134                             break;
    135                         }
    136 
    137                         case LVEQNB_DoublePrecision:
    138                         {
    139                             PK_2I_D32F32C30G11_TRC_WRA_01(pBiquad,
    140                                                           (LVM_INT32 *)pScratch,
    141                                                           (LVM_INT32 *)pScratch,
    142                                                           (LVM_INT16)NumSamples);
    143                             break;
    144                         }
    145                         default:
    146                             break;
    147                     }
    148                 }
    149             }
    150         }
    151 
    152 
    153         if(pInstance->bInOperatingModeTransition == LVM_TRUE){
    154                 /*
    155                  * Convert from 32-bit to 16- bit and saturate
    156                  */
    157                 Int32RShiftToInt16_Sat_32x16(pScratch,                      /* Source */
    158                                              (LVM_INT16 *)pScratch,         /* Destination */
    159                                              (LVM_INT16)(2*NumSamples),     /* Left and Right */
    160                                              SHIFT);                        /* Scaling shift */
    161 
    162                 LVC_MixSoft_2St_D16C31_SAT(&pInstance->BypassMixer,
    163                                                 (LVM_INT16 *)pScratch,
    164                                                 (LVM_INT16 *)pInData,
    165                                                 (LVM_INT16 *)pScratch,
    166                                                 (LVM_INT16)(2*NumSamples));
    167 
    168                 Copy_16((LVM_INT16*)pScratch,                           /* Source */
    169                         pOutData,                                       /* Destination */
    170                         (LVM_INT16)(2*NumSamples));                     /* Left and Right samples */
    171         }
    172         else{
    173 
    174             /*
    175              * Convert from 32-bit to 16- bit and saturate
    176              */
    177             Int32RShiftToInt16_Sat_32x16(pScratch,              /* Source */
    178                                          pOutData,              /* Destination */
    179                                          (LVM_INT16 )(2*NumSamples), /* Left and Right */
    180                                          SHIFT);                /* Scaling shift */
    181         }
    182     }
    183     else
    184     {
    185         /*
    186          * Mode is OFF so copy the data if necessary
    187          */
    188         if (pInData != pOutData)
    189         {
    190             Copy_16(pInData,                                    /* Source */
    191                     pOutData,                                   /* Destination */
    192                     (LVM_INT16)(2*NumSamples));                 /* Left and Right samples */
    193         }
    194     }
    195 
    196 
    197 
    198     return(LVEQNB_SUCCESS);
    199 
    200 }
    201