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 "LVEQNB.h" 25 #include "LVEQNB_Private.h" 26 #include "VectorArithmetic.h" 27 #include "BIQUAD.h" 28 29 30 /****************************************************************************************/ 31 /* */ 32 /* Defines */ 33 /* */ 34 /****************************************************************************************/ 35 36 #define LOW_FREQ 298 /* 32768/110 for low test frequency */ 37 #define HIGH_FREQ 386 /* 32768/85 for high test frequency */ 38 39 /****************************************************************************************/ 40 /* */ 41 /* FUNCTION: LVEQNB_GetParameters */ 42 /* */ 43 /* DESCRIPTION: */ 44 /* Request the N-Band equaliser parameters. The current parameter set is returned via */ 45 /* the parameter pointer. */ 46 /* */ 47 /* PARAMETERS: */ 48 /* hInstance Instance handle */ 49 /* pParams Pointer to an empty parameter structure */ 50 /* */ 51 /* RETURNS: */ 52 /* LVEQNB_SUCCESS Succeeds */ 53 /* LVEQNB_NULLADDRESS Instance or pParams is NULL pointer */ 54 /* */ 55 /* NOTES: */ 56 /* 1. This function may be interrupted by the LVEQNB_Process function */ 57 /* */ 58 /****************************************************************************************/ 59 60 LVEQNB_ReturnStatus_en LVEQNB_GetParameters(LVEQNB_Handle_t hInstance, 61 LVEQNB_Params_t *pParams) 62 { 63 64 LVEQNB_Instance_t *pInstance =(LVEQNB_Instance_t *)hInstance; 65 66 /* 67 * Check for error conditions 68 */ 69 if((hInstance == LVM_NULL) || (pParams == LVM_NULL)) 70 { 71 return LVEQNB_NULLADDRESS; 72 } 73 74 *pParams = pInstance->Params; 75 76 return(LVEQNB_SUCCESS); 77 } 78 79 80 /************************************************************************************/ 81 /* */ 82 /* FUNCTION: LVEQNB_GetCapabilities */ 83 /* */ 84 /* DESCRIPTION: */ 85 /* Get the N-Band equaliser capabilities. The current capabilities are returned */ 86 /* via the pointer. */ 87 /* */ 88 /* PARAMETERS: */ 89 /* hInstance Instance handle */ 90 /* pCapabilities Pointer to an empty capability structure */ 91 /* */ 92 /* RETURNS: */ 93 /* LVEQNB_Success Succeeds */ 94 /* LVEQNB_NULLADDRESS hInstance or pCapabilities is NULL */ 95 /* */ 96 /* NOTES: */ 97 /* 1. This function may be interrupted by the LVEQNB_Process function */ 98 /* */ 99 /************************************************************************************/ 100 101 LVEQNB_ReturnStatus_en LVEQNB_GetCapabilities(LVEQNB_Handle_t hInstance, 102 LVEQNB_Capabilities_t *pCapabilities) 103 { 104 105 LVEQNB_Instance_t *pInstance =(LVEQNB_Instance_t *)hInstance; 106 107 if((hInstance == LVM_NULL) || (pCapabilities == LVM_NULL)) 108 { 109 return LVEQNB_NULLADDRESS; 110 } 111 112 *pCapabilities = pInstance->Capabilities; 113 114 return(LVEQNB_SUCCESS); 115 } 116 117 118 /************************************************************************************/ 119 /* */ 120 /* FUNCTION: LVEQNB_SetFilters */ 121 /* */ 122 /* DESCRIPTION: */ 123 /* Sets the filter type based on the definition. */ 124 /* */ 125 /* PARAMETERS: */ 126 /* pInstance Pointer to the instance */ 127 /* pParams Initialisation parameters */ 128 /* */ 129 /* RETURNS: */ 130 /* void Nothing */ 131 /* */ 132 /* NOTES: */ 133 /* 1. To select the biquad type the follow rules are applied: */ 134 /* Double precision if (fc <= fs/110) */ 135 /* Double precision if (fs/110 < fc < fs/85) & (Q>3) */ 136 /* Single precision otherwise */ 137 /* */ 138 /************************************************************************************/ 139 140 void LVEQNB_SetFilters(LVEQNB_Instance_t *pInstance, 141 LVEQNB_Params_t *pParams) 142 { 143 144 extern const LVM_UINT16 LVEQNB_SampleRateTab[]; /* Sample rate table */ 145 LVM_UINT16 i; /* Filter band index */ 146 LVM_UINT32 fs = (LVM_UINT32)LVEQNB_SampleRateTab[(LVM_UINT16)pParams->SampleRate]; /* Sample rate */ 147 LVM_UINT32 fc; /* Filter centre frequency */ 148 LVM_INT16 QFactor; /* Filter Q factor */ 149 150 151 pInstance->NBands = pParams->NBands; 152 153 for (i=0; i<pParams->NBands; i++) 154 { 155 /* 156 * Get the filter settings 157 */ 158 fc = (LVM_UINT32)pParams->pBandDefinition[i].Frequency; /* Get the band centre frequency */ 159 QFactor = (LVM_INT16)pParams->pBandDefinition[i].QFactor; /* Get the band Q factor */ 160 161 162 /* 163 * For each filter set the type of biquad required 164 */ 165 pInstance->pBiquadType[i] = LVEQNB_SinglePrecision; /* Default to single precision */ 166 if ((fc << 15) <= (LOW_FREQ * fs)) 167 { 168 /* 169 * fc <= fs/110 170 */ 171 pInstance->pBiquadType[i] = LVEQNB_DoublePrecision; 172 } 173 else if (((fc << 15) <= (HIGH_FREQ * fs)) && (QFactor > 300)) 174 { 175 /* 176 * (fs/110 < fc < fs/85) & (Q>3) 177 */ 178 pInstance->pBiquadType[i] = LVEQNB_DoublePrecision; 179 } 180 181 182 /* 183 * Check for out of range frequencies 184 */ 185 if (fc > (fs >> 1)) 186 { 187 pInstance->pBiquadType[i] = LVEQNB_OutOfRange; 188 } 189 190 191 /* 192 * Copy the filter definition to persistant memory 193 */ 194 pInstance->pBandDefinitions[i] = pParams->pBandDefinition[i]; 195 196 } 197 } 198 199 200 /************************************************************************************/ 201 /* */ 202 /* FUNCTION: LVEQNB_SetCoefficients */ 203 /* */ 204 /* DESCRIPTION: */ 205 /* Sets the filter coefficients. This uses the type to select single or double */ 206 /* precision coefficients. */ 207 /* */ 208 /* PARAMETERS: */ 209 /* pInstance Pointer to the instance */ 210 /* pParams Initialisation parameters */ 211 /* */ 212 /************************************************************************************/ 213 214 void LVEQNB_SetCoefficients(LVEQNB_Instance_t *pInstance) 215 { 216 217 LVM_UINT16 i; /* Filter band index */ 218 LVEQNB_BiquadType_en BiquadType; /* Filter biquad type */ 219 220 221 /* 222 * Set the coefficients for each band by the init function 223 */ 224 for (i=0; i<pInstance->Params.NBands; i++) 225 { 226 227 /* 228 * Check band type for correct initialisation method and recalculate the coefficients 229 */ 230 BiquadType = pInstance->pBiquadType[i]; 231 switch (BiquadType) 232 { 233 case LVEQNB_DoublePrecision: 234 { 235 PK_C32_Coefs_t Coefficients; 236 237 /* 238 * Calculate the double precision coefficients 239 */ 240 LVEQNB_DoublePrecCoefs((LVM_UINT16)pInstance->Params.SampleRate, 241 &pInstance->pBandDefinitions[i], 242 &Coefficients); 243 244 /* 245 * Set the coefficients 246 */ 247 PK_2I_D32F32CllGss_TRC_WRA_01_Init(&pInstance->pEQNB_FilterState[i], 248 &pInstance->pEQNB_Taps[i], 249 &Coefficients); 250 break; 251 } 252 253 case LVEQNB_SinglePrecision: 254 { 255 PK_C16_Coefs_t Coefficients; 256 257 /* 258 * Calculate the single precision coefficients 259 */ 260 LVEQNB_SinglePrecCoefs((LVM_UINT16)pInstance->Params.SampleRate, 261 &pInstance->pBandDefinitions[i], 262 &Coefficients); 263 264 /* 265 * Set the coefficients 266 */ 267 PK_2I_D32F32CssGss_TRC_WRA_01_Init(&pInstance->pEQNB_FilterState[i], 268 &pInstance->pEQNB_Taps[i], 269 &Coefficients); 270 break; 271 } 272 default: 273 break; 274 } 275 } 276 277 } 278 279 280 /************************************************************************************/ 281 /* */ 282 /* FUNCTION: LVEQNB_ClearFilterHistory */ 283 /* */ 284 /* DESCRIPTION: */ 285 /* Clears the filter data history */ 286 /* */ 287 /* PARAMETERS: */ 288 /* pInstance Pointer to the instance */ 289 /* */ 290 /************************************************************************************/ 291 292 void LVEQNB_ClearFilterHistory(LVEQNB_Instance_t *pInstance) 293 { 294 LVM_INT16 *pTapAddress; 295 LVM_INT16 NumTaps; 296 297 298 pTapAddress = (LVM_INT16 *)pInstance->pEQNB_Taps; 299 NumTaps = (LVM_INT16)((pInstance->Capabilities.MaxBands * sizeof(Biquad_2I_Order2_Taps_t))/sizeof(LVM_INT16)); 300 301 if (NumTaps != 0) 302 { 303 LoadConst_16(0, /* Clear the history, value 0 */ 304 pTapAddress, /* Destination */ 305 NumTaps); /* Number of words */ 306 } 307 } 308 309 310 /****************************************************************************************/ 311 /* */ 312 /* FUNCTION: LVEQNB_Control */ 313 /* */ 314 /* DESCRIPTION: */ 315 /* Sets or changes the LifeVibes module parameters. */ 316 /* */ 317 /* PARAMETERS: */ 318 /* hInstance Instance handle */ 319 /* pParams Pointer to a parameter structure */ 320 /* */ 321 /* RETURNS: */ 322 /* LVEQNB_Success Always succeeds */ 323 /* LVEQNB_NULLADDRESS Instance or pParams is NULL pointer */ 324 /* LVEQNB_NULLADDRESS NULL address for the equaliser filter definitions and the */ 325 /* number of bands is non-zero */ 326 /* */ 327 /* NOTES: */ 328 /* 1. This function may be interrupted by the LVEQNB_Process function */ 329 /* */ 330 /****************************************************************************************/ 331 332 LVEQNB_ReturnStatus_en LVEQNB_Control(LVEQNB_Handle_t hInstance, 333 LVEQNB_Params_t *pParams) 334 { 335 336 LVEQNB_Instance_t *pInstance = (LVEQNB_Instance_t *)hInstance; 337 LVM_INT16 bChange = LVM_FALSE; 338 LVM_INT16 i = 0; 339 LVEQNB_Mode_en OperatingModeSave ; 340 341 /* 342 * Check for error conditions 343 */ 344 if((hInstance == LVM_NULL) || (pParams == LVM_NULL)) 345 { 346 return LVEQNB_NULLADDRESS; 347 } 348 349 if((pParams->NBands !=0) && (pParams->pBandDefinition==LVM_NULL)) 350 { 351 return LVEQNB_NULLADDRESS; 352 } 353 354 OperatingModeSave = pInstance->Params.OperatingMode; 355 356 /* Set the alpha factor of the mixer */ 357 if (pParams->SampleRate != pInstance->Params.SampleRate) 358 { 359 LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->BypassMixer.MixerStream[0],LVEQNB_BYPASS_MIXER_TC,(LVM_Fs_en)pParams->SampleRate,2); 360 LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->BypassMixer.MixerStream[1],LVEQNB_BYPASS_MIXER_TC,(LVM_Fs_en)pParams->SampleRate,2); 361 } 362 363 364 if( (pInstance->Params.NBands != pParams->NBands ) || 365 (pInstance->Params.OperatingMode != pParams->OperatingMode ) || 366 (pInstance->Params.pBandDefinition != pParams->pBandDefinition ) || 367 (pInstance->Params.SampleRate != pParams->SampleRate ) || 368 (pInstance->Params.SourceFormat != pParams->SourceFormat )) 369 { 370 371 bChange = LVM_TRUE; 372 } 373 else 374 { 375 for(i = 0; i < pParams->NBands; i++) 376 { 377 378 if((pInstance->pBandDefinitions[i].Frequency != pParams->pBandDefinition[i].Frequency )|| 379 (pInstance->pBandDefinitions[i].Gain != pParams->pBandDefinition[i].Gain )|| 380 (pInstance->pBandDefinitions[i].QFactor != pParams->pBandDefinition[i].QFactor )) 381 { 382 383 bChange = LVM_TRUE; 384 } 385 } 386 } 387 388 389 if(bChange){ 390 391 /* 392 * If the sample rate has changed clear the history 393 */ 394 if (pInstance->Params.SampleRate != pParams->SampleRate) 395 { 396 LVEQNB_ClearFilterHistory(pInstance); /* Clear the history */ 397 } 398 399 /* 400 * Update the instance parameters 401 */ 402 pInstance->Params = *pParams; 403 404 405 /* 406 * Reset the filters except if the algo is switched off 407 */ 408 if(pParams->OperatingMode != LVEQNB_BYPASS){ 409 /* 410 * Reset the filters as all parameters could have changed 411 */ 412 LVEQNB_SetFilters(pInstance, /* Instance pointer */ 413 pParams); /* New parameters */ 414 415 /* 416 * Update the filters 417 */ 418 LVEQNB_SetCoefficients(pInstance); /* Instance pointer */ 419 } 420 421 if(pParams->OperatingMode != OperatingModeSave) 422 { 423 if(pParams->OperatingMode == LVEQNB_ON) 424 { 425 LVC_Mixer_SetTarget(&pInstance->BypassMixer.MixerStream[0],LVM_MAXINT_16); 426 LVC_Mixer_SetTarget(&pInstance->BypassMixer.MixerStream[1],0); 427 428 pInstance->BypassMixer.MixerStream[0].CallbackSet = 1; 429 pInstance->BypassMixer.MixerStream[1].CallbackSet = 1; 430 } 431 else 432 { 433 /* Stay on the ON operating mode until the transition is done */ 434 pInstance->Params.OperatingMode = LVEQNB_ON; 435 436 LVC_Mixer_SetTarget(&pInstance->BypassMixer.MixerStream[0],0); 437 LVC_Mixer_SetTarget(&pInstance->BypassMixer.MixerStream[1],LVM_MAXINT_16); 438 pInstance->BypassMixer.MixerStream[0].CallbackSet = 1; 439 pInstance->BypassMixer.MixerStream[1].CallbackSet = 1; 440 } 441 LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->BypassMixer.MixerStream[0],LVEQNB_BYPASS_MIXER_TC,(LVM_Fs_en)pParams->SampleRate,2); 442 LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->BypassMixer.MixerStream[1],LVEQNB_BYPASS_MIXER_TC,(LVM_Fs_en)pParams->SampleRate,2); 443 444 pInstance->bInOperatingModeTransition = LVM_TRUE; 445 } 446 447 } 448 return(LVEQNB_SUCCESS); 449 } 450 451 452 /****************************************************************************************/ 453 /* */ 454 /* FUNCTION: LVEQNB_BypassMixerCallBack */ 455 /* */ 456 /* DESCRIPTION: */ 457 /* CallBack function of the mixer */ 458 /* transition */ 459 /* */ 460 /****************************************************************************************/ 461 LVM_INT32 LVEQNB_BypassMixerCallBack (void* hInstance, 462 void *pGeneralPurpose, 463 LVM_INT16 CallbackParam) 464 { 465 LVEQNB_Instance_t *pInstance =(LVEQNB_Instance_t *)hInstance; 466 LVM_Callback CallBack = pInstance->Capabilities.CallBack; 467 468 (void) pGeneralPurpose; 469 470 /* 471 * Send an ALGOFF event if the ON->OFF switch transition is finished 472 */ 473 if((LVC_Mixer_GetTarget(&pInstance->BypassMixer.MixerStream[0]) == 0x00000000) && 474 (CallbackParam == 0)){ 475 pInstance->Params.OperatingMode = LVEQNB_BYPASS; 476 if (CallBack != LVM_NULL){ 477 CallBack(pInstance->Capabilities.pBundleInstance, LVM_NULL, ALGORITHM_EQNB_ID|LVEQNB_EVENT_ALGOFF); 478 } 479 } 480 481 /* 482 * Exit transition state 483 */ 484 pInstance->bInOperatingModeTransition = LVM_FALSE; 485 486 return 1; 487 } 488 489 490 491 492 493 494