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 #include "VectorArithmetic.h"
27 #include "LVDBE_Coeffs.h"
28 #include "LVDBE_Tables.h"
29
30 /****************************************************************************************/
31 /* */
32 /* FUNCTION: LVDBE_GetParameters */
33 /* */
34 /* DESCRIPTION: */
35 /* Request the Dynamic Bass Enhancement parameters. The current parameter set is */
36 /* returned via the parameter pointer. */
37 /* */
38 /* PARAMETERS: */
39 /* hInstance Instance handle */
40 /* pParams Pointer to an empty parameter structure */
41 /* */
42 /* RETURNS: */
43 /* LVDBE_SUCCESS Always succeeds */
44 /* */
45 /* NOTES: */
46 /* 1. This function may be interrupted by the LVDBE_Process function */
47 /* */
48 /****************************************************************************************/
49
LVDBE_GetParameters(LVDBE_Handle_t hInstance,LVDBE_Params_t * pParams)50 LVDBE_ReturnStatus_en LVDBE_GetParameters(LVDBE_Handle_t hInstance,
51 LVDBE_Params_t *pParams)
52 {
53
54 LVDBE_Instance_t *pInstance =(LVDBE_Instance_t *)hInstance;
55
56 *pParams = pInstance->Params;
57
58 return(LVDBE_SUCCESS);
59 }
60
61
62 /************************************************************************************/
63 /* */
64 /* FUNCTION: LVDBE_GetCapabilities */
65 /* */
66 /* DESCRIPTION: Dynamic Bass Enhnacement capabilities. The current capabilities are */
67 /* returned via the pointer. */
68 /* */
69 /* PARAMETERS: */
70 /* hInstance Instance handle */
71 /* pCapabilities Pointer to an empty capability structure */
72 /* */
73 /* RETURNS: */
74 /* LVDBE_Success Always succeeds */
75 /* */
76 /* NOTES: */
77 /* 1. This function may be interrupted by the LVDBE_Process function */
78 /* */
79 /************************************************************************************/
80
LVDBE_GetCapabilities(LVDBE_Handle_t hInstance,LVDBE_Capabilities_t * pCapabilities)81 LVDBE_ReturnStatus_en LVDBE_GetCapabilities(LVDBE_Handle_t hInstance,
82 LVDBE_Capabilities_t *pCapabilities)
83 {
84
85 LVDBE_Instance_t *pInstance =(LVDBE_Instance_t *)hInstance;
86
87 *pCapabilities = pInstance->Capabilities;
88
89 return(LVDBE_SUCCESS);
90 }
91
92
93 /************************************************************************************/
94 /* */
95 /* FUNCTION: LVDBE_SetFilters */
96 /* */
97 /* DESCRIPTION: */
98 /* Sets the filter coefficients and clears the data history */
99 /* */
100 /* PARAMETERS: */
101 /* pInstance Pointer to the instance */
102 /* pParams Initialisation parameters */
103 /* */
104 /************************************************************************************/
105
LVDBE_SetFilters(LVDBE_Instance_t * pInstance,LVDBE_Params_t * pParams)106 void LVDBE_SetFilters(LVDBE_Instance_t *pInstance,
107 LVDBE_Params_t *pParams)
108 {
109
110 /*
111 * Calculate the table offsets
112 */
113 LVM_UINT16 Offset = (LVM_UINT16)((LVM_UINT16)pParams->SampleRate + (LVM_UINT16)(pParams->CentreFrequency * (1+LVDBE_FS_48000)));
114
115
116 /*
117 * Setup the high pass filter
118 */
119 LoadConst_16(0, /* Clear the history, value 0 */
120 (void *)&pInstance->pData->HPFTaps, /* Destination Cast to void: \
121 no dereferencing in function*/
122 sizeof(pInstance->pData->HPFTaps)/sizeof(LVM_INT16)); /* Number of words */
123 BQ_2I_D32F32Cll_TRC_WRA_01_Init(&pInstance->pCoef->HPFInstance, /* Initialise the filter */
124 &pInstance->pData->HPFTaps,
125 (BQ_C32_Coefs_t *)&LVDBE_HPF_Table[Offset]);
126
127
128 /*
129 * Setup the band pass filter
130 */
131 LoadConst_16(0, /* Clear the history, value 0 */
132 (void *)&pInstance->pData->BPFTaps, /* Destination Cast to void:\
133 no dereferencing in function*/
134 sizeof(pInstance->pData->BPFTaps)/sizeof(LVM_INT16)); /* Number of words */
135 BP_1I_D32F32Cll_TRC_WRA_02_Init(&pInstance->pCoef->BPFInstance, /* Initialise the filter */
136 &pInstance->pData->BPFTaps,
137 (BP_C32_Coefs_t *)&LVDBE_BPF_Table[Offset]);
138
139 }
140
141
142
143 /************************************************************************************/
144 /* */
145 /* FUNCTION: LVDBE_SetAGC */
146 /* */
147 /* DESCRIPTION: */
148 /* Sets the AGC gain level and attack and decay times constants. */
149 /* */
150 /* PARAMETERS: */
151 /* pInstance Pointer to the instance */
152 /* pParams Initialisation parameters */
153 /* */
154 /************************************************************************************/
155
LVDBE_SetAGC(LVDBE_Instance_t * pInstance,LVDBE_Params_t * pParams)156 void LVDBE_SetAGC(LVDBE_Instance_t *pInstance,
157 LVDBE_Params_t *pParams)
158 {
159
160 /*
161 * Get the attack and decay time constants
162 */
163 pInstance->pData->AGCInstance.AGC_Attack = LVDBE_AGC_ATTACK_Table[(LVM_UINT16)pParams->SampleRate]; /* Attack multiplier */
164 pInstance->pData->AGCInstance.AGC_Decay = LVDBE_AGC_DECAY_Table[(LVM_UINT16)pParams->SampleRate]; /* Decay multipler */
165
166
167 /*
168 * Get the boost gain
169 */
170 if (pParams->HPFSelect == LVDBE_HPF_ON)
171 {
172 pInstance->pData->AGCInstance.AGC_MaxGain = LVDBE_AGC_HPFGAIN_Table[(LVM_UINT16)pParams->EffectLevel]; /* High pass filter on */
173 }
174 else
175 {
176 pInstance->pData->AGCInstance.AGC_MaxGain = LVDBE_AGC_GAIN_Table[(LVM_UINT16)pParams->EffectLevel]; /* High pass filter off */
177 }
178 pInstance->pData->AGCInstance.AGC_GainShift = AGC_GAIN_SHIFT;
179 pInstance->pData->AGCInstance.AGC_Target = AGC_TARGETLEVEL;
180
181 }
182
183
184 /************************************************************************************/
185 /* */
186 /* FUNCTION: LVDBE_SetVolume */
187 /* */
188 /* DESCRIPTION: */
189 /* Converts the input volume demand from dBs to linear. */
190 /* */
191 /* PARAMETERS: */
192 /* pInstance Pointer to the instance */
193 /* pParams Initialisation parameters */
194 /* */
195 /* NOTES: */
196 /* 1. The volume should have the following settings: */
197 /* */
198 /* DBE Vol Control Volume setting */
199 /* === =========== =================== */
200 /* Off Off HeadroomdB */
201 /* Off On VolumedB+HeadroomdB */
202 /* On Off HeadroomdB */
203 /* On On VolumedB+HeadroomdB */
204 /* */
205 /************************************************************************************/
206
LVDBE_SetVolume(LVDBE_Instance_t * pInstance,LVDBE_Params_t * pParams)207 void LVDBE_SetVolume(LVDBE_Instance_t *pInstance,
208 LVDBE_Params_t *pParams)
209 {
210
211 LVM_UINT16 dBShifts; /* 6dB shifts */
212 LVM_UINT16 dBOffset; /* Table offset */
213 LVM_INT16 Volume = 0; /* Required volume in dBs */
214
215 /*
216 * Apply the volume if enabled
217 */
218 if (pParams->VolumeControl == LVDBE_VOLUME_ON)
219 {
220 /*
221 * Limit the gain to the maximum allowed
222 */
223 if (pParams->VolumedB > VOLUME_MAX)
224 {
225 Volume = VOLUME_MAX;
226 }
227 else
228 {
229 Volume = pParams->VolumedB;
230 }
231 }
232
233
234 /*
235 * Calculate the required gain and shifts
236 */
237 dBOffset = (LVM_UINT16)(6 + Volume % 6); /* Get the dBs 0-5 */
238 dBShifts = (LVM_UINT16)(Volume / -6); /* Get the 6dB shifts */
239
240
241 /*
242 * When DBE is enabled use AGC volume
243 */
244 pInstance->pData->AGCInstance.Target = ((LVM_INT32)LVDBE_VolumeTable[dBOffset] << 16);
245 pInstance->pData->AGCInstance.Target = pInstance->pData->AGCInstance.Target >> dBShifts;
246
247 pInstance->pData->AGCInstance.VolumeTC = LVDBE_VolumeTCTable[(LVM_UINT16)pParams->SampleRate]; /* Volume update time constant */
248 pInstance->pData->AGCInstance.VolumeShift = VOLUME_SHIFT+1;
249
250 /*
251 * When DBE is disabled use the bypass volume control
252 */
253 if(dBShifts > 0)
254 {
255 LVC_Mixer_SetTarget(&pInstance->pData->BypassVolume.MixerStream[0],(((LVM_INT32)LVDBE_VolumeTable[dBOffset]) >> dBShifts));
256 }
257 else
258 {
259 LVC_Mixer_SetTarget(&pInstance->pData->BypassVolume.MixerStream[0],(LVM_INT32)LVDBE_VolumeTable[dBOffset]);
260 }
261
262 pInstance->pData->BypassVolume.MixerStream[0].CallbackSet = 1;
263 LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->pData->BypassVolume.MixerStream[0],
264 LVDBE_MIXER_TC,
265 (LVM_Fs_en)pInstance->Params.SampleRate,
266 2);
267 }
268
269
270 /****************************************************************************************/
271 /* */
272 /* FUNCTION: LVDBE_Control */
273 /* */
274 /* DESCRIPTION: */
275 /* Sets or changes the Bass Enhancement parameters. Changing the parameters while the */
276 /* module is processing signals may have the following side effects: */
277 /* */
278 /* General parameters: */
279 /* =================== */
280 /* OperatingMode: Changing the mode of operation may cause a change in volume */
281 /* level or cause pops and clicks. */
282 /* */
283 /* SampleRate: Changing the sample rate may cause pops and clicks. */
284 /* */
285 /* EffectLevel: Changing the effect level may cause pops and clicks */
286 /* */
287 /* CentreFrequency: Changing the centre frequency may cause pops and clicks */
288 /* */
289 /* HPFSelect: Selecting/de-selecting the high pass filter may cause pops and */
290 /* clicks */
291 /* */
292 /* VolumedB Changing the volume setting will have no side effects */
293 /* */
294 /* */
295 /* PARAMETERS: */
296 /* hInstance Instance handle */
297 /* pParams Pointer to a parameter structure */
298 /* */
299 /* RETURNS: */
300 /* LVDBE_SUCCESS Always succeeds */
301 /* */
302 /* NOTES: */
303 /* 1. This function must not be interrupted by the LVDBE_Process function */
304 /* */
305 /****************************************************************************************/
306
LVDBE_Control(LVDBE_Handle_t hInstance,LVDBE_Params_t * pParams)307 LVDBE_ReturnStatus_en LVDBE_Control(LVDBE_Handle_t hInstance,
308 LVDBE_Params_t *pParams)
309 {
310
311 LVDBE_Instance_t *pInstance =(LVDBE_Instance_t *)hInstance;
312 LVMixer3_2St_st *pBypassMixer_Instance = &pInstance->pData->BypassMixer;
313
314
315 /*
316 * Update the filters
317 */
318 if ((pInstance->Params.SampleRate != pParams->SampleRate) ||
319 (pInstance->Params.CentreFrequency != pParams->CentreFrequency))
320 {
321 LVDBE_SetFilters(pInstance, /* Instance pointer */
322 pParams); /* New parameters */
323 }
324
325
326 /*
327 * Update the AGC is the effect level has changed
328 */
329 if ((pInstance->Params.SampleRate != pParams->SampleRate) ||
330 (pInstance->Params.EffectLevel != pParams->EffectLevel) ||
331 (pInstance->Params.HPFSelect != pParams->HPFSelect))
332 {
333 LVDBE_SetAGC(pInstance, /* Instance pointer */
334 pParams); /* New parameters */
335
336 LVC_Mixer_SetTimeConstant(&pBypassMixer_Instance->MixerStream[0],
337 LVDBE_BYPASS_MIXER_TC,pParams->SampleRate,2);
338
339 LVC_Mixer_SetTimeConstant(&pBypassMixer_Instance->MixerStream[1],
340 LVDBE_BYPASS_MIXER_TC,pParams->SampleRate,2);
341
342
343 }
344
345
346 /*
347 * Update the Volume if the volume demand has changed
348 */
349 if ((pInstance->Params.VolumedB != pParams->VolumedB) ||
350 (pInstance->Params.SampleRate != pParams->SampleRate) ||
351 (pInstance->Params.HeadroomdB != pParams->HeadroomdB) ||
352 (pInstance->Params.VolumeControl != pParams->VolumeControl))
353 {
354 LVDBE_SetVolume(pInstance, /* Instance pointer */
355 pParams); /* New parameters */
356 }
357
358 if (pInstance->Params.OperatingMode==LVDBE_ON && pParams->OperatingMode==LVDBE_OFF)
359 {
360 LVC_Mixer_SetTarget(&pInstance->pData->BypassMixer.MixerStream[0],0);
361 LVC_Mixer_SetTarget(&pInstance->pData->BypassMixer.MixerStream[1],0x00007FFF);
362 }
363 if (pInstance->Params.OperatingMode==LVDBE_OFF && pParams->OperatingMode==LVDBE_ON)
364 {
365 LVC_Mixer_SetTarget(&pInstance->pData->BypassMixer.MixerStream[0],0x00007FFF);
366 LVC_Mixer_SetTarget(&pInstance->pData->BypassMixer.MixerStream[1],0);
367 }
368
369 /*
370 * Update the instance parameters
371 */
372 pInstance->Params = *pParams;
373
374
375 return(LVDBE_SUCCESS);
376 }
377