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