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
LVM_Process(LVM_Handle_t hInstance,const LVM_INT16 * pInData,LVM_INT16 * pOutData,LVM_UINT16 NumSamples,LVM_UINT32 AudioTime)55 LVM_ReturnStatus_en LVM_Process(LVM_Handle_t hInstance,
56 const LVM_INT16 *pInData,
57 LVM_INT16 *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_INT16 *pInput = (LVM_INT16 *)pInData;
65 LVM_INT16 *pToProcess = (LVM_INT16 *)pInData;
66 LVM_INT16 *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_16(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 instance handle */
199 pToProcess,
200 pProcessed,
201 SampleCount);
202 pToProcess = pProcessed;
203 }
204
205 /*
206 * Bypass mode or everything off, so copy the input to the output
207 */
208 if (pToProcess != pProcessed)
209 {
210 Copy_16(pToProcess, /* Source */
211 pProcessed, /* Destination */
212 (LVM_INT16)(2*SampleCount)); /* Left and right */
213 }
214
215 /*
216 * Apply treble boost if required
217 */
218 if (pInstance->TE_Active == LVM_TRUE)
219 {
220 /*
221 * Apply the filter
222 */
223 FO_2I_D16F32C15_LShx_TRC_WRA_01(&pInstance->pTE_State->TrebleBoost_State,
224 pProcessed,
225 pProcessed,
226 (LVM_INT16)SampleCount);
227
228 }
229
230 /*
231 * Volume balance
232 */
233 LVC_MixSoft_1St_2i_D16C31_SAT(&pInstance->VC_BalanceMix,
234 pProcessed,
235 pProcessed,
236 SampleCount);
237
238 /*
239 * Perform Parametric Spectum Analysis
240 */
241 if ((pInstance->Params.PSA_Enable == LVM_PSA_ON)&&(pInstance->InstParams.PSA_Included==LVM_PSA_ON))
242 {
243 From2iToMono_16(pProcessed,
244 pInstance->pPSAInput,
245 (LVM_INT16) (SampleCount));
246
247 LVPSA_Process(pInstance->hPSAInstance,
248 pInstance->pPSAInput,
249 (LVM_UINT16) (SampleCount),
250 AudioTime);
251 }
252
253
254 /*
255 * DC removal
256 */
257 DC_2I_D16_TRC_WRA_01(&pInstance->DC_RemovalInstance,
258 pProcessed,
259 pProcessed,
260 (LVM_INT16)SampleCount);
261
262
263 }
264
265 /*
266 * Manage the output buffer
267 */
268 LVM_BufferOut(hInstance,
269 pOutData,
270 &SampleCount);
271
272 }
273
274 return(LVM_SUCCESS);
275 }
276