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 #include "LVREV_Private.h"
24 #include "InstAlloc.h"
25
26 /****************************************************************************************/
27 /* */
28 /* FUNCTION: LVREV_GetInstanceHandle */
29 /* */
30 /* DESCRIPTION: */
31 /* This function is used to create a LVREV module instance. It returns the created */
32 /* instance handle through phInstance. All parameters are set to their default, */
33 /* inactive state. */
34 /* */
35 /* PARAMETERS: */
36 /* phInstance pointer to the instance handle */
37 /* pMemoryTable Pointer to the memory definition table */
38 /* pInstanceParams Pointer to the instance parameters */
39 /* */
40 /* RETURNS: */
41 /* LVREV_SUCCESS Succeeded */
42 /* LVREV_NULLADDRESS When phInstance or pMemoryTable or pInstanceParams is NULL */
43 /* LVREV_NULLADDRESS When one of the memory regions has a NULL pointer */
44 /* */
45 /* NOTES: */
46 /* */
47 /****************************************************************************************/
LVREV_GetInstanceHandle(LVREV_Handle_t * phInstance,LVREV_MemoryTable_st * pMemoryTable,LVREV_InstanceParams_st * pInstanceParams)48 LVREV_ReturnStatus_en LVREV_GetInstanceHandle(LVREV_Handle_t *phInstance,
49 LVREV_MemoryTable_st *pMemoryTable,
50 LVREV_InstanceParams_st *pInstanceParams)
51 {
52
53 INST_ALLOC SlowData;
54 INST_ALLOC FastData;
55 INST_ALLOC FastCoef;
56 INST_ALLOC Temporary;
57 LVREV_Instance_st *pLVREV_Private;
58 LVM_INT16 i;
59 LVM_UINT16 MaxBlockSize;
60
61 /*
62 * Check for error conditions
63 */
64 /* Check for NULL pointers */
65 if((phInstance == LVM_NULL) || (pMemoryTable == LVM_NULL) || (pInstanceParams == LVM_NULL))
66 {
67 return LVREV_NULLADDRESS;
68 }
69 /* Check the memory table for NULL pointers */
70 for (i = 0; i < LVREV_NR_MEMORY_REGIONS; i++)
71 {
72 if (pMemoryTable->Region[i].Size!=0)
73 {
74 if (pMemoryTable->Region[i].pBaseAddress==LVM_NULL)
75 {
76 return(LVREV_NULLADDRESS);
77 }
78 }
79 }
80
81 /*
82 * Check all instance parameters are in range
83 */
84 /* Check for a non-zero block size */
85 if (pInstanceParams->MaxBlockSize == 0)
86 {
87 return LVREV_OUTOFRANGE;
88 }
89
90 /* Check for a valid number of delay lines */
91 if ((pInstanceParams->NumDelays != LVREV_DELAYLINES_1)&&
92 (pInstanceParams->NumDelays != LVREV_DELAYLINES_2)&&
93 (pInstanceParams->NumDelays != LVREV_DELAYLINES_4))
94 {
95 return LVREV_OUTOFRANGE;
96 }
97
98 /*
99 * Initialise the InstAlloc instances
100 */
101 InstAlloc_Init(&SlowData, pMemoryTable->Region[LVM_PERSISTENT_SLOW_DATA].pBaseAddress);
102 InstAlloc_Init(&FastData, pMemoryTable->Region[LVM_PERSISTENT_FAST_DATA].pBaseAddress);
103 InstAlloc_Init(&FastCoef, pMemoryTable->Region[LVM_PERSISTENT_FAST_COEF].pBaseAddress);
104 InstAlloc_Init(&Temporary, pMemoryTable->Region[LVM_TEMPORARY_FAST].pBaseAddress);
105
106 /*
107 * Zero all memory regions
108 */
109 LoadConst_Float(0,
110 (LVM_FLOAT *)pMemoryTable->Region[LVM_PERSISTENT_SLOW_DATA].pBaseAddress,
111 (LVM_INT16)((pMemoryTable->Region[LVM_PERSISTENT_SLOW_DATA].Size) / \
112 sizeof(LVM_FLOAT)));
113 LoadConst_Float(0,
114 (LVM_FLOAT *)pMemoryTable->Region[LVM_PERSISTENT_FAST_DATA].pBaseAddress,
115 (LVM_INT16)((pMemoryTable->Region[LVM_PERSISTENT_FAST_DATA].Size) / \
116 sizeof(LVM_FLOAT)));
117 LoadConst_Float(0,
118 (LVM_FLOAT *)pMemoryTable->Region[LVM_PERSISTENT_FAST_COEF].pBaseAddress,
119 (LVM_INT16)((pMemoryTable->Region[LVM_PERSISTENT_FAST_COEF].Size) / \
120 sizeof(LVM_FLOAT)));
121 LoadConst_Float(0,
122 (LVM_FLOAT *)pMemoryTable->Region[LVM_TEMPORARY_FAST].pBaseAddress,
123 (LVM_INT16)((pMemoryTable->Region[LVM_TEMPORARY_FAST].Size) / \
124 sizeof(LVM_FLOAT)));
125 /*
126 * Set the instance handle if not already initialised
127 */
128 if (*phInstance == LVM_NULL)
129 {
130 *phInstance = InstAlloc_AddMember(&SlowData, sizeof(LVREV_Instance_st));
131 }
132 pLVREV_Private =(LVREV_Instance_st *)*phInstance;
133 pLVREV_Private->MemoryTable = *pMemoryTable;
134
135 if(pInstanceParams->NumDelays ==LVREV_DELAYLINES_4)
136 {
137 MaxBlockSize = LVREV_MAX_AP3_DELAY;
138 }
139 else if(pInstanceParams->NumDelays ==LVREV_DELAYLINES_2)
140 {
141 MaxBlockSize = LVREV_MAX_AP1_DELAY;
142 }
143 else
144 {
145 MaxBlockSize = LVREV_MAX_AP0_DELAY;
146 }
147
148 if(MaxBlockSize>pInstanceParams->MaxBlockSize)
149 {
150 MaxBlockSize=pInstanceParams->MaxBlockSize;
151 }
152
153 /*
154 * Set the data, coefficient and temporary memory pointers
155 */
156 /* Fast data memory base address */
157 pLVREV_Private->pFastData = (LVREV_FastData_st *)
158 InstAlloc_AddMember(&FastData, sizeof(LVREV_FastData_st));
159 if(pInstanceParams->NumDelays == LVREV_DELAYLINES_4)
160 {
161 pLVREV_Private->pDelay_T[3] =
162 (LVM_FLOAT *)InstAlloc_AddMember(&FastData, LVREV_MAX_T3_DELAY * \
163 sizeof(LVM_FLOAT));
164 pLVREV_Private->pDelay_T[2] =
165 (LVM_FLOAT *)InstAlloc_AddMember(&FastData, LVREV_MAX_T2_DELAY * \
166 sizeof(LVM_FLOAT));
167 pLVREV_Private->pDelay_T[1] =
168 (LVM_FLOAT *)InstAlloc_AddMember(&FastData, LVREV_MAX_T1_DELAY * \
169 sizeof(LVM_FLOAT));
170 pLVREV_Private->pDelay_T[0] =
171 (LVM_FLOAT *)InstAlloc_AddMember(&FastData, LVREV_MAX_T0_DELAY * \
172 sizeof(LVM_FLOAT));
173
174 for(i = 0; i < 4; i++)
175 {
176 /* Scratch for each delay line output */
177 pLVREV_Private->pScratchDelayLine[i] = (LVM_FLOAT *)InstAlloc_AddMember(&Temporary,
178 sizeof(LVM_FLOAT) * \
179 MaxBlockSize);
180 }
181
182 LoadConst_Float(0, pLVREV_Private->pDelay_T[3], LVREV_MAX_T3_DELAY);
183 LoadConst_Float(0, pLVREV_Private->pDelay_T[2], LVREV_MAX_T2_DELAY);
184 LoadConst_Float(0, pLVREV_Private->pDelay_T[1], LVREV_MAX_T1_DELAY);
185 LoadConst_Float(0, pLVREV_Private->pDelay_T[0], LVREV_MAX_T0_DELAY);
186 }
187
188 if(pInstanceParams->NumDelays == LVREV_DELAYLINES_2)
189 {
190 pLVREV_Private->pDelay_T[1] = (LVM_FLOAT *)
191 InstAlloc_AddMember(&FastData, LVREV_MAX_T1_DELAY * \
192 sizeof(LVM_FLOAT));
193 pLVREV_Private->pDelay_T[0] = (LVM_FLOAT *)
194 InstAlloc_AddMember(&FastData, LVREV_MAX_T0_DELAY * \
195 sizeof(LVM_FLOAT));
196
197 for(i = 0; i < 2; i++)
198 {
199 /* Scratch for each delay line output */
200 pLVREV_Private->pScratchDelayLine[i] = (LVM_FLOAT *)InstAlloc_AddMember(&Temporary,
201 sizeof(LVM_FLOAT) * \
202 MaxBlockSize);
203 }
204
205 LoadConst_Float(0, pLVREV_Private->pDelay_T[1], (LVM_INT16)LVREV_MAX_T1_DELAY);
206 LoadConst_Float(0, pLVREV_Private->pDelay_T[0], (LVM_INT16)LVREV_MAX_T0_DELAY);
207 }
208
209 if(pInstanceParams->NumDelays == LVREV_DELAYLINES_1)
210 {
211 pLVREV_Private->pDelay_T[0] = (LVM_FLOAT *)InstAlloc_AddMember(&FastData,
212 LVREV_MAX_T0_DELAY * sizeof(LVM_FLOAT));
213
214 for(i = 0; i < 1; i++)
215 {
216 /* Scratch for each delay line output */
217 pLVREV_Private->pScratchDelayLine[i] = (LVM_FLOAT *)InstAlloc_AddMember(&Temporary,
218 sizeof(LVM_FLOAT) * \
219 MaxBlockSize);
220 }
221
222 LoadConst_Float(0, pLVREV_Private->pDelay_T[0], (LVM_INT16)LVREV_MAX_T0_DELAY);
223 }
224 /* All-pass delay buffer addresses and sizes */
225 pLVREV_Private->T[0] = LVREV_MAX_T0_DELAY;
226 pLVREV_Private->T[1] = LVREV_MAX_T1_DELAY;
227 pLVREV_Private->T[2] = LVREV_MAX_T2_DELAY;
228 pLVREV_Private->T[3] = LVREV_MAX_T3_DELAY;
229 pLVREV_Private->AB_Selection = 1; /* Select smoothing A to B */
230
231 /* Fast coefficient memory base address */
232 pLVREV_Private->pFastCoef =
233 (LVREV_FastCoef_st *)InstAlloc_AddMember(&FastCoef, sizeof(LVREV_FastCoef_st));
234 /* General purpose scratch */
235 pLVREV_Private->pScratch =
236 (LVM_FLOAT *)InstAlloc_AddMember(&Temporary, sizeof(LVM_FLOAT) * \
237 MaxBlockSize);
238 /* Mono->stereo input save for end mix */
239 pLVREV_Private->pInputSave =
240 (LVM_FLOAT *)InstAlloc_AddMember(&Temporary, 2 * sizeof(LVM_FLOAT) * \
241 MaxBlockSize);
242 LoadConst_Float(0, pLVREV_Private->pInputSave, (LVM_INT16)(MaxBlockSize * 2));
243
244 /*
245 * Save the instance parameters in the instance structure
246 */
247 pLVREV_Private->InstanceParams = *pInstanceParams;
248
249 /*
250 * Set the parameters to invalid
251 */
252 pLVREV_Private->CurrentParams.SampleRate = LVM_FS_INVALID;
253 pLVREV_Private->CurrentParams.OperatingMode = LVM_MODE_DUMMY;
254 pLVREV_Private->CurrentParams.SourceFormat = LVM_SOURCE_DUMMY;
255
256 pLVREV_Private->bControlPending = LVM_FALSE;
257 pLVREV_Private->bFirstControl = LVM_TRUE;
258 pLVREV_Private->bDisableReverb = LVM_FALSE;
259
260 /*
261 * Set mixer parameters
262 */
263 pLVREV_Private->BypassMixer.CallbackParam2 = 0;
264 pLVREV_Private->BypassMixer.pCallbackHandle2 = pLVREV_Private;
265 pLVREV_Private->BypassMixer.pGeneralPurpose2 = LVM_NULL;
266 pLVREV_Private->BypassMixer.pCallBack2 = BypassMixer_Callback;
267 pLVREV_Private->BypassMixer.CallbackSet2 = LVM_FALSE;
268 pLVREV_Private->BypassMixer.Current2 = 0;
269 pLVREV_Private->BypassMixer.Target2 = 0;
270 pLVREV_Private->BypassMixer.CallbackParam1 = 0;
271 pLVREV_Private->BypassMixer.pCallbackHandle1 = LVM_NULL;
272 pLVREV_Private->BypassMixer.pGeneralPurpose1 = LVM_NULL;
273 pLVREV_Private->BypassMixer.pCallBack1 = LVM_NULL;
274 pLVREV_Private->BypassMixer.CallbackSet1 = LVM_FALSE;
275 pLVREV_Private->BypassMixer.Current1 = 0x00000000;
276 pLVREV_Private->BypassMixer.Target1 = 0x00000000;
277
278 pLVREV_Private->RoomSizeInms = 100; // 100 msec
279
280 /*
281 * Set the output gain mixer parameters
282 */
283 pLVREV_Private->GainMixer.CallbackParam = 0;
284 pLVREV_Private->GainMixer.pCallbackHandle = LVM_NULL;
285 pLVREV_Private->GainMixer.pGeneralPurpose = LVM_NULL;
286 pLVREV_Private->GainMixer.pCallBack = LVM_NULL;
287 pLVREV_Private->GainMixer.CallbackSet = LVM_FALSE;
288 pLVREV_Private->GainMixer.Current = 0.03125f;//0x03ffffff;
289 pLVREV_Private->GainMixer.Target = 0.03125f;//0x03ffffff;
290
291 /*
292 * Set the All-Pass Filter mixers
293 */
294 for (i=0; i<4; i++)
295 {
296 pLVREV_Private->pOffsetA[i] = pLVREV_Private->pDelay_T[i];
297 pLVREV_Private->pOffsetB[i] = pLVREV_Private->pDelay_T[i];
298 /* Delay tap selection mixer */
299 pLVREV_Private->Mixer_APTaps[i].CallbackParam2 = 0;
300 pLVREV_Private->Mixer_APTaps[i].pCallbackHandle2 = LVM_NULL;
301 pLVREV_Private->Mixer_APTaps[i].pGeneralPurpose2 = LVM_NULL;
302 pLVREV_Private->Mixer_APTaps[i].pCallBack2 = LVM_NULL;
303 pLVREV_Private->Mixer_APTaps[i].CallbackSet2 = LVM_FALSE;
304 pLVREV_Private->Mixer_APTaps[i].Current2 = 0;
305 pLVREV_Private->Mixer_APTaps[i].Target2 = 0;
306 pLVREV_Private->Mixer_APTaps[i].CallbackParam1 = 0;
307 pLVREV_Private->Mixer_APTaps[i].pCallbackHandle1 = LVM_NULL;
308 pLVREV_Private->Mixer_APTaps[i].pGeneralPurpose1 = LVM_NULL;
309 pLVREV_Private->Mixer_APTaps[i].pCallBack1 = LVM_NULL;
310 pLVREV_Private->Mixer_APTaps[i].CallbackSet1 = LVM_FALSE;
311 pLVREV_Private->Mixer_APTaps[i].Current1 = 0;
312 pLVREV_Private->Mixer_APTaps[i].Target1 = 1;
313 /* Feedforward mixer */
314 pLVREV_Private->Mixer_SGFeedforward[i].CallbackParam = 0;
315 pLVREV_Private->Mixer_SGFeedforward[i].pCallbackHandle = LVM_NULL;
316 pLVREV_Private->Mixer_SGFeedforward[i].pGeneralPurpose = LVM_NULL;
317 pLVREV_Private->Mixer_SGFeedforward[i].pCallBack = LVM_NULL;
318 pLVREV_Private->Mixer_SGFeedforward[i].CallbackSet = LVM_FALSE;
319 pLVREV_Private->Mixer_SGFeedforward[i].Current = 0;
320 pLVREV_Private->Mixer_SGFeedforward[i].Target = 0;
321 /* Feedback mixer */
322 pLVREV_Private->Mixer_SGFeedback[i].CallbackParam = 0;
323 pLVREV_Private->Mixer_SGFeedback[i].pCallbackHandle = LVM_NULL;
324 pLVREV_Private->Mixer_SGFeedback[i].pGeneralPurpose = LVM_NULL;
325 pLVREV_Private->Mixer_SGFeedback[i].pCallBack = LVM_NULL;
326 pLVREV_Private->Mixer_SGFeedback[i].CallbackSet = LVM_FALSE;
327 pLVREV_Private->Mixer_SGFeedback[i].Current = 0;
328 pLVREV_Private->Mixer_SGFeedback[i].Target = 0;
329 /* Feedback gain mixer */
330 pLVREV_Private->FeedbackMixer[i].CallbackParam = 0;
331 pLVREV_Private->FeedbackMixer[i].pCallbackHandle = LVM_NULL;
332 pLVREV_Private->FeedbackMixer[i].pGeneralPurpose = LVM_NULL;
333 pLVREV_Private->FeedbackMixer[i].pCallBack = LVM_NULL;
334 pLVREV_Private->FeedbackMixer[i].CallbackSet = LVM_FALSE;
335 pLVREV_Private->FeedbackMixer[i].Current = 0;
336 pLVREV_Private->FeedbackMixer[i].Target = 0;
337 }
338 /* Delay tap index */
339 pLVREV_Private->A_DelaySize[0] = LVREV_MAX_AP0_DELAY;
340 pLVREV_Private->B_DelaySize[0] = LVREV_MAX_AP0_DELAY;
341 pLVREV_Private->A_DelaySize[1] = LVREV_MAX_AP1_DELAY;
342 pLVREV_Private->B_DelaySize[1] = LVREV_MAX_AP1_DELAY;
343 pLVREV_Private->A_DelaySize[2] = LVREV_MAX_AP2_DELAY;
344 pLVREV_Private->B_DelaySize[2] = LVREV_MAX_AP2_DELAY;
345 pLVREV_Private->A_DelaySize[3] = LVREV_MAX_AP3_DELAY;
346 pLVREV_Private->B_DelaySize[3] = LVREV_MAX_AP3_DELAY;
347
348 LVREV_ClearAudioBuffers(*phInstance);
349
350 return LVREV_SUCCESS;
351 }
352
353 /* End of file */
354