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         pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_DATA].Size         = sizeof(LVDBE_Data_t);
84         pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_DATA].Alignment    = LVDBE_PERSISTENT_DATA_ALIGN;
85         pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_DATA].Type         = LVDBE_PERSISTENT_DATA;
86         pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_DATA].pBaseAddress = LVM_NULL;
87 
88         /*
89          * Coef memory
90          */
91         pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].Size         = sizeof(LVDBE_Coef_t);
92         pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].Alignment    = LVDBE_PERSISTENT_COEF_ALIGN;
93         pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].Type         = LVDBE_PERSISTENT_COEF;
94         pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].pBaseAddress = LVM_NULL;
95 
96         /*
97          * Scratch memory
98          */
99         ScratchSize = (LVM_UINT32)(LVDBE_SCRATCHBUFFERS_INPLACE*sizeof(LVM_INT16)*pCapabilities->MaxBlockSize);
100         pMemoryTable->Region[LVDBE_MEMREGION_SCRATCH].Size         = ScratchSize;
101         pMemoryTable->Region[LVDBE_MEMREGION_SCRATCH].Alignment    = LVDBE_SCRATCH_ALIGN;
102         pMemoryTable->Region[LVDBE_MEMREGION_SCRATCH].Type         = LVDBE_SCRATCH;
103         pMemoryTable->Region[LVDBE_MEMREGION_SCRATCH].pBaseAddress = LVM_NULL;
104     }
105     else
106     {
107         /* Read back memory allocation table */
108         *pMemoryTable = pInstance->MemoryTable;
109     }
110 
111     return(LVDBE_SUCCESS);
112 }
113 
114 
115 /****************************************************************************************/
116 /*                                                                                      */
117 /* FUNCTION:                 LVDBE_Init                                                 */
118 /*                                                                                      */
119 /* DESCRIPTION:                                                                         */
120 /*    Create and initialisation function for the Dynamic Bass Enhancement module        */
121 /*                                                                                      */
122 /*    This function can be used to create an algorithm instance by calling with         */
123 /*    hInstance set to NULL. In this case the algorithm returns the new instance        */
124 /*    handle.                                                                           */
125 /*                                                                                      */
126 /*    This function can be used to force a full re-initialisation of the algorithm      */
127 /*    by calling with hInstance = Instance Handle. In this case the memory table        */
128 /*    should be correct for the instance, this can be ensured by calling the function   */
129 /*    DBE_Memory before calling this function.                                          */
130 /*                                                                                      */
131 /* PARAMETERS:                                                                          */
132 /*  hInstance                  Instance handle                                          */
133 /*  pMemoryTable             Pointer to the memory definition table                     */
134 /*  pCapabilities              Pointer to the instance capabilities                     */
135 /*                                                                                      */
136 /* RETURNS:                                                                             */
137 /*  LVDBE_SUCCESS            Initialisation succeeded                                   */
138 /*  LVDBE_ALIGNMENTERROR    Instance or scratch memory on incorrect alignment           */
139 /*    LVDBE_NULLADDRESS        Instance or scratch memory has a NULL pointer            */
140 /*                                                                                      */
141 /* NOTES:                                                                               */
142 /*  1.     The instance handle is the pointer to the base address of the first memory   */
143 /*        region.                                                                       */
144 /*    2.    This function must not be interrupted by the LVDBE_Process function         */
145 /*                                                                                      */
146 /****************************************************************************************/
147 
LVDBE_Init(LVDBE_Handle_t * phInstance,LVDBE_MemTab_t * pMemoryTable,LVDBE_Capabilities_t * pCapabilities)148 LVDBE_ReturnStatus_en LVDBE_Init(LVDBE_Handle_t         *phInstance,
149                                    LVDBE_MemTab_t       *pMemoryTable,
150                                    LVDBE_Capabilities_t *pCapabilities)
151 {
152 
153     LVDBE_Instance_t      *pInstance;
154     LVMixer3_1St_st       *pMixer_Instance;
155     LVMixer3_2St_st       *pBypassMixer_Instance;
156     LVM_INT16             i;
157     LVM_INT32             MixGain;
158 
159 
160     /*
161      * Set the instance handle if not already initialised
162      */
163     if (*phInstance == LVM_NULL)
164     {
165         *phInstance = (LVDBE_Handle_t)pMemoryTable->Region[LVDBE_MEMREGION_INSTANCE].pBaseAddress;
166     }
167     pInstance =(LVDBE_Instance_t  *)*phInstance;
168 
169 
170     /*
171      * Check the memory table for NULL pointers and incorrectly aligned data
172      */
173     for (i=0; i<LVDBE_NR_MEMORY_REGIONS; i++)
174     {
175         if (pMemoryTable->Region[i].Size!=0)
176         {
177             if (pMemoryTable->Region[i].pBaseAddress==LVM_NULL)
178             {
179                 return(LVDBE_NULLADDRESS);
180             }
181             if (((uintptr_t)pMemoryTable->Region[i].pBaseAddress % pMemoryTable->Region[i].Alignment)!=0){
182                 return(LVDBE_ALIGNMENTERROR);
183             }
184         }
185     }
186 
187 
188     /*
189      * Save the memory table in the instance structure
190      */
191     pInstance->Capabilities = *pCapabilities;
192 
193 
194     /*
195      * Save the memory table in the instance structure
196      */
197     pInstance->MemoryTable = *pMemoryTable;
198 
199 
200     /*
201      * Set the default instance parameters
202      */
203     pInstance->Params.CentreFrequency   =    LVDBE_CENTRE_55HZ;
204     pInstance->Params.EffectLevel       =    0;
205     pInstance->Params.HeadroomdB        =    0;
206     pInstance->Params.HPFSelect         =    LVDBE_HPF_OFF;
207     pInstance->Params.OperatingMode     =    LVDBE_OFF;
208     pInstance->Params.SampleRate        =    LVDBE_FS_8000;
209     pInstance->Params.VolumeControl     =    LVDBE_VOLUME_OFF;
210     pInstance->Params.VolumedB          =    0;
211 
212 
213     /*
214      * Set pointer to data and coef memory
215      */
216     pInstance->pData = pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_DATA].pBaseAddress;
217     pInstance->pCoef = pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].pBaseAddress;
218 
219 
220     /*
221      * Initialise the filters
222      */
223     LVDBE_SetFilters(pInstance,                 /* Set the filter taps and coefficients */
224                      &pInstance->Params);
225 
226 
227     /*
228      * Initialise the AGC
229      */
230     LVDBE_SetAGC(pInstance,                                     /* Set the AGC gain */
231                  &pInstance->Params);
232     pInstance->pData->AGCInstance.AGC_Gain = pInstance->pData->AGCInstance.AGC_MaxGain;
233                                                 /* Default to the bass boost setting */
234 
235     // initialize the mixer with some fixes values since otherwise LVDBE_SetVolume ends up
236     // reading uninitialized data
237     pMixer_Instance = &pInstance->pData->BypassVolume;
238     LVC_Mixer_Init(&pMixer_Instance->MixerStream[0],0x00007FFF,0x00007FFF);
239 
240     /*
241      * Initialise the volume
242      */
243     LVDBE_SetVolume(pInstance,                                         /* Set the Volume */
244                     &pInstance->Params);
245 
246     pInstance->pData->AGCInstance.Volume = pInstance->pData->AGCInstance.Target;
247                                                 /* Initialise as the target */
248 
249     MixGain = LVC_Mixer_GetTarget(&pMixer_Instance->MixerStream[0]);
250     LVC_Mixer_Init(&pMixer_Instance->MixerStream[0],MixGain,MixGain);
251 
252     /* Configure the mixer process path */
253     pMixer_Instance->MixerStream[0].CallbackParam = 0;
254     pMixer_Instance->MixerStream[0].pCallbackHandle = LVM_NULL;
255     pMixer_Instance->MixerStream[0].pCallBack = LVM_NULL;
256     pMixer_Instance->MixerStream[0].CallbackSet = 0;
257 
258     /*
259      * Initialise the clicks minimisation BypassMixer
260      */
261 
262     pBypassMixer_Instance = &pInstance->pData->BypassMixer;
263 
264     /*
265      * Setup the mixer gain for the processed path
266      */
267     pBypassMixer_Instance->MixerStream[0].CallbackParam = 0;
268     pBypassMixer_Instance->MixerStream[0].pCallbackHandle = LVM_NULL;
269     pBypassMixer_Instance->MixerStream[0].pCallBack = LVM_NULL;
270     pBypassMixer_Instance->MixerStream[0].CallbackSet=0;
271     LVC_Mixer_Init(&pBypassMixer_Instance->MixerStream[0],0,0);
272     LVC_Mixer_SetTimeConstant(&pBypassMixer_Instance->MixerStream[0],
273         LVDBE_BYPASS_MIXER_TC,pInstance->Params.SampleRate,2);
274     /*
275      * Setup the mixer gain for the unprocessed path
276      */
277     pBypassMixer_Instance->MixerStream[1].CallbackParam = 0;
278     pBypassMixer_Instance->MixerStream[1].pCallbackHandle = LVM_NULL;
279     pBypassMixer_Instance->MixerStream[1].pCallBack = LVM_NULL;
280     pBypassMixer_Instance->MixerStream[1].CallbackSet=0;
281     LVC_Mixer_Init(&pBypassMixer_Instance->MixerStream[1],0x00007FFF,0x00007FFF);
282     LVC_Mixer_SetTimeConstant(&pBypassMixer_Instance->MixerStream[1],
283         LVDBE_BYPASS_MIXER_TC,pInstance->Params.SampleRate,2);
284 
285     return(LVDBE_SUCCESS);
286 }
287 
288