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