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 "VectorArithmetic.h"
26 #include "ScalarArithmetic.h"
27 #include "LVM_Coeffs.h"
28 #include "LVM_Tables.h"
29 #include "LVM_Private.h"
30
31 /****************************************************************************************/
32 /* */
33 /* FUNCTION: LVM_SetControlParameters */
34 /* */
35 /* DESCRIPTION: */
36 /* Sets or changes the LifeVibes module parameters. */
37 /* */
38 /* PARAMETERS: */
39 /* hInstance Instance handle */
40 /* pParams Pointer to a parameter structure */
41 /* */
42 /* RETURNS: */
43 /* LVM_SUCCESS Succeeded */
44 /* LVM_NULLADDRESS When hInstance, pParams or any control pointers are NULL */
45 /* LVM_OUTOFRANGE When any of the control parameters are out of range */
46 /* */
47 /* NOTES: */
48 /* 1. This function may be interrupted by the LVM_Process function */
49 /* */
50 /****************************************************************************************/
51
LVM_SetControlParameters(LVM_Handle_t hInstance,LVM_ControlParams_t * pParams)52 LVM_ReturnStatus_en LVM_SetControlParameters(LVM_Handle_t hInstance,
53 LVM_ControlParams_t *pParams)
54 {
55 LVM_Instance_t *pInstance =(LVM_Instance_t *)hInstance;
56
57
58 if ((pParams == LVM_NULL) || (hInstance == LVM_NULL))
59 {
60 return (LVM_NULLADDRESS);
61 }
62
63 pInstance->NewParams = *pParams;
64
65 if(
66 /* General parameters */
67 ((pParams->OperatingMode != LVM_MODE_OFF) && (pParams->OperatingMode != LVM_MODE_ON)) ||
68 #if defined(BUILD_FLOAT) && defined(HIGHER_FS)
69 ((pParams->SampleRate != LVM_FS_8000) && (pParams->SampleRate != LVM_FS_11025) && (pParams->SampleRate != LVM_FS_12000) &&
70 (pParams->SampleRate != LVM_FS_16000) && (pParams->SampleRate != LVM_FS_22050) && (pParams->SampleRate != LVM_FS_24000) &&
71 (pParams->SampleRate != LVM_FS_32000) && (pParams->SampleRate != LVM_FS_44100) && (pParams->SampleRate != LVM_FS_48000) &&
72 (pParams->SampleRate != LVM_FS_96000) && (pParams->SampleRate != LVM_FS_192000)) ||
73 #else
74 ((pParams->SampleRate != LVM_FS_8000) && (pParams->SampleRate != LVM_FS_11025) && (pParams->SampleRate != LVM_FS_12000) &&
75 (pParams->SampleRate != LVM_FS_16000) && (pParams->SampleRate != LVM_FS_22050) && (pParams->SampleRate != LVM_FS_24000) &&
76 (pParams->SampleRate != LVM_FS_32000) && (pParams->SampleRate != LVM_FS_44100) && (pParams->SampleRate != LVM_FS_48000)) ||
77 #endif
78 ((pParams->SourceFormat != LVM_STEREO) && (pParams->SourceFormat != LVM_MONOINSTEREO) && (pParams->SourceFormat != LVM_MONO)) ||
79 (pParams->SpeakerType > LVM_EX_HEADPHONES))
80 {
81 return (LVM_OUTOFRANGE);
82 }
83
84 /*
85 * Cinema Sound parameters
86 */
87 if((pParams->VirtualizerOperatingMode != LVM_MODE_OFF) && (pParams->VirtualizerOperatingMode != LVM_MODE_ON))
88 {
89 return (LVM_OUTOFRANGE);
90 }
91
92 if(pParams->VirtualizerType != LVM_CONCERTSOUND)
93 {
94 return (LVM_OUTOFRANGE);
95 }
96
97 if(pParams->VirtualizerReverbLevel > LVM_VIRTUALIZER_MAX_REVERB_LEVEL)
98 {
99 return (LVM_OUTOFRANGE);
100 }
101
102 if(pParams->CS_EffectLevel < LVM_CS_MIN_EFFECT_LEVEL)
103 {
104 return (LVM_OUTOFRANGE);
105 }
106
107 /*
108 * N-Band Equalizer
109 */
110 if(pParams->EQNB_NBands > pInstance->InstParams.EQNB_NumBands)
111 {
112 return (LVM_OUTOFRANGE);
113 }
114
115 /* Definition pointer */
116 if ((pParams->pEQNB_BandDefinition == LVM_NULL) &&
117 (pParams->EQNB_NBands != 0))
118 {
119 return (LVM_NULLADDRESS);
120 }
121
122 /*
123 * Copy the filter definitions for the Equaliser
124 */
125 {
126 LVM_INT16 i;
127
128 if (pParams->EQNB_NBands != 0)
129 {
130 for (i=0; i<pParams->EQNB_NBands; i++)
131 {
132 pInstance->pEQNB_BandDefs[i] = pParams->pEQNB_BandDefinition[i];
133 }
134 pInstance->NewParams.pEQNB_BandDefinition = pInstance->pEQNB_BandDefs;
135 }
136 }
137 if( /* N-Band Equaliser parameters */
138 ((pParams->EQNB_OperatingMode != LVM_EQNB_OFF) && (pParams->EQNB_OperatingMode != LVM_EQNB_ON)) ||
139 (pParams->EQNB_NBands > pInstance->InstParams.EQNB_NumBands))
140 {
141 return (LVM_OUTOFRANGE);
142 }
143 /* Band parameters*/
144 {
145 LVM_INT16 i;
146 for(i = 0; i < pParams->EQNB_NBands; i++)
147 {
148 if(((pParams->pEQNB_BandDefinition[i].Frequency < LVM_EQNB_MIN_BAND_FREQ) ||
149 (pParams->pEQNB_BandDefinition[i].Frequency > LVM_EQNB_MAX_BAND_FREQ)) ||
150 ((pParams->pEQNB_BandDefinition[i].Gain < LVM_EQNB_MIN_BAND_GAIN) ||
151 (pParams->pEQNB_BandDefinition[i].Gain > LVM_EQNB_MAX_BAND_GAIN)) ||
152 ((pParams->pEQNB_BandDefinition[i].QFactor < LVM_EQNB_MIN_QFACTOR) ||
153 (pParams->pEQNB_BandDefinition[i].QFactor > LVM_EQNB_MAX_QFACTOR)))
154 {
155 return (LVM_OUTOFRANGE);
156 }
157 }
158 }
159
160 /*
161 * Bass Enhancement parameters
162 */
163 if(((pParams->BE_OperatingMode != LVM_BE_OFF) && (pParams->BE_OperatingMode != LVM_BE_ON)) ||
164 ((pParams->BE_EffectLevel < LVM_BE_MIN_EFFECTLEVEL ) || (pParams->BE_EffectLevel > LVM_BE_MAX_EFFECTLEVEL ))||
165 ((pParams->BE_CentreFreq != LVM_BE_CENTRE_55Hz) && (pParams->BE_CentreFreq != LVM_BE_CENTRE_66Hz) &&
166 (pParams->BE_CentreFreq != LVM_BE_CENTRE_78Hz) && (pParams->BE_CentreFreq != LVM_BE_CENTRE_90Hz)) ||
167 ((pParams->BE_HPF != LVM_BE_HPF_OFF) && (pParams->BE_HPF != LVM_BE_HPF_ON)))
168 {
169 return (LVM_OUTOFRANGE);
170 }
171
172 /*
173 * Volume Control parameters
174 */
175 if((pParams->VC_EffectLevel < LVM_VC_MIN_EFFECTLEVEL ) || (pParams->VC_EffectLevel > LVM_VC_MAX_EFFECTLEVEL ))
176 {
177 return (LVM_OUTOFRANGE);
178 }
179 if((pParams->VC_Balance < LVM_VC_BALANCE_MIN ) || (pParams->VC_Balance > LVM_VC_BALANCE_MAX ))
180 {
181 return (LVM_OUTOFRANGE);
182 }
183
184 /*
185 * PSA parameters
186 */
187 if( (pParams->PSA_PeakDecayRate > LVPSA_SPEED_HIGH) ||
188 (pParams->PSA_Enable > LVM_PSA_ON))
189 {
190 return (LVM_OUTOFRANGE);
191 }
192
193
194 /*
195 * Set the flag to indicate there are new parameters to use
196 *
197 * Protect the copy of the new parameters from interrupts to avoid possible problems
198 * with loss control parameters. This problem can occur if this control function is called more
199 * than once before a call to the process function. If the process function interrupts
200 * the copy to NewParams then one frame may have mixed parameters, some old and some new.
201 */
202 pInstance->ControlPending = LVM_TRUE;
203
204 return(LVM_SUCCESS);
205 }
206
207
208 /****************************************************************************************/
209 /* */
210 /* FUNCTION: LVM_GetControlParameters */
211 /* */
212 /* DESCRIPTION: */
213 /* Request the LifeVibes module parameters. The current parameter set is returned */
214 /* via the parameter pointer. */
215 /* */
216 /* PARAMETERS: */
217 /* hInstance Instance handle */
218 /* pParams Pointer to an empty parameter structure */
219 /* */
220 /* RETURNS: */
221 /* LVM_SUCCESS Succeeded */
222 /* LVM_NULLADDRESS when any of hInstance or pParams is NULL */
223 /* */
224 /* NOTES: */
225 /* 1. This function may be interrupted by the LVM_Process function */
226 /* */
227 /****************************************************************************************/
228
LVM_GetControlParameters(LVM_Handle_t hInstance,LVM_ControlParams_t * pParams)229 LVM_ReturnStatus_en LVM_GetControlParameters(LVM_Handle_t hInstance,
230 LVM_ControlParams_t *pParams)
231 {
232 LVM_Instance_t *pInstance =(LVM_Instance_t *)hInstance;
233
234
235 /*
236 * Check pointer
237 */
238 if ((pParams == LVM_NULL) || (hInstance == LVM_NULL))
239 {
240 return (LVM_NULLADDRESS);
241 }
242 *pParams = pInstance->NewParams;
243
244 /*
245 * Copy the filter definitions for the Equaliser
246 */
247 {
248 LVM_INT16 i;
249
250 if (pInstance->NewParams.EQNB_NBands != 0)
251 for (i=0; i<pInstance->NewParams.EQNB_NBands; i++)
252 {
253 pInstance->pEQNB_UserDefs[i] = pInstance->pEQNB_BandDefs[i];
254 }
255 pParams->pEQNB_BandDefinition = pInstance->pEQNB_UserDefs;
256 }
257
258 return(LVM_SUCCESS);
259 }
260
261
262 /****************************************************************************************/
263 /* */
264 /* FUNCTION: LVM_SetTrebleBoost */
265 /* */
266 /* DESCRIPTION: */
267 /* Enable the treble boost when the settings are appropriate, i.e. non-zero gain */
268 /* and the sample rate is high enough for the effect to be heard. */
269 /* */
270 /* PARAMETERS: */
271 /* pInstance Pointer to the instance structure */
272 /* pParams Pointer to the parameters to use */
273 /* */
274 /****************************************************************************************/
LVM_SetTrebleBoost(LVM_Instance_t * pInstance,LVM_ControlParams_t * pParams)275 void LVM_SetTrebleBoost(LVM_Instance_t *pInstance,
276 LVM_ControlParams_t *pParams)
277 {
278 #ifdef BUILD_FLOAT
279 extern FO_FLOAT_LShx_Coefs_t LVM_TrebleBoostCoefs[];
280 #else
281 extern FO_C16_LShx_Coefs_t LVM_TrebleBoostCoefs[];
282 #endif
283
284 LVM_INT16 Offset;
285 LVM_INT16 EffectLevel = 0;
286
287 /*
288 * Load the coefficients
289 */
290 if ((pParams->TE_OperatingMode == LVM_TE_ON) &&
291 (pParams->SampleRate >= TrebleBoostMinRate) &&
292 (pParams->OperatingMode == LVM_MODE_ON) &&
293 (pParams->TE_EffectLevel > 0))
294 {
295 if((pParams->TE_EffectLevel == LVM_TE_LOW_MIPS) &&
296 ((pParams->SpeakerType == LVM_HEADPHONES)||
297 (pParams->SpeakerType == LVM_EX_HEADPHONES)))
298 {
299 pInstance->TE_Active = LVM_FALSE;
300 }
301 else
302 {
303 EffectLevel = pParams->TE_EffectLevel;
304 pInstance->TE_Active = LVM_TRUE;
305 }
306
307 if(pInstance->TE_Active == LVM_TRUE)
308 {
309 /*
310 * Load the coefficients and enabled the treble boost
311 */
312 Offset = (LVM_INT16)(EffectLevel - 1 + TrebleBoostSteps * (pParams->SampleRate - TrebleBoostMinRate));
313 #ifdef BUILD_FLOAT
314 FO_2I_D16F32Css_LShx_TRC_WRA_01_Init(&pInstance->pTE_State->TrebleBoost_State,
315 &pInstance->pTE_Taps->TrebleBoost_Taps,
316 &LVM_TrebleBoostCoefs[Offset]);
317
318 /*
319 * Clear the taps
320 */
321 LoadConst_Float((LVM_FLOAT)0, /* Value */
322 (void *)&pInstance->pTE_Taps->TrebleBoost_Taps, /* Destination.\
323 Cast to void: no dereferencing in function */
324 (LVM_UINT16)(sizeof(pInstance->pTE_Taps->TrebleBoost_Taps) / \
325 sizeof(LVM_FLOAT))); /* Number of words */
326 #else
327 FO_2I_D16F32Css_LShx_TRC_WRA_01_Init(&pInstance->pTE_State->TrebleBoost_State,
328 &pInstance->pTE_Taps->TrebleBoost_Taps,
329 &LVM_TrebleBoostCoefs[Offset]);
330
331 /*
332 * Clear the taps
333 */
334 LoadConst_16((LVM_INT16)0, /* Value */
335 (void *)&pInstance->pTE_Taps->TrebleBoost_Taps, /* Destination.\
336 Cast to void: no dereferencing in function */
337 (LVM_UINT16)(sizeof(pInstance->pTE_Taps->TrebleBoost_Taps)/sizeof(LVM_INT16))); /* Number of words */
338 #endif
339 }
340 }
341 else
342 {
343 /*
344 * Disable the treble boost
345 */
346 pInstance->TE_Active = LVM_FALSE;
347 }
348
349 return;
350 }
351
352
353 /************************************************************************************/
354 /* */
355 /* FUNCTION: LVM_SetVolume */
356 /* */
357 /* DESCRIPTION: */
358 /* Converts the input volume demand from dBs to linear. */
359 /* */
360 /* PARAMETERS: */
361 /* pInstance Pointer to the instance */
362 /* pParams Initialisation parameters */
363 /* */
364 /************************************************************************************/
LVM_SetVolume(LVM_Instance_t * pInstance,LVM_ControlParams_t * pParams)365 void LVM_SetVolume(LVM_Instance_t *pInstance,
366 LVM_ControlParams_t *pParams)
367 {
368
369 LVM_UINT16 dBShifts; /* 6dB shifts */
370 LVM_UINT16 dBOffset; /* Table offset */
371 LVM_INT16 Volume = 0; /* Required volume in dBs */
372 #ifdef BUILD_FLOAT
373 LVM_FLOAT Temp;
374 #endif
375
376 /*
377 * Limit the gain to the maximum allowed
378 */
379 if (pParams->VC_EffectLevel > 0)
380 {
381 Volume = 0;
382 }
383 else
384 {
385 Volume = pParams->VC_EffectLevel;
386 }
387
388 /* Compensate this volume in PSA plot */
389 if(Volume > -60) /* Limit volume loss to PSA Limits*/
390 pInstance->PSA_GainOffset=(LVM_INT16)(-Volume);/* Loss is compensated by Gain*/
391 else
392 pInstance->PSA_GainOffset=(LVM_INT16)60;/* Loss is compensated by Gain*/
393
394 pInstance->VC_AVLFixedVolume = 0;
395
396 /*
397 * Set volume control and AVL volumes according to headroom and volume user setting
398 */
399 if(pParams->OperatingMode == LVM_MODE_ON)
400 {
401 /* Default Situation with no AVL and no RS */
402 if(pParams->EQNB_OperatingMode == LVM_EQNB_ON)
403 {
404 if(Volume > -pInstance->Headroom)
405 Volume = (LVM_INT16)-pInstance->Headroom;
406 }
407 }
408
409 /*
410 * Activate volume control if necessary
411 */
412 pInstance->VC_Active = LVM_TRUE;
413 if (Volume != 0)
414 {
415 pInstance->VC_VolumedB = Volume;
416 }
417 else
418 {
419 pInstance->VC_VolumedB = 0;
420 }
421
422 /*
423 * Calculate the required gain and shifts
424 */
425 dBOffset = (LVM_UINT16)((-Volume) % 6); /* Get the dBs 0-5 */
426 dBShifts = (LVM_UINT16)(Volume / -6); /* Get the 6dB shifts */
427
428
429 /*
430 * Set the parameters
431 */
432 if(dBShifts == 0)
433 {
434 #ifdef BUILD_FLOAT
435 LVC_Mixer_SetTarget(&pInstance->VC_Volume.MixerStream[0],
436 (LVM_FLOAT)LVM_VolumeTable[dBOffset]);
437 #else
438 LVC_Mixer_SetTarget(&pInstance->VC_Volume.MixerStream[0],
439 (LVM_INT32)LVM_VolumeTable[dBOffset]);
440 #endif
441 }
442 else
443 {
444 #ifdef BUILD_FLOAT
445 Temp = LVM_VolumeTable[dBOffset];
446 while(dBShifts) {
447 Temp = Temp / 2.0f;
448 dBShifts--;
449 }
450 LVC_Mixer_SetTarget(&pInstance->VC_Volume.MixerStream[0], Temp);
451 #else
452 LVC_Mixer_SetTarget(&pInstance->VC_Volume.MixerStream[0],
453 (((LVM_INT32)LVM_VolumeTable[dBOffset])>>dBShifts));
454 #endif
455 }
456 pInstance->VC_Volume.MixerStream[0].CallbackSet = 1;
457 if(pInstance->NoSmoothVolume == LVM_TRUE)
458 {
459 #ifdef BUILD_FLOAT
460 LVC_Mixer_SetTimeConstant(&pInstance->VC_Volume.MixerStream[0], 0,
461 pInstance->Params.SampleRate, 2);
462 #else
463 LVC_Mixer_SetTimeConstant(&pInstance->VC_Volume.MixerStream[0],0,pInstance->Params.SampleRate,2);
464 #endif
465 }
466 else
467 {
468 #ifdef BUILD_FLOAT
469 LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_Volume.MixerStream[0],
470 LVM_VC_MIXER_TIME, pInstance->Params.SampleRate, 2);
471 #else
472 LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_Volume.MixerStream[0],LVM_VC_MIXER_TIME,pInstance->Params.SampleRate,2);
473 #endif
474 }
475 }
476
477
478 /************************************************************************************/
479 /* */
480 /* FUNCTION: LVM_SetHeadroom */
481 /* */
482 /* DESCRIPTION: */
483 /* Find suitable headroom based on EQ settings. */
484 /* */
485 /* PARAMETERS: */
486 /* pInstance Pointer to the instance */
487 /* pParams Initialisation parameters */
488 /* */
489 /* RETURNS: */
490 /* void Nothing */
491 /* */
492 /* NOTES: */
493 /* */
494 /************************************************************************************/
LVM_SetHeadroom(LVM_Instance_t * pInstance,LVM_ControlParams_t * pParams)495 void LVM_SetHeadroom(LVM_Instance_t *pInstance,
496 LVM_ControlParams_t *pParams)
497 {
498 LVM_INT16 ii, jj;
499 LVM_INT16 Headroom = 0;
500 LVM_INT16 MaxGain = 0;
501
502
503 if ((pParams->EQNB_OperatingMode == LVEQNB_ON) && (pInstance->HeadroomParams.Headroom_OperatingMode == LVM_HEADROOM_ON))
504 {
505 /* Find typical headroom value */
506 for(jj = 0; jj < pInstance->HeadroomParams.NHeadroomBands; jj++)
507 {
508 MaxGain = 0;
509 for( ii = 0; ii < pParams->EQNB_NBands; ii++)
510 {
511 if((pParams->pEQNB_BandDefinition[ii].Frequency >= pInstance->HeadroomParams.pHeadroomDefinition[jj].Limit_Low) &&
512 (pParams->pEQNB_BandDefinition[ii].Frequency <= pInstance->HeadroomParams.pHeadroomDefinition[jj].Limit_High))
513 {
514 if(pParams->pEQNB_BandDefinition[ii].Gain > MaxGain)
515 {
516 MaxGain = pParams->pEQNB_BandDefinition[ii].Gain;
517 }
518 }
519 }
520
521 if((MaxGain - pInstance->HeadroomParams.pHeadroomDefinition[jj].Headroom_Offset) > Headroom){
522 Headroom = (LVM_INT16)(MaxGain - pInstance->HeadroomParams.pHeadroomDefinition[jj].Headroom_Offset);
523 }
524 }
525
526 /* Saturate */
527 if(Headroom < 0)
528 Headroom = 0;
529 }
530 pInstance->Headroom = (LVM_UINT16)Headroom ;
531
532 }
533
534
535 /****************************************************************************************/
536 /* */
537 /* FUNCTION: LVM_ApplyNewSettings */
538 /* */
539 /* DESCRIPTION: */
540 /* Applies changes to parametres. This function makes no assumptions about what */
541 /* each module needs for initialisation and hence passes all parameters to all the */
542 /* the modules in turn. */
543 /* */
544 /* */
545 /* PARAMETERS: */
546 /* hInstance Instance handle */
547 /* */
548 /* RETURNS: */
549 /* LVM_Success Succeeded */
550 /* */
551 /****************************************************************************************/
552
LVM_ApplyNewSettings(LVM_Handle_t hInstance)553 LVM_ReturnStatus_en LVM_ApplyNewSettings(LVM_Handle_t hInstance)
554 {
555 LVM_Instance_t *pInstance =(LVM_Instance_t *)hInstance;
556 LVM_ControlParams_t LocalParams;
557 LVM_INT16 Count = 5;
558
559
560 /*
561 * Copy the new parameters but make sure they didn't change while copying
562 */
563 do
564 {
565 pInstance->ControlPending = LVM_FALSE;
566 LocalParams = pInstance->NewParams;
567 pInstance->HeadroomParams = pInstance->NewHeadroomParams;
568 Count--;
569 } while ((pInstance->ControlPending != LVM_FALSE) &&
570 (Count > 0));
571
572 /* Clear all internal data if format change*/
573 if(LocalParams.SourceFormat != pInstance->Params.SourceFormat)
574 {
575 LVM_ClearAudioBuffers(pInstance);
576 pInstance->ControlPending = LVM_FALSE;
577 }
578
579 /*
580 * Update the treble boost if required
581 */
582 if ((pInstance->Params.SampleRate != LocalParams.SampleRate) ||
583 (pInstance->Params.TE_EffectLevel != LocalParams.TE_EffectLevel) ||
584 (pInstance->Params.TE_OperatingMode != LocalParams.TE_OperatingMode) ||
585 (pInstance->Params.OperatingMode != LocalParams.OperatingMode) ||
586 (pInstance->Params.SpeakerType != LocalParams.SpeakerType))
587 {
588 LVM_SetTrebleBoost(pInstance,
589 &LocalParams);
590 }
591
592 /*
593 * Update the headroom if required
594 */
595 LVM_SetHeadroom(pInstance, /* Instance pointer */
596 &LocalParams); /* New parameters */
597
598 /*
599 * Update the volume if required
600 */
601 {
602 LVM_SetVolume(pInstance, /* Instance pointer */
603 &LocalParams); /* New parameters */
604 }
605 /* Apply balance changes*/
606 if(pInstance->Params.VC_Balance != LocalParams.VC_Balance)
607 {
608 /* Configure Mixer module for gradual changes to volume*/
609 if(LocalParams.VC_Balance < 0)
610 {
611 #ifdef BUILD_FLOAT
612 LVM_FLOAT Target_Float;
613 #else
614 LVM_INT32 Target;
615 #endif
616 /* Drop in right channel volume*/
617 #ifdef BUILD_FLOAT
618 Target_Float = LVM_MAXFLOAT;
619 LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[0], Target_Float);
620 LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[0],
621 LVM_VC_MIXER_TIME, LocalParams.SampleRate, 1);
622
623 Target_Float = dB_to_LinFloat((LVM_INT16)(LocalParams.VC_Balance << 4));
624 LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[1], Target_Float);
625 LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[1],
626 LVM_VC_MIXER_TIME, LocalParams.SampleRate, 1);
627 #else
628 Target = LVM_MAXINT_16;
629 LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[0],Target);
630 LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[0],LVM_VC_MIXER_TIME,LocalParams.SampleRate,1);
631
632 Target = dB_to_Lin32((LVM_INT16)(LocalParams.VC_Balance<<4));
633 LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[1],Target);
634 LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[1],LVM_VC_MIXER_TIME,LocalParams.SampleRate,1);
635 #endif
636 }
637 else if(LocalParams.VC_Balance >0)
638 {
639 #ifdef BUILD_FLOAT
640 LVM_FLOAT Target_Float;
641 #else
642 LVM_INT32 Target;
643 #endif
644 /* Drop in left channel volume*/
645 #ifdef BUILD_FLOAT
646 Target_Float = dB_to_LinFloat((LVM_INT16)((-LocalParams.VC_Balance) << 4));
647 LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[0], Target_Float);
648 LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[0],
649 LVM_VC_MIXER_TIME, LocalParams.SampleRate, 1);
650
651 Target_Float = LVM_MAXFLOAT;
652 LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[1], Target_Float);
653 LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[1],
654 LVM_VC_MIXER_TIME, LocalParams.SampleRate, 1);
655 #else
656 Target = dB_to_Lin32((LVM_INT16)((-LocalParams.VC_Balance)<<4));
657 LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[0],Target);
658 LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[0],LVM_VC_MIXER_TIME,LocalParams.SampleRate,1);
659
660 Target = LVM_MAXINT_16;
661 LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[1],Target);
662 LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[1],LVM_VC_MIXER_TIME,LocalParams.SampleRate,1);
663 #endif
664 }
665 else
666 {
667 #ifdef BUILD_FLOAT
668 LVM_FLOAT Target_Float;
669 #else
670 LVM_INT32 Target;
671 #endif
672 /* No drop*/
673 #ifdef BUILD_FLOAT
674 Target_Float = LVM_MAXFLOAT;
675 #else
676 Target = LVM_MAXINT_16;
677 #endif
678 #ifdef BUILD_FLOAT
679 LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[0],Target_Float);
680 LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[0],
681 LVM_VC_MIXER_TIME,LocalParams.SampleRate, 1);
682
683 LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[1],Target_Float);
684 LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[1],
685 LVM_VC_MIXER_TIME,LocalParams.SampleRate, 1);
686 #else
687 LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[0],Target);
688 LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[0],LVM_VC_MIXER_TIME,LocalParams.SampleRate,1);
689
690 LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[1],Target);
691 LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[1],LVM_VC_MIXER_TIME,LocalParams.SampleRate,1);
692 #endif
693 }
694 }
695 /*
696 * Update the bass enhancement
697 */
698 {
699 LVDBE_ReturnStatus_en DBE_Status;
700 LVDBE_Params_t DBE_Params;
701 LVDBE_Handle_t *hDBEInstance = pInstance->hDBEInstance;
702
703
704 /*
705 * Set the new parameters
706 */
707 if(LocalParams.OperatingMode == LVM_MODE_OFF)
708 {
709 DBE_Params.OperatingMode = LVDBE_OFF;
710 }
711 else
712 {
713 DBE_Params.OperatingMode = (LVDBE_Mode_en)LocalParams.BE_OperatingMode;
714 }
715 DBE_Params.SampleRate = (LVDBE_Fs_en)LocalParams.SampleRate;
716 DBE_Params.EffectLevel = LocalParams.BE_EffectLevel;
717 DBE_Params.CentreFrequency = (LVDBE_CentreFreq_en)LocalParams.BE_CentreFreq;
718 DBE_Params.HPFSelect = (LVDBE_FilterSelect_en)LocalParams.BE_HPF;
719 DBE_Params.HeadroomdB = 0;
720 DBE_Params.VolumeControl = LVDBE_VOLUME_OFF;
721 DBE_Params.VolumedB = 0;
722
723 /*
724 * Make the changes
725 */
726 DBE_Status = LVDBE_Control(hDBEInstance,
727 &DBE_Params);
728
729
730 /*
731 * Quit if the changes were not accepted
732 */
733 if (DBE_Status != LVDBE_SUCCESS)
734 {
735 return((LVM_ReturnStatus_en)DBE_Status);
736 }
737
738
739 /*
740 * Set the control flag
741 */
742 pInstance->DBE_Active = LVM_TRUE;
743 }
744
745 /*
746 * Update the N-Band Equaliser
747 */
748 {
749 LVEQNB_ReturnStatus_en EQNB_Status;
750 LVEQNB_Params_t EQNB_Params;
751 LVEQNB_Handle_t *hEQNBInstance = pInstance->hEQNBInstance;
752
753
754 /*
755 * Set the new parameters
756 */
757
758 if(LocalParams.OperatingMode == LVM_MODE_OFF)
759 {
760 EQNB_Params.OperatingMode = LVEQNB_BYPASS;
761 }
762 else
763 {
764 EQNB_Params.OperatingMode = (LVEQNB_Mode_en)LocalParams.EQNB_OperatingMode;
765 }
766
767 EQNB_Params.SampleRate = (LVEQNB_Fs_en)LocalParams.SampleRate;
768 EQNB_Params.NBands = LocalParams.EQNB_NBands;
769 EQNB_Params.pBandDefinition = (LVEQNB_BandDef_t *)LocalParams.pEQNB_BandDefinition;
770 if (LocalParams.SourceFormat == LVM_STEREO) /* Mono format not supported */
771 {
772 EQNB_Params.SourceFormat = LVEQNB_STEREO;
773 }
774 else
775 {
776 EQNB_Params.SourceFormat = LVEQNB_MONOINSTEREO; /* Force to Mono-in-Stereo mode */
777 }
778
779
780 /*
781 * Set the control flag
782 */
783 if ((LocalParams.OperatingMode == LVM_MODE_ON) &&
784 (LocalParams.EQNB_OperatingMode == LVM_EQNB_ON))
785 {
786 pInstance->EQNB_Active = LVM_TRUE;
787 }
788 else
789 {
790 EQNB_Params.OperatingMode = LVEQNB_BYPASS;
791 }
792
793 /*
794 * Make the changes
795 */
796 EQNB_Status = LVEQNB_Control(hEQNBInstance,
797 &EQNB_Params);
798
799
800 /*
801 * Quit if the changes were not accepted
802 */
803 if (EQNB_Status != LVEQNB_SUCCESS)
804 {
805 return((LVM_ReturnStatus_en)EQNB_Status);
806 }
807
808 }
809
810
811 /*
812 * Update concert sound
813 */
814 {
815 LVCS_ReturnStatus_en CS_Status;
816 LVCS_Params_t CS_Params;
817 LVCS_Handle_t *hCSInstance = pInstance->hCSInstance;
818 LVM_Mode_en CompressorMode=LVM_MODE_ON;
819
820 /*
821 * Set the new parameters
822 */
823 if(LocalParams.VirtualizerOperatingMode == LVM_MODE_ON)
824 {
825 CS_Params.OperatingMode = LVCS_ON;
826 }
827 else
828 {
829 CS_Params.OperatingMode = LVCS_OFF;
830 }
831
832 if((LocalParams.TE_OperatingMode == LVM_TE_ON) && (LocalParams.TE_EffectLevel == LVM_TE_LOW_MIPS))
833 {
834 CS_Params.SpeakerType = LVCS_EX_HEADPHONES;
835 }
836 else
837 {
838 CS_Params.SpeakerType = LVCS_HEADPHONES;
839 }
840
841 if (LocalParams.SourceFormat == LVM_STEREO) /* Mono format not supported */
842 {
843 CS_Params.SourceFormat = LVCS_STEREO;
844 }
845 else
846 {
847 CS_Params.SourceFormat = LVCS_MONOINSTEREO; /* Force to Mono-in-Stereo mode */
848 }
849 CS_Params.SampleRate = LocalParams.SampleRate;
850 CS_Params.ReverbLevel = LocalParams.VirtualizerReverbLevel;
851 CS_Params.EffectLevel = LocalParams.CS_EffectLevel;
852
853
854 /*
855 * Set the control flag
856 */
857 if ((LocalParams.OperatingMode == LVM_MODE_ON) &&
858 (LocalParams.VirtualizerOperatingMode != LVCS_OFF))
859 {
860 pInstance->CS_Active = LVM_TRUE;
861 }
862 else
863 {
864 CS_Params.OperatingMode = LVCS_OFF;
865 }
866
867 CS_Params.CompressorMode=CompressorMode;
868
869 /*
870 * Make the changes
871 */
872 CS_Status = LVCS_Control(hCSInstance,
873 &CS_Params);
874
875
876 /*
877 * Quit if the changes were not accepted
878 */
879 if (CS_Status != LVCS_SUCCESS)
880 {
881 return((LVM_ReturnStatus_en)CS_Status);
882 }
883
884 }
885
886 /*
887 * Update the Power Spectrum Analyser
888 */
889 {
890 LVPSA_RETURN PSA_Status;
891 LVPSA_ControlParams_t PSA_Params;
892 pLVPSA_Handle_t *hPSAInstance = pInstance->hPSAInstance;
893
894
895 /*
896 * Set the new parameters
897 */
898 PSA_Params.Fs = LocalParams.SampleRate;
899 PSA_Params.LevelDetectionSpeed = (LVPSA_LevelDetectSpeed_en)LocalParams.PSA_PeakDecayRate;
900
901 /*
902 * Make the changes
903 */
904 if(pInstance->InstParams.PSA_Included==LVM_PSA_ON)
905 {
906 PSA_Status = LVPSA_Control(hPSAInstance,
907 &PSA_Params);
908
909 if (PSA_Status != LVPSA_OK)
910 {
911 return((LVM_ReturnStatus_en)PSA_Status);
912 }
913
914 /*
915 * Apply new settings
916 */
917 PSA_Status = LVPSA_ApplyNewSettings ((LVPSA_InstancePr_t*)hPSAInstance);
918 if(PSA_Status != LVPSA_OK)
919 {
920 return((LVM_ReturnStatus_en)PSA_Status);
921 }
922 }
923 }
924
925 /*
926 * Update the parameters and clear the flag
927 */
928 pInstance->NoSmoothVolume = LVM_FALSE;
929 pInstance->Params = LocalParams;
930
931
932 return(LVM_SUCCESS);
933 }
934
935
936 /****************************************************************************************/
937 /* */
938 /* FUNCTION: LVM_SetHeadroomParams */
939 /* */
940 /* DESCRIPTION: */
941 /* This function is used to set the automatiuc headroom management parameters. */
942 /* */
943 /* PARAMETERS: */
944 /* hInstance Instance Handle */
945 /* pHeadroomParams Pointer to headroom parameter structure */
946 /* */
947 /* RETURNS: */
948 /* LVM_Success Succeeded */
949 /* */
950 /* NOTES: */
951 /* 1. This function may be interrupted by the LVM_Process function */
952 /* */
953 /****************************************************************************************/
954
LVM_SetHeadroomParams(LVM_Handle_t hInstance,LVM_HeadroomParams_t * pHeadroomParams)955 LVM_ReturnStatus_en LVM_SetHeadroomParams(LVM_Handle_t hInstance,
956 LVM_HeadroomParams_t *pHeadroomParams)
957 {
958 LVM_Instance_t *pInstance =(LVM_Instance_t *)hInstance;
959 LVM_UINT16 ii, NBands;
960
961 /* Check for NULL pointers */
962 if ((hInstance == LVM_NULL) || (pHeadroomParams == LVM_NULL))
963 {
964 return (LVM_NULLADDRESS);
965 }
966 if ((pHeadroomParams->NHeadroomBands != 0) && (pHeadroomParams->pHeadroomDefinition == LVM_NULL))
967 {
968 return (LVM_NULLADDRESS);
969 }
970
971 /* Consider only the LVM_HEADROOM_MAX_NBANDS first bands*/
972 if (pHeadroomParams->NHeadroomBands > LVM_HEADROOM_MAX_NBANDS)
973 {
974 NBands = LVM_HEADROOM_MAX_NBANDS;
975 }
976 else
977 {
978 NBands = pHeadroomParams->NHeadroomBands;
979 }
980 pInstance->NewHeadroomParams.NHeadroomBands = NBands;
981
982 /* Copy settings in memory */
983 for(ii = 0; ii < NBands; ii++)
984 {
985 pInstance->pHeadroom_BandDefs[ii] = pHeadroomParams->pHeadroomDefinition[ii];
986 }
987
988 pInstance->NewHeadroomParams.pHeadroomDefinition = pInstance->pHeadroom_BandDefs;
989 pInstance->NewHeadroomParams.Headroom_OperatingMode = pHeadroomParams->Headroom_OperatingMode;
990 pInstance->ControlPending = LVM_TRUE;
991
992 return(LVM_SUCCESS);
993 }
994
995 /****************************************************************************************/
996 /* */
997 /* FUNCTION: LVM_GetHeadroomParams */
998 /* */
999 /* DESCRIPTION: */
1000 /* This function is used to get the automatic headroom management parameters. */
1001 /* */
1002 /* PARAMETERS: */
1003 /* hInstance Instance Handle */
1004 /* pHeadroomParams Pointer to headroom parameter structure (output) */
1005 /* */
1006 /* RETURNS: */
1007 /* LVM_SUCCESS Succeeded */
1008 /* LVM_NULLADDRESS When hInstance or pHeadroomParams are NULL */
1009 /* */
1010 /* NOTES: */
1011 /* 1. This function may be interrupted by the LVM_Process function */
1012 /* */
1013 /****************************************************************************************/
1014
LVM_GetHeadroomParams(LVM_Handle_t hInstance,LVM_HeadroomParams_t * pHeadroomParams)1015 LVM_ReturnStatus_en LVM_GetHeadroomParams(LVM_Handle_t hInstance,
1016 LVM_HeadroomParams_t *pHeadroomParams)
1017 {
1018 LVM_Instance_t *pInstance =(LVM_Instance_t *)hInstance;
1019 LVM_UINT16 ii;
1020
1021 /* Check for NULL pointers */
1022 if ((hInstance == LVM_NULL) || (pHeadroomParams == LVM_NULL))
1023 {
1024 return (LVM_NULLADDRESS);
1025 }
1026
1027 pHeadroomParams->NHeadroomBands = pInstance->NewHeadroomParams.NHeadroomBands;
1028
1029
1030 /* Copy settings in memory */
1031 for(ii = 0; ii < pInstance->NewHeadroomParams.NHeadroomBands; ii++)
1032 {
1033 pInstance->pHeadroom_UserDefs[ii] = pInstance->pHeadroom_BandDefs[ii];
1034 }
1035
1036
1037 pHeadroomParams->pHeadroomDefinition = pInstance->pHeadroom_UserDefs;
1038 pHeadroomParams->Headroom_OperatingMode = pInstance->NewHeadroomParams.Headroom_OperatingMode;
1039 return(LVM_SUCCESS);
1040 }
1041
1042 /****************************************************************************************/
1043 /* */
1044 /* FUNCTION: LVM_AlgoCallBack */
1045 /* */
1046 /* DESCRIPTION: */
1047 /* This is the callback function of the algorithm. */
1048 /* */
1049 /* PARAMETERS: */
1050 /* pBundleHandle Pointer to the Instance Handle */
1051 /* pData Pointer to the data */
1052 /* callbackId ID of the callback */
1053 /* */
1054 /* NOTES: */
1055 /* 1. This function may be interrupted by the LVM_Process function */
1056 /* */
1057 /****************************************************************************************/
LVM_AlgoCallBack(void * pBundleHandle,void * pData,LVM_INT16 callbackId)1058 LVM_INT32 LVM_AlgoCallBack( void *pBundleHandle,
1059 void *pData,
1060 LVM_INT16 callbackId)
1061 {
1062 LVM_Instance_t *pInstance =(LVM_Instance_t *)pBundleHandle;
1063
1064 (void) pData;
1065
1066 switch(callbackId & 0xFF00){
1067 case ALGORITHM_CS_ID:
1068 switch(callbackId & 0x00FF)
1069 {
1070 case LVCS_EVENT_ALGOFF:
1071 pInstance->CS_Active = LVM_FALSE;
1072 break;
1073 default:
1074 break;
1075 }
1076 break;
1077 case ALGORITHM_EQNB_ID:
1078 switch(callbackId & 0x00FF)
1079 {
1080 case LVEQNB_EVENT_ALGOFF:
1081 pInstance->EQNB_Active = LVM_FALSE;
1082 break;
1083 default:
1084 break;
1085 }
1086 break;
1087 default:
1088 break;
1089 }
1090
1091 return 0;
1092 }
1093
1094 /****************************************************************************************/
1095 /* */
1096 /* FUNCTION: LVM_VCCallBack */
1097 /* */
1098 /* DESCRIPTION: */
1099 /* This is the callback function of the Volume control. */
1100 /* */
1101 /* PARAMETERS: */
1102 /* pBundleHandle Pointer to the Instance Handle */
1103 /* pGeneralPurpose Pointer to the data */
1104 /* CallBackParam ID of the callback */
1105 /* */
1106 /* NOTES: */
1107 /* 1. This function may be interrupted by the LVM_Process function */
1108 /* */
1109 /****************************************************************************************/
LVM_VCCallBack(void * pBundleHandle,void * pGeneralPurpose,short CallBackParam)1110 LVM_INT32 LVM_VCCallBack(void* pBundleHandle,
1111 void* pGeneralPurpose,
1112 short CallBackParam)
1113 {
1114 LVM_Instance_t *pInstance =(LVM_Instance_t *)pBundleHandle;
1115 #ifdef BUILD_FLOAT
1116 LVM_FLOAT Target;
1117 #else
1118 LVM_INT32 Target;
1119 #endif
1120
1121 (void) pGeneralPurpose;
1122 (void) CallBackParam;
1123
1124 /* When volume mixer has reached 0 dB target then stop it to avoid
1125 unnecessary processing. */
1126 #ifdef BUILD_FLOAT
1127 Target = LVC_Mixer_GetTarget(&pInstance->VC_Volume.MixerStream[0]);
1128 if(Target == 1.0f)
1129 {
1130 pInstance->VC_Active = LVM_FALSE;
1131 }
1132 #else
1133 Target = LVC_Mixer_GetTarget(&pInstance->VC_Volume.MixerStream[0]);
1134
1135 if(Target == 0x7FFF)
1136 {
1137 pInstance->VC_Active = LVM_FALSE;
1138 }
1139 #endif
1140 return 1;
1141 }
1142