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_QPD.h"
     19 #include "LVPSA_Private.h"
     20 
     21 /************************************************************************************/
     22 /*                                                                                  */
     23 /* FUNCTION:            LVPSA_QPD_WritePeak                                         */
     24 /*                                                                                  */
     25 /* DESCRIPTION:                                                                     */
     26 /*  Write a level value in the buffer in the corresponding band.                    */
     27 /*                                                                                  */
     28 /* PARAMETERS:                                                                      */
     29 /*  pInst               Pointer to the LVPSA instance                               */
     30 /*  ppWrite             Pointer to pointer to the buffer                            */
     31 /*  CallNumber          Number of the band the value should be written in           */
     32 /*  Value               Value to write in the buffer                                */
     33 /*                                                                                  */
     34 /* RETURNS:             void                                                        */
     35 /*                                                                                  */
     36 /************************************************************************************/
     37 void LVPSA_QPD_WritePeak(   pLVPSA_InstancePr_t       pLVPSA_Inst,
     38                             LVM_UINT8             **ppWrite,
     39                             LVM_INT16               BandIndex,
     40                             LVM_INT16               Value   );
     41 
     42 
     43 
     44 /************************************************************************************/
     45 /*                                                                                  */
     46 /* FUNCTION:            LVPSA_QPD_Process                                           */
     47 /*                                                                                  */
     48 /* DESCRIPTION:                                                                     */
     49 /*  Apply downsampling, post gain, quasi peak filtering and write the levels values */
     50 /*  in the buffer every 20 ms.                                                      */
     51 /*                                                                                  */
     52 /* PARAMETERS:                                                                      */
     53 /*                                                                                  */
     54 /* RETURNS:             void                                                        */
     55 /*                                                                                  */
     56 /************************************************************************************/
     57 void LVPSA_QPD_Process (            void                               *hInstance,
     58                                     LVM_INT16                          *pInSamps,
     59                                     LVM_INT16                           numSamples,
     60                                     LVM_INT16                           BandIndex)
     61 {
     62 
     63     /******************************************************************************
     64        PARAMETERS
     65     *******************************************************************************/
     66     LVPSA_InstancePr_t     *pLVPSA_Inst = (LVPSA_InstancePr_t*)hInstance;
     67     QPD_State_t *pQPDState =  (QPD_State_t*)&pLVPSA_Inst->pQPD_States[BandIndex];
     68 
     69     /* Pointer to taps */
     70     LVM_INT32* pDelay  = pQPDState->pDelay;
     71 
     72     /* Parameters needed during quasi peak calculations */
     73     LVM_INT32   X0;
     74     LVM_INT32   temp,temp2;
     75     LVM_INT32   accu;
     76     LVM_INT16   Xg0;
     77     LVM_INT16   D0;
     78     LVM_INT16   V0 = (LVM_INT16)(*pDelay);
     79 
     80     /* Filter's coef */
     81     LVM_INT32   Kp = pQPDState->Coefs[0];
     82     LVM_INT32   Km = pQPDState->Coefs[1];
     83 
     84     LVM_INT16   ii = numSamples;
     85 
     86     LVM_UINT8  *pWrite = pLVPSA_Inst->pSpectralDataBufferWritePointer;
     87     LVM_INT32   BufferUpdateSamplesCount = pLVPSA_Inst->BufferUpdateSamplesCount;
     88     LVM_UINT16  DownSamplingFactor = pLVPSA_Inst->DownSamplingFactor;
     89 
     90     /******************************************************************************
     91        INITIALIZATION
     92     *******************************************************************************/
     93     /* Correct the pointer to take the first down sampled signal sample */
     94     pInSamps += pLVPSA_Inst->DownSamplingCount;
     95     /* Correct also the number of samples */
     96     ii = (LVM_INT16)(ii - (LVM_INT16)pLVPSA_Inst->DownSamplingCount);
     97 
     98     while (ii > 0)
     99     {
    100         /* Apply post gain */
    101         X0 = ((*pInSamps) * pLVPSA_Inst->pPostGains[BandIndex]) >> (LVPSA_GAINSHIFT-1); /* - 1 to compensate scaling in process function*/
    102         pInSamps = pInSamps + DownSamplingFactor;
    103 
    104         /* Saturate and take absolute value */
    105         if(X0 < 0)
    106             X0 = -X0;
    107         if (X0 > 0x7FFF)
    108             Xg0 = 0x7FFF;
    109         else
    110             Xg0 = (LVM_INT16)(X0);
    111 
    112 
    113         /* Quasi peak filter calculation */
    114         D0  = (LVM_INT16)(Xg0 - V0);
    115 
    116         temp2 = (LVM_INT32)D0;
    117         MUL32x32INTO32(temp2,Kp,accu,31);
    118 
    119         D0    = (LVM_INT16)(D0>>1);
    120         if (D0 < 0){
    121             D0 = (LVM_INT16)(-D0);
    122         }
    123 
    124         temp2 = (LVM_INT32)D0;
    125         MUL32x32INTO32((LVM_INT32)D0,Km,temp,31);
    126         accu +=temp + Xg0;
    127 
    128         if (accu > 0x7FFF)
    129             accu = 0x7FFF;
    130         else if(accu < 0)
    131             accu = 0x0000;
    132 
    133         V0 = (LVM_INT16)accu;
    134 
    135         if(((pLVPSA_Inst->nSamplesBufferUpdate - BufferUpdateSamplesCount) < DownSamplingFactor))
    136         {
    137             LVPSA_QPD_WritePeak( pLVPSA_Inst,
    138                                 &pWrite,
    139                                  BandIndex,
    140                                  V0);
    141             BufferUpdateSamplesCount -= pLVPSA_Inst->nSamplesBufferUpdate;
    142             pLVPSA_Inst->LocalSamplesCount = (LVM_UINT16)(numSamples - ii);
    143         }
    144         BufferUpdateSamplesCount+=DownSamplingFactor;
    145 
    146         ii = (LVM_INT16)(ii-DownSamplingFactor);
    147 
    148     }
    149 
    150     /* Store last taps in memory */
    151     *pDelay = (LVM_INT32)(V0);
    152 
    153     /* If this is the last call to the function after last band processing,
    154        update the parameters. */
    155     if(BandIndex == (pLVPSA_Inst->nRelevantFilters-1))
    156     {
    157         pLVPSA_Inst->pSpectralDataBufferWritePointer = pWrite;
    158         /* Adjustment for 11025Hz input, 220,5 is normally
    159            the exact number of samples for 20ms.*/
    160         if((pLVPSA_Inst->pSpectralDataBufferWritePointer != pWrite)&&(pLVPSA_Inst->CurrentParams.Fs == LVM_FS_11025))
    161         {
    162             if(pLVPSA_Inst->nSamplesBufferUpdate == 220)
    163             {
    164                 pLVPSA_Inst->nSamplesBufferUpdate = 221;
    165             }
    166             else
    167             {
    168                 pLVPSA_Inst->nSamplesBufferUpdate = 220;
    169             }
    170         }
    171         pLVPSA_Inst->pSpectralDataBufferWritePointer = pWrite;
    172         pLVPSA_Inst->BufferUpdateSamplesCount = BufferUpdateSamplesCount;
    173         pLVPSA_Inst->DownSamplingCount = (LVM_UINT16)(-ii);
    174     }
    175 }
    176 
    177 /************************************************************************************/
    178 /*                                                                                  */
    179 /* FUNCTION:            LVPSA_QPD_WritePeak                                         */
    180 /*                                                                                  */
    181 /* DESCRIPTION:                                                                     */
    182 /*  Write a level value in the spectrum data buffer in the corresponding band.      */
    183 /*                                                                                  */
    184 /* PARAMETERS:                                                                      */
    185 /*  pLVPSA_Inst               Pointer to the LVPSA instance                         */
    186 /*  ppWrite             Pointer to pointer to the buffer                            */
    187 /*  CallNumber          Number of the band the value should be written in           */
    188 /*  Value               Value to write in the spectrum data buffer                  */
    189 /*                                                                                  */
    190 /* RETURNS:             void                                                        */
    191 /*                                                                                  */
    192 /************************************************************************************/
    193 void LVPSA_QPD_WritePeak(   pLVPSA_InstancePr_t       pLVPSA_Inst,
    194                             LVM_UINT8             **ppWrite,
    195                             LVM_INT16               BandIndex,
    196                             LVM_INT16               Value   )
    197 {
    198     LVM_UINT8 *pWrite = *ppWrite;
    199 
    200 
    201     /* Write the value and update the write pointer */
    202     *(pWrite + BandIndex) = (LVM_UINT8)(Value>>7);
    203     pWrite += pLVPSA_Inst->nBands;
    204     if (pWrite == (pLVPSA_Inst->pSpectralDataBufferStart + pLVPSA_Inst->nBands * pLVPSA_Inst->SpectralDataBufferLength))
    205     {
    206         pWrite = pLVPSA_Inst->pSpectralDataBufferStart;
    207     }
    208 
    209     *ppWrite = pWrite;
    210 
    211 }
    212 
    213