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