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    "LVPSA.h"
     19 #include    "LVPSA_Private.h"
     20 #include    "VectorArithmetic.h"
     21 
     22 #define     LOW_FREQ            298             /* 32768/110 for low test frequency */
     23 #define     HIGH_FREQ           386             /* 32768/85 for high test frequency */
     24 
     25 LVPSA_RETURN LVPSA_SetBPFiltersType (  LVPSA_InstancePr_t        *pInst,
     26                                        LVPSA_ControlParams_t      *pParams  );
     27 
     28 LVPSA_RETURN LVPSA_SetQPFCoefficients( LVPSA_InstancePr_t        *pInst,
     29                                        LVPSA_ControlParams_t      *pParams  );
     30 
     31 LVPSA_RETURN LVPSA_BPSinglePrecCoefs(  LVM_UINT16             Fs,
     32                                        LVPSA_FilterParam_t   *pFilterParams,
     33                                        BP_C16_Coefs_t        *pCoefficients);
     34 
     35 LVPSA_RETURN LVPSA_BPDoublePrecCoefs(  LVM_UINT16            Fs,
     36                                        LVPSA_FilterParam_t  *pFilterParams,
     37                                        BP_C32_Coefs_t       *pCoefficients);
     38 
     39 LVPSA_RETURN LVPSA_BPDoublePrecCoefs(  LVM_UINT16              Fs,
     40                                        LVPSA_FilterParam_t     *pFilterParams,
     41                                        BP_C32_Coefs_t          *pCoefficients);
     42 
     43 LVPSA_RETURN LVPSA_SetBPFCoefficients( LVPSA_InstancePr_t        *pInst,
     44                                        LVPSA_ControlParams_t      *pParams  );
     45 
     46 LVPSA_RETURN LVPSA_ClearFilterHistory( LVPSA_InstancePr_t        *pInst);
     47 
     48 
     49 
     50 
     51 /************************************************************************************/
     52 /*                                                                                  */
     53 /* FUNCTION:            LVPSA_Control                                               */
     54 /*                                                                                  */
     55 /* DESCRIPTION:                                                                     */
     56 /*  Give some new control parameters to the module.                                 */
     57 /*                                                                                  */
     58 /* PARAMETERS:                                                                      */
     59 /*  hInstance           Pointer to the instance                                     */
     60 /*  NewParams           Structure that contains the new parameters                  */
     61 /*                                                                                  */
     62 /* RETURNS:                                                                         */
     63 /*  LVPSA_OK            Succeeds                                                    */
     64 /*  otherwise           Error due to bad parameters                                 */
     65 /*                                                                                  */
     66 /************************************************************************************/
     67 LVPSA_RETURN LVPSA_Control           ( pLVPSA_Handle_t             hInstance,
     68                                        LVPSA_ControlParams_t      *pNewParams     )
     69 {
     70 
     71     LVPSA_InstancePr_t     *pLVPSA_Inst    = (LVPSA_InstancePr_t*)hInstance;
     72 
     73     if((hInstance == LVM_NULL) || (pNewParams == LVM_NULL))
     74     {
     75         return(LVPSA_ERROR_NULLADDRESS);
     76     }
     77     if(pNewParams->Fs >= LVPSA_NR_SUPPORTED_RATE)
     78     {
     79         return(LVPSA_ERROR_INVALIDPARAM);
     80     }
     81     if(pNewParams->LevelDetectionSpeed >= LVPSA_NR_SUPPORTED_SPEED)
     82     {
     83         return(LVPSA_ERROR_INVALIDPARAM);
     84     }
     85 
     86     pLVPSA_Inst->NewParams = *pNewParams;
     87     pLVPSA_Inst->bControlPending = LVM_TRUE;
     88 
     89     return(LVPSA_OK);
     90 }
     91 
     92 /************************************************************************************/
     93 /*                                                                                  */
     94 /* FUNCTION:            LVPSA_GetControlParams                                      */
     95 /*                                                                                  */
     96 /* DESCRIPTION:                                                                     */
     97 /*  Get the current control parameters of the module                                */
     98 /*                                                                                  */
     99 /* PARAMETERS:                                                                      */
    100 /*  hInstance       Pointer to the instance                                         */
    101 /*  pParams         Pointer to an empty control structure                           */
    102 /* RETURNS:                                                                         */
    103 /*  LVPSA_OK            Succeeds                                                    */
    104 /*  otherwise           Error due to bad parameters                                 */
    105 /*                                                                                  */
    106 /************************************************************************************/
    107 LVPSA_RETURN LVPSA_GetControlParams         (    pLVPSA_Handle_t            hInstance,
    108                                                  LVPSA_ControlParams_t     *pParams )
    109 {
    110     LVPSA_InstancePr_t     *pLVPSA_Inst    = (LVPSA_InstancePr_t*)hInstance;
    111 
    112     if((hInstance == LVM_NULL) || (pParams == LVM_NULL))
    113     {
    114         return(LVPSA_ERROR_NULLADDRESS);
    115     }
    116 
    117     pParams->Fs                     = pLVPSA_Inst->CurrentParams.Fs;
    118     pParams->LevelDetectionSpeed    = pLVPSA_Inst->CurrentParams.LevelDetectionSpeed;
    119 
    120     return(LVPSA_OK);
    121 }
    122 
    123 
    124 /************************************************************************************/
    125 /*                                                                                  */
    126 /* FUNCTION:            LVPSA_GetInitParams                                         */
    127 /*                                                                                  */
    128 /* DESCRIPTION:                                                                     */
    129 /*  Get the initialization parameters of the module                                 */
    130 /*                                                                                  */
    131 /* PARAMETERS:                                                                      */
    132 /*  hInstance       Pointer to the instance                                         */
    133 /*  pParams         Pointer to an empty control structure                           */
    134 /* RETURNS:                                                                         */
    135 /*  LVPSA_OK            Succeeds                                                    */
    136 /*  otherwise           Error due to bad parameters                                 */
    137 /*                                                                                  */
    138 /************************************************************************************/
    139 LVPSA_RETURN LVPSA_GetInitParams         (    pLVPSA_Handle_t            hInstance,
    140                                               LVPSA_InitParams_t        *pParams )
    141 {
    142     LVPSA_InstancePr_t     *pLVPSA_Inst    = (LVPSA_InstancePr_t*)hInstance;
    143 
    144     if((hInstance == LVM_NULL) || (pParams == LVM_NULL))
    145     {
    146         return(LVPSA_ERROR_NULLADDRESS);
    147     }
    148 
    149     pParams->SpectralDataBufferDuration   = pLVPSA_Inst->SpectralDataBufferDuration;
    150     pParams->MaxInputBlockSize            = pLVPSA_Inst->MaxInputBlockSize;
    151     pParams->nBands                       = pLVPSA_Inst->nBands;
    152     pParams->pFiltersParams               = pLVPSA_Inst->pFiltersParams;
    153 
    154     return(LVPSA_OK);
    155 }
    156 
    157 
    158 /************************************************************************************/
    159 /*                                                                                  */
    160 /* FUNCTION:            LVPSA_ApplyNewSettings                                      */
    161 /*                                                                                  */
    162 /* DESCRIPTION:                                                                     */
    163 /*  Reinitialize some parameters and changes filters' coefficients if               */
    164 /*  some control parameters have changed.                                           */
    165 /*                                                                                  */
    166 /* PARAMETERS:                                                                      */
    167 /*  pInst               Pointer to the instance                                     */
    168 /*                                                                                  */
    169 /* RETURNS:                                                                         */
    170 /*  LVPSA_OK            Succeeds                                                    */
    171 /*  otherwise           Error due to bad parameters                                 */
    172 /*                                                                                  */
    173 /* NOTES:                                                                           */
    174 /*                                                                                  */
    175 /************************************************************************************/
    176 LVPSA_RETURN LVPSA_ApplyNewSettings (LVPSA_InstancePr_t     *pInst)
    177 {
    178     LVM_UINT16 ii;
    179     LVM_UINT16 Freq;
    180     LVPSA_ControlParams_t   Params;
    181     extern LVM_INT16        LVPSA_nSamplesBufferUpdate[];
    182     extern LVM_UINT16       LVPSA_SampleRateTab[];
    183     extern LVM_UINT16       LVPSA_DownSamplingFactor[];
    184 
    185 
    186     if(pInst == 0)
    187     {
    188         return(LVPSA_ERROR_NULLADDRESS);
    189     }
    190 
    191     Params = pInst->NewParams;
    192 
    193     /* Modifies filters types and coefficients, clear the taps and
    194        re-initializes parameters if sample frequency has changed    */
    195     if(Params.Fs != pInst->CurrentParams.Fs)
    196     {
    197         pInst->CurrentParams.Fs = Params.Fs;
    198 
    199         /* Initialize the center freqeuncies as a function of the sample rate */
    200         Freq = (LVM_UINT16) ((LVPSA_SampleRateTab[pInst->CurrentParams.Fs]>>1) / (pInst->nBands + 1));
    201         for(ii = pInst->nBands; ii > 0; ii--)
    202         {
    203             pInst->pFiltersParams[ii-1].CenterFrequency = (LVM_UINT16) (Freq * ii);
    204         }
    205 
    206         /* Count the number of relevant filters. If the center frequency of the filter is
    207            bigger than the nyquist frequency, then the filter is not relevant and doesn't
    208            need to be used */
    209         for(ii = pInst->nBands; ii > 0; ii--)
    210         {
    211             if(pInst->pFiltersParams[ii-1].CenterFrequency < (LVPSA_SampleRateTab[pInst->CurrentParams.Fs]>>1))
    212             {
    213                 pInst->nRelevantFilters = ii;
    214                 break;
    215             }
    216         }
    217         LVPSA_SetBPFiltersType(pInst, &Params);
    218         LVPSA_SetBPFCoefficients(pInst, &Params);
    219         LVPSA_SetQPFCoefficients(pInst, &Params);
    220         LVPSA_ClearFilterHistory(pInst);
    221         pInst->nSamplesBufferUpdate = (LVM_UINT16)LVPSA_nSamplesBufferUpdate[Params.Fs];
    222         pInst->BufferUpdateSamplesCount = 0;
    223         pInst->DownSamplingFactor = LVPSA_DownSamplingFactor[Params.Fs];
    224         pInst->DownSamplingCount = 0;
    225         for(ii = 0; ii < (pInst->nBands * pInst->SpectralDataBufferLength); ii++)
    226         {
    227             pInst->pSpectralDataBufferStart[ii] = 0;
    228         }
    229         for(ii = 0; ii < pInst->nBands; ii++)
    230         {
    231             pInst->pPreviousPeaks[ii] = 0;
    232         }
    233     }
    234     else
    235     {
    236         if(Params.LevelDetectionSpeed != pInst->CurrentParams.LevelDetectionSpeed)
    237         {
    238             LVPSA_SetQPFCoefficients(pInst, &Params);
    239         }
    240     }
    241 
    242     pInst->CurrentParams = pInst->NewParams;
    243 
    244     return (LVPSA_OK);
    245 }
    246 /************************************************************************************/
    247 /*                                                                                  */
    248 /* FUNCTION:            LVPSA_SetBPFiltersType                                      */
    249 /*                                                                                  */
    250 /* DESCRIPTION:                                                                     */
    251 /*  Sets the filter type based on the BPFilterType.                                 */
    252 /*                                                                                  */
    253 /* PARAMETERS:                                                                      */
    254 /*  pInst               Pointer to the instance                                     */
    255 /*  pParams             Poniter to conrol parameters                                */
    256 /*                                                                                  */
    257 /* RETURNS:                                                                         */
    258 /*  LVPSA_OK            Always succeeds                                             */
    259 /*                                                                                  */
    260 /* NOTES:                                                                           */
    261 /*  1. To select the biquad type the follow rules are applied:                      */
    262 /*          Double precision    if (fc <= fs/110)                                   */
    263 /*          Double precision    if (fs/110 < fc < fs/85) & (Q>3)                    */
    264 /*          Single precision    otherwise                                           */
    265 /*                                                                                  */
    266 /************************************************************************************/
    267 LVPSA_RETURN LVPSA_SetBPFiltersType (   LVPSA_InstancePr_t        *pInst,
    268                                         LVPSA_ControlParams_t      *pParams  )
    269 {
    270 
    271     extern LVM_UINT16   LVPSA_SampleRateTab[];                                            /* Sample rate table */
    272     LVM_UINT16          ii;                                                         /* Filter band index */
    273     LVM_UINT32          fs = (LVM_UINT32)LVPSA_SampleRateTab[(LVM_UINT16)pParams->Fs];      /* Sample rate */
    274     LVM_UINT32          fc;                                                         /* Filter centre frequency */
    275     LVM_INT16           QFactor;                                                    /* Filter Q factor */
    276 
    277     for (ii = 0; ii < pInst->nRelevantFilters; ii++)
    278     {
    279         /*
    280          * Get the filter settings
    281          */
    282         fc = (LVM_UINT32)pInst->pFiltersParams[ii].CenterFrequency;     /* Get the band centre frequency */
    283         QFactor =(LVM_INT16) pInst->pFiltersParams[ii].QFactor;                    /* Get the band Q factor */
    284 
    285 
    286         /*
    287          * For each filter set the type of biquad required
    288          */
    289         pInst->pBPFiltersPrecision[ii] = LVPSA_SimplePrecisionFilter;     /* Default to single precision */
    290         if ((LOW_FREQ * fs) >= (fc << 15))
    291         {
    292             /*
    293              * fc <= fs/110
    294              */
    295             pInst->pBPFiltersPrecision[ii] = LVPSA_DoublePrecisionFilter;
    296         }
    297         else
    298         {
    299             if (((LOW_FREQ * fs) < (fc << 15)) && ((fc << 15) < (HIGH_FREQ * fs)) && (QFactor > 300))
    300             {
    301                 /*
    302                 * (fs/110 < fc < fs/85) & (Q>3)
    303                 */
    304                 pInst->pBPFiltersPrecision[ii] = LVPSA_DoublePrecisionFilter;
    305             }
    306         }
    307     }
    308 
    309     return(LVPSA_OK);
    310 }
    311 
    312 /************************************************************************************/
    313 /*                                                                                  */
    314 /* FUNCTION:            LVPSA_SetBPFCoefficients                                    */
    315 /*                                                                                  */
    316 /* DESCRIPTION:                                                                     */
    317 /*  Sets the band pass filter coefficients. This uses the type to select            */
    318 /*  single or double precision coefficients.                                        */
    319 /*                                                                                  */
    320 /* PARAMETERS:                                                                      */
    321 /*  pInst               Pointer to the instance                                     */
    322 /*  Params              Initialisation parameters                                   */
    323 /*                                                                                  */
    324 /* RETURNS:                                                                         */
    325 /*  LVPSA_OK            Always succeeds                                             */
    326 /*                                                                                  */
    327 /* NOTES:                                                                           */
    328 /*                                                                                  */
    329 /************************************************************************************/
    330 LVPSA_RETURN LVPSA_SetBPFCoefficients(  LVPSA_InstancePr_t        *pInst,
    331                                         LVPSA_ControlParams_t      *pParams)
    332 {
    333 
    334     LVM_UINT16                      ii;
    335 
    336     /*
    337      * Set the coefficients for each band by the init function
    338      */
    339     for (ii = 0; ii < pInst->nRelevantFilters; ii++)
    340     {
    341         switch  (pInst->pBPFiltersPrecision[ii])
    342         {
    343             case    LVPSA_DoublePrecisionFilter:
    344             {
    345                 BP_C32_Coefs_t      Coefficients;
    346 
    347                 /*
    348                  * Calculate the double precision coefficients
    349                  */
    350                 LVPSA_BPDoublePrecCoefs((LVM_UINT16)pParams->Fs,
    351                                        &pInst->pFiltersParams[ii],
    352                                        &Coefficients);
    353 
    354                 /*
    355                  * Set the coefficients
    356                  */
    357                 BP_1I_D16F32Cll_TRC_WRA_01_Init ( &pInst->pBP_Instances[ii],
    358                                                   &pInst->pBP_Taps[ii],
    359                                                   &Coefficients);
    360                 break;
    361             }
    362 
    363             case    LVPSA_SimplePrecisionFilter:
    364             {
    365                 BP_C16_Coefs_t      Coefficients;
    366 
    367                 /*
    368                  * Calculate the single precision coefficients
    369                  */
    370                 LVPSA_BPSinglePrecCoefs((LVM_UINT16)pParams->Fs,
    371                                        &pInst->pFiltersParams[ii],
    372                                        &Coefficients);
    373 
    374                 /*
    375                  * Set the coefficients
    376                  */
    377                 BP_1I_D16F16Css_TRC_WRA_01_Init ( &pInst->pBP_Instances[ii],
    378                                                   &pInst->pBP_Taps[ii],
    379                                                   &Coefficients);
    380                 break;
    381             }
    382         }
    383     }
    384 
    385     return(LVPSA_OK);
    386 }
    387 
    388 
    389 /************************************************************************************/
    390 /*                                                                                  */
    391 /* FUNCTION:            LVPSA_SetQPFCoefficients                                    */
    392 /*                                                                                  */
    393 /* DESCRIPTION:                                                                     */
    394 /*  Sets the quasi peak filters coefficients. This uses the chosen                  */
    395 /*  LevelDetectionSpeed from the control parameters.                                */
    396 /*                                                                                  */
    397 /* PARAMETERS:                                                                      */
    398 /*  pInst               Pointer to the instance                                     */
    399 /*  Params              Control parameters                                          */
    400 /*                                                                                  */
    401 /* RETURNS:                                                                         */
    402 /*  LVPSA_OK            Always succeeds                                             */
    403 /*                                                                                  */
    404 /* NOTES:                                                                           */
    405 /*                                                                                  */
    406 /************************************************************************************/
    407 LVPSA_RETURN LVPSA_SetQPFCoefficients(   LVPSA_InstancePr_t        *pInst,
    408                                          LVPSA_ControlParams_t      *pParams  )
    409 {
    410     LVM_UINT16     ii;
    411     LVM_Fs_en      Fs = pParams->Fs;
    412     QPD_C32_Coefs  *pCoefficients;
    413     extern         QPD_C32_Coefs     LVPSA_QPD_Coefs[];
    414 
    415 
    416     pCoefficients = &LVPSA_QPD_Coefs[(pParams->LevelDetectionSpeed * LVPSA_NR_SUPPORTED_RATE) + Fs];
    417 
    418 
    419     for (ii = 0; ii < pInst->nRelevantFilters; ii++)
    420     {
    421             LVPSA_QPD_Init (&pInst->pQPD_States[ii],
    422                             &pInst->pQPD_Taps[ii],
    423                             pCoefficients );
    424     }
    425 
    426     return(LVPSA_OK);
    427 
    428 }
    429 
    430 /****************************************************************************************/
    431 /*                                                                                      */
    432 /* FUNCTION:                 LVPSA_BPSinglePrecCoefs                                    */
    433 /*                                                                                      */
    434 /* DESCRIPTION:                                                                         */
    435 /*  Calculate single precision coefficients for a band pass filter                      */
    436 /*                                                                                      */
    437 /* PARAMETERS:                                                                          */
    438 /*  Fs                       Sampling frequency index                                   */
    439 /*  pFilterParams            Pointer to the filter definition                           */
    440 /*  pCoefficients            Pointer to the coefficients                                */
    441 /*                                                                                      */
    442 /* RETURNS:                                                                             */
    443 /*  LVPSA_OK         Always succeeds                                                    */
    444 /*                                                                                      */
    445 /* NOTES:                                                                               */
    446 /*  1. The equations used are as follows:                                               */
    447 /*                                                                                      */
    448 /*      t0 = 2 * Pi * Fc / Fs                                                           */
    449 /*                                                                                      */
    450 /*      b2 = -0.5 * (2Q - t0) / (2Q + t0)                                               */
    451 /*      b1 = (0.5 - b2) * cos(t0)                                                       */
    452 /*      a0 = (0.5 + b2) / 2                                                             */
    453 /*                                                                                      */
    454 /*  Where:                                                                              */
    455 /*      Fc          is the centre frequency, DC to Nyquist                              */
    456 /*      Fs          is the sample frequency, 8000 to 48000 in descrete steps            */
    457 /*      Q           is the Q factor, 0.25 to 12                                         */
    458 /*                                                                                      */
    459 /*  2. This function is entirely based on the LVEQNB_SinglePrecCoefs function           */
    460 /*     of the n bands equalizer (LVEQNB                                                 */
    461 /*                                                                                      */
    462 /****************************************************************************************/
    463 LVPSA_RETURN LVPSA_BPSinglePrecCoefs(    LVM_UINT16              Fs,
    464                                          LVPSA_FilterParam_t    *pFilterParams,
    465                                          BP_C16_Coefs_t         *pCoefficients)
    466 {
    467 
    468     extern LVM_INT16    LVPSA_TwoPiOnFsTable[];
    469     extern LVM_INT16    LVPSA_CosCoef[];
    470 
    471 
    472     /*
    473      * Intermediate variables and temporary values
    474      */
    475     LVM_INT32           T0;
    476     LVM_INT16           D;
    477     LVM_INT32           A0;
    478     LVM_INT32           B1;
    479     LVM_INT32           B2;
    480     LVM_INT32           Dt0;
    481     LVM_INT32           B2_Den;
    482     LVM_INT32           B2_Num;
    483     LVM_INT32           COS_T0;
    484     LVM_INT16           coef;
    485     LVM_INT32           factor;
    486     LVM_INT16           t0;
    487     LVM_INT16           i;
    488 
    489 
    490     /*
    491      * Get the filter definition
    492      */
    493     LVM_UINT16          Frequency   = pFilterParams->CenterFrequency;
    494     LVM_UINT16          QFactor     = pFilterParams->QFactor;
    495 
    496 
    497     /*
    498      * Calculating the intermediate values
    499      */
    500     T0 = (LVM_INT32)Frequency * LVPSA_TwoPiOnFsTable[Fs];   /* T0 = 2 * Pi * Fc / Fs */
    501     D = 3200;                                               /* Floating point value 1.000000 (1*100*2^5) */
    502                                                             /* Force D = 1 : the function was originally used for a peaking filter.
    503                                                                The D parameter do not exist for a BandPass filter coefficients */
    504 
    505     /*
    506      * Calculate the B2 coefficient
    507      */
    508     Dt0 = D * (T0 >> 10);
    509     B2_Den = (LVM_INT32)(((LVM_UINT32)QFactor << 19) + (LVM_UINT32)(Dt0 >> 2));
    510     B2_Num = (LVM_INT32)((LVM_UINT32)(Dt0 >> 3) - ((LVM_UINT32)QFactor << 18));
    511     B2 = (B2_Num / (B2_Den >> 16)) << 15;
    512 
    513     /*
    514      * Calculate the cosine by a polynomial expansion using the equation:
    515      *
    516      *  Cos += coef(n) * t0^n                   For n = 0 to 6
    517      */
    518     T0 = (T0 >> 10) * 20859;                    /* Scale to 1.0 in 16-bit for range 0 to fs/2 */
    519     t0 = (LVM_INT16)(T0 >> 16);
    520     factor = 0x7fff;                            /* Initialise to 1.0 for the a0 coefficient */
    521     COS_T0 = 0;                                 /* Initialise the error to zero */
    522     for (i=1; i<7; i++)
    523     {
    524         coef = LVPSA_CosCoef[i];                /* Get the nth coefficient */
    525         COS_T0 += (factor * coef) >> 5;         /* The nth partial sum */
    526         factor = (factor * t0) >> 15;           /* Calculate t0^n */
    527     }
    528     COS_T0 = COS_T0 << (LVPSA_CosCoef[0]+6);          /* Correct the scaling */
    529 
    530 
    531     B1 = ((0x40000000 - B2) >> 16) * (COS_T0 >> 16);    /* B1 = (0.5 - b2) * cos(t0) */
    532     A0 = (0x40000000 + B2) >> 1;                        /* A0 = (0.5 + b2) / 2 */
    533 
    534     /*
    535      * Write coeff into the data structure
    536      */
    537     pCoefficients->A0 = (LVM_INT16)(A0>>16);
    538     pCoefficients->B1 = (LVM_INT16)(B1>>15);
    539     pCoefficients->B2 = (LVM_INT16)(B2>>16);
    540 
    541 
    542     return(LVPSA_OK);
    543 }
    544 
    545 /****************************************************************************************/
    546 /*                                                                                      */
    547 /* FUNCTION:                 LVPSA_BPDoublePrecCoefs                                    */
    548 /*                                                                                      */
    549 /* DESCRIPTION:                                                                         */
    550 /*  Calculate double precision coefficients for a band pass filter                      */
    551 /*                                                                                      */
    552 /* PARAMETERS:                                                                          */
    553 /*  Fs                       Sampling frequency index                                   */
    554 /*  pFilterParams            Pointer to the filter definition                           */
    555 /*  pCoefficients            Pointer to the coefficients                                */
    556 /*                                                                                      */
    557 /* RETURNS:                                                                             */
    558 /*  LVPSA_OK                 Always succeeds                                            */
    559 /*                                                                                      */
    560 /* NOTES:                                                                               */
    561 /*  1. The equations used are as follows:                                               */
    562 /*                                                                                      */
    563 /*      t0 = 2 * Pi * Fc / Fs                                                           */
    564 /*                                                                                      */
    565 /*      b2 = -0.5 * (2Q - t0) / (2Q + t0)                                               */
    566 /*      b1 = (0.5 - b2) * (1 - coserr(t0))                                              */
    567 /*      a0 = (0.5 + b2) / 2                                                             */
    568 /*                                                                                      */
    569 /*  Where:                                                                              */
    570 /*      Fc          is the centre frequency, DC to Fs/50                                */
    571 /*      Fs          is the sample frequency, 8000 to 48000 in descrete steps            */
    572 /*      Q           is the Q factor, 0.25 to 12 (represented by 25 to 1200)             */
    573 /*                                                                                      */
    574 /*  2. The double precision coefficients are only used when fc is less than fs/85, so   */
    575 /*     the cosine of t0 is always close to 1.0. Instead of calculating the cosine       */
    576 /*     itself the difference from the value 1.0 is calculated, this can be done with    */
    577 /*     lower precision maths.                                                           */
    578 /*                                                                                      */
    579 /*  3. The value of the B2 coefficient is only calculated as a single precision value,  */
    580 /*     small errors in this value have a combined effect on the Q and Gain but not the  */
    581 /*     the frequency of the filter.                                                     */
    582 /*                                                                                      */
    583 /*  4. This function is entirely based on the LVEQNB_DoublePrecCoefs function           */
    584 /*     of the n bands equalizer (LVEQNB                                                 */
    585 /*                                                                                      */
    586 /****************************************************************************************/
    587 LVPSA_RETURN LVPSA_BPDoublePrecCoefs(   LVM_UINT16            Fs,
    588                                         LVPSA_FilterParam_t  *pFilterParams,
    589                                         BP_C32_Coefs_t       *pCoefficients)
    590 {
    591 
    592     extern LVM_INT16    LVPSA_TwoPiOnFsTable[];
    593     extern LVM_INT16    LVPSA_DPCosCoef[];
    594 
    595     /*
    596      * Intermediate variables and temporary values
    597      */
    598     LVM_INT32           T0;
    599     LVM_INT16           D;
    600     LVM_INT32           A0;
    601     LVM_INT32           B1;
    602     LVM_INT32           B2;
    603     LVM_INT32           Dt0;
    604     LVM_INT32           B2_Den;
    605     LVM_INT32           B2_Num;
    606     LVM_INT32           CosErr;
    607     LVM_INT16           coef;
    608     LVM_INT32           factor;
    609     LVM_INT16           t0;
    610     LVM_INT16           i;
    611 
    612     /*
    613      * Get the filter definition
    614      */
    615     LVM_UINT16          Frequency   = pFilterParams->CenterFrequency;
    616     LVM_UINT16          QFactor     = pFilterParams->QFactor;
    617 
    618 
    619     /*
    620      * Calculating the intermediate values
    621      */
    622     T0 = (LVM_INT32)Frequency * LVPSA_TwoPiOnFsTable[Fs];   /* T0 = 2 * Pi * Fc / Fs */
    623     D = 3200;                                               /* Floating point value 1.000000 (1*100*2^5) */
    624                                                             /* Force D = 1 : the function was originally used for a peaking filter.
    625                                                                The D parameter do not exist for a BandPass filter coefficients */
    626 
    627     /*
    628      * Calculate the B2 coefficient
    629      */
    630     Dt0 = D * (T0 >> 10);
    631     B2_Den = (LVM_INT32)(((LVM_UINT32)QFactor << 19) + (LVM_UINT32)(Dt0 >> 2));
    632     B2_Num = (LVM_INT32)((LVM_UINT32)(Dt0 >> 3) - ((LVM_UINT32)QFactor << 18));
    633     B2 = (B2_Num / (B2_Den >> 16)) << 15;
    634 
    635     /*
    636      * Calculate the cosine error by a polynomial expansion using the equation:
    637      *
    638      *  CosErr += coef(n) * t0^n                For n = 0 to 4
    639      */
    640     T0 = (T0 >> 6) * 0x7f53;                    /* Scale to 1.0 in 16-bit for range 0 to fs/50 */
    641     t0 = (LVM_INT16)(T0 >> 16);
    642     factor = 0x7fff;                            /* Initialise to 1.0 for the a0 coefficient */
    643     CosErr = 0;                                 /* Initialise the error to zero */
    644     for (i=1; i<5; i++)
    645     {
    646         coef = LVPSA_DPCosCoef[i];              /* Get the nth coefficient */
    647         CosErr += (factor * coef) >> 5;         /* The nth partial sum */
    648         factor = (factor * t0) >> 15;           /* Calculate t0^n */
    649     }
    650     CosErr = CosErr << (LVPSA_DPCosCoef[0]);          /* Correct the scaling */
    651 
    652     /*
    653      * Calculate the B1 and A0 coefficients
    654      */
    655     B1 = (0x40000000 - B2);                     /* B1 = (0.5 - b2) */
    656     A0 = ((B1 >> 16) * (CosErr >> 10)) >> 6;    /* Temporary storage for (0.5 - b2) * coserr(t0) */
    657     B1 -= A0;                                   /* B1 = (0.5 - b2) * (1 - coserr(t0))  */
    658     A0 = (0x40000000 + B2) >> 1;                /* A0 = (0.5 + b2) / 2 */
    659 
    660     /*
    661      * Write coeff into the data structure
    662      */
    663     pCoefficients->A0 = A0;
    664     pCoefficients->B1 = B1;
    665     pCoefficients->B2 = B2;
    666 
    667     return(LVPSA_OK);
    668 }
    669 
    670 /************************************************************************************/
    671 /*                                                                                  */
    672 /* FUNCTION:            LVPSA_ClearFilterHistory                                    */
    673 /*                                                                                  */
    674 /* DESCRIPTION:                                                                     */
    675 /*  Clears the filters' data history                                                */
    676 /*                                                                                  */
    677 /* PARAMETERS:                                                                      */
    678 /*  pInst           Pointer to the instance                                         */
    679 /*                                                                                  */
    680 /* RETURNS:                                                                         */
    681 /*  LVPSA_OK         Always succeeds                                                */
    682 /*                                                                                  */
    683 /* NOTES:                                                                           */
    684 /*                                                                                  */
    685 /************************************************************************************/
    686 LVPSA_RETURN LVPSA_ClearFilterHistory(LVPSA_InstancePr_t        *pInst)
    687 {
    688     LVM_INT8       *pTapAddress;
    689     LVM_UINT32       i;
    690 
    691     /* Band Pass filters taps */
    692     pTapAddress = (LVM_INT8 *)pInst->pBP_Taps;
    693     for(i = 0; i < pInst->nBands * sizeof(Biquad_1I_Order2_Taps_t); i++)
    694     {
    695         pTapAddress[i] = 0;
    696     }
    697 
    698     /* Quasi-peak filters taps */
    699     pTapAddress = (LVM_INT8 *)pInst->pQPD_Taps;
    700     for(i = 0; i < pInst->nBands * sizeof(QPD_Taps_t); i++)
    701     {
    702         pTapAddress[i] = 0;
    703     }
    704 
    705     return(LVPSA_OK);
    706 }
    707 
    708