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 
     27 /****************************************************************************************/
     28 /*                                                                                      */
     29 /* FUNCTION:                 LVDBE_Memory                                               */
     30 /*                                                                                      */
     31 /* DESCRIPTION:                                                                         */
     32 /*    This function is used for memory allocation and free. It can be called in         */
     33 /*    two ways:                                                                         */
     34 /*                                                                                      */
     35 /*        hInstance = NULL                Returns the memory requirements               */
     36 /*        hInstance = Instance handle        Returns the memory requirements and        */
     37 /*                                        allocated base addresses for the instance     */
     38 /*                                                                                      */
     39 /*    When this function is called for memory allocation (hInstance=NULL) the memory    */
     40 /*  base address pointers are NULL on return.                                           */
     41 /*                                                                                      */
     42 /*    When the function is called for free (hInstance = Instance Handle) the memory     */
     43 /*  table returns the allocated memory and base addresses used during initialisation.   */
     44 /*                                                                                      */
     45 /* PARAMETERS:                                                                          */
     46 /*  hInstance                Instance Handle                                            */
     47 /*  pMemoryTable             Pointer to an empty memory definition table                */
     48 /*    pCapabilities           Pointer to the instance capabilities                      */
     49 /*                                                                                      */
     50 /* RETURNS:                                                                             */
     51 /*  LVDBE_SUCCESS            Succeeded                                                  */
     52 /*                                                                                      */
     53 /* NOTES:                                                                               */
     54 /*    1.    This function may be interrupted by the LVDBE_Process function              */
     55 /*                                                                                      */
     56 /****************************************************************************************/
     57 
     58 LVDBE_ReturnStatus_en LVDBE_Memory(LVDBE_Handle_t            hInstance,
     59                                    LVDBE_MemTab_t            *pMemoryTable,
     60                                    LVDBE_Capabilities_t      *pCapabilities)
     61 {
     62 
     63     LVM_UINT32          ScratchSize;
     64     LVDBE_Instance_t    *pInstance = (LVDBE_Instance_t *)hInstance;
     65 
     66 
     67     /*
     68      * Fill in the memory table
     69      */
     70     if (hInstance == LVM_NULL)
     71     {
     72         /*
     73          * Instance memory
     74          */
     75         pMemoryTable->Region[LVDBE_MEMREGION_INSTANCE].Size         = sizeof(LVDBE_Instance_t);
     76         pMemoryTable->Region[LVDBE_MEMREGION_INSTANCE].Alignment    = LVDBE_INSTANCE_ALIGN;
     77         pMemoryTable->Region[LVDBE_MEMREGION_INSTANCE].Type         = LVDBE_PERSISTENT;
     78         pMemoryTable->Region[LVDBE_MEMREGION_INSTANCE].pBaseAddress = LVM_NULL;
     79 
     80         /*
     81          * Data memory
     82          */
     83 #ifdef BUILD_FLOAT
     84         pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_DATA].Size   = sizeof(LVDBE_Data_FLOAT_t);
     85 #else
     86         pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_DATA].Size         = sizeof(LVDBE_Data_t);
     87 #endif
     88         pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_DATA].Alignment    = LVDBE_PERSISTENT_DATA_ALIGN;
     89         pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_DATA].Type         = LVDBE_PERSISTENT_DATA;
     90         pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_DATA].pBaseAddress = LVM_NULL;
     91 
     92         /*
     93          * Coef memory
     94          */
     95 #ifdef BUILD_FLOAT
     96         pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].Size   = sizeof(LVDBE_Coef_FLOAT_t);
     97 #else
     98         pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].Size         = sizeof(LVDBE_Coef_t);
     99 #endif
    100         pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].Alignment    = LVDBE_PERSISTENT_COEF_ALIGN;
    101         pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].Type         = LVDBE_PERSISTENT_COEF;
    102         pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].pBaseAddress = LVM_NULL;
    103 
    104         /*
    105          * Scratch memory
    106          */
    107 #ifdef BUILD_FLOAT
    108         ScratchSize = (LVM_UINT32)(LVDBE_SCRATCHBUFFERS_INPLACE*sizeof(LVM_FLOAT) * \
    109                                         pCapabilities->MaxBlockSize);
    110 #else /*BUILD_FLOAT*/
    111         ScratchSize = (LVM_UINT32)(LVDBE_SCRATCHBUFFERS_INPLACE*sizeof(LVM_INT16)*pCapabilities->MaxBlockSize);
    112 #endif
    113         pMemoryTable->Region[LVDBE_MEMREGION_SCRATCH].Size         = ScratchSize;
    114         pMemoryTable->Region[LVDBE_MEMREGION_SCRATCH].Alignment    = LVDBE_SCRATCH_ALIGN;
    115         pMemoryTable->Region[LVDBE_MEMREGION_SCRATCH].Type         = LVDBE_SCRATCH;
    116         pMemoryTable->Region[LVDBE_MEMREGION_SCRATCH].pBaseAddress = LVM_NULL;
    117     }
    118     else
    119     {
    120         /* Read back memory allocation table */
    121         *pMemoryTable = pInstance->MemoryTable;
    122     }
    123 
    124     return(LVDBE_SUCCESS);
    125 }
    126 
    127 
    128 /****************************************************************************************/
    129 /*                                                                                      */
    130 /* FUNCTION:                 LVDBE_Init                                                 */
    131 /*                                                                                      */
    132 /* DESCRIPTION:                                                                         */
    133 /*    Create and initialisation function for the Dynamic Bass Enhancement module        */
    134 /*                                                                                      */
    135 /*    This function can be used to create an algorithm instance by calling with         */
    136 /*    hInstance set to NULL. In this case the algorithm returns the new instance        */
    137 /*    handle.                                                                           */
    138 /*                                                                                      */
    139 /*    This function can be used to force a full re-initialisation of the algorithm      */
    140 /*    by calling with hInstance = Instance Handle. In this case the memory table        */
    141 /*    should be correct for the instance, this can be ensured by calling the function   */
    142 /*    DBE_Memory before calling this function.                                          */
    143 /*                                                                                      */
    144 /* PARAMETERS:                                                                          */
    145 /*  hInstance                  Instance handle                                          */
    146 /*  pMemoryTable             Pointer to the memory definition table                     */
    147 /*  pCapabilities              Pointer to the instance capabilities                     */
    148 /*                                                                                      */
    149 /* RETURNS:                                                                             */
    150 /*  LVDBE_SUCCESS            Initialisation succeeded                                   */
    151 /*  LVDBE_ALIGNMENTERROR    Instance or scratch memory on incorrect alignment           */
    152 /*    LVDBE_NULLADDRESS        Instance or scratch memory has a NULL pointer            */
    153 /*                                                                                      */
    154 /* NOTES:                                                                               */
    155 /*  1.     The instance handle is the pointer to the base address of the first memory   */
    156 /*        region.                                                                       */
    157 /*    2.    This function must not be interrupted by the LVDBE_Process function         */
    158 /*                                                                                      */
    159 /****************************************************************************************/
    160 
    161 LVDBE_ReturnStatus_en LVDBE_Init(LVDBE_Handle_t         *phInstance,
    162                                    LVDBE_MemTab_t       *pMemoryTable,
    163                                    LVDBE_Capabilities_t *pCapabilities)
    164 {
    165 
    166     LVDBE_Instance_t      *pInstance;
    167 #ifdef BUILD_FLOAT
    168     LVMixer3_1St_FLOAT_st       *pMixer_Instance;
    169     LVMixer3_2St_FLOAT_st       *pBypassMixer_Instance;
    170     LVM_FLOAT             MixGain;
    171 #else
    172     LVMixer3_1St_st       *pMixer_Instance;
    173     LVMixer3_2St_st       *pBypassMixer_Instance;
    174     LVM_INT32             MixGain;
    175 #endif
    176     LVM_INT16             i;
    177 
    178 
    179     /*
    180      * Set the instance handle if not already initialised
    181      */
    182     if (*phInstance == LVM_NULL)
    183     {
    184         *phInstance = (LVDBE_Handle_t)pMemoryTable->Region[LVDBE_MEMREGION_INSTANCE].pBaseAddress;
    185     }
    186     pInstance =(LVDBE_Instance_t  *)*phInstance;
    187 
    188 
    189     /*
    190      * Check the memory table for NULL pointers and incorrectly aligned data
    191      */
    192     for (i=0; i<LVDBE_NR_MEMORY_REGIONS; i++)
    193     {
    194         if (pMemoryTable->Region[i].Size!=0)
    195         {
    196             if (pMemoryTable->Region[i].pBaseAddress==LVM_NULL)
    197             {
    198                 return(LVDBE_NULLADDRESS);
    199             }
    200             if (((uintptr_t)pMemoryTable->Region[i].pBaseAddress % pMemoryTable->Region[i].Alignment)!=0){
    201                 return(LVDBE_ALIGNMENTERROR);
    202             }
    203         }
    204     }
    205 
    206 
    207     /*
    208      * Save the memory table in the instance structure
    209      */
    210     pInstance->Capabilities = *pCapabilities;
    211 
    212 
    213     /*
    214      * Save the memory table in the instance structure
    215      */
    216     pInstance->MemoryTable = *pMemoryTable;
    217 
    218 
    219     /*
    220      * Set the default instance parameters
    221      */
    222     pInstance->Params.CentreFrequency   =    LVDBE_CENTRE_55HZ;
    223     pInstance->Params.EffectLevel       =    0;
    224     pInstance->Params.HeadroomdB        =    0;
    225     pInstance->Params.HPFSelect         =    LVDBE_HPF_OFF;
    226     pInstance->Params.OperatingMode     =    LVDBE_OFF;
    227     pInstance->Params.SampleRate        =    LVDBE_FS_8000;
    228     pInstance->Params.VolumeControl     =    LVDBE_VOLUME_OFF;
    229     pInstance->Params.VolumedB          =    0;
    230 
    231 
    232     /*
    233      * Set pointer to data and coef memory
    234      */
    235     pInstance->pData = pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_DATA].pBaseAddress;
    236     pInstance->pCoef = pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].pBaseAddress;
    237 
    238 
    239     /*
    240      * Initialise the filters
    241      */
    242     LVDBE_SetFilters(pInstance,                 /* Set the filter taps and coefficients */
    243                      &pInstance->Params);
    244 
    245 
    246     /*
    247      * Initialise the AGC
    248      */
    249     LVDBE_SetAGC(pInstance,                                     /* Set the AGC gain */
    250                  &pInstance->Params);
    251     pInstance->pData->AGCInstance.AGC_Gain = pInstance->pData->AGCInstance.AGC_MaxGain;
    252                                                 /* Default to the bass boost setting */
    253 
    254     // initialize the mixer with some fixes values since otherwise LVDBE_SetVolume ends up
    255     // reading uninitialized data
    256     pMixer_Instance = &pInstance->pData->BypassVolume;
    257 #ifndef BUILD_FLOAT
    258     LVC_Mixer_Init(&pMixer_Instance->MixerStream[0],0x00007FFF,0x00007FFF);
    259 #else
    260     LVC_Mixer_Init(&pMixer_Instance->MixerStream[0], 1.0, 1.0);
    261 #endif
    262 
    263     /*
    264      * Initialise the volume
    265      */
    266     LVDBE_SetVolume(pInstance,                                         /* Set the Volume */
    267                     &pInstance->Params);
    268 
    269     pInstance->pData->AGCInstance.Volume = pInstance->pData->AGCInstance.Target;
    270                                                 /* Initialise as the target */
    271 #ifndef BUILD_FLOAT
    272     MixGain = LVC_Mixer_GetTarget(&pMixer_Instance->MixerStream[0]);
    273     LVC_Mixer_Init(&pMixer_Instance->MixerStream[0],MixGain,MixGain);
    274 #else
    275     MixGain = LVC_Mixer_GetTarget(&pMixer_Instance->MixerStream[0]);
    276     LVC_Mixer_Init(&pMixer_Instance->MixerStream[0], MixGain, MixGain);
    277 #endif
    278 
    279     /* Configure the mixer process path */
    280     pMixer_Instance->MixerStream[0].CallbackParam = 0;
    281     pMixer_Instance->MixerStream[0].pCallbackHandle = LVM_NULL;
    282     pMixer_Instance->MixerStream[0].pCallBack = LVM_NULL;
    283     pMixer_Instance->MixerStream[0].CallbackSet = 0;
    284 
    285     /*
    286      * Initialise the clicks minimisation BypassMixer
    287      */
    288 
    289     pBypassMixer_Instance = &pInstance->pData->BypassMixer;
    290 
    291     /*
    292      * Setup the mixer gain for the processed path
    293      */
    294     pBypassMixer_Instance->MixerStream[0].CallbackParam = 0;
    295     pBypassMixer_Instance->MixerStream[0].pCallbackHandle = LVM_NULL;
    296     pBypassMixer_Instance->MixerStream[0].pCallBack = LVM_NULL;
    297     pBypassMixer_Instance->MixerStream[0].CallbackSet=0;
    298 
    299     LVC_Mixer_Init(&pBypassMixer_Instance->MixerStream[0],0,0);
    300     LVC_Mixer_SetTimeConstant(&pBypassMixer_Instance->MixerStream[0],
    301         LVDBE_BYPASS_MIXER_TC,(LVM_Fs_en)pInstance->Params.SampleRate,2);
    302 
    303     /*
    304      * Setup the mixer gain for the unprocessed path
    305      */
    306     pBypassMixer_Instance->MixerStream[1].CallbackParam = 0;
    307     pBypassMixer_Instance->MixerStream[1].pCallbackHandle = LVM_NULL;
    308     pBypassMixer_Instance->MixerStream[1].pCallBack = LVM_NULL;
    309     pBypassMixer_Instance->MixerStream[1].CallbackSet=0;
    310 #ifndef BUILD_FLOAT
    311     LVC_Mixer_Init(&pBypassMixer_Instance->MixerStream[1],0x00007FFF,0x00007FFF);
    312     LVC_Mixer_SetTimeConstant(&pBypassMixer_Instance->MixerStream[1],
    313         LVDBE_BYPASS_MIXER_TC,(LVM_Fs_en)pInstance->Params.SampleRate,2);
    314 #else
    315     LVC_Mixer_Init(&pBypassMixer_Instance->MixerStream[1], 1.0, 1.0);
    316     LVC_Mixer_SetTimeConstant(&pBypassMixer_Instance->MixerStream[1],
    317         LVDBE_BYPASS_MIXER_TC,(LVM_Fs_en)pInstance->Params.SampleRate, 2);
    318 #endif
    319 
    320     return(LVDBE_SUCCESS);
    321 }
    322