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 <system/audio.h>
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 /****************************************************************************************/
LVM_Process(LVM_Handle_t hInstance,const LVM_FLOAT * pInData,LVM_FLOAT * pOutData,LVM_UINT16 NumSamples,LVM_UINT32 AudioTime)54 LVM_ReturnStatus_en LVM_Process(LVM_Handle_t hInstance,
55 const LVM_FLOAT *pInData,
56 LVM_FLOAT *pOutData,
57 LVM_UINT16 NumSamples,
58 LVM_UINT32 AudioTime)
59 {
60
61 LVM_Instance_t *pInstance = (LVM_Instance_t *)hInstance;
62 LVM_UINT16 SampleCount = NumSamples;
63 LVM_FLOAT *pInput = (LVM_FLOAT *)pInData;
64 LVM_FLOAT *pToProcess = (LVM_FLOAT *)pInData;
65 LVM_FLOAT *pProcessed = pOutData;
66 LVM_ReturnStatus_en Status;
67 #ifdef SUPPORT_MC
68 LVM_INT32 NrChannels = pInstance->NrChannels;
69 LVM_INT32 ChMask = pInstance->ChMask;
70 #define NrFrames SampleCount // alias for clarity
71 #endif
72
73 /*
74 * Check if the number of samples is zero
75 */
76 if (NumSamples == 0)
77 {
78 return(LVM_SUCCESS);
79 }
80
81 /*
82 * Check valid points have been given
83 */
84 if ((hInstance == LVM_NULL) || (pInData == LVM_NULL) || (pOutData == LVM_NULL))
85 {
86 return (LVM_NULLADDRESS);
87 }
88
89 /*
90 * For unmanaged mode only
91 */
92 if(pInstance->InstParams.BufferMode == LVM_UNMANAGED_BUFFERS)
93 {
94 /*
95 * Check if the number of samples is a good multiple (unmanaged mode only)
96 */
97 if((NumSamples % pInstance->BlickSizeMultiple) != 0)
98 {
99 return(LVM_INVALIDNUMSAMPLES);
100 }
101
102 /*
103 * Check the buffer alignment
104 */
105 if((((uintptr_t)pInData % 4) != 0) || (((uintptr_t)pOutData % 4) != 0))
106 {
107 return(LVM_ALIGNMENTERROR);
108 }
109 }
110
111 /*
112 * Update new parameters if necessary
113 */
114 if (pInstance->ControlPending == LVM_TRUE)
115 {
116 Status = LVM_ApplyNewSettings(hInstance);
117 #ifdef SUPPORT_MC
118 /* Update the local variable NrChannels from pInstance->NrChannels value */
119 NrChannels = pInstance->NrChannels;
120 ChMask = pInstance->ChMask;
121 #endif
122
123 if(Status != LVM_SUCCESS)
124 {
125 return Status;
126 }
127 }
128
129 /*
130 * Convert from Mono if necessary
131 */
132 if (pInstance->Params.SourceFormat == LVM_MONO)
133 {
134 MonoTo2I_Float(pInData, /* Source */
135 pOutData, /* Destination */
136 (LVM_INT16)NumSamples); /* Number of input samples */
137 pInput = pOutData;
138 pToProcess = pOutData;
139 #ifdef SUPPORT_MC
140 NrChannels = 2;
141 ChMask = AUDIO_CHANNEL_OUT_STEREO;
142 #endif
143 }
144
145 /*
146 * Process the data with managed buffers
147 */
148 while (SampleCount != 0)
149 {
150 /*
151 * Manage the input buffer and frame processing
152 */
153 LVM_BufferIn(hInstance,
154 pInput,
155 &pToProcess,
156 &pProcessed,
157 &SampleCount);
158
159 /*
160 * Only process data when SampleCount is none zero, a zero count can occur when
161 * the BufferIn routine is working in managed mode.
162 */
163 if (SampleCount != 0)
164 {
165 /*
166 * Apply ConcertSound if required
167 */
168 if (pInstance->CS_Active == LVM_TRUE)
169 {
170 (void)LVCS_Process(pInstance->hCSInstance, /* Concert Sound instance handle */
171 pToProcess,
172 pProcessed,
173 SampleCount);
174 pToProcess = pProcessed;
175 }
176
177 /*
178 * Apply volume if required
179 */
180 if (pInstance->VC_Active!=0)
181 {
182 #ifdef SUPPORT_MC
183 LVC_MixSoft_Mc_D16C31_SAT(&pInstance->VC_Volume,
184 pToProcess,
185 pProcessed,
186 (LVM_INT16)(NrFrames),
187 NrChannels);
188 #else
189 LVC_MixSoft_1St_D16C31_SAT(&pInstance->VC_Volume,
190 pToProcess,
191 pProcessed,
192 (LVM_INT16)(2 * SampleCount)); /* Left and right*/
193 #endif
194 pToProcess = pProcessed;
195 }
196
197 /*
198 * Call N-Band equaliser if enabled
199 */
200 if (pInstance->EQNB_Active == LVM_TRUE)
201 {
202 LVEQNB_Process(pInstance->hEQNBInstance, /* N-Band equaliser instance handle */
203 pToProcess,
204 pProcessed,
205 SampleCount);
206 pToProcess = pProcessed;
207 }
208
209 /*
210 * Call bass enhancement if enabled
211 */
212 if (pInstance->DBE_Active == LVM_TRUE)
213 {
214 LVDBE_Process(pInstance->hDBEInstance, /* Dynamic Bass Enhancement \
215 instance handle */
216 pToProcess,
217 pProcessed,
218 SampleCount);
219 pToProcess = pProcessed;
220 }
221
222 /*
223 * Bypass mode or everything off, so copy the input to the output
224 */
225 if (pToProcess != pProcessed)
226 {
227 #ifdef SUPPORT_MC
228 Copy_Float(pToProcess, /* Source */
229 pProcessed, /* Destination */
230 (LVM_INT16)(NrChannels * NrFrames)); /* Copy all samples */
231 #else
232 Copy_Float(pToProcess, /* Source */
233 pProcessed, /* Destination */
234 (LVM_INT16)(2 * SampleCount)); /* Left and right */
235 #endif
236 }
237
238 /*
239 * Apply treble boost if required
240 */
241 if (pInstance->TE_Active == LVM_TRUE)
242 {
243 /*
244 * Apply the filter
245 */
246 #ifdef SUPPORT_MC
247 FO_Mc_D16F32C15_LShx_TRC_WRA_01(&pInstance->pTE_State->TrebleBoost_State,
248 pProcessed,
249 pProcessed,
250 (LVM_INT16)NrFrames,
251 (LVM_INT16)NrChannels);
252 #else
253 FO_2I_D16F32C15_LShx_TRC_WRA_01(&pInstance->pTE_State->TrebleBoost_State,
254 pProcessed,
255 pProcessed,
256 (LVM_INT16)SampleCount);
257 #endif
258
259 }
260 #ifdef SUPPORT_MC
261 /*
262 * Volume balance
263 */
264 LVC_MixSoft_1St_MC_float_SAT(&pInstance->VC_BalanceMix,
265 pProcessed,
266 pProcessed,
267 NrFrames,
268 NrChannels,
269 ChMask);
270 #else
271 /*
272 * Volume balance
273 */
274 LVC_MixSoft_1St_2i_D16C31_SAT(&pInstance->VC_BalanceMix,
275 pProcessed,
276 pProcessed,
277 SampleCount);
278 #endif
279
280 /*
281 * Perform Parametric Spectum Analysis
282 */
283 if ((pInstance->Params.PSA_Enable == LVM_PSA_ON) &&
284 (pInstance->InstParams.PSA_Included == LVM_PSA_ON))
285 {
286 #ifdef SUPPORT_MC
287 FromMcToMono_Float(pProcessed,
288 pInstance->pPSAInput,
289 (LVM_INT16)(NrFrames),
290 NrChannels);
291 #else
292 From2iToMono_Float(pProcessed,
293 pInstance->pPSAInput,
294 (LVM_INT16)(SampleCount));
295 #endif
296
297 LVPSA_Process(pInstance->hPSAInstance,
298 pInstance->pPSAInput,
299 (LVM_UINT16)(SampleCount),
300 AudioTime);
301 }
302
303 /*
304 * DC removal
305 */
306 #ifdef SUPPORT_MC
307 DC_Mc_D16_TRC_WRA_01(&pInstance->DC_RemovalInstance,
308 pProcessed,
309 pProcessed,
310 (LVM_INT16)NrFrames,
311 NrChannels);
312 #else
313 DC_2I_D16_TRC_WRA_01(&pInstance->DC_RemovalInstance,
314 pProcessed,
315 pProcessed,
316 (LVM_INT16)SampleCount);
317 #endif
318 }
319 /*
320 * Manage the output buffer
321 */
322 LVM_BufferOut(hInstance,
323 pOutData,
324 &SampleCount);
325
326 }
327
328 return(LVM_SUCCESS);
329 }
330