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