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