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 "LVDBE.h"
     25 #include "LVDBE_Private.h"
     26 #include "VectorArithmetic.h"
     27 #include "AGC.h"
     28 #include "LVDBE_Coeffs.h"               /* Filter coefficients */
     29 
     30 
     31 /********************************************************************************************/
     32 /*                                                                                          */
     33 /* FUNCTION:                 LVDBE_Process                                                  */
     34 /*                                                                                          */
     35 /* DESCRIPTION:                                                                             */
     36 /*  Process function for the Bass Enhancement module.                                       */
     37 /*                                                                                          */
     38 /*  Data can be processed in two formats, stereo or mono-in-stereo. Data in mono            */
     39 /*  format is not supported, the calling routine must convert the mono stream to            */
     40 /*  mono-in-stereo.                                                                         */
     41 /*                                                        ___________                       */
     42 /*       ________                                        |           |    ________          */
     43 /*      |        |    _____   |------------------------->|           |   |        |         */
     44 /*      | 16-bit |   |     |  |    ________              |           |   | 32-bit |         */
     45 /* -+-->|   to   |-->| HPF |--|   |        |    _____    | AGC Mixer |-->|   to   |--|      */
     46 /*  |   | 32-bit |   |_____|  |   | Stereo |   |     |   |           |   | 16-bit |  |      */
     47 /*  |   |________|            |-->|   to   |-->| BPF |-->|           |   |________|  0      */
     48 /*  |                             |  Mono  |   |_____|   |___________|                \-->  */
     49 /*  |                             |________|                                                */
     50 /*  |                                                     _________                  0      */
     51 /*  |                                                    |         |                 |      */
     52 /*  |----------------------------------------------------| Volume  |-----------------|      */
     53 /*                                                       | Control |                        */
     54 /*                                                       |_________|                        */
     55 /*                                                                                          */
     56 /* PARAMETERS:                                                                              */
     57 /*  hInstance                 Instance handle                                               */
     58 /*  pInData                  Pointer to the input data                                      */
     59 /*  pOutData                 Pointer to the output data                                     */
     60 /*  NumSamples                 Number of samples in the input buffer                        */
     61 /*                                                                                          */
     62 /* RETURNS:                                                                                 */
     63 /*  LVDBE_SUCCESS            Succeeded                                                      */
     64 /*    LVDBE_TOOMANYSAMPLES    NumSamples was larger than the maximum block size             */
     65 /*                                                                                          */
     66 /* NOTES:                                                                                   */
     67 /*  1. The input and output data must be 32-bit format. The input is scaled by a shift      */
     68 /*     when converting from 16-bit format, this scaling allows for internal headroom in the */
     69 /*     bass enhancement algorithm.                                                          */
     70 /*  2. For a 16-bit implementation the converstion to 32-bit is removed and replaced with   */
     71 /*     the headroom loss. This headroom loss is compensated in the volume control so the    */
     72 /*     overall end to end gain is odB.                                                      */
     73 /*                                                                                          */
     74 /********************************************************************************************/
     75 
     76 LVDBE_ReturnStatus_en LVDBE_Process(LVDBE_Handle_t            hInstance,
     77                                        const LVM_INT16         *pInData,
     78                                        LVM_INT16               *pOutData,
     79                                        LVM_UINT16                   NumSamples)
     80 {
     81 
     82     LVDBE_Instance_t    *pInstance =(LVDBE_Instance_t  *)hInstance;
     83     LVM_INT32           *pScratch  = (LVM_INT32 *)pInstance->MemoryTable.Region[LVDBE_MEMREGION_SCRATCH].pBaseAddress;
     84     LVM_INT32           *pMono;
     85     LVM_INT16           *pInput    = (LVM_INT16 *)pInData;
     86 
     87 
     88     /* Scratch for Volume Control starts at offset of 2*NumSamples short values from pScratch */
     89     LVM_INT16           *pScratchVol = (LVM_INT16 *)(&pScratch[NumSamples]);
     90 
     91     /* Scratch for Mono path starts at offset of 2*NumSamples 32-bit values from pScratch */
     92     pMono                            = &pScratch[2*NumSamples];
     93 
     94     /*
     95      * Check the number of samples is not too large
     96      */
     97     if (NumSamples > pInstance->Capabilities.MaxBlockSize)
     98     {
     99         return(LVDBE_TOOMANYSAMPLES);
    100     }
    101 
    102     /*
    103      * Check if the algorithm is enabled
    104      */
    105     /* DBE path is processed when DBE is ON or during On/Off transitions */
    106     if ((pInstance->Params.OperatingMode == LVDBE_ON)||
    107         (LVC_Mixer_GetCurrent(&pInstance->pData->BypassMixer.MixerStream[0])
    108          !=LVC_Mixer_GetTarget(&pInstance->pData->BypassMixer.MixerStream[0])))
    109     {
    110 
    111         /*
    112          * Convert 16-bit samples to 32-bit and scale
    113          * (For a 16-bit implementation apply headroom loss here)
    114          */
    115         Int16LShiftToInt32_16x32(pInput,                               /* Source 16-bit data    */
    116                                  pScratch,                             /* Dest. 32-bit data     */
    117                                  (LVM_INT16)(2*NumSamples),            /* Left and right        */
    118                                  LVDBE_SCALESHIFT);                    /* Shift scale           */
    119 
    120 
    121         /*
    122          * Apply the high pass filter if selected
    123          */
    124         if (pInstance->Params.HPFSelect == LVDBE_HPF_ON)
    125         {
    126               BQ_2I_D32F32C30_TRC_WRA_01(&pInstance->pCoef->HPFInstance,/* Filter instance      */
    127                                        (LVM_INT32 *)pScratch,           /* Source               */
    128                                        (LVM_INT32 *)pScratch,           /* Destination          */
    129                                        (LVM_INT16)NumSamples);          /* Number of samples    */
    130         }
    131 
    132 
    133         /*
    134          * Create the mono stream
    135          */
    136         From2iToMono_32(pScratch,                                      /* Stereo source         */
    137                         pMono,                                         /* Mono destination      */
    138                         (LVM_INT16)NumSamples);                        /* Number of samples     */
    139 
    140 
    141         /*
    142          * Apply the band pass filter
    143          */
    144         BP_1I_D32F32C30_TRC_WRA_02(&pInstance->pCoef->BPFInstance,     /* Filter instance       */
    145                                    (LVM_INT32 *)pMono,                 /* Source                */
    146                                    (LVM_INT32 *)pMono,                 /* Destination           */
    147                                    (LVM_INT16)NumSamples);             /* Number of samples     */
    148 
    149 
    150         /*
    151          * Apply the AGC and mix
    152          */
    153         AGC_MIX_VOL_2St1Mon_D32_WRA(&pInstance->pData->AGCInstance,    /* Instance pointer      */
    154                                     pScratch,                          /* Stereo source         */
    155                                     pMono,                             /* Mono band pass source */
    156                                     pScratch,                          /* Stereo destination    */
    157                                     NumSamples);                       /* Number of samples     */
    158 
    159         /*
    160          * Convert 32-bit samples to 16-bit and saturate
    161          * (Not required for 16-bit implemenations)
    162          */
    163         Int32RShiftToInt16_Sat_32x16(pScratch,                         /* Source 32-bit data    */
    164                                      (LVM_INT16 *)pScratch,            /* Dest. 16-bit data     */
    165                                      (LVM_INT16)(2*NumSamples),        /* Left and right        */
    166                                      LVDBE_SCALESHIFT);                /* Shift scale           */
    167 
    168     }
    169 
    170     /* Bypass Volume path is processed when DBE is OFF or during On/Off transitions */
    171     if ((pInstance->Params.OperatingMode == LVDBE_OFF)||
    172         (LVC_Mixer_GetCurrent(&pInstance->pData->BypassMixer.MixerStream[1])
    173          !=LVC_Mixer_GetTarget(&pInstance->pData->BypassMixer.MixerStream[1])))
    174     {
    175 
    176         /*
    177          * The algorithm is disabled but volume management is required to compensate for
    178          * headroom and volume (if enabled)
    179          */
    180         LVC_MixSoft_1St_D16C31_SAT(&pInstance->pData->BypassVolume,
    181                                   pInData,
    182                                   pScratchVol,
    183                                (LVM_INT16)(2*NumSamples));           /* Left and right          */
    184 
    185     }
    186 
    187     /*
    188      * Mix DBE processed path and bypass volume path
    189      */
    190     LVC_MixSoft_2St_D16C31_SAT(&pInstance->pData->BypassMixer,
    191                                     (LVM_INT16 *) pScratch,
    192                                     pScratchVol,
    193                                     pOutData,
    194                                     (LVM_INT16)(2*NumSamples));
    195 
    196     return(LVDBE_SUCCESS);
    197 }
    198 
    199 
    200 
    201 
    202 
    203 
    204 
    205 
    206 
    207 
    208