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