LVDBE_Control.c revision 2c8e5cab3faa6d360e222b7a6c40a80083d021ac
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: 1223 $ 22 $Date: 2010-07-15 14:27:01 +0200 (Thu, 15 Jul 2010) $ 23 24*****************************************************************************************/ 25 26/****************************************************************************************/ 27/* */ 28/* Includes */ 29/* */ 30/****************************************************************************************/ 31 32#include "LVDBE.h" 33#include "LVDBE_Private.h" 34#include "VectorArithmetic.h" 35#include "LVDBE_Coeffs.h" 36#include "LVDBE_Tables.h" 37 38/****************************************************************************************/ 39/* */ 40/* FUNCTION: LVDBE_GetParameters */ 41/* */ 42/* DESCRIPTION: */ 43/* Request the Dynamic Bass Enhancement parameters. The current parameter set is */ 44/* returned via the parameter pointer. */ 45/* */ 46/* PARAMETERS: */ 47/* hInstance Instance handle */ 48/* pParams Pointer to an empty parameter structure */ 49/* */ 50/* RETURNS: */ 51/* LVDBE_SUCCESS Always succeeds */ 52/* */ 53/* NOTES: */ 54/* 1. This function may be interrupted by the LVDBE_Process function */ 55/* */ 56/****************************************************************************************/ 57 58LVDBE_ReturnStatus_en LVDBE_GetParameters(LVDBE_Handle_t hInstance, 59 LVDBE_Params_t *pParams) 60{ 61 62 LVDBE_Instance_t *pInstance =(LVDBE_Instance_t *)hInstance; 63 64 *pParams = pInstance->Params; 65 66 return(LVDBE_SUCCESS); 67} 68 69 70/************************************************************************************/ 71/* */ 72/* FUNCTION: LVDBE_GetCapabilities */ 73/* */ 74/* DESCRIPTION: Dynamic Bass Enhnacement capabilities. The current capabilities are */ 75/* returned via the pointer. */ 76/* */ 77/* PARAMETERS: */ 78/* hInstance Instance handle */ 79/* pCapabilities Pointer to an empty capability structure */ 80/* */ 81/* RETURNS: */ 82/* LVDBE_Success Always succeeds */ 83/* */ 84/* NOTES: */ 85/* 1. This function may be interrupted by the LVDBE_Process function */ 86/* */ 87/************************************************************************************/ 88 89LVDBE_ReturnStatus_en LVDBE_GetCapabilities(LVDBE_Handle_t hInstance, 90 LVDBE_Capabilities_t *pCapabilities) 91{ 92 93 LVDBE_Instance_t *pInstance =(LVDBE_Instance_t *)hInstance; 94 95 *pCapabilities = pInstance->Capabilities; 96 97 return(LVDBE_SUCCESS); 98} 99 100 101/************************************************************************************/ 102/* */ 103/* FUNCTION: LVDBE_SetFilters */ 104/* */ 105/* DESCRIPTION: */ 106/* Sets the filter coefficients and clears the data history */ 107/* */ 108/* PARAMETERS: */ 109/* pInstance Pointer to the instance */ 110/* pParams Initialisation parameters */ 111/* */ 112/************************************************************************************/ 113 114void LVDBE_SetFilters(LVDBE_Instance_t *pInstance, 115 LVDBE_Params_t *pParams) 116{ 117 118 /* 119 * Calculate the table offsets 120 */ 121 LVM_UINT16 Offset = (LVM_UINT16)((LVM_UINT16)pParams->SampleRate + (LVM_UINT16)(pParams->CentreFrequency * (1+LVDBE_FS_48000))); 122 123 124 /* 125 * Setup the high pass filter 126 */ 127 LoadConst_16(0, /* Clear the history, value 0 */ 128 (LVM_INT16 *)&pInstance->pData->HPFTaps, /* Destination */ 129 sizeof(pInstance->pData->HPFTaps)/sizeof(LVM_INT16)); /* Number of words */ 130 BQ_2I_D32F32Cll_TRC_WRA_01_Init(&pInstance->pCoef->HPFInstance, /* Initialise the filter */ 131 &pInstance->pData->HPFTaps, 132 (BQ_C32_Coefs_t *)&LVDBE_HPF_Table[Offset]); 133 134 135 /* 136 * Setup the band pass filter 137 */ 138 LoadConst_16(0, /* Clear the history, value 0 */ 139 (LVM_INT16 *)&pInstance->pData->BPFTaps, /* Destination */ 140 sizeof(pInstance->pData->BPFTaps)/sizeof(LVM_INT16)); /* Number of words */ 141 BP_1I_D32F32Cll_TRC_WRA_02_Init(&pInstance->pCoef->BPFInstance, /* Initialise the filter */ 142 &pInstance->pData->BPFTaps, 143 (BP_C32_Coefs_t *)&LVDBE_BPF_Table[Offset]); 144 145} 146 147 148 149/************************************************************************************/ 150/* */ 151/* FUNCTION: LVDBE_SetAGC */ 152/* */ 153/* DESCRIPTION: */ 154/* Sets the AGC gain level and attack and decay times constants. */ 155/* */ 156/* PARAMETERS: */ 157/* pInstance Pointer to the instance */ 158/* pParams Initialisation parameters */ 159/* */ 160/************************************************************************************/ 161 162void LVDBE_SetAGC(LVDBE_Instance_t *pInstance, 163 LVDBE_Params_t *pParams) 164{ 165 166 /* 167 * Get the attack and decay time constants 168 */ 169 pInstance->pData->AGCInstance.AGC_Attack = LVDBE_AGC_ATTACK_Table[(LVM_UINT16)pParams->SampleRate]; /* Attack multiplier */ 170 pInstance->pData->AGCInstance.AGC_Decay = LVDBE_AGC_DECAY_Table[(LVM_UINT16)pParams->SampleRate]; /* Decay multipler */ 171 172 173 /* 174 * Get the boost gain 175 */ 176 if (pParams->HPFSelect == LVDBE_HPF_ON) 177 { 178 pInstance->pData->AGCInstance.AGC_MaxGain = LVDBE_AGC_HPFGAIN_Table[(LVM_UINT16)pParams->EffectLevel]; /* High pass filter on */ 179 } 180 else 181 { 182 pInstance->pData->AGCInstance.AGC_MaxGain = LVDBE_AGC_GAIN_Table[(LVM_UINT16)pParams->EffectLevel]; /* High pass filter off */ 183 } 184 pInstance->pData->AGCInstance.AGC_GainShift = AGC_GAIN_SHIFT; 185 pInstance->pData->AGCInstance.AGC_Target = AGC_TARGETLEVEL; 186 187} 188 189 190/************************************************************************************/ 191/* */ 192/* FUNCTION: LVDBE_SetVolume */ 193/* */ 194/* DESCRIPTION: */ 195/* Converts the input volume demand from dBs to linear. */ 196/* */ 197/* PARAMETERS: */ 198/* pInstance Pointer to the instance */ 199/* pParams Initialisation parameters */ 200/* */ 201/* NOTES: */ 202/* 1. The volume should have the following settings: */ 203/* */ 204/* DBE Vol Control Volume setting */ 205/* === =========== =================== */ 206/* Off Off HeadroomdB */ 207/* Off On VolumedB+HeadroomdB */ 208/* On Off HeadroomdB */ 209/* On On VolumedB+HeadroomdB */ 210/* */ 211/************************************************************************************/ 212 213void LVDBE_SetVolume(LVDBE_Instance_t *pInstance, 214 LVDBE_Params_t *pParams) 215{ 216 217 LVM_UINT16 dBShifts; /* 6dB shifts */ 218 LVM_UINT16 dBOffset; /* Table offset */ 219 LVM_INT16 Volume = 0; /* Required volume in dBs */ 220 221 /* 222 * Apply the volume if enabled 223 */ 224 if (pParams->VolumeControl == LVDBE_VOLUME_ON) 225 { 226 /* 227 * Limit the gain to the maximum allowed 228 */ 229 if (pParams->VolumedB > VOLUME_MAX) 230 { 231 Volume = VOLUME_MAX; 232 } 233 else 234 { 235 Volume = pParams->VolumedB; 236 } 237 } 238 239 240 /* 241 * Calculate the required gain and shifts 242 */ 243 dBOffset = (LVM_UINT16)(6 + Volume % 6); /* Get the dBs 0-5 */ 244 dBShifts = (LVM_UINT16)(Volume / -6); /* Get the 6dB shifts */ 245 246 247 /* 248 * When DBE is enabled use AGC volume 249 */ 250 pInstance->pData->AGCInstance.Target = ((LVM_INT32)LVDBE_VolumeTable[dBOffset] << 16); 251 pInstance->pData->AGCInstance.Target = pInstance->pData->AGCInstance.Target >> dBShifts; 252 253 pInstance->pData->AGCInstance.VolumeTC = LVDBE_VolumeTCTable[(LVM_UINT16)pParams->SampleRate]; /* Volume update time constant */ 254 pInstance->pData->AGCInstance.VolumeShift = VOLUME_SHIFT+1; 255 256 /* 257 * When DBE is disabled use the bypass volume control 258 */ 259 if(dBShifts > 0) 260 { 261 LVC_Mixer_SetTarget(&pInstance->pData->BypassVolume.MixerStream[0],(((LVM_INT32)LVDBE_VolumeTable[dBOffset]) >> dBShifts)); 262 } 263 else 264 { 265 LVC_Mixer_SetTarget(&pInstance->pData->BypassVolume.MixerStream[0],(LVM_INT32)LVDBE_VolumeTable[dBOffset]); 266 } 267 268 pInstance->pData->BypassVolume.MixerStream[0].CallbackSet = 1; 269 LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->pData->BypassVolume.MixerStream[0], 270 LVDBE_MIXER_TC, 271 (LVM_Fs_en)pInstance->Params.SampleRate, 272 2); 273} 274 275 276/****************************************************************************************/ 277/* */ 278/* FUNCTION: LVDBE_Control */ 279/* */ 280/* DESCRIPTION: */ 281/* Sets or changes the Bass Enhancement parameters. Changing the parameters while the */ 282/* module is processing signals may have the following side effects: */ 283/* */ 284/* General parameters: */ 285/* =================== */ 286/* OperatingMode: Changing the mode of operation may cause a change in volume */ 287/* level or cause pops and clicks. */ 288/* */ 289/* SampleRate: Changing the sample rate may cause pops and clicks. */ 290/* */ 291/* EffectLevel: Changing the effect level may cause pops and clicks */ 292/* */ 293/* CentreFrequency: Changing the centre frequency may cause pops and clicks */ 294/* */ 295/* HPFSelect: Selecting/de-selecting the high pass filter may cause pops and */ 296/* clicks */ 297/* */ 298/* VolumedB Changing the volume setting will have no side effects */ 299/* */ 300/* */ 301/* PARAMETERS: */ 302/* hInstance Instance handle */ 303/* pParams Pointer to a parameter structure */ 304/* */ 305/* RETURNS: */ 306/* LVDBE_SUCCESS Always succeeds */ 307/* */ 308/* NOTES: */ 309/* 1. This function must not be interrupted by the LVDBE_Process function */ 310/* */ 311/****************************************************************************************/ 312 313LVDBE_ReturnStatus_en LVDBE_Control(LVDBE_Handle_t hInstance, 314 LVDBE_Params_t *pParams) 315{ 316 317 LVDBE_Instance_t *pInstance =(LVDBE_Instance_t *)hInstance; 318 319 320 /* 321 * Update the filters 322 */ 323 if ((pInstance->Params.SampleRate != pParams->SampleRate) || 324 (pInstance->Params.CentreFrequency != pParams->CentreFrequency)) 325 { 326 LVDBE_SetFilters(pInstance, /* Instance pointer */ 327 pParams); /* New parameters */ 328 } 329 330 331 /* 332 * Update the AGC is the effect level has changed 333 */ 334 if ((pInstance->Params.SampleRate != pParams->SampleRate) || 335 (pInstance->Params.EffectLevel != pParams->EffectLevel) || 336 (pInstance->Params.HPFSelect != pParams->HPFSelect)) 337 { 338 LVDBE_SetAGC(pInstance, /* Instance pointer */ 339 pParams); /* New parameters */ 340 } 341 342 343 /* 344 * Update the Volume if the volume demand has changed 345 */ 346 if ((pInstance->Params.VolumedB != pParams->VolumedB) || 347 (pInstance->Params.SampleRate != pParams->SampleRate) || 348 (pInstance->Params.HeadroomdB != pParams->HeadroomdB) || 349 (pInstance->Params.VolumeControl != pParams->VolumeControl)) 350 { 351 LVDBE_SetVolume(pInstance, /* Instance pointer */ 352 pParams); /* New parameters */ 353 } 354 355 if (pInstance->Params.OperatingMode==LVDBE_ON && pParams->OperatingMode==LVDBE_OFF) 356 { 357 LVDBE_Params_t Params = *pParams; /* make local copy of params */ 358 Params.EffectLevel = 0; /* zero effect level before switching off module*/ 359 pInstance->bTransitionOnToOff = LVM_TRUE; /* Set the CallBack */ 360 LVDBE_SetAGC(pInstance, /* Instance pointer */ 361 &Params); /* New parameters */ 362 } 363 if (pInstance->Params.OperatingMode==LVDBE_OFF && pParams->OperatingMode==LVDBE_ON) 364 { 365 pInstance->bTransitionOnToOff = LVM_FALSE; /* Set the CallBack */ 366 LVDBE_SetAGC(pInstance, /* Instance pointer */ 367 pParams); /* New parameters */ 368 } 369 370 /* 371 * Update the instance parameters 372 */ 373 pInstance->Params = *pParams; 374 375 376 return(LVDBE_SUCCESS); 377} 378