1 /*
2 * Copyright (C) 2004-2010 NXP Software
3 * Copyright (C) 2010 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18
19 /****************************************************************************************/
20 /* */
21 /* Includes */
22 /* */
23 /****************************************************************************************/
24
25 #include "LVM_Private.h"
26 #include "VectorArithmetic.h"
27 #include "LVM_Coeffs.h"
28
29 /****************************************************************************************/
30 /* */
31 /* FUNCTION: LVM_Process */
32 /* */
33 /* DESCRIPTION: */
34 /* Process function for the LifeVibes module. */
35 /* */
36 /* PARAMETERS: */
37 /* hInstance Instance handle */
38 /* pInData Pointer to the input data */
39 /* pOutData Pointer to the output data */
40 /* NumSamples Number of samples in the input buffer */
41 /* AudioTime Audio Time of the current input buffer in ms */
42 /* */
43 /* RETURNS: */
44 /* LVM_SUCCESS Succeeded */
45 /* LVM_INVALIDNUMSAMPLES When the NumSamples is not a valied multiple in unmanaged */
46 /* buffer mode */
47 /* LVM_ALIGNMENTERROR When either the input our output buffers are not 32-bit */
48 /* aligned in unmanaged mode */
49 /* LVM_NULLADDRESS When one of hInstance, pInData or pOutData is NULL */
50 /* */
51 /* NOTES: */
52 /* */
53 /****************************************************************************************/
54 #ifdef BUILD_FLOAT
LVM_Process(LVM_Handle_t hInstance,const LVM_FLOAT * pInData,LVM_FLOAT * pOutData,LVM_UINT16 NumSamples,LVM_UINT32 AudioTime)55 LVM_ReturnStatus_en LVM_Process(LVM_Handle_t hInstance,
56 const LVM_FLOAT *pInData,
57 LVM_FLOAT *pOutData,
58 LVM_UINT16 NumSamples,
59 LVM_UINT32 AudioTime)
60 {
61
62 LVM_Instance_t *pInstance = (LVM_Instance_t *)hInstance;
63 LVM_UINT16 SampleCount = NumSamples;
64 LVM_FLOAT *pInput = (LVM_FLOAT *)pInData;
65 LVM_FLOAT *pToProcess = (LVM_FLOAT *)pInData;
66 LVM_FLOAT *pProcessed = pOutData;
67 LVM_ReturnStatus_en Status;
68
69 /*
70 * Check if the number of samples is zero
71 */
72 if (NumSamples == 0)
73 {
74 return(LVM_SUCCESS);
75 }
76
77
78 /*
79 * Check valid points have been given
80 */
81 if ((hInstance == LVM_NULL) || (pInData == LVM_NULL) || (pOutData == LVM_NULL))
82 {
83 return (LVM_NULLADDRESS);
84 }
85
86 /*
87 * For unmanaged mode only
88 */
89 if(pInstance->InstParams.BufferMode == LVM_UNMANAGED_BUFFERS)
90 {
91 /*
92 * Check if the number of samples is a good multiple (unmanaged mode only)
93 */
94 if((NumSamples % pInstance->BlickSizeMultiple) != 0)
95 {
96 return(LVM_INVALIDNUMSAMPLES);
97 }
98
99 /*
100 * Check the buffer alignment
101 */
102 if((((uintptr_t)pInData % 4) != 0) || (((uintptr_t)pOutData % 4) != 0))
103 {
104 return(LVM_ALIGNMENTERROR);
105 }
106 }
107
108
109 /*
110 * Update new parameters if necessary
111 */
112 if (pInstance->ControlPending == LVM_TRUE)
113 {
114 Status = LVM_ApplyNewSettings(hInstance);
115
116 if(Status != LVM_SUCCESS)
117 {
118 return Status;
119 }
120 }
121
122
123 /*
124 * Convert from Mono if necessary
125 */
126 if (pInstance->Params.SourceFormat == LVM_MONO)
127 {
128 MonoTo2I_Float(pInData, /* Source */
129 pOutData, /* Destination */
130 (LVM_INT16)NumSamples); /* Number of input samples */
131 pInput = pOutData;
132 pToProcess = pOutData;
133 }
134
135
136 /*
137 * Process the data with managed buffers
138 */
139 while (SampleCount != 0)
140 {
141 /*
142 * Manage the input buffer and frame processing
143 */
144 LVM_BufferIn(hInstance,
145 pInput,
146 &pToProcess,
147 &pProcessed,
148 &SampleCount);
149
150 /*
151 * Only process data when SampleCount is none zero, a zero count can occur when
152 * the BufferIn routine is working in managed mode.
153 */
154 if (SampleCount != 0)
155 {
156
157 /*
158 * Apply ConcertSound if required
159 */
160 if (pInstance->CS_Active == LVM_TRUE)
161 {
162 (void)LVCS_Process(pInstance->hCSInstance, /* Concert Sound instance handle */
163 pToProcess,
164 pProcessed,
165 SampleCount);
166 pToProcess = pProcessed;
167 }
168
169 /*
170 * Apply volume if required
171 */
172 if (pInstance->VC_Active!=0)
173 {
174 LVC_MixSoft_1St_D16C31_SAT(&pInstance->VC_Volume,
175 pToProcess,
176 pProcessed,
177 (LVM_INT16)(2 * SampleCount)); /* Left and right*/
178 pToProcess = pProcessed;
179 }
180
181 /*
182 * Call N-Band equaliser if enabled
183 */
184 if (pInstance->EQNB_Active == LVM_TRUE)
185 {
186 LVEQNB_Process(pInstance->hEQNBInstance, /* N-Band equaliser instance handle */
187 pToProcess,
188 pProcessed,
189 SampleCount);
190 pToProcess = pProcessed;
191 }
192
193 /*
194 * Call bass enhancement if enabled
195 */
196 if (pInstance->DBE_Active == LVM_TRUE)
197 {
198 LVDBE_Process(pInstance->hDBEInstance, /* Dynamic Bass Enhancement \
199 instance handle */
200 pToProcess,
201 pProcessed,
202 SampleCount);
203 pToProcess = pProcessed;
204 }
205
206 /*
207 * Bypass mode or everything off, so copy the input to the output
208 */
209 if (pToProcess != pProcessed)
210 {
211 Copy_Float(pToProcess, /* Source */
212 pProcessed, /* Destination */
213 (LVM_INT16)(2 * SampleCount)); /* Left and right */
214 }
215
216 /*
217 * Apply treble boost if required
218 */
219 if (pInstance->TE_Active == LVM_TRUE)
220 {
221 /*
222 * Apply the filter
223 */
224 FO_2I_D16F32C15_LShx_TRC_WRA_01(&pInstance->pTE_State->TrebleBoost_State,
225 pProcessed,
226 pProcessed,
227 (LVM_INT16)SampleCount);
228
229 }
230
231 /*
232 * Volume balance
233 */
234 LVC_MixSoft_1St_2i_D16C31_SAT(&pInstance->VC_BalanceMix,
235 pProcessed,
236 pProcessed,
237 SampleCount);
238
239 /*
240 * Perform Parametric Spectum Analysis
241 */
242 if ((pInstance->Params.PSA_Enable == LVM_PSA_ON) &&
243 (pInstance->InstParams.PSA_Included == LVM_PSA_ON))
244 {
245 From2iToMono_Float(pProcessed,
246 pInstance->pPSAInput,
247 (LVM_INT16)(SampleCount));
248
249 LVPSA_Process(pInstance->hPSAInstance,
250 pInstance->pPSAInput,
251 (LVM_UINT16)(SampleCount),
252 AudioTime);
253 }
254
255
256 /*
257 * DC removal
258 */
259 DC_2I_D16_TRC_WRA_01(&pInstance->DC_RemovalInstance,
260 pProcessed,
261 pProcessed,
262 (LVM_INT16)SampleCount);
263
264
265 }
266
267 /*
268 * Manage the output buffer
269 */
270 LVM_BufferOut(hInstance,
271 pOutData,
272 &SampleCount);
273
274 }
275
276 return(LVM_SUCCESS);
277 }
278 #else
LVM_Process(LVM_Handle_t hInstance,const LVM_INT16 * pInData,LVM_INT16 * pOutData,LVM_UINT16 NumSamples,LVM_UINT32 AudioTime)279 LVM_ReturnStatus_en LVM_Process(LVM_Handle_t hInstance,
280 const LVM_INT16 *pInData,
281 LVM_INT16 *pOutData,
282 LVM_UINT16 NumSamples,
283 LVM_UINT32 AudioTime)
284 {
285
286 LVM_Instance_t *pInstance = (LVM_Instance_t *)hInstance;
287 LVM_UINT16 SampleCount = NumSamples;
288 LVM_INT16 *pInput = (LVM_INT16 *)pInData;
289 LVM_INT16 *pToProcess = (LVM_INT16 *)pInData;
290 LVM_INT16 *pProcessed = pOutData;
291 LVM_ReturnStatus_en Status;
292
293 /*
294 * Check if the number of samples is zero
295 */
296 if (NumSamples == 0)
297 {
298 return(LVM_SUCCESS);
299 }
300
301
302 /*
303 * Check valid points have been given
304 */
305 if ((hInstance == LVM_NULL) || (pInData == LVM_NULL) || (pOutData == LVM_NULL))
306 {
307 return (LVM_NULLADDRESS);
308 }
309
310 /*
311 * For unmanaged mode only
312 */
313 if(pInstance->InstParams.BufferMode == LVM_UNMANAGED_BUFFERS)
314 {
315 /*
316 * Check if the number of samples is a good multiple (unmanaged mode only)
317 */
318 if((NumSamples % pInstance->BlickSizeMultiple) != 0)
319 {
320 return(LVM_INVALIDNUMSAMPLES);
321 }
322
323 /*
324 * Check the buffer alignment
325 */
326 if((((uintptr_t)pInData % 4) != 0) || (((uintptr_t)pOutData % 4) != 0))
327 {
328 return(LVM_ALIGNMENTERROR);
329 }
330 }
331
332
333 /*
334 * Update new parameters if necessary
335 */
336 if (pInstance->ControlPending == LVM_TRUE)
337 {
338 Status = LVM_ApplyNewSettings(hInstance);
339
340 if(Status != LVM_SUCCESS)
341 {
342 return Status;
343 }
344 }
345
346
347 /*
348 * Convert from Mono if necessary
349 */
350 if (pInstance->Params.SourceFormat == LVM_MONO)
351 {
352 MonoTo2I_16(pInData, /* Source */
353 pOutData, /* Destination */
354 (LVM_INT16)NumSamples); /* Number of input samples */
355 pInput = pOutData;
356 pToProcess = pOutData;
357 }
358
359
360 /*
361 * Process the data with managed buffers
362 */
363 while (SampleCount != 0)
364 {
365 /*
366 * Manage the input buffer and frame processing
367 */
368 LVM_BufferIn(hInstance,
369 pInput,
370 &pToProcess,
371 &pProcessed,
372 &SampleCount);
373
374 /*
375 * Only process data when SampleCount is none zero, a zero count can occur when
376 * the BufferIn routine is working in managed mode.
377 */
378 if (SampleCount != 0)
379 {
380
381 /*
382 * Apply ConcertSound if required
383 */
384 if (pInstance->CS_Active == LVM_TRUE)
385 {
386 (void)LVCS_Process(pInstance->hCSInstance, /* Concert Sound instance handle */
387 pToProcess,
388 pProcessed,
389 SampleCount);
390 pToProcess = pProcessed;
391 }
392
393 /*
394 * Apply volume if required
395 */
396 if (pInstance->VC_Active!=0)
397 {
398 LVC_MixSoft_1St_D16C31_SAT(&pInstance->VC_Volume,
399 pToProcess,
400 pProcessed,
401 (LVM_INT16)(2*SampleCount)); /* Left and right*/
402 pToProcess = pProcessed;
403 }
404
405 /*
406 * Call N-Band equaliser if enabled
407 */
408 if (pInstance->EQNB_Active == LVM_TRUE)
409 {
410 LVEQNB_Process(pInstance->hEQNBInstance, /* N-Band equaliser instance handle */
411 pToProcess,
412 pProcessed,
413 SampleCount);
414 pToProcess = pProcessed;
415 }
416
417 /*
418 * Call bass enhancement if enabled
419 */
420 if (pInstance->DBE_Active == LVM_TRUE)
421 {
422 LVDBE_Process(pInstance->hDBEInstance, /* Dynamic Bass Enhancement instance handle */
423 pToProcess,
424 pProcessed,
425 SampleCount);
426 pToProcess = pProcessed;
427 }
428
429 /*
430 * Bypass mode or everything off, so copy the input to the output
431 */
432 if (pToProcess != pProcessed)
433 {
434 Copy_16(pToProcess, /* Source */
435 pProcessed, /* Destination */
436 (LVM_INT16)(2*SampleCount)); /* Left and right */
437 }
438
439 /*
440 * Apply treble boost if required
441 */
442 if (pInstance->TE_Active == LVM_TRUE)
443 {
444 /*
445 * Apply the filter
446 */
447 FO_2I_D16F32C15_LShx_TRC_WRA_01(&pInstance->pTE_State->TrebleBoost_State,
448 pProcessed,
449 pProcessed,
450 (LVM_INT16)SampleCount);
451
452 }
453
454 /*
455 * Volume balance
456 */
457 LVC_MixSoft_1St_2i_D16C31_SAT(&pInstance->VC_BalanceMix,
458 pProcessed,
459 pProcessed,
460 SampleCount);
461
462 /*
463 * Perform Parametric Spectum Analysis
464 */
465 if ((pInstance->Params.PSA_Enable == LVM_PSA_ON)&&(pInstance->InstParams.PSA_Included==LVM_PSA_ON))
466 {
467 From2iToMono_16(pProcessed,
468 pInstance->pPSAInput,
469 (LVM_INT16) (SampleCount));
470
471 LVPSA_Process(pInstance->hPSAInstance,
472 pInstance->pPSAInput,
473 (LVM_UINT16) (SampleCount),
474 AudioTime);
475 }
476
477
478 /*
479 * DC removal
480 */
481 DC_2I_D16_TRC_WRA_01(&pInstance->DC_RemovalInstance,
482 pProcessed,
483 pProcessed,
484 (LVM_INT16)SampleCount);
485
486
487 }
488
489 /*
490 * Manage the output buffer
491 */
492 LVM_BufferOut(hInstance,
493 pOutData,
494 &SampleCount);
495
496 }
497
498 return(LVM_SUCCESS);
499 }
500 #endif