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 48LVCS_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 79LVCS_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 124 LVC_Mixer_Init(&pInstance->BypassMix.Mixer_Instance.MixerStream[0],0,0); 125 126 127 { 128 LVM_UINT32 Gain; 129 const Gain_t *pOutputGainTable = (Gain_t*)&LVCS_OutputGainTable[0]; 130 Gain = (LVM_UINT32)(pOutputGainTable[Offset].Loss * LVM_MAXINT_16); 131 Gain = (LVM_UINT32)pOutputGainTable[Offset].UnprocLoss * (Gain >> 15); 132 Gain=Gain>>15; 133 /* 134 * Apply the gain correction and shift, note the result is in Q3.13 format 135 */ 136 Gain = (Gain * pInstance->VolCorrect.GainMin) >>12; 137 138 LVC_Mixer_Init(&pInstance->BypassMix.Mixer_Instance.MixerStream[1],0,Gain); 139 LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->BypassMix.Mixer_Instance.MixerStream[0], 140 LVCS_BYPASS_MIXER_TC,pParams->SampleRate,2); 141 LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->BypassMix.Mixer_Instance.MixerStream[1], 142 LVCS_BYPASS_MIXER_TC,pParams->SampleRate,2); 143 144 } 145 146 147 err=LVCS_SEnhancerInit(hInstance, 148 pParams); 149 150 err=LVCS_ReverbGeneratorInit(hInstance, 151 pParams); 152 153 err=LVCS_EqualiserInit(hInstance, 154 pParams); 155 156 err=LVCS_BypassMixInit(hInstance, 157 pParams); 158 159 } 160 161 162 /* 163 * Check if the effect level or source format has changed 164 */ 165 else if ((pInstance->Params.EffectLevel != pParams->EffectLevel) || 166 (pInstance->Params.SourceFormat != pParams->SourceFormat)) 167 { 168 const LVCS_VolCorrect_t *pLVCS_VolCorrectTable; 169 170 /* 171 * Get the volume correction parameters 172 */ 173 /* Use internal coefficient table */ 174 pLVCS_VolCorrectTable = (LVCS_VolCorrect_t*)&LVCS_VolCorrectTable[0]; 175 Offset = (LVM_INT16)(pParams->SpeakerType + pParams->SourceFormat*(1+LVCS_EX_HEADPHONES)); 176 177 pInstance->VolCorrect = pLVCS_VolCorrectTable[Offset]; 178 179 /* Update the effect level and alpha-mixer gains */ 180 err=LVCS_BypassMixInit(hInstance, 181 pParams); 182 183 if(err != LVCS_SUCCESS) 184 { 185 return err; 186 } 187 } 188 else 189 { 190 pInstance->Params = *pParams; 191 } 192 193 /* 194 * Update the instance parameters 195 */ 196 pInstance->Params = *pParams; 197 198 /* Stay on the current operating mode until the transition is done */ 199 if((pParams->OperatingMode != OperatingModeSave) || 200 (pInstance->bInOperatingModeTransition == LVM_TRUE)){ 201 202 /* Set the reverb delay timeout */ 203 if(pInstance->bInOperatingModeTransition != LVM_TRUE){ 204 pInstance->bTimerDone = LVM_FALSE; 205 pInstance->TimerParams.TimeInMs = 206 (LVM_INT16)(((pInstance->Reverberation.DelaySize << 2) 207 /pInstance->TimerParams.SamplingRate) + 1); 208 LVM_Timer_Init ( &pInstance->TimerInstance, 209 &pInstance->TimerParams); 210 } 211 212 /* Update the effect level and alpha-mixer gains */ 213 err=LVCS_BypassMixInit(hInstance, 214 pParams); 215 216 /* Change transition bypass mixer settings if needed depending on transition type */ 217 if(pParams->OperatingMode != LVCS_OFF){ 218 pInstance->MSTarget0=LVM_MAXINT_16; 219 pInstance->MSTarget1=0; 220 } 221 else 222 { 223 pInstance->Params.OperatingMode = OperatingModeSave; 224 pInstance->MSTarget1=LVM_MAXINT_16; 225 pInstance->MSTarget0=0; 226 } 227 228 229 /* Set transition flag */ 230 pInstance->bInOperatingModeTransition = LVM_TRUE; 231 } 232 233 return(LVCS_SUCCESS); 234} 235 236/****************************************************************************************/ 237/* */ 238/* FUNCTION: LVCS_TimerCallBack */ 239/* */ 240/* DESCRIPTION: */ 241/* CallBack function of the Timer. */ 242/* */ 243/****************************************************************************************/ 244void LVCS_TimerCallBack (void* hInstance, void* pCallBackParams, LVM_INT32 CallbackParam) 245{ 246 LVCS_Instance_t *pInstance = (LVCS_Instance_t *)hInstance; 247 248 /* Avoid warnings because pCallBackParams and CallbackParam are not used*/ 249 if((pCallBackParams != LVM_NULL) || (CallbackParam != 0)){ 250 pCallBackParams = hInstance; 251 CallbackParam = 0; 252 return; 253 } 254 255 pInstance->bTimerDone = LVM_TRUE; 256 257 258 return; 259} 260 261