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