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 /*  Includes                                                                        */
     21 /*                                                                                  */
     22 /************************************************************************************/
     23 
     24 #include "LVCS.h"
     25 #include "LVCS_Private.h"
     26 #include "LVCS_Tables.h"
     27 
     28 /************************************************************************************/
     29 /*                                                                                  */
     30 /* FUNCTION:                 LVCS_GetParameters                                     */
     31 /*                                                                                  */
     32 /* DESCRIPTION:                                                                     */
     33 /*  Request the Concert Sound parameters. The current parameter set is returned     */
     34 /*  via the parameter pointer.                                                      */
     35 /*                                                                                  */
     36 /* PARAMETERS:                                                                      */
     37 /*  hInstance                Instance handle                                        */
     38 /*  pParams                  Pointer to an empty parameter structure                */
     39 /*                                                                                  */
     40 /* RETURNS:                                                                         */
     41 /*  LVCS_Success             Always succeeds                                        */
     42 /*                                                                                  */
     43 /* NOTES:                                                                           */
     44 /*  1.  This function may be interrupted by the LVCS_Process function               */
     45 /*                                                                                  */
     46 /************************************************************************************/
     47 
     48 LVCS_ReturnStatus_en LVCS_GetParameters(LVCS_Handle_t   hInstance,
     49                                         LVCS_Params_t   *pParams)
     50 {
     51 
     52     LVCS_Instance_t     *pInstance =(LVCS_Instance_t  *)hInstance;
     53 
     54     *pParams = pInstance->Params;
     55 
     56     return(LVCS_SUCCESS);
     57 }
     58 
     59 
     60 /************************************************************************************/
     61 /*                                                                                  */
     62 /* FUNCTION:                LVCS_Control                                            */
     63 /*                                                                                  */
     64 /* DESCRIPTION:                                                                     */
     65 /*  Sets or changes the Concert Sound parameters.                                   */
     66 /*                                                                                  */
     67 /* PARAMETERS:                                                                      */
     68 /*  hInstance               Instance handle                                         */
     69 /*  pParams                 Pointer to a parameter structure                        */
     70 /*                                                                                  */
     71 /* RETURNS:                                                                         */
     72 /*  LVCS_Success            Succeeded                                               */
     73 /*                                                                                  */
     74 /* NOTES:                                                                           */
     75 /*  1.  This function must not be interrupted by the LVCS_Process function          */
     76 /*                                                                                  */
     77 /************************************************************************************/
     78 
     79 LVCS_ReturnStatus_en LVCS_Control(LVCS_Handle_t      hInstance,
     80                                   LVCS_Params_t      *pParams)
     81 {
     82     LVM_INT16                   Offset;
     83     LVCS_Instance_t             *pInstance =(LVCS_Instance_t  *)hInstance;
     84     LVCS_ReturnStatus_en        err;
     85     LVCS_Modes_en               OperatingModeSave = pInstance->Params.OperatingMode;
     86 
     87     if (pParams->SampleRate != pInstance->Params.SampleRate)
     88     {
     89         pInstance->TimerParams.SamplingRate = LVCS_SampleRateTable[pParams->SampleRate];
     90     }
     91 
     92     /*
     93      * If the reverb level has changed
     94      */
     95     if(pInstance->Params.ReverbLevel != pParams->ReverbLevel)
     96     {
     97         err=LVCS_ReverbGeneratorInit(hInstance,pParams);
     98     }
     99 
    100     /*
    101      * If the sample rate or speaker has changed then perform a full re-initialisation
    102      */
    103     if ((pInstance->Params.SampleRate != pParams->SampleRate) ||
    104        (pInstance->Params.SpeakerType != pParams->SpeakerType))
    105     {
    106         const LVCS_VolCorrect_t *pLVCS_VolCorrectTable;
    107 
    108         /*
    109          * Output device
    110          */
    111         pInstance->OutputDevice = LVCS_HEADPHONE;
    112 
    113         /*
    114          * Get the volume correction parameters
    115          */
    116         /* Use internal coefficient table */
    117         pLVCS_VolCorrectTable = (LVCS_VolCorrect_t*)&LVCS_VolCorrectTable[0];
    118         Offset = (LVM_INT16)(pParams->SpeakerType + pParams->SourceFormat*(1+LVCS_EX_HEADPHONES));
    119 
    120         pInstance->VolCorrect = pLVCS_VolCorrectTable[Offset];
    121 
    122         pInstance->CompressGain = pInstance->VolCorrect.CompMin;
    123 #ifdef BUILD_FLOAT
    124         LVC_Mixer_Init(&pInstance->BypassMix.Mixer_Instance.MixerStream[0], 0, 0);
    125 #else
    126         LVC_Mixer_Init(&pInstance->BypassMix.Mixer_Instance.MixerStream[0],0,0);
    127 #endif
    128         {
    129 #ifndef BUILD_FLOAT
    130             LVM_UINT32          Gain;
    131             const Gain_t        *pOutputGainTable = (Gain_t*)&LVCS_OutputGainTable[0];
    132             Gain = (LVM_UINT32)(pOutputGainTable[Offset].Loss * LVM_MAXINT_16);
    133             Gain = (LVM_UINT32)pOutputGainTable[Offset].UnprocLoss * (Gain >> 15);
    134             Gain=Gain>>15;
    135             /*
    136              * Apply the gain correction and shift, note the result is in Q3.13 format
    137              */
    138             Gain = (Gain * pInstance->VolCorrect.GainMin) >>12;
    139 
    140             LVC_Mixer_Init(&pInstance->BypassMix.Mixer_Instance.MixerStream[1],0,Gain);
    141             LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->BypassMix.Mixer_Instance.MixerStream[0],
    142                     LVCS_BYPASS_MIXER_TC,pParams->SampleRate,2);
    143             LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->BypassMix.Mixer_Instance.MixerStream[1],
    144                     LVCS_BYPASS_MIXER_TC,pParams->SampleRate,2);
    145 #else
    146             LVM_FLOAT          Gain;
    147             const Gain_t        *pOutputGainTable = (Gain_t*)&LVCS_OutputGainTable[0];
    148             Gain = (LVM_FLOAT)(pOutputGainTable[Offset].Loss);
    149             Gain = (LVM_FLOAT)pOutputGainTable[Offset].UnprocLoss * (Gain);
    150 
    151             /*
    152              * Apply the gain correction
    153              */
    154             Gain = (Gain * pInstance->VolCorrect.GainMin);
    155 
    156             LVC_Mixer_Init(&pInstance->BypassMix.Mixer_Instance.MixerStream[1], 0, Gain);
    157             LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->BypassMix.Mixer_Instance.MixerStream[0],
    158                     LVCS_BYPASS_MIXER_TC, pParams->SampleRate, 2);
    159             LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->BypassMix.Mixer_Instance.MixerStream[1],
    160                     LVCS_BYPASS_MIXER_TC, pParams->SampleRate, 2);
    161 #endif
    162         }
    163 
    164 
    165         err=LVCS_SEnhancerInit(hInstance,
    166                            pParams);
    167 
    168         err=LVCS_ReverbGeneratorInit(hInstance,
    169                                  pParams);
    170 
    171         err=LVCS_EqualiserInit(hInstance,
    172                            pParams);
    173 
    174         err=LVCS_BypassMixInit(hInstance,
    175                            pParams);
    176 
    177     }
    178 
    179 
    180     /*
    181      * Check if the effect level or source format has changed
    182      */
    183     else if ((pInstance->Params.EffectLevel != pParams->EffectLevel) ||
    184             (pInstance->Params.SourceFormat != pParams->SourceFormat))
    185     {
    186         const LVCS_VolCorrect_t *pLVCS_VolCorrectTable;
    187 
    188         /*
    189          * Get the volume correction parameters
    190          */
    191         /* Use internal coefficient table */
    192         pLVCS_VolCorrectTable = (LVCS_VolCorrect_t*)&LVCS_VolCorrectTable[0];
    193         Offset = (LVM_INT16)(pParams->SpeakerType + pParams->SourceFormat*(1+LVCS_EX_HEADPHONES));
    194 
    195         pInstance->VolCorrect = pLVCS_VolCorrectTable[Offset];
    196 
    197         /* Update the effect level and alpha-mixer gains */
    198         err=LVCS_BypassMixInit(hInstance,
    199                            pParams);
    200 
    201         if(err != LVCS_SUCCESS)
    202         {
    203             return err;
    204         }
    205     }
    206     else
    207     {
    208         pInstance->Params = *pParams;
    209     }
    210 
    211     /*
    212      * Update the instance parameters
    213      */
    214     pInstance->Params = *pParams;
    215 
    216     /* Stay on the current operating mode until the transition is done */
    217     if((pParams->OperatingMode != OperatingModeSave) ||
    218        (pInstance->bInOperatingModeTransition == LVM_TRUE)){
    219 
    220         /* Set the reverb delay timeout */
    221         if(pInstance->bInOperatingModeTransition != LVM_TRUE){
    222             pInstance->bTimerDone = LVM_FALSE;
    223             pInstance->TimerParams.TimeInMs =
    224             (LVM_INT16)(((pInstance->Reverberation.DelaySize << 2)
    225             /pInstance->TimerParams.SamplingRate) + 1);
    226             LVM_Timer_Init ( &pInstance->TimerInstance,
    227                              &pInstance->TimerParams);
    228         }
    229 
    230         /* Update the effect level and alpha-mixer gains */
    231         err=LVCS_BypassMixInit(hInstance,
    232                            pParams);
    233 
    234         /* Change transition bypass mixer settings if needed depending on transition type */
    235         if(pParams->OperatingMode != LVCS_OFF){
    236             pInstance->MSTarget0=LVM_MAXINT_16;
    237             pInstance->MSTarget1=0;
    238         }
    239         else
    240         {
    241             pInstance->Params.OperatingMode = OperatingModeSave;
    242             pInstance->MSTarget1=LVM_MAXINT_16;
    243             pInstance->MSTarget0=0;
    244         }
    245 
    246 
    247         /* Set transition flag */
    248         pInstance->bInOperatingModeTransition = LVM_TRUE;
    249     }
    250 
    251     return(LVCS_SUCCESS);
    252 }
    253 
    254 /****************************************************************************************/
    255 /*                                                                                      */
    256 /* FUNCTION:                LVCS_TimerCallBack                                          */
    257 /*                                                                                      */
    258 /* DESCRIPTION:                                                                         */
    259 /*  CallBack function of the Timer.                                                     */
    260 /*                                                                                      */
    261 /****************************************************************************************/
    262 void LVCS_TimerCallBack (void* hInstance, void* pCallBackParams, LVM_INT32 CallbackParam)
    263 {
    264     LVCS_Instance_t     *pInstance  = (LVCS_Instance_t  *)hInstance;
    265 
    266     /* Avoid warnings because pCallBackParams and CallbackParam are not used*/
    267     if((pCallBackParams != LVM_NULL) || (CallbackParam != 0)){
    268         pCallBackParams = hInstance;
    269         CallbackParam = 0;
    270         return;
    271     }
    272 
    273     pInstance->bTimerDone = LVM_TRUE;
    274 
    275 
    276     return;
    277 }
    278 
    279