LVM_Control.c revision d918324d44aa48b3b064ea9b87d0c520c38f15a9
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
52LVM_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
222LVM_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/****************************************************************************************/
268void 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/************************************************************************************/
338void    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/************************************************************************************/
441void    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
499LVM_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
851LVM_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
911LVM_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/****************************************************************************************/
954LVM_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/****************************************************************************************/
1006LVM_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