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