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 /*                                                                                      */
     21 /*  Includes                                                                            */
     22 /*                                                                                      */
     23 /****************************************************************************************/
     24 
     25 #include "LVEQNB.h"
     26 #include "LVEQNB_Private.h"
     27 #include "InstAlloc.h"
     28 
     29 /****************************************************************************************/
     30 /*                                                                                      */
     31 /* FUNCTION:                LVEQNB_Memory                                               */
     32 /*                                                                                      */
     33 /* DESCRIPTION:                                                                         */
     34 /*  This function is used for memory allocation and free. It can be called in           */
     35 /*  two ways:                                                                           */
     36 /*                                                                                      */
     37 /*      hInstance = NULL                Returns the memory requirements                 */
     38 /*      hInstance = Instance handle     Returns the memory requirements and             */
     39 /*                                      allocated base addresses for the instance       */
     40 /*                                                                                      */
     41 /*  When this function is called for memory allocation (hInstance=NULL) the memory      */
     42 /*  base address pointers are NULL on return.                                           */
     43 /*                                                                                      */
     44 /*  When the function is called for free (hInstance = Instance Handle) the memory       */
     45 /*  table returns the allocated memory and base addresses used during initialisation.   */
     46 /*                                                                                      */
     47 /* PARAMETERS:                                                                          */
     48 /*  hInstance               Instance Handle                                             */
     49 /*  pMemoryTable            Pointer to an empty memory definition table                 */
     50 /*  pCapabilities           Pointer to the instance capabilities                        */
     51 /*                                                                                      */
     52 /* RETURNS:                                                                             */
     53 /*  LVEQNB_SUCCESS          Succeeded                                                   */
     54 /*  LVEQNB_NULLADDRESS      When any of pMemoryTable and pCapabilities is NULL address  */
     55 /*                                                                                      */
     56 /* NOTES:                                                                               */
     57 /*  1.  This function may be interrupted by the LVEQNB_Process function                 */
     58 /*                                                                                      */
     59 /****************************************************************************************/
     60 
     61 LVEQNB_ReturnStatus_en LVEQNB_Memory(LVEQNB_Handle_t            hInstance,
     62                                      LVEQNB_MemTab_t            *pMemoryTable,
     63                                      LVEQNB_Capabilities_t      *pCapabilities)
     64 {
     65 
     66     INST_ALLOC          AllocMem;
     67     LVEQNB_Instance_t   *pInstance = (LVEQNB_Instance_t *)hInstance;
     68 
     69 
     70     if((pMemoryTable == LVM_NULL)|| (pCapabilities == LVM_NULL))
     71     {
     72         return LVEQNB_NULLADDRESS;
     73     }
     74 
     75 
     76     /*
     77      * Fill in the memory table
     78      */
     79     if (hInstance == LVM_NULL)
     80     {
     81         /*
     82          * Instance memory
     83          */
     84         InstAlloc_Init(&AllocMem,
     85                        LVM_NULL);
     86         InstAlloc_AddMember(&AllocMem,                              /* Low pass filter */
     87                             sizeof(LVEQNB_Instance_t));
     88         pMemoryTable->Region[LVEQNB_MEMREGION_INSTANCE].Size         = InstAlloc_GetTotal(&AllocMem);
     89         pMemoryTable->Region[LVEQNB_MEMREGION_INSTANCE].Alignment    = LVEQNB_INSTANCE_ALIGN;
     90         pMemoryTable->Region[LVEQNB_MEMREGION_INSTANCE].Type         = LVEQNB_PERSISTENT;
     91         pMemoryTable->Region[LVEQNB_MEMREGION_INSTANCE].pBaseAddress = LVM_NULL;
     92 
     93 
     94         /*
     95          * Persistant data memory
     96          */
     97         InstAlloc_Init(&AllocMem,
     98                        LVM_NULL);
     99         InstAlloc_AddMember(&AllocMem,                              /* Low pass filter */
    100                             sizeof(Biquad_2I_Order2_Taps_t));
    101         InstAlloc_AddMember(&AllocMem,                              /* High pass filter */
    102                             sizeof(Biquad_2I_Order2_Taps_t));
    103         InstAlloc_AddMember(&AllocMem,
    104                             (pCapabilities->MaxBands * sizeof(Biquad_2I_Order2_Taps_t))); /* Equaliser Biquad Taps */
    105         InstAlloc_AddMember(&AllocMem,
    106                             (pCapabilities->MaxBands * sizeof(LVEQNB_BandDef_t)));        /* Filter definitions */
    107         InstAlloc_AddMember(&AllocMem,
    108                             (pCapabilities->MaxBands * sizeof(LVEQNB_BiquadType_en)));    /* Biquad types */
    109         pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_DATA].Size         = InstAlloc_GetTotal(&AllocMem);
    110         pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_DATA].Alignment    = LVEQNB_DATA_ALIGN;
    111         pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_DATA].Type         = LVEQNB_PERSISTENT_DATA;
    112         pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_DATA].pBaseAddress = LVM_NULL;
    113 
    114         /*
    115          * Persistant coefficient memory
    116          */
    117         InstAlloc_Init(&AllocMem,
    118                        LVM_NULL);
    119         InstAlloc_AddMember(&AllocMem,                              /* Low pass filter */
    120                             sizeof(Biquad_Instance_t));
    121         InstAlloc_AddMember(&AllocMem,                              /* High pass filter */
    122                             sizeof(Biquad_Instance_t));
    123         InstAlloc_AddMember(&AllocMem,
    124                             pCapabilities->MaxBands * sizeof(Biquad_Instance_t)); /* Equaliser Biquad Instance */
    125         pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_COEF].Size         = InstAlloc_GetTotal(&AllocMem);
    126         pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_COEF].Alignment    = LVEQNB_COEF_ALIGN;
    127         pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_COEF].Type         = LVEQNB_PERSISTENT_COEF;
    128         pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_COEF].pBaseAddress = LVM_NULL;
    129 
    130         /*
    131          * Scratch memory
    132          */
    133         InstAlloc_Init(&AllocMem,
    134                        LVM_NULL);
    135         InstAlloc_AddMember(&AllocMem,                              /* Low pass filter */
    136                             LVEQNB_SCRATCHBUFFERS*sizeof(LVM_INT16)*pCapabilities->MaxBlockSize);
    137         pMemoryTable->Region[LVEQNB_MEMREGION_SCRATCH].Size              = InstAlloc_GetTotal(&AllocMem);
    138         pMemoryTable->Region[LVEQNB_MEMREGION_SCRATCH].Alignment         = LVEQNB_SCRATCH_ALIGN;
    139         pMemoryTable->Region[LVEQNB_MEMREGION_SCRATCH].Type              = LVEQNB_SCRATCH;
    140         pMemoryTable->Region[LVEQNB_MEMREGION_SCRATCH].pBaseAddress      = LVM_NULL;
    141     }
    142     else
    143     {
    144         /* Read back memory allocation table */
    145         *pMemoryTable = pInstance->MemoryTable;
    146     }
    147 
    148     return(LVEQNB_SUCCESS);
    149 }
    150 
    151 
    152 /****************************************************************************************/
    153 /*                                                                                      */
    154 /* FUNCTION:                LVEQNB_Init                                                 */
    155 /*                                                                                      */
    156 /* DESCRIPTION:                                                                         */
    157 /*  Create and initialisation function for the N-Band equaliser module                  */
    158 /*                                                                                      */
    159 /*  This function can be used to create an algorithm instance by calling with           */
    160 /*  hInstance set to NULL. In this case the algorithm returns the new instance          */
    161 /*  handle.                                                                             */
    162 /*                                                                                      */
    163 /*  This function can be used to force a full re-initialisation of the algorithm        */
    164 /*  by calling with hInstance = Instance Handle. In this case the memory table          */
    165 /*  should be correct for the instance, this can be ensured by calling the function     */
    166 /*  DBE_Memory before calling this function.                                            */
    167 /*                                                                                      */
    168 /* PARAMETERS:                                                                          */
    169 /*  hInstance               Instance handle                                             */
    170 /*  pMemoryTable            Pointer to the memory definition table                      */
    171 /*  pCapabilities           Pointer to the instance capabilities                        */
    172 /*                                                                                      */
    173 /* RETURNS:                                                                             */
    174 /*  LVEQNB_SUCCESS          Initialisation succeeded                                    */
    175 /*  LVEQNB_NULLADDRESS        When pCapabilities or pMemoryTableis or phInstance are NULL */
    176 /*  LVEQNB_NULLADDRESS        One or more of the memory regions has a NULL base address   */
    177 /*                          pointer for a memory region with a non-zero size.           */
    178 /*                                                                                      */
    179 /* NOTES:                                                                               */
    180 /*  1.  The instance handle is the pointer to the base address of the first memory      */
    181 /*      region.                                                                         */
    182 /*  2.  This function must not be interrupted by the LVEQNB_Process function            */
    183 /*                                                                                      */
    184 /****************************************************************************************/
    185 
    186 LVEQNB_ReturnStatus_en LVEQNB_Init(LVEQNB_Handle_t          *phInstance,
    187                                    LVEQNB_MemTab_t          *pMemoryTable,
    188                                    LVEQNB_Capabilities_t    *pCapabilities)
    189 {
    190 
    191     LVEQNB_Instance_t   *pInstance;
    192     LVM_UINT32          MemSize;
    193     INST_ALLOC          AllocMem;
    194     LVM_INT32           i;
    195 
    196     /*
    197      * Check for NULL pointers
    198      */
    199     if((phInstance == LVM_NULL) || (pMemoryTable == LVM_NULL) || (pCapabilities == LVM_NULL))
    200     {
    201         return LVEQNB_NULLADDRESS;
    202     }
    203 
    204     /*
    205      * Check the memory table for NULL pointers
    206      */
    207     for (i = 0; i < LVEQNB_NR_MEMORY_REGIONS; i++)
    208     {
    209         if (pMemoryTable->Region[i].Size!=0)
    210         {
    211             if (pMemoryTable->Region[i].pBaseAddress==LVM_NULL)
    212             {
    213                 return(LVEQNB_NULLADDRESS);
    214             }
    215         }
    216     }
    217 
    218     /*
    219      * Set the instance handle if not already initialised
    220      */
    221 
    222     InstAlloc_Init(&AllocMem,  pMemoryTable->Region[LVEQNB_MEMREGION_INSTANCE].pBaseAddress);
    223 
    224     if (*phInstance == LVM_NULL)
    225     {
    226         *phInstance = InstAlloc_AddMember(&AllocMem, sizeof(LVEQNB_Instance_t));
    227     }
    228     pInstance =(LVEQNB_Instance_t  *)*phInstance;
    229 
    230 
    231 
    232     /*
    233      * Save the memory table in the instance structure
    234      */
    235     pInstance->Capabilities = *pCapabilities;
    236 
    237 
    238     /*
    239      * Save the memory table in the instance structure and
    240      * set the structure pointers
    241      */
    242     pInstance->MemoryTable       = *pMemoryTable;
    243 
    244     /*
    245      * Allocate coefficient memory
    246      */
    247     InstAlloc_Init(&AllocMem,
    248                    pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_COEF].pBaseAddress);
    249 
    250     pInstance->pEQNB_FilterState = InstAlloc_AddMember(&AllocMem,
    251                                                        pCapabilities->MaxBands * sizeof(Biquad_Instance_t)); /* Equaliser Biquad Instance */
    252 
    253 
    254 
    255     /*
    256      * Allocate data memory
    257      */
    258     InstAlloc_Init(&AllocMem,
    259                    pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_DATA].pBaseAddress);
    260 
    261     MemSize = (pCapabilities->MaxBands * sizeof(Biquad_2I_Order2_Taps_t));
    262     pInstance->pEQNB_Taps = (Biquad_2I_Order2_Taps_t *)InstAlloc_AddMember(&AllocMem,
    263                                                                            MemSize);
    264     MemSize = (pCapabilities->MaxBands * sizeof(LVEQNB_BandDef_t));
    265     pInstance->pBandDefinitions  = (LVEQNB_BandDef_t *)InstAlloc_AddMember(&AllocMem,
    266                                                                            MemSize);
    267     // clear all the bands, setting their gain to 0, otherwise when applying new params,
    268     // it will compare against uninitialized values
    269     memset(pInstance->pBandDefinitions, 0, MemSize);
    270     MemSize = (pCapabilities->MaxBands * sizeof(LVEQNB_BiquadType_en));
    271     pInstance->pBiquadType = (LVEQNB_BiquadType_en *)InstAlloc_AddMember(&AllocMem,
    272                                                                          MemSize);
    273 
    274 
    275     /*
    276      * Internally map, structure and allign scratch memory
    277      */
    278     InstAlloc_Init(&AllocMem,
    279                    pMemoryTable->Region[LVEQNB_MEMREGION_SCRATCH].pBaseAddress);
    280 
    281     pInstance->pFastTemporary = (LVM_INT16 *)InstAlloc_AddMember(&AllocMem,
    282                                                                  sizeof(LVM_INT16));
    283 
    284     /*
    285      * Update the instance parameters
    286      */
    287     pInstance->Params.NBands          = 0;
    288     pInstance->Params.OperatingMode   = LVEQNB_BYPASS;
    289     pInstance->Params.pBandDefinition = LVM_NULL;
    290     pInstance->Params.SampleRate      = LVEQNB_FS_8000;
    291     pInstance->Params.SourceFormat    = LVEQNB_STEREO;
    292 
    293     /*
    294      * Initialise the filters
    295      */
    296     LVEQNB_SetFilters(pInstance,                        /* Set the filter types */
    297                       &pInstance->Params);
    298 
    299     LVEQNB_SetCoefficients(pInstance);                  /* Set the filter coefficients */
    300 
    301     LVEQNB_ClearFilterHistory(pInstance);               /* Clear the filter history */
    302 
    303     /*
    304      * Initialise the bypass variables
    305      */
    306     pInstance->BypassMixer.MixerStream[0].CallbackSet        = 0;
    307     pInstance->BypassMixer.MixerStream[0].CallbackParam      = 0;
    308     pInstance->BypassMixer.MixerStream[0].pCallbackHandle    = (void*)pInstance;
    309     pInstance->BypassMixer.MixerStream[0].pCallBack          = LVEQNB_BypassMixerCallBack;
    310     LVC_Mixer_Init(&pInstance->BypassMixer.MixerStream[0],0,0);
    311     LVC_Mixer_SetTimeConstant(&pInstance->BypassMixer.MixerStream[0],0,LVM_FS_8000,2);
    312 
    313     pInstance->BypassMixer.MixerStream[1].CallbackSet        = 1;
    314     pInstance->BypassMixer.MixerStream[1].CallbackParam      = 0;
    315     pInstance->BypassMixer.MixerStream[1].pCallbackHandle    = LVM_NULL;
    316     pInstance->BypassMixer.MixerStream[1].pCallBack          = LVM_NULL;
    317     LVC_Mixer_Init(&pInstance->BypassMixer.MixerStream[1],0,LVM_MAXINT_16);
    318     LVC_Mixer_SetTimeConstant(&pInstance->BypassMixer.MixerStream[1],0,LVM_FS_8000,2);
    319 
    320     pInstance->bInOperatingModeTransition      = LVM_FALSE;
    321 
    322     return(LVEQNB_SUCCESS);
    323 }
    324 
    325