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 "LVM_Private.h"
25 #include "LVM_Tables.h"
26 #include "VectorArithmetic.h"
27 #include "InstAlloc.h"
28 
29 /****************************************************************************************/
30 /*                                                                                      */
31 /* FUNCTION:                LVM_GetMemoryTable                                          */
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 default capabilities                         */
51 /*                                                                                      */
52 /* RETURNS:                                                                             */
53 /*  LVM_SUCCESS             Succeeded                                                   */
54 /*  LVM_NULLADDRESS         When one of pMemoryTable or pInstParams is NULL             */
55 /*  LVM_OUTOFRANGE          When any of the Instance parameters are out of range        */
56 /*                                                                                      */
57 /* NOTES:                                                                               */
58 /*  1.  This function may be interrupted by the LVM_Process function                    */
59 /*  2.  The scratch memory is the largest required by any of the sub-modules plus any   */
60 /*      additional scratch requirements of the bundle                                   */
61 /*                                                                                      */
62 /****************************************************************************************/
63 
64 /*
65  * 4 Types of Memory Regions of LVM
66  * TODO: Allocate on the fly.
67  * i)   LVM_MEMREGION_PERSISTENT_SLOW_DATA - For Instance Handles
68  * ii)  LVM_MEMREGION_PERSISTENT_FAST_DATA - Persistent Buffers
69  * iii) LVM_MEMREGION_PERSISTENT_FAST_COEF - For Holding Structure values
70  * iv)  LVM_MEMREGION_TEMPORARY_FAST       - For Holding Structure values
71  *
72  * LVM_MEMREGION_PERSISTENT_SLOW_DATA:
73  *   Total Memory size:
74  *     sizeof(LVM_Instance_t) + \
75  *     sizeof(LVM_Buffer_t) + \
76  *     sizeof(LVPSA_InstancePr_t) + \
77  *     sizeof(LVM_Buffer_t) - needed if buffer mode is LVM_MANAGED_BUFFER
78  *
79  * LVM_MEMREGION_PERSISTENT_FAST_DATA:
80  *   Total Memory size:
81  *     sizeof(LVM_TE_Data_t) + \
82  *     2 * pInstParams->EQNB_NumBands * sizeof(LVM_EQNB_BandDef_t) + \
83  *     sizeof(LVCS_Data_t) + \
84  *     sizeof(LVDBE_Data_FLOAT_t) + \
85  *     sizeof(Biquad_2I_Order2_FLOAT_Taps_t) + \
86  *     sizeof(Biquad_2I_Order2_FLOAT_Taps_t) + \
87  *     pInstParams->EQNB_NumBands * sizeof(Biquad_2I_Order2_FLOAT_Taps_t) + \
88  *     pInstParams->EQNB_NumBands * sizeof(LVEQNB_BandDef_t) + \
89  *     pInstParams->EQNB_NumBands * sizeof(LVEQNB_BiquadType_en) + \
90  *     2 * LVM_HEADROOM_MAX_NBANDS * sizeof(LVM_HeadroomBandDef_t) + \
91  *     PSA_InitParams.nBands * sizeof(Biquad_1I_Order2_Taps_t) + \
92  *     PSA_InitParams.nBands * sizeof(QPD_Taps_t)
93  *
94  * LVM_MEMREGION_PERSISTENT_FAST_COEF:
95  *   Total Memory size:
96  *     sizeof(LVM_TE_Coefs_t) + \
97  *     sizeof(LVCS_Coefficient_t) + \
98  *     sizeof(LVDBE_Coef_FLOAT_t) + \
99  *     sizeof(Biquad_FLOAT_Instance_t) + \
100  *     sizeof(Biquad_FLOAT_Instance_t) + \
101  *     pInstParams->EQNB_NumBands * sizeof(Biquad_FLOAT_Instance_t) + \
102  *     PSA_InitParams.nBands * sizeof(Biquad_Instance_t) + \
103  *     PSA_InitParams.nBands * sizeof(QPD_State_t)
104  *
105  * LVM_MEMREGION_TEMPORARY_FAST (Scratch):
106  *   Total Memory Size:
107  *     BundleScratchSize + \
108  *     MAX_INTERNAL_BLOCKSIZE * sizeof(LVM_FLOAT) + \
109  *     MaxScratchOf (CS, EQNB, DBE, PSA)
110  *
111  *     a)BundleScratchSize:
112  *         3 * LVM_MAX_CHANNELS \
113  *         * (MIN_INTERNAL_BLOCKSIZE + InternalBlockSize) * sizeof(LVM_FLOAT)
114  *       This Memory is allocated only when Buffer mode is LVM_MANAGED_BUFFER.
115  *     b)MaxScratchOf (CS, EQNB, DBE, PSA)
116  *       This Memory is needed for scratch usage for CS, EQNB, DBE, PSA.
117  *       CS   = (LVCS_SCRATCHBUFFERS * sizeof(LVM_FLOAT)
118  *               * pCapabilities->MaxBlockSize)
119  *       EQNB = (LVEQNB_SCRATCHBUFFERS * sizeof(LVM_FLOAT)
120  *               * pCapabilities->MaxBlockSize)
121  *       DBE  = (LVDBE_SCRATCHBUFFERS_INPLACE*sizeof(LVM_FLOAT)
122  *               * pCapabilities->MaxBlockSize)
123  *       PSA  = (2 * pInitParams->MaxInputBlockSize * sizeof(LVM_FLOAT))
124  *              one MaxInputBlockSize for input and another for filter output
125  *     c)MAX_INTERNAL_BLOCKSIZE
126  *       This Memory is needed for PSAInput - Temp memory to store output
127  *       from McToMono block and given as input to PSA block
128  */
129 
LVM_GetMemoryTable(LVM_Handle_t hInstance,LVM_MemTab_t * pMemoryTable,LVM_InstParams_t * pInstParams)130 LVM_ReturnStatus_en LVM_GetMemoryTable(LVM_Handle_t         hInstance,
131                                        LVM_MemTab_t         *pMemoryTable,
132                                        LVM_InstParams_t     *pInstParams)
133 {
134 
135     LVM_Instance_t      *pInstance = (LVM_Instance_t *)hInstance;
136     LVM_UINT32          AlgScratchSize;
137     LVM_UINT32          BundleScratchSize;
138     LVM_UINT16          InternalBlockSize;
139     INST_ALLOC          AllocMem[LVM_NR_MEMORY_REGIONS];
140     LVM_INT16           i;
141 
142     /*
143      * Check parameters
144      */
145     if(pMemoryTable == LVM_NULL)
146     {
147         return LVM_NULLADDRESS;
148     }
149 
150     /*
151      * Return memory table if the instance has already been created
152      */
153     if (hInstance != LVM_NULL)
154     {
155        /* Read back memory allocation table */
156         *pMemoryTable = pInstance->MemoryTable;
157         return(LVM_SUCCESS);
158     }
159 
160     if(pInstParams == LVM_NULL)
161     {
162         return LVM_NULLADDRESS;
163     }
164 
165     /*
166      *  Power Spectrum Analyser
167      */
168     if(pInstParams->PSA_Included > LVM_PSA_ON)
169     {
170         return (LVM_OUTOFRANGE);
171     }
172 
173     /*
174      * Check the instance parameters
175      */
176     if( (pInstParams->BufferMode != LVM_MANAGED_BUFFERS) && (pInstParams->BufferMode != LVM_UNMANAGED_BUFFERS) )
177     {
178         return (LVM_OUTOFRANGE);
179     }
180 
181     /* N-Band Equalizer */
182     if( pInstParams->EQNB_NumBands > 32 )
183     {
184         return (LVM_OUTOFRANGE);
185     }
186 
187     if(pInstParams->BufferMode == LVM_MANAGED_BUFFERS)
188     {
189         if( (pInstParams->MaxBlockSize < LVM_MIN_MAXBLOCKSIZE ) || (pInstParams->MaxBlockSize > LVM_MANAGED_MAX_MAXBLOCKSIZE ) )
190         {
191             return (LVM_OUTOFRANGE);
192         }
193     }
194     else
195     {
196         if( (pInstParams->MaxBlockSize < LVM_MIN_MAXBLOCKSIZE ) || (pInstParams->MaxBlockSize > LVM_UNMANAGED_MAX_MAXBLOCKSIZE) )
197         {
198             return (LVM_OUTOFRANGE);
199         }
200     }
201 
202     /*
203     * Initialise the AllocMem structures
204     */
205     for (i=0; i<LVM_NR_MEMORY_REGIONS; i++)
206     {
207         InstAlloc_Init(&AllocMem[i], LVM_NULL);
208     }
209     InternalBlockSize = (LVM_UINT16)((pInstParams->MaxBlockSize) & MIN_INTERNAL_BLOCKMASK); /* Force to a multiple of MIN_INTERNAL_BLOCKSIZE */
210 
211     if (InternalBlockSize < MIN_INTERNAL_BLOCKSIZE)
212     {
213         InternalBlockSize = MIN_INTERNAL_BLOCKSIZE;
214     }
215 
216     /* Maximum Internal Black Size should not be more than MAX_INTERNAL_BLOCKSIZE*/
217     if(InternalBlockSize > MAX_INTERNAL_BLOCKSIZE)
218     {
219         InternalBlockSize = MAX_INTERNAL_BLOCKSIZE;
220     }
221 
222     /*
223     * Bundle requirements
224     */
225     InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_SLOW_DATA],
226         sizeof(LVM_Instance_t));
227 
228     /*
229      * Set the algorithm and bundle scratch requirements
230      */
231     AlgScratchSize    = 0;
232     if (pInstParams->BufferMode == LVM_MANAGED_BUFFERS)
233     {
234         BundleScratchSize = 3 * LVM_MAX_CHANNELS \
235                             * (MIN_INTERNAL_BLOCKSIZE + InternalBlockSize) \
236                             * sizeof(LVM_FLOAT);
237         InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_TEMPORARY_FAST],        /* Scratch buffer */
238                             BundleScratchSize);
239         InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_SLOW_DATA],
240                             sizeof(LVM_Buffer_t));
241     }
242 
243     /*
244      * Treble Enhancement requirements
245      */
246     InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_DATA],
247                         sizeof(LVM_TE_Data_t));
248     InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_COEF],
249                         sizeof(LVM_TE_Coefs_t));
250 
251     /*
252      * N-Band Equalizer requirements
253      */
254     InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_DATA],      /* Local storage */
255                         (pInstParams->EQNB_NumBands * sizeof(LVM_EQNB_BandDef_t)));
256     InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_DATA],      /* User storage */
257                         (pInstParams->EQNB_NumBands * sizeof(LVM_EQNB_BandDef_t)));
258 
259     /*
260      * Concert Sound requirements
261      */
262     {
263         LVCS_MemTab_t           CS_MemTab;
264         LVCS_Capabilities_t     CS_Capabilities;
265 
266         /*
267          * Set the capabilities
268          */
269         CS_Capabilities.MaxBlockSize     = InternalBlockSize;
270 
271         /*
272          * Get the memory requirements
273          */
274         LVCS_Memory(LVM_NULL,
275                     &CS_MemTab,
276                     &CS_Capabilities);
277 
278         /*
279          * Update the memory allocation structures
280          */
281         InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_DATA],
282                             CS_MemTab.Region[LVM_MEMREGION_PERSISTENT_FAST_DATA].Size);
283         InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_COEF],
284                             CS_MemTab.Region[LVM_MEMREGION_PERSISTENT_FAST_COEF].Size);
285         if (CS_MemTab.Region[LVM_MEMREGION_TEMPORARY_FAST].Size > AlgScratchSize) AlgScratchSize = CS_MemTab.Region[LVM_MEMREGION_TEMPORARY_FAST].Size;
286 
287     }
288 
289     /*
290      * Dynamic Bass Enhancement requirements
291      */
292     {
293         LVDBE_MemTab_t          DBE_MemTab;
294         LVDBE_Capabilities_t    DBE_Capabilities;
295 
296         /*
297          * Set the capabilities
298          */
299         DBE_Capabilities.SampleRate      = LVDBE_CAP_FS_8000 | LVDBE_CAP_FS_11025 |
300                                            LVDBE_CAP_FS_12000 | LVDBE_CAP_FS_16000 |
301                                            LVDBE_CAP_FS_22050 | LVDBE_CAP_FS_24000 |
302                                            LVDBE_CAP_FS_32000 | LVDBE_CAP_FS_44100 |
303                                            LVDBE_CAP_FS_48000 | LVDBE_CAP_FS_88200 |
304                                            LVDBE_CAP_FS_96000 | LVDBE_CAP_FS_176400 |
305                                            LVDBE_CAP_FS_192000;
306         DBE_Capabilities.CentreFrequency = LVDBE_CAP_CENTRE_55Hz | LVDBE_CAP_CENTRE_55Hz | LVDBE_CAP_CENTRE_66Hz | LVDBE_CAP_CENTRE_78Hz | LVDBE_CAP_CENTRE_90Hz;
307         DBE_Capabilities.MaxBlockSize    = InternalBlockSize;
308 
309         /*
310          * Get the memory requirements
311          */
312         LVDBE_Memory(LVM_NULL,
313                     &DBE_MemTab,
314 
315                     &DBE_Capabilities);
316         /*
317          * Update the bundle table
318          */
319         InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_DATA],
320                             DBE_MemTab.Region[LVM_MEMREGION_PERSISTENT_FAST_DATA].Size);
321         InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_COEF],
322                             DBE_MemTab.Region[LVM_MEMREGION_PERSISTENT_FAST_COEF].Size);
323         if (DBE_MemTab.Region[LVM_MEMREGION_TEMPORARY_FAST].Size > AlgScratchSize) AlgScratchSize = DBE_MemTab.Region[LVM_MEMREGION_TEMPORARY_FAST].Size;
324 
325     }
326 
327     /*
328      * N-Band equaliser requirements
329      */
330     {
331         LVEQNB_MemTab_t         EQNB_MemTab;            /* For N-Band Equaliser */
332         LVEQNB_Capabilities_t   EQNB_Capabilities;
333 
334         /*
335          * Set the capabilities
336          */
337         EQNB_Capabilities.SampleRate   = LVEQNB_CAP_FS_8000 | LVEQNB_CAP_FS_11025 |
338                                          LVEQNB_CAP_FS_12000 | LVEQNB_CAP_FS_16000 |
339                                          LVEQNB_CAP_FS_22050 | LVEQNB_CAP_FS_24000 |
340                                          LVEQNB_CAP_FS_32000 | LVEQNB_CAP_FS_44100 |
341                                          LVEQNB_CAP_FS_48000 | LVEQNB_CAP_FS_88200 |
342                                          LVEQNB_CAP_FS_96000 | LVEQNB_CAP_FS_176400 |
343                                          LVEQNB_CAP_FS_192000;
344         EQNB_Capabilities.SourceFormat = LVEQNB_CAP_STEREO | LVEQNB_CAP_MONOINSTEREO;
345         EQNB_Capabilities.MaxBlockSize = InternalBlockSize;
346         EQNB_Capabilities.MaxBands     = pInstParams->EQNB_NumBands;
347 
348         /*
349          * Get the memory requirements
350          */
351         LVEQNB_Memory(LVM_NULL,
352                       &EQNB_MemTab,
353                       &EQNB_Capabilities);
354 
355         /*
356          * Update the bundle table
357          */
358         InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_DATA],
359                             EQNB_MemTab.Region[LVM_MEMREGION_PERSISTENT_FAST_DATA].Size);
360         InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_COEF],
361                             EQNB_MemTab.Region[LVM_MEMREGION_PERSISTENT_FAST_COEF].Size);
362         if (EQNB_MemTab.Region[LVM_MEMREGION_TEMPORARY_FAST].Size > AlgScratchSize) AlgScratchSize = EQNB_MemTab.Region[LVM_MEMREGION_TEMPORARY_FAST].Size;
363 
364     }
365 
366     /*
367      * Headroom management memory allocation
368      */
369     InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_DATA],
370                        (LVM_HEADROOM_MAX_NBANDS * sizeof(LVM_HeadroomBandDef_t)));
371     InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_DATA],
372                        (LVM_HEADROOM_MAX_NBANDS * sizeof(LVM_HeadroomBandDef_t)));
373 
374     /*
375      * Spectrum Analyzer memory requirements
376      */
377     {
378         pLVPSA_Handle_t     hPSAInst = LVM_NULL;
379         LVPSA_MemTab_t      PSA_MemTab;
380         LVPSA_InitParams_t  PSA_InitParams;
381         LVPSA_FilterParam_t FiltersParams[9];
382         LVPSA_RETURN        PSA_Status;
383 
384         if(pInstParams->PSA_Included == LVM_PSA_ON)
385         {
386             PSA_InitParams.SpectralDataBufferDuration   = (LVM_UINT16) 500;
387             PSA_InitParams.MaxInputBlockSize            = (LVM_UINT16) 1000;
388             PSA_InitParams.nBands                       = (LVM_UINT16) 9;
389 
390             PSA_InitParams.pFiltersParams = &FiltersParams[0];
391             for(i = 0; i < PSA_InitParams.nBands; i++)
392             {
393                 FiltersParams[i].CenterFrequency    = (LVM_UINT16) 1000;
394                 FiltersParams[i].QFactor            = (LVM_UINT16) 25;
395                 FiltersParams[i].PostGain           = (LVM_INT16)  0;
396             }
397 
398             /*
399             * Get the memory requirements
400             */
401             PSA_Status = LVPSA_Memory (hPSAInst,
402                                         &PSA_MemTab,
403                                         &PSA_InitParams);
404 
405             if (PSA_Status != LVPSA_OK)
406             {
407                 return((LVM_ReturnStatus_en) LVM_ALGORITHMPSA);
408             }
409 
410             /*
411             * Update the bundle table
412             */
413             /* Slow Data */
414             InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_SLOW_DATA],
415                 PSA_MemTab.Region[LVM_PERSISTENT_SLOW_DATA].Size);
416 
417             /* Fast Data */
418             InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_DATA],
419                 PSA_MemTab.Region[LVM_PERSISTENT_FAST_DATA].Size);
420 
421             /* Fast Coef */
422             InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_COEF],
423                 PSA_MemTab.Region[LVM_PERSISTENT_FAST_COEF].Size);
424 
425             /* Fast Temporary */
426             InstAlloc_AddMember(&AllocMem[LVM_TEMPORARY_FAST],
427                                 MAX_INTERNAL_BLOCKSIZE * sizeof(LVM_FLOAT));
428 
429             if (PSA_MemTab.Region[LVM_TEMPORARY_FAST].Size > AlgScratchSize)
430             {
431                 AlgScratchSize = PSA_MemTab.Region[LVM_TEMPORARY_FAST].Size;
432             }
433         }
434     }
435 
436     /*
437      * Return the memory table
438      */
439     pMemoryTable->Region[LVM_MEMREGION_PERSISTENT_SLOW_DATA].Size         = InstAlloc_GetTotal(&AllocMem[LVM_MEMREGION_PERSISTENT_SLOW_DATA]);
440     pMemoryTable->Region[LVM_MEMREGION_PERSISTENT_SLOW_DATA].Type         = LVM_PERSISTENT_SLOW_DATA;
441     pMemoryTable->Region[LVM_MEMREGION_PERSISTENT_SLOW_DATA].pBaseAddress = LVM_NULL;
442 
443     pMemoryTable->Region[LVM_MEMREGION_PERSISTENT_FAST_DATA].Size         = InstAlloc_GetTotal(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_DATA]);
444     pMemoryTable->Region[LVM_MEMREGION_PERSISTENT_FAST_DATA].Type         = LVM_PERSISTENT_FAST_DATA;
445     pMemoryTable->Region[LVM_MEMREGION_PERSISTENT_FAST_DATA].pBaseAddress = LVM_NULL;
446     if (pMemoryTable->Region[LVM_MEMREGION_PERSISTENT_FAST_DATA].Size < 4)
447     {
448         pMemoryTable->Region[LVM_MEMREGION_PERSISTENT_FAST_DATA].Size = 0;
449     }
450 
451     pMemoryTable->Region[LVM_MEMREGION_PERSISTENT_FAST_COEF].Size         = InstAlloc_GetTotal(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_COEF]);
452     pMemoryTable->Region[LVM_MEMREGION_PERSISTENT_FAST_COEF].Type         = LVM_PERSISTENT_FAST_COEF;
453     pMemoryTable->Region[LVM_MEMREGION_PERSISTENT_FAST_COEF].pBaseAddress = LVM_NULL;
454     if (pMemoryTable->Region[LVM_MEMREGION_PERSISTENT_FAST_COEF].Size < 4)
455     {
456         pMemoryTable->Region[LVM_MEMREGION_PERSISTENT_FAST_COEF].Size = 0;
457     }
458 
459     InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_TEMPORARY_FAST],
460                         AlgScratchSize);
461     pMemoryTable->Region[LVM_MEMREGION_TEMPORARY_FAST].Size             = InstAlloc_GetTotal(&AllocMem[LVM_MEMREGION_TEMPORARY_FAST]);
462     pMemoryTable->Region[LVM_MEMREGION_TEMPORARY_FAST].Type             = LVM_TEMPORARY_FAST;
463     pMemoryTable->Region[LVM_MEMREGION_TEMPORARY_FAST].pBaseAddress     = LVM_NULL;
464     if (pMemoryTable->Region[LVM_MEMREGION_TEMPORARY_FAST].Size < 4)
465     {
466         pMemoryTable->Region[LVM_MEMREGION_TEMPORARY_FAST].Size = 0;
467     }
468 
469     return(LVM_SUCCESS);
470 
471 }
472 
473 /****************************************************************************************/
474 /*                                                                                      */
475 /* FUNCTION:                LVM_GetInstanceHandle                                       */
476 /*                                                                                      */
477 /* DESCRIPTION:                                                                         */
478 /*  This function is used to create a bundle instance. It returns the created instance  */
479 /*  handle through phInstance. All parameters are set to their default, inactive state. */
480 /*                                                                                      */
481 /* PARAMETERS:                                                                          */
482 /*  phInstance              pointer to the instance handle                              */
483 /*  pMemoryTable            Pointer to the memory definition table                      */
484 /*  pInstParams             Pointer to the initialisation capabilities                  */
485 /*                                                                                      */
486 /* RETURNS:                                                                             */
487 /*  LVM_SUCCESS             Initialisation succeeded                                    */
488 /*  LVM_OUTOFRANGE          When any of the Instance parameters are out of range        */
489 /*  LVM_NULLADDRESS         When one of phInstance, pMemoryTable or pInstParams are NULL*/
490 /*                                                                                      */
491 /* NOTES:                                                                               */
492 /*  1. This function must not be interrupted by the LVM_Process function                */
493 /*                                                                                      */
494 /****************************************************************************************/
495 
LVM_GetInstanceHandle(LVM_Handle_t * phInstance,LVM_MemTab_t * pMemoryTable,LVM_InstParams_t * pInstParams)496 LVM_ReturnStatus_en LVM_GetInstanceHandle(LVM_Handle_t           *phInstance,
497                                           LVM_MemTab_t           *pMemoryTable,
498                                           LVM_InstParams_t       *pInstParams)
499 {
500 
501     LVM_ReturnStatus_en     Status = LVM_SUCCESS;
502     LVM_Instance_t          *pInstance;
503     INST_ALLOC              AllocMem[LVM_NR_MEMORY_REGIONS];
504     LVM_INT16               i;
505     LVM_UINT16              InternalBlockSize;
506     LVM_INT32               BundleScratchSize;
507 
508     /*
509      * Check valid points have been given
510      */
511     if ((phInstance == LVM_NULL) || (pMemoryTable == LVM_NULL) || (pInstParams == LVM_NULL))
512     {
513         return (LVM_NULLADDRESS);
514     }
515 
516     /*
517      * Check the memory table for NULL pointers
518      */
519     for (i=0; i<LVM_NR_MEMORY_REGIONS; i++)
520     {
521         if ((pMemoryTable->Region[i].Size != 0) &&
522             (pMemoryTable->Region[i].pBaseAddress==LVM_NULL))
523         {
524             return(LVM_NULLADDRESS);
525         }
526     }
527 
528     /*
529      * Check the instance parameters
530      */
531     if( (pInstParams->BufferMode != LVM_MANAGED_BUFFERS) && (pInstParams->BufferMode != LVM_UNMANAGED_BUFFERS) )
532     {
533         return (LVM_OUTOFRANGE);
534     }
535 
536     if( pInstParams->EQNB_NumBands > 32 )
537     {
538         return (LVM_OUTOFRANGE);
539     }
540 
541     if(pInstParams->BufferMode == LVM_MANAGED_BUFFERS)
542     {
543         if( (pInstParams->MaxBlockSize < LVM_MIN_MAXBLOCKSIZE ) || (pInstParams->MaxBlockSize > LVM_MANAGED_MAX_MAXBLOCKSIZE ) )
544         {
545             return (LVM_OUTOFRANGE);
546         }
547     }
548     else
549     {
550         if( (pInstParams->MaxBlockSize < LVM_MIN_MAXBLOCKSIZE ) || (pInstParams->MaxBlockSize > LVM_UNMANAGED_MAX_MAXBLOCKSIZE) )
551         {
552             return (LVM_OUTOFRANGE);
553         }
554     }
555 
556     if(pInstParams->PSA_Included > LVM_PSA_ON)
557     {
558         return (LVM_OUTOFRANGE);
559     }
560 
561     /*
562      * Initialise the AllocMem structures
563      */
564     for (i=0; i<LVM_NR_MEMORY_REGIONS; i++)
565     {
566         InstAlloc_Init(&AllocMem[i],
567                        pMemoryTable->Region[i].pBaseAddress);
568     }
569 
570     /*
571      * Set the instance handle
572      */
573     *phInstance  = (LVM_Handle_t)InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_SLOW_DATA],
574                                                      sizeof(LVM_Instance_t));
575     pInstance =(LVM_Instance_t  *)*phInstance;
576 
577     /*
578      * Save the memory table, parameters and capabilities
579      */
580     pInstance->MemoryTable    = *pMemoryTable;
581     pInstance->InstParams     = *pInstParams;
582 
583     /*
584      * Set the bundle scratch memory and initialse the buffer management
585      */
586     InternalBlockSize = (LVM_UINT16)((pInstParams->MaxBlockSize) & MIN_INTERNAL_BLOCKMASK); /* Force to a multiple of MIN_INTERNAL_BLOCKSIZE */
587     if (InternalBlockSize < MIN_INTERNAL_BLOCKSIZE)
588     {
589         InternalBlockSize = MIN_INTERNAL_BLOCKSIZE;
590     }
591 
592     /* Maximum Internal Black Size should not be more than MAX_INTERNAL_BLOCKSIZE*/
593     if(InternalBlockSize > MAX_INTERNAL_BLOCKSIZE)
594     {
595         InternalBlockSize = MAX_INTERNAL_BLOCKSIZE;
596     }
597     pInstance->InternalBlockSize = (LVM_INT16)InternalBlockSize;
598 
599     /*
600      * Common settings for managed and unmanaged buffers
601      */
602     pInstance->SamplesToProcess = 0;                /* No samples left to process */
603     if (pInstParams->BufferMode == LVM_MANAGED_BUFFERS)
604     {
605         /*
606          * Managed buffers required
607          */
608         pInstance->pBufferManagement = (LVM_Buffer_t *)
609             InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_SLOW_DATA],
610                                                            sizeof(LVM_Buffer_t));
611         BundleScratchSize = (LVM_INT32)
612                             (3 * LVM_MAX_CHANNELS \
613                              * (MIN_INTERNAL_BLOCKSIZE + InternalBlockSize) \
614                              * sizeof(LVM_FLOAT));
615         pInstance->pBufferManagement->pScratch = (LVM_FLOAT *)
616             InstAlloc_AddMember(
617                          &AllocMem[LVM_MEMREGION_TEMPORARY_FAST], /* Scratch 1 buffer */
618                                                   (LVM_UINT32)BundleScratchSize);
619         LoadConst_Float(0,                                   /* Clear the input delay buffer */
620                         (LVM_FLOAT *)&pInstance->pBufferManagement->InDelayBuffer,
621                         (LVM_INT16)(LVM_MAX_CHANNELS * MIN_INTERNAL_BLOCKSIZE));
622         pInstance->pBufferManagement->InDelaySamples = MIN_INTERNAL_BLOCKSIZE; /* Set the number of delay samples */
623         pInstance->pBufferManagement->OutDelaySamples = 0;                     /* No samples in the output buffer */
624         pInstance->pBufferManagement->BufferState = LVM_FIRSTCALL;             /* Set the state ready for the first call */
625     }
626 
627     /*
628      * Set default parameters
629      */
630     pInstance->Params.OperatingMode    = LVM_MODE_OFF;
631     pInstance->Params.SampleRate       = LVM_FS_8000;
632     pInstance->Params.SourceFormat     = LVM_MONO;
633     pInstance->Params.SpeakerType      = LVM_HEADPHONES;
634     pInstance->Params.VC_EffectLevel   = 0;
635     pInstance->Params.VC_Balance       = 0;
636 
637     /*
638      * Set callback
639      */
640     pInstance->CallBack = LVM_AlgoCallBack;
641 
642     /*
643      * DC removal filter
644      */
645 #ifdef SUPPORT_MC
646     DC_Mc_D16_TRC_WRA_01_Init(&pInstance->DC_RemovalInstance);
647 #else
648     DC_2I_D16_TRC_WRA_01_Init(&pInstance->DC_RemovalInstance);
649 #endif
650 
651     /*
652      * Treble Enhancement
653      */
654     pInstance->pTE_Taps  = (LVM_TE_Data_t *)InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_DATA],
655                                                                 sizeof(LVM_TE_Data_t));
656 
657     pInstance->pTE_State = (LVM_TE_Coefs_t *)InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_COEF],
658                                                                  sizeof(LVM_TE_Coefs_t));
659     pInstance->Params.TE_OperatingMode = LVM_TE_OFF;
660     pInstance->Params.TE_EffectLevel   = 0;
661     pInstance->TE_Active               = LVM_FALSE;
662 
663     /*
664      * Set the volume control and initialise Current to Target
665      */
666     pInstance->VC_Volume.MixerStream[0].CallbackParam      = 0;
667     pInstance->VC_Volume.MixerStream[0].CallbackSet        = 0;
668     pInstance->VC_Volume.MixerStream[0].pCallbackHandle    = pInstance;
669     pInstance->VC_Volume.MixerStream[0].pCallBack          = LVM_VCCallBack;
670 
671     /* In managed buffering, start with low signal level as delay in buffer management causes a click*/
672     if (pInstParams->BufferMode == LVM_MANAGED_BUFFERS)
673     {
674         LVC_Mixer_Init(&pInstance->VC_Volume.MixerStream[0], 0, 0);
675     }
676     else
677     {
678         LVC_Mixer_Init(&pInstance->VC_Volume.MixerStream[0], LVM_MAXFLOAT, LVM_MAXFLOAT);
679     }
680 
681     LVC_Mixer_SetTimeConstant(&pInstance->VC_Volume.MixerStream[0],0,LVM_FS_8000,2);
682 
683     pInstance->VC_VolumedB                  = 0;
684     pInstance->VC_AVLFixedVolume            = 0;
685     pInstance->VC_Active                    = LVM_FALSE;
686 
687     pInstance->VC_BalanceMix.MixerStream[0].CallbackParam      = 0;
688     pInstance->VC_BalanceMix.MixerStream[0].CallbackSet        = 0;
689     pInstance->VC_BalanceMix.MixerStream[0].pCallbackHandle    = pInstance;
690     pInstance->VC_BalanceMix.MixerStream[0].pCallBack          = LVM_VCCallBack;
691     LVC_Mixer_Init(&pInstance->VC_BalanceMix.MixerStream[0], LVM_MAXFLOAT, LVM_MAXFLOAT);
692     LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[0],LVM_VC_MIXER_TIME,LVM_FS_8000,2);
693 
694     pInstance->VC_BalanceMix.MixerStream[1].CallbackParam      = 0;
695     pInstance->VC_BalanceMix.MixerStream[1].CallbackSet        = 0;
696     pInstance->VC_BalanceMix.MixerStream[1].pCallbackHandle    = pInstance;
697     pInstance->VC_BalanceMix.MixerStream[1].pCallBack          = LVM_VCCallBack;
698     LVC_Mixer_Init(&pInstance->VC_BalanceMix.MixerStream[1], LVM_MAXFLOAT, LVM_MAXFLOAT);
699     LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[1],LVM_VC_MIXER_TIME,LVM_FS_8000,2);
700 
701     /*
702      * Set the default EQNB pre-gain and pointer to the band definitions
703      */
704     pInstance->pEQNB_BandDefs =
705         (LVM_EQNB_BandDef_t *)InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_DATA],
706                                    (pInstParams->EQNB_NumBands * sizeof(LVM_EQNB_BandDef_t)));
707     pInstance->pEQNB_UserDefs =
708         (LVM_EQNB_BandDef_t *)InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_DATA],
709                                    (pInstParams->EQNB_NumBands * sizeof(LVM_EQNB_BandDef_t)));
710 
711     /*
712      * Initialise the Concert Sound module
713      */
714     {
715         LVCS_Handle_t           hCSInstance;                /* Instance handle */
716         LVCS_MemTab_t           CS_MemTab;                  /* Memory table */
717         LVCS_Capabilities_t     CS_Capabilities;            /* Initial capabilities */
718         LVCS_ReturnStatus_en    LVCS_Status;                /* Function call status */
719 
720         /*
721          * Set default parameters
722          */
723         pInstance->Params.VirtualizerReverbLevel    = 100;
724         pInstance->Params.VirtualizerType           = LVM_CONCERTSOUND;
725         pInstance->Params.VirtualizerOperatingMode  = LVM_MODE_OFF;
726         pInstance->CS_Active                        = LVM_FALSE;
727 
728         /*
729          * Set the initialisation capabilities
730          */
731         CS_Capabilities.MaxBlockSize    = (LVM_UINT16)InternalBlockSize;
732         CS_Capabilities.CallBack = pInstance->CallBack;
733         CS_Capabilities.pBundleInstance = (void*)pInstance;
734 
735         /*
736          * Get the memory requirements and then set the address pointers, forcing alignment
737          */
738         LVCS_Status = LVCS_Memory(LVM_NULL,                /* Get the memory requirements */
739                                   &CS_MemTab,
740                                   &CS_Capabilities);
741         CS_MemTab.Region[LVCS_MEMREGION_PERSISTENT_SLOW_DATA].pBaseAddress = &pInstance->CS_Instance;
742         CS_MemTab.Region[LVCS_MEMREGION_PERSISTENT_FAST_DATA].pBaseAddress = (void *)InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_DATA],
743                                                                                                          CS_MemTab.Region[LVCS_MEMREGION_PERSISTENT_FAST_DATA].Size);
744         CS_MemTab.Region[LVCS_MEMREGION_PERSISTENT_FAST_COEF].pBaseAddress = (void *)InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_COEF],
745                                                                                                          CS_MemTab.Region[LVCS_MEMREGION_PERSISTENT_FAST_COEF].Size);
746         CS_MemTab.Region[LVCS_MEMREGION_TEMPORARY_FAST].pBaseAddress       = (void *)InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_TEMPORARY_FAST],
747                                                                                                          0);
748 
749         /*
750          * Initialise the Concert Sound instance and save the instance handle
751          */
752         hCSInstance = LVM_NULL;                            /* Set to NULL to return handle */
753         LVCS_Status = LVCS_Init(&hCSInstance,              /* Initiailse */
754                                 &CS_MemTab,
755                                 &CS_Capabilities);
756         if (LVCS_Status != LVCS_SUCCESS) return((LVM_ReturnStatus_en)LVCS_Status);
757         pInstance->hCSInstance = hCSInstance;              /* Save the instance handle */
758 
759     }
760 
761     /*
762      * Initialise the Bass Enhancement module
763      */
764     {
765         LVDBE_Handle_t          hDBEInstance;               /* Instance handle */
766         LVDBE_MemTab_t          DBE_MemTab;                 /* Memory table */
767         LVDBE_Capabilities_t    DBE_Capabilities;           /* Initial capabilities */
768         LVDBE_ReturnStatus_en   LVDBE_Status;               /* Function call status */
769 
770         /*
771          * Set the initialisation parameters
772          */
773         pInstance->Params.BE_OperatingMode = LVM_BE_OFF;
774         pInstance->Params.BE_CentreFreq    = LVM_BE_CENTRE_55Hz;
775         pInstance->Params.BE_EffectLevel   = 0;
776         pInstance->Params.BE_HPF           = LVM_BE_HPF_OFF;
777 
778         pInstance->DBE_Active              = LVM_FALSE;
779 
780         /*
781          * Set the initialisation capabilities
782          */
783         DBE_Capabilities.SampleRate      = LVDBE_CAP_FS_8000 | LVDBE_CAP_FS_11025 |
784                                            LVDBE_CAP_FS_12000 | LVDBE_CAP_FS_16000 |
785                                            LVDBE_CAP_FS_22050 | LVDBE_CAP_FS_24000 |
786                                            LVDBE_CAP_FS_32000 | LVDBE_CAP_FS_44100 |
787                                            LVDBE_CAP_FS_48000 | LVDBE_CAP_FS_88200 |
788                                            LVDBE_CAP_FS_96000 | LVDBE_CAP_FS_176400 |
789                                            LVDBE_CAP_FS_192000;
790         DBE_Capabilities.CentreFrequency = LVDBE_CAP_CENTRE_55Hz | LVDBE_CAP_CENTRE_55Hz | LVDBE_CAP_CENTRE_66Hz | LVDBE_CAP_CENTRE_78Hz | LVDBE_CAP_CENTRE_90Hz;
791         DBE_Capabilities.MaxBlockSize    = (LVM_UINT16)InternalBlockSize;
792 
793         /*
794          * Get the memory requirements and then set the address pointers
795          */
796         LVDBE_Status = LVDBE_Memory(LVM_NULL,               /* Get the memory requirements */
797                                     &DBE_MemTab,
798                                     &DBE_Capabilities);
799         DBE_MemTab.Region[LVDBE_MEMREGION_INSTANCE].pBaseAddress        = &pInstance->DBE_Instance;
800         DBE_MemTab.Region[LVDBE_MEMREGION_PERSISTENT_DATA].pBaseAddress = (void *)InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_DATA],
801                                                                                                       DBE_MemTab.Region[LVDBE_MEMREGION_PERSISTENT_DATA].Size);
802         DBE_MemTab.Region[LVDBE_MEMREGION_PERSISTENT_COEF].pBaseAddress = (void *)InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_COEF],
803                                                                                                       DBE_MemTab.Region[LVDBE_MEMREGION_PERSISTENT_COEF].Size);
804         DBE_MemTab.Region[LVDBE_MEMREGION_SCRATCH].pBaseAddress         = (void *)InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_TEMPORARY_FAST],
805                                                                                                       0);
806 
807         /*
808          * Initialise the Dynamic Bass Enhancement instance and save the instance handle
809          */
810         hDBEInstance = LVM_NULL;                            /* Set to NULL to return handle */
811         LVDBE_Status = LVDBE_Init(&hDBEInstance,            /* Initiailse */
812                                   &DBE_MemTab,
813                                   &DBE_Capabilities);
814         if (LVDBE_Status != LVDBE_SUCCESS) return((LVM_ReturnStatus_en)LVDBE_Status);
815         pInstance->hDBEInstance = hDBEInstance;             /* Save the instance handle */
816     }
817 
818     /*
819      * Initialise the N-Band Equaliser module
820      */
821     {
822         LVEQNB_Handle_t          hEQNBInstance;             /* Instance handle */
823         LVEQNB_MemTab_t          EQNB_MemTab;               /* Memory table */
824         LVEQNB_Capabilities_t    EQNB_Capabilities;         /* Initial capabilities */
825         LVEQNB_ReturnStatus_en   LVEQNB_Status;             /* Function call status */
826 
827         /*
828          * Set the initialisation parameters
829          */
830         pInstance->Params.EQNB_OperatingMode   = LVM_EQNB_OFF;
831         pInstance->Params.EQNB_NBands          = 0;
832         pInstance->Params.pEQNB_BandDefinition = LVM_NULL;
833         pInstance->EQNB_Active                 = LVM_FALSE;
834 
835         /*
836          * Set the initialisation capabilities
837          */
838         EQNB_Capabilities.SampleRate      = LVEQNB_CAP_FS_8000 | LVEQNB_CAP_FS_11025 |
839                                             LVEQNB_CAP_FS_12000 | LVEQNB_CAP_FS_16000 |
840                                             LVEQNB_CAP_FS_22050 | LVEQNB_CAP_FS_24000 |
841                                             LVEQNB_CAP_FS_32000 | LVEQNB_CAP_FS_44100 |
842                                             LVEQNB_CAP_FS_48000 | LVEQNB_CAP_FS_88200 |
843                                             LVEQNB_CAP_FS_96000 | LVEQNB_CAP_FS_176400 |
844                                             LVEQNB_CAP_FS_192000;
845         EQNB_Capabilities.MaxBlockSize    = (LVM_UINT16)InternalBlockSize;
846         EQNB_Capabilities.MaxBands        = pInstParams->EQNB_NumBands;
847         EQNB_Capabilities.SourceFormat    = LVEQNB_CAP_STEREO | LVEQNB_CAP_MONOINSTEREO;
848         EQNB_Capabilities.CallBack        = pInstance->CallBack;
849         EQNB_Capabilities.pBundleInstance  = (void*)pInstance;
850 
851         /*
852          * Get the memory requirements and then set the address pointers, forcing alignment
853          */
854         LVEQNB_Status = LVEQNB_Memory(LVM_NULL,             /* Get the memory requirements */
855                                       &EQNB_MemTab,
856                                       &EQNB_Capabilities);
857         EQNB_MemTab.Region[LVEQNB_MEMREGION_INSTANCE].pBaseAddress        = &pInstance->EQNB_Instance;
858         EQNB_MemTab.Region[LVEQNB_MEMREGION_PERSISTENT_DATA].pBaseAddress = (void *)InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_DATA],
859                                                                                                         EQNB_MemTab.Region[LVEQNB_MEMREGION_PERSISTENT_DATA].Size);
860         EQNB_MemTab.Region[LVEQNB_MEMREGION_PERSISTENT_COEF].pBaseAddress = (void *)InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_COEF],
861                                                                                                         EQNB_MemTab.Region[LVEQNB_MEMREGION_PERSISTENT_COEF].Size);
862         EQNB_MemTab.Region[LVEQNB_MEMREGION_SCRATCH].pBaseAddress         = (void *)InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_TEMPORARY_FAST],
863                                                                                                         0);
864 
865         /*
866          * Initialise the Dynamic Bass Enhancement instance and save the instance handle
867          */
868         hEQNBInstance = LVM_NULL;                           /* Set to NULL to return handle */
869         LVEQNB_Status = LVEQNB_Init(&hEQNBInstance,         /* Initiailse */
870                                     &EQNB_MemTab,
871                                     &EQNB_Capabilities);
872         if (LVEQNB_Status != LVEQNB_SUCCESS) return((LVM_ReturnStatus_en)LVEQNB_Status);
873         pInstance->hEQNBInstance = hEQNBInstance;           /* Save the instance handle */
874     }
875 
876     /*
877      * Headroom management memory allocation
878      */
879     {
880         pInstance->pHeadroom_BandDefs = (LVM_HeadroomBandDef_t *)
881               InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_DATA],
882                                        (LVM_HEADROOM_MAX_NBANDS * sizeof(LVM_HeadroomBandDef_t)));
883         pInstance->pHeadroom_UserDefs = (LVM_HeadroomBandDef_t *)
884               InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_DATA],
885                                        (LVM_HEADROOM_MAX_NBANDS * sizeof(LVM_HeadroomBandDef_t)));
886 
887         /* Headroom management parameters initialisation */
888         pInstance->NewHeadroomParams.NHeadroomBands = 2;
889         pInstance->NewHeadroomParams.pHeadroomDefinition = pInstance->pHeadroom_BandDefs;
890         pInstance->NewHeadroomParams.pHeadroomDefinition[0].Limit_Low          = 20;
891         pInstance->NewHeadroomParams.pHeadroomDefinition[0].Limit_High         = 4999;
892         pInstance->NewHeadroomParams.pHeadroomDefinition[0].Headroom_Offset    = 3;
893         pInstance->NewHeadroomParams.pHeadroomDefinition[1].Limit_Low          = 5000;
894         pInstance->NewHeadroomParams.pHeadroomDefinition[1].Limit_High         = 24000;
895         pInstance->NewHeadroomParams.pHeadroomDefinition[1].Headroom_Offset    = 4;
896         pInstance->NewHeadroomParams.Headroom_OperatingMode = LVM_HEADROOM_ON;
897 
898         pInstance->Headroom =0;
899     }
900 
901     /*
902      * Initialise the PSA module
903      */
904     {
905         pLVPSA_Handle_t     hPSAInstance = LVM_NULL;   /* Instance handle */
906         LVPSA_MemTab_t      PSA_MemTab;
907         LVPSA_RETURN        PSA_Status;                 /* Function call status */
908         LVPSA_FilterParam_t FiltersParams[9];
909 
910         if(pInstParams->PSA_Included==LVM_PSA_ON)
911         {
912             pInstance->PSA_InitParams.SpectralDataBufferDuration   = (LVM_UINT16) 500;
913             pInstance->PSA_InitParams.MaxInputBlockSize            = (LVM_UINT16) 2048;
914             pInstance->PSA_InitParams.nBands                       = (LVM_UINT16) 9;
915             pInstance->PSA_InitParams.pFiltersParams               = &FiltersParams[0];
916             for(i = 0; i < pInstance->PSA_InitParams.nBands; i++)
917             {
918                 FiltersParams[i].CenterFrequency    = (LVM_UINT16) 1000;
919                 FiltersParams[i].QFactor            = (LVM_UINT16) 100;
920                 FiltersParams[i].PostGain           = (LVM_INT16)  0;
921             }
922 
923             /*Get the memory requirements and then set the address pointers*/
924             PSA_Status = LVPSA_Memory (hPSAInstance,
925                                           &PSA_MemTab,
926                                           &pInstance->PSA_InitParams);
927 
928             if (PSA_Status != LVPSA_OK)
929             {
930                 return((LVM_ReturnStatus_en) LVM_ALGORITHMPSA);
931             }
932 
933             /* Slow Data */
934             PSA_MemTab.Region[LVM_PERSISTENT_SLOW_DATA].pBaseAddress = (void *)InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_SLOW_DATA],
935                 PSA_MemTab.Region[LVM_PERSISTENT_SLOW_DATA].Size);
936 
937             /* Fast Data */
938             PSA_MemTab.Region[LVM_PERSISTENT_FAST_DATA].pBaseAddress = (void *)InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_DATA],
939                 PSA_MemTab.Region[LVM_PERSISTENT_FAST_DATA].Size);
940 
941             /* Fast Coef */
942             PSA_MemTab.Region[LVM_PERSISTENT_FAST_COEF].pBaseAddress = (void *)InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_PERSISTENT_FAST_COEF],
943                 PSA_MemTab.Region[LVM_PERSISTENT_FAST_COEF].Size);
944 
945             /* Fast Temporary */
946             pInstance->pPSAInput = (LVM_FLOAT *)InstAlloc_AddMember(&AllocMem[LVM_TEMPORARY_FAST],
947                                                        (LVM_UINT32) MAX_INTERNAL_BLOCKSIZE * \
948                                                        sizeof(LVM_FLOAT));
949             PSA_MemTab.Region[LVM_TEMPORARY_FAST].pBaseAddress       = (void *)InstAlloc_AddMember(&AllocMem[LVM_MEMREGION_TEMPORARY_FAST],0);
950 
951             /*Initialise PSA instance and save the instance handle*/
952             pInstance->PSA_ControlParams.Fs = LVM_FS_48000;
953             pInstance->PSA_ControlParams.LevelDetectionSpeed  = LVPSA_SPEED_MEDIUM;
954             PSA_Status = LVPSA_Init (&hPSAInstance,
955                                     &pInstance->PSA_InitParams,
956                                     &pInstance->PSA_ControlParams,
957                                     &PSA_MemTab);
958 
959             if (PSA_Status != LVPSA_OK)
960             {
961                 return((LVM_ReturnStatus_en) LVM_ALGORITHMPSA);
962             }
963 
964             pInstance->hPSAInstance = hPSAInstance;       /* Save the instance handle */
965             pInstance->PSA_GainOffset = 0;
966         }
967         else
968         {
969             pInstance->hPSAInstance = LVM_NULL;
970         }
971 
972         /*
973          * Set the initialisation parameters.
974          */
975         pInstance->Params.PSA_PeakDecayRate   = LVM_PSA_SPEED_MEDIUM;
976         pInstance->Params.PSA_Enable          = LVM_PSA_OFF;
977     }
978 
979     /*
980      * Copy the initial parameters to the new parameters for correct readback of
981      * the settings.
982      */
983     pInstance->NewParams = pInstance->Params;
984 
985     /*
986      * Create configuration number
987      */
988     pInstance->ConfigurationNumber = 0x00000000;
989     pInstance->ConfigurationNumber += LVM_CS_MASK;
990     pInstance->ConfigurationNumber += LVM_EQNB_MASK;
991     pInstance->ConfigurationNumber += LVM_DBE_MASK;
992     pInstance->ConfigurationNumber += LVM_VC_MASK;
993     pInstance->ConfigurationNumber += LVM_PSA_MASK;
994 
995     if(((pInstance->ConfigurationNumber  & LVM_CS_MASK)!=0)  ||
996         ((pInstance->ConfigurationNumber & LVM_DBE_MASK)!=0) ||
997         ((pInstance->ConfigurationNumber & LVM_EQNB_MASK)!=0)||
998         ((pInstance->ConfigurationNumber & LVM_TE_MASK)!=0)  ||
999         ((pInstance->ConfigurationNumber & LVM_VC_MASK)!=0))
1000     {
1001         pInstance->BlickSizeMultiple    = 4;
1002     }
1003     else
1004     {
1005         pInstance->BlickSizeMultiple    = 1;
1006     }
1007 
1008     return(Status);
1009 }
1010 
1011 /****************************************************************************************/
1012 /*                                                                                      */
1013 /* FUNCTION:                LVM_ClearAudioBuffers                                       */
1014 /*                                                                                      */
1015 /* DESCRIPTION:                                                                         */
1016 /*  This function is used to clear the internal audio buffers of the bundle.            */
1017 /*                                                                                      */
1018 /* PARAMETERS:                                                                          */
1019 /*  hInstance               Instance handle                                             */
1020 /*                                                                                      */
1021 /* RETURNS:                                                                             */
1022 /*  LVM_SUCCESS             Initialisation succeeded                                    */
1023 /*  LVM_NULLADDRESS         Instance or scratch memory has a NULL pointer               */
1024 /*                                                                                      */
1025 /* NOTES:                                                                               */
1026 /*  1. This function must not be interrupted by the LVM_Process function                */
1027 /*                                                                                      */
1028 /****************************************************************************************/
1029 
LVM_ClearAudioBuffers(LVM_Handle_t hInstance)1030 LVM_ReturnStatus_en LVM_ClearAudioBuffers(LVM_Handle_t  hInstance)
1031 {
1032     LVM_MemTab_t            MemTab;                                     /* Memory table */
1033     LVM_InstParams_t        InstParams;                                 /* Instance parameters */
1034     LVM_ControlParams_t     Params;                                     /* Control Parameters */
1035     LVM_Instance_t          *pInstance  = (LVM_Instance_t  *)hInstance; /* Pointer to Instance */
1036     LVM_HeadroomParams_t    HeadroomParams;
1037 
1038     if(hInstance == LVM_NULL){
1039         return LVM_NULLADDRESS;
1040     }
1041 
1042     /* Save the control parameters */ /* coverity[unchecked_value] */ /* Do not check return value internal function calls */
1043     LVM_GetControlParameters(hInstance, &Params);
1044 
1045     /*Save the headroom parameters*/
1046     LVM_GetHeadroomParams(hInstance, &HeadroomParams);
1047 
1048     /*  Retrieve allocated buffers in memtab */
1049     LVM_GetMemoryTable(hInstance, &MemTab,  LVM_NULL);
1050 
1051     /*  Save the instance parameters */
1052     InstParams = pInstance->InstParams;
1053 
1054     /*  Call  LVM_GetInstanceHandle to re-initialise the bundle */
1055     LVM_GetInstanceHandle( &hInstance,
1056                            &MemTab,
1057                            &InstParams);
1058 
1059     /* Restore control parameters */ /* coverity[unchecked_value] */ /* Do not check return value internal function calls */
1060     LVM_SetControlParameters(hInstance, &Params);
1061 
1062     /*Restore the headroom parameters*/
1063     LVM_SetHeadroomParams(hInstance, &HeadroomParams);
1064 
1065     /* DC removal filter */
1066 #ifdef SUPPORT_MC
1067     DC_Mc_D16_TRC_WRA_01_Init(&pInstance->DC_RemovalInstance);
1068 #else
1069     DC_2I_D16_TRC_WRA_01_Init(&pInstance->DC_RemovalInstance);
1070 #endif
1071 
1072     return LVM_SUCCESS;
1073 }
1074 
1075