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 #include "BIQUAD.h"
     19 #include "FO_2I_D16F32Css_LShx_TRC_WRA_01_Private.h"
     20 #include "LVM_Macros.h"
     21 
     22 /**************************************************************************
     23 ASSUMPTIONS:
     24 COEFS-
     25 pBiquadState->coefs[0] is A1,
     26 pBiquadState->coefs[1] is A0,
     27 pBiquadState->coefs[2] is -B1, these are in Q15 format
     28 pBiquadState->Shift    is Shift value
     29 DELAYS-
     30 pBiquadState->pDelays[0] is x(n-1)L in Q15 format
     31 pBiquadState->pDelays[1] is y(n-1)L in Q30 format
     32 pBiquadState->pDelays[2] is x(n-1)R in Q15 format
     33 pBiquadState->pDelays[3] is y(n-1)R in Q30 format
     34 ***************************************************************************/
     35 #ifdef BUILD_FLOAT
     36 void FO_2I_D16F32C15_LShx_TRC_WRA_01(Biquad_FLOAT_Instance_t       *pInstance,
     37                                      LVM_FLOAT               *pDataIn,
     38                                      LVM_FLOAT               *pDataOut,
     39                                      LVM_INT16               NrSamples)
     40     {
     41         LVM_FLOAT   ynL,ynR;
     42         LVM_FLOAT   Temp;
     43         LVM_FLOAT   NegSatValue;
     44         LVM_INT16   ii;
     45 
     46         PFilter_Float_State pBiquadState = (PFilter_Float_State) pInstance;
     47 
     48         NegSatValue = -1.0f;
     49 
     50         for (ii = NrSamples; ii != 0; ii--)
     51         {
     52 
     53             /**************************************************************************
     54                             PROCESSING OF THE LEFT CHANNEL
     55             ***************************************************************************/
     56 
     57             // ynL =A1  * x(n-1)L
     58             ynL = (LVM_FLOAT)pBiquadState->coefs[0] * pBiquadState->pDelays[0];
     59             // ynR =A1  * x(n-1)R
     60             ynR = (LVM_FLOAT)pBiquadState->coefs[0] * pBiquadState->pDelays[2];
     61 
     62 
     63             // ynL+=A0  * x(n)L
     64             ynL += (LVM_FLOAT)pBiquadState->coefs[1] * (*pDataIn);
     65             // ynR+=A0  * x(n)L
     66             ynR += (LVM_FLOAT)pBiquadState->coefs[1] * (*(pDataIn+1));
     67 
     68 
     69             // ynL +=  (-B1  * y(n-1)L  )
     70             Temp = pBiquadState->pDelays[1] * pBiquadState->coefs[2];
     71             ynL += Temp;
     72             // ynR +=  (-B1  * y(n-1)R ) )
     73             Temp = pBiquadState->pDelays[3] * pBiquadState->coefs[2];
     74             ynR += Temp;
     75 
     76 
     77             /**************************************************************************
     78                             UPDATING THE DELAYS
     79             ***************************************************************************/
     80             pBiquadState->pDelays[1] = ynL; // Update y(n-1)L
     81             pBiquadState->pDelays[0] = (*pDataIn++); // Update x(n-1)L
     82 
     83             pBiquadState->pDelays[3] = ynR; // Update y(n-1)R
     84             pBiquadState->pDelays[2] = (*pDataIn++); // Update x(n-1)R
     85 
     86             /**************************************************************************
     87                             WRITING THE OUTPUT
     88             ***************************************************************************/
     89 
     90             /*Saturate results*/
     91             if(ynL > 1.0f)
     92             {
     93                 ynL = 1.0f;
     94             }
     95             else
     96             {
     97                 if(ynL < NegSatValue)
     98                 {
     99                     ynL = NegSatValue;
    100                 }
    101             }
    102 
    103             if(ynR > 1.0f)
    104             {
    105                 ynR = 1.0f;
    106             }
    107             else
    108             {
    109                 if(ynR < NegSatValue)
    110                 {
    111                     ynR = NegSatValue;
    112                 }
    113             }
    114 
    115             *pDataOut++ = (LVM_FLOAT)ynL;
    116             *pDataOut++ = (LVM_FLOAT)ynR;
    117         }
    118 
    119     }
    120 #else
    121 void FO_2I_D16F32C15_LShx_TRC_WRA_01(Biquad_Instance_t       *pInstance,
    122                                      LVM_INT16               *pDataIn,
    123                                      LVM_INT16               *pDataOut,
    124                                      LVM_INT16               NrSamples)
    125     {
    126         LVM_INT32   ynL,ynR;
    127         LVM_INT32   Temp;
    128         LVM_INT32   NegSatValue;
    129         LVM_INT16   ii;
    130         LVM_INT16   Shift;
    131         PFilter_State pBiquadState = (PFilter_State) pInstance;
    132 
    133         NegSatValue = LVM_MAXINT_16 +1;
    134         NegSatValue = -NegSatValue;
    135 
    136         Shift = pBiquadState->Shift;
    137 
    138 
    139         for (ii = NrSamples; ii != 0; ii--)
    140         {
    141 
    142             /**************************************************************************
    143                             PROCESSING OF THE LEFT CHANNEL
    144             ***************************************************************************/
    145 
    146             // ynL =A1 (Q15) * x(n-1)L (Q15) in Q30
    147             ynL=(LVM_INT32)pBiquadState->coefs[0]* pBiquadState->pDelays[0];
    148             // ynR =A1 (Q15) * x(n-1)R (Q15) in Q30
    149             ynR=(LVM_INT32)pBiquadState->coefs[0]* pBiquadState->pDelays[2];
    150 
    151 
    152             // ynL+=A0 (Q15) * x(n)L (Q15) in Q30
    153             ynL+=(LVM_INT32)pBiquadState->coefs[1]* (*pDataIn);
    154             // ynR+=A0 (Q15) * x(n)L (Q15) in Q30
    155             ynR+=(LVM_INT32)pBiquadState->coefs[1]* (*(pDataIn+1));
    156 
    157 
    158             // ynL +=  (-B1 (Q15) * y(n-1)L (Q30) ) in Q30
    159             MUL32x16INTO32(pBiquadState->pDelays[1],pBiquadState->coefs[2],Temp,15);
    160             ynL +=Temp;
    161             // ynR +=  (-B1 (Q15) * y(n-1)R (Q30) ) in Q30
    162             MUL32x16INTO32(pBiquadState->pDelays[3],pBiquadState->coefs[2],Temp,15);
    163             ynR +=Temp;
    164 
    165 
    166             /**************************************************************************
    167                             UPDATING THE DELAYS
    168             ***************************************************************************/
    169             pBiquadState->pDelays[1]=ynL; // Update y(n-1)L in Q30
    170             pBiquadState->pDelays[0]=(*pDataIn++); // Update x(n-1)L in Q15
    171 
    172             pBiquadState->pDelays[3]=ynR; // Update y(n-1)R in Q30
    173             pBiquadState->pDelays[2]=(*pDataIn++); // Update x(n-1)R in Q15
    174 
    175             /**************************************************************************
    176                             WRITING THE OUTPUT
    177             ***************************************************************************/
    178             /*Apply shift: Instead of left shift on 16-bit result, right shift of (15-shift) is applied
    179               for better SNR*/
    180             ynL = ynL>>(15-Shift);
    181             ynR = ynR>>(15-Shift);
    182 
    183             /*Saturate results*/
    184             if(ynL > LVM_MAXINT_16)
    185             {
    186                 ynL = LVM_MAXINT_16;
    187             }
    188             else
    189             {
    190                 if(ynL < NegSatValue)
    191                 {
    192                     ynL = NegSatValue;
    193                 }
    194             }
    195 
    196             if(ynR > LVM_MAXINT_16)
    197             {
    198                 ynR = LVM_MAXINT_16;
    199             }
    200             else
    201             {
    202                 if(ynR < NegSatValue)
    203                 {
    204                     ynR = NegSatValue;
    205                 }
    206             }
    207 
    208             *pDataOut++=(LVM_INT16)ynL;
    209             *pDataOut++=(LVM_INT16)ynR;
    210         }
    211 
    212     }
    213 #endif
    214