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 
LVDBE_Memory(LVDBE_Handle_t hInstance,LVDBE_MemTab_t * pMemoryTable,LVDBE_Capabilities_t * pCapabilities)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 
LVDBE_Init(LVDBE_Handle_t * phInstance,LVDBE_MemTab_t * pMemoryTable,LVDBE_Capabilities_t * pCapabilities)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