LVEQNB_Init.c revision d918324d44aa48b3b064ea9b87d0c520c38f15a9
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
61LVEQNB_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
186LVEQNB_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    MemSize = (pCapabilities->MaxBands * sizeof(LVEQNB_BiquadType_en));
268    pInstance->pBiquadType = (LVEQNB_BiquadType_en *)InstAlloc_AddMember(&AllocMem,
269                                                                         MemSize);
270
271
272    /*
273     * Internally map, structure and allign scratch memory
274     */
275    InstAlloc_Init(&AllocMem,
276                   pMemoryTable->Region[LVEQNB_MEMREGION_SCRATCH].pBaseAddress);
277
278    pInstance->pFastTemporary = (LVM_INT16 *)InstAlloc_AddMember(&AllocMem,
279                                                                 sizeof(LVM_INT16));
280
281    /*
282     * Update the instance parameters
283     */
284    pInstance->Params.NBands          = 0;
285    pInstance->Params.OperatingMode   = LVEQNB_BYPASS;
286    pInstance->Params.pBandDefinition = LVM_NULL;
287    pInstance->Params.SampleRate      = LVEQNB_FS_8000;
288    pInstance->Params.SourceFormat    = LVEQNB_STEREO;
289
290    /*
291     * Initialise the filters
292     */
293    LVEQNB_SetFilters(pInstance,                        /* Set the filter types */
294                      &pInstance->Params);
295
296    LVEQNB_SetCoefficients(pInstance);                  /* Set the filter coefficients */
297
298    LVEQNB_ClearFilterHistory(pInstance);               /* Clear the filter history */
299
300    /*
301     * Initialise the bypass variables
302     */
303    pInstance->BypassMixer.MixerStream[0].CallbackSet        = 0;
304    pInstance->BypassMixer.MixerStream[0].CallbackParam      = 0;
305    pInstance->BypassMixer.MixerStream[0].pCallbackHandle    = (void*)pInstance;
306    pInstance->BypassMixer.MixerStream[0].pCallBack          = LVEQNB_BypassMixerCallBack;
307    LVC_Mixer_Init(&pInstance->BypassMixer.MixerStream[0],0,0);
308    LVC_Mixer_SetTimeConstant(&pInstance->BypassMixer.MixerStream[0],0,LVM_FS_8000,2);
309
310    pInstance->BypassMixer.MixerStream[1].CallbackSet        = 1;
311    pInstance->BypassMixer.MixerStream[1].CallbackParam      = 0;
312    pInstance->BypassMixer.MixerStream[1].pCallbackHandle    = LVM_NULL;
313    pInstance->BypassMixer.MixerStream[1].pCallBack          = LVM_NULL;
314    LVC_Mixer_Init(&pInstance->BypassMixer.MixerStream[1],0,LVM_MAXINT_16);
315    LVC_Mixer_SetTimeConstant(&pInstance->BypassMixer.MixerStream[1],0,LVM_FS_8000,2);
316
317    pInstance->bInOperatingModeTransition      = LVM_FALSE;
318
319    return(LVEQNB_SUCCESS);
320}
321
322