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 #include "LVPSA.h" 19 #include "LVPSA_Private.h" 20 #include "VectorArithmetic.h" 21 22 #define LOW_FREQ 298 /* 32768/110 for low test frequency */ 23 #define HIGH_FREQ 386 /* 32768/85 for high test frequency */ 24 25 LVPSA_RETURN LVPSA_SetBPFiltersType ( LVPSA_InstancePr_t *pInst, 26 LVPSA_ControlParams_t *pParams ); 27 28 LVPSA_RETURN LVPSA_SetQPFCoefficients( LVPSA_InstancePr_t *pInst, 29 LVPSA_ControlParams_t *pParams ); 30 31 LVPSA_RETURN LVPSA_BPSinglePrecCoefs( LVM_UINT16 Fs, 32 LVPSA_FilterParam_t *pFilterParams, 33 BP_C16_Coefs_t *pCoefficients); 34 35 LVPSA_RETURN LVPSA_BPDoublePrecCoefs( LVM_UINT16 Fs, 36 LVPSA_FilterParam_t *pFilterParams, 37 BP_C32_Coefs_t *pCoefficients); 38 39 LVPSA_RETURN LVPSA_BPDoublePrecCoefs( LVM_UINT16 Fs, 40 LVPSA_FilterParam_t *pFilterParams, 41 BP_C32_Coefs_t *pCoefficients); 42 43 LVPSA_RETURN LVPSA_SetBPFCoefficients( LVPSA_InstancePr_t *pInst, 44 LVPSA_ControlParams_t *pParams ); 45 46 LVPSA_RETURN LVPSA_ClearFilterHistory( LVPSA_InstancePr_t *pInst); 47 48 49 50 51 /************************************************************************************/ 52 /* */ 53 /* FUNCTION: LVPSA_Control */ 54 /* */ 55 /* DESCRIPTION: */ 56 /* Give some new control parameters to the module. */ 57 /* */ 58 /* PARAMETERS: */ 59 /* hInstance Pointer to the instance */ 60 /* NewParams Structure that contains the new parameters */ 61 /* */ 62 /* RETURNS: */ 63 /* LVPSA_OK Succeeds */ 64 /* otherwise Error due to bad parameters */ 65 /* */ 66 /************************************************************************************/ 67 LVPSA_RETURN LVPSA_Control ( pLVPSA_Handle_t hInstance, 68 LVPSA_ControlParams_t *pNewParams ) 69 { 70 71 LVPSA_InstancePr_t *pLVPSA_Inst = (LVPSA_InstancePr_t*)hInstance; 72 73 if((hInstance == LVM_NULL) || (pNewParams == LVM_NULL)) 74 { 75 return(LVPSA_ERROR_NULLADDRESS); 76 } 77 if(pNewParams->Fs >= LVPSA_NR_SUPPORTED_RATE) 78 { 79 return(LVPSA_ERROR_INVALIDPARAM); 80 } 81 if(pNewParams->LevelDetectionSpeed >= LVPSA_NR_SUPPORTED_SPEED) 82 { 83 return(LVPSA_ERROR_INVALIDPARAM); 84 } 85 86 pLVPSA_Inst->NewParams = *pNewParams; 87 pLVPSA_Inst->bControlPending = LVM_TRUE; 88 89 return(LVPSA_OK); 90 } 91 92 /************************************************************************************/ 93 /* */ 94 /* FUNCTION: LVPSA_GetControlParams */ 95 /* */ 96 /* DESCRIPTION: */ 97 /* Get the current control parameters of the module */ 98 /* */ 99 /* PARAMETERS: */ 100 /* hInstance Pointer to the instance */ 101 /* pParams Pointer to an empty control structure */ 102 /* RETURNS: */ 103 /* LVPSA_OK Succeeds */ 104 /* otherwise Error due to bad parameters */ 105 /* */ 106 /************************************************************************************/ 107 LVPSA_RETURN LVPSA_GetControlParams ( pLVPSA_Handle_t hInstance, 108 LVPSA_ControlParams_t *pParams ) 109 { 110 LVPSA_InstancePr_t *pLVPSA_Inst = (LVPSA_InstancePr_t*)hInstance; 111 112 if((hInstance == LVM_NULL) || (pParams == LVM_NULL)) 113 { 114 return(LVPSA_ERROR_NULLADDRESS); 115 } 116 117 pParams->Fs = pLVPSA_Inst->CurrentParams.Fs; 118 pParams->LevelDetectionSpeed = pLVPSA_Inst->CurrentParams.LevelDetectionSpeed; 119 120 return(LVPSA_OK); 121 } 122 123 124 /************************************************************************************/ 125 /* */ 126 /* FUNCTION: LVPSA_GetInitParams */ 127 /* */ 128 /* DESCRIPTION: */ 129 /* Get the initialization parameters of the module */ 130 /* */ 131 /* PARAMETERS: */ 132 /* hInstance Pointer to the instance */ 133 /* pParams Pointer to an empty control structure */ 134 /* RETURNS: */ 135 /* LVPSA_OK Succeeds */ 136 /* otherwise Error due to bad parameters */ 137 /* */ 138 /************************************************************************************/ 139 LVPSA_RETURN LVPSA_GetInitParams ( pLVPSA_Handle_t hInstance, 140 LVPSA_InitParams_t *pParams ) 141 { 142 LVPSA_InstancePr_t *pLVPSA_Inst = (LVPSA_InstancePr_t*)hInstance; 143 144 if((hInstance == LVM_NULL) || (pParams == LVM_NULL)) 145 { 146 return(LVPSA_ERROR_NULLADDRESS); 147 } 148 149 pParams->SpectralDataBufferDuration = pLVPSA_Inst->SpectralDataBufferDuration; 150 pParams->MaxInputBlockSize = pLVPSA_Inst->MaxInputBlockSize; 151 pParams->nBands = pLVPSA_Inst->nBands; 152 pParams->pFiltersParams = pLVPSA_Inst->pFiltersParams; 153 154 return(LVPSA_OK); 155 } 156 157 158 /************************************************************************************/ 159 /* */ 160 /* FUNCTION: LVPSA_ApplyNewSettings */ 161 /* */ 162 /* DESCRIPTION: */ 163 /* Reinitialize some parameters and changes filters' coefficients if */ 164 /* some control parameters have changed. */ 165 /* */ 166 /* PARAMETERS: */ 167 /* pInst Pointer to the instance */ 168 /* */ 169 /* RETURNS: */ 170 /* LVPSA_OK Succeeds */ 171 /* otherwise Error due to bad parameters */ 172 /* */ 173 /* NOTES: */ 174 /* */ 175 /************************************************************************************/ 176 LVPSA_RETURN LVPSA_ApplyNewSettings (LVPSA_InstancePr_t *pInst) 177 { 178 LVM_UINT16 ii; 179 LVM_UINT16 Freq; 180 LVPSA_ControlParams_t Params; 181 extern LVM_INT16 LVPSA_nSamplesBufferUpdate[]; 182 extern LVM_UINT16 LVPSA_SampleRateTab[]; 183 extern LVM_UINT16 LVPSA_DownSamplingFactor[]; 184 185 186 if(pInst == 0) 187 { 188 return(LVPSA_ERROR_NULLADDRESS); 189 } 190 191 Params = pInst->NewParams; 192 193 /* Modifies filters types and coefficients, clear the taps and 194 re-initializes parameters if sample frequency has changed */ 195 if(Params.Fs != pInst->CurrentParams.Fs) 196 { 197 pInst->CurrentParams.Fs = Params.Fs; 198 199 /* Initialize the center freqeuncies as a function of the sample rate */ 200 Freq = (LVM_UINT16) ((LVPSA_SampleRateTab[pInst->CurrentParams.Fs]>>1) / (pInst->nBands + 1)); 201 for(ii = pInst->nBands; ii > 0; ii--) 202 { 203 pInst->pFiltersParams[ii-1].CenterFrequency = (LVM_UINT16) (Freq * ii); 204 } 205 206 /* Count the number of relevant filters. If the center frequency of the filter is 207 bigger than the nyquist frequency, then the filter is not relevant and doesn't 208 need to be used */ 209 for(ii = pInst->nBands; ii > 0; ii--) 210 { 211 if(pInst->pFiltersParams[ii-1].CenterFrequency < (LVPSA_SampleRateTab[pInst->CurrentParams.Fs]>>1)) 212 { 213 pInst->nRelevantFilters = ii; 214 break; 215 } 216 } 217 LVPSA_SetBPFiltersType(pInst, &Params); 218 LVPSA_SetBPFCoefficients(pInst, &Params); 219 LVPSA_SetQPFCoefficients(pInst, &Params); 220 LVPSA_ClearFilterHistory(pInst); 221 pInst->nSamplesBufferUpdate = (LVM_UINT16)LVPSA_nSamplesBufferUpdate[Params.Fs]; 222 pInst->BufferUpdateSamplesCount = 0; 223 pInst->DownSamplingFactor = LVPSA_DownSamplingFactor[Params.Fs]; 224 pInst->DownSamplingCount = 0; 225 for(ii = 0; ii < (pInst->nBands * pInst->SpectralDataBufferLength); ii++) 226 { 227 pInst->pSpectralDataBufferStart[ii] = 0; 228 } 229 for(ii = 0; ii < pInst->nBands; ii++) 230 { 231 pInst->pPreviousPeaks[ii] = 0; 232 } 233 } 234 else 235 { 236 if(Params.LevelDetectionSpeed != pInst->CurrentParams.LevelDetectionSpeed) 237 { 238 LVPSA_SetQPFCoefficients(pInst, &Params); 239 } 240 } 241 242 pInst->CurrentParams = pInst->NewParams; 243 244 return (LVPSA_OK); 245 } 246 /************************************************************************************/ 247 /* */ 248 /* FUNCTION: LVPSA_SetBPFiltersType */ 249 /* */ 250 /* DESCRIPTION: */ 251 /* Sets the filter type based on the BPFilterType. */ 252 /* */ 253 /* PARAMETERS: */ 254 /* pInst Pointer to the instance */ 255 /* pParams Poniter to conrol parameters */ 256 /* */ 257 /* RETURNS: */ 258 /* LVPSA_OK Always succeeds */ 259 /* */ 260 /* NOTES: */ 261 /* 1. To select the biquad type the follow rules are applied: */ 262 /* Double precision if (fc <= fs/110) */ 263 /* Double precision if (fs/110 < fc < fs/85) & (Q>3) */ 264 /* Single precision otherwise */ 265 /* */ 266 /************************************************************************************/ 267 LVPSA_RETURN LVPSA_SetBPFiltersType ( LVPSA_InstancePr_t *pInst, 268 LVPSA_ControlParams_t *pParams ) 269 { 270 271 extern LVM_UINT16 LVPSA_SampleRateTab[]; /* Sample rate table */ 272 LVM_UINT16 ii; /* Filter band index */ 273 LVM_UINT32 fs = (LVM_UINT32)LVPSA_SampleRateTab[(LVM_UINT16)pParams->Fs]; /* Sample rate */ 274 LVM_UINT32 fc; /* Filter centre frequency */ 275 LVM_INT16 QFactor; /* Filter Q factor */ 276 277 for (ii = 0; ii < pInst->nRelevantFilters; ii++) 278 { 279 /* 280 * Get the filter settings 281 */ 282 fc = (LVM_UINT32)pInst->pFiltersParams[ii].CenterFrequency; /* Get the band centre frequency */ 283 QFactor =(LVM_INT16) pInst->pFiltersParams[ii].QFactor; /* Get the band Q factor */ 284 285 286 /* 287 * For each filter set the type of biquad required 288 */ 289 pInst->pBPFiltersPrecision[ii] = LVPSA_SimplePrecisionFilter; /* Default to single precision */ 290 if ((LOW_FREQ * fs) >= (fc << 15)) 291 { 292 /* 293 * fc <= fs/110 294 */ 295 pInst->pBPFiltersPrecision[ii] = LVPSA_DoublePrecisionFilter; 296 } 297 else 298 { 299 if (((LOW_FREQ * fs) < (fc << 15)) && ((fc << 15) < (HIGH_FREQ * fs)) && (QFactor > 300)) 300 { 301 /* 302 * (fs/110 < fc < fs/85) & (Q>3) 303 */ 304 pInst->pBPFiltersPrecision[ii] = LVPSA_DoublePrecisionFilter; 305 } 306 } 307 } 308 309 return(LVPSA_OK); 310 } 311 312 /************************************************************************************/ 313 /* */ 314 /* FUNCTION: LVPSA_SetBPFCoefficients */ 315 /* */ 316 /* DESCRIPTION: */ 317 /* Sets the band pass filter coefficients. This uses the type to select */ 318 /* single or double precision coefficients. */ 319 /* */ 320 /* PARAMETERS: */ 321 /* pInst Pointer to the instance */ 322 /* Params Initialisation parameters */ 323 /* */ 324 /* RETURNS: */ 325 /* LVPSA_OK Always succeeds */ 326 /* */ 327 /* NOTES: */ 328 /* */ 329 /************************************************************************************/ 330 LVPSA_RETURN LVPSA_SetBPFCoefficients( LVPSA_InstancePr_t *pInst, 331 LVPSA_ControlParams_t *pParams) 332 { 333 334 LVM_UINT16 ii; 335 336 /* 337 * Set the coefficients for each band by the init function 338 */ 339 for (ii = 0; ii < pInst->nRelevantFilters; ii++) 340 { 341 switch (pInst->pBPFiltersPrecision[ii]) 342 { 343 case LVPSA_DoublePrecisionFilter: 344 { 345 BP_C32_Coefs_t Coefficients; 346 347 /* 348 * Calculate the double precision coefficients 349 */ 350 LVPSA_BPDoublePrecCoefs((LVM_UINT16)pParams->Fs, 351 &pInst->pFiltersParams[ii], 352 &Coefficients); 353 354 /* 355 * Set the coefficients 356 */ 357 BP_1I_D16F32Cll_TRC_WRA_01_Init ( &pInst->pBP_Instances[ii], 358 &pInst->pBP_Taps[ii], 359 &Coefficients); 360 break; 361 } 362 363 case LVPSA_SimplePrecisionFilter: 364 { 365 BP_C16_Coefs_t Coefficients; 366 367 /* 368 * Calculate the single precision coefficients 369 */ 370 LVPSA_BPSinglePrecCoefs((LVM_UINT16)pParams->Fs, 371 &pInst->pFiltersParams[ii], 372 &Coefficients); 373 374 /* 375 * Set the coefficients 376 */ 377 BP_1I_D16F16Css_TRC_WRA_01_Init ( &pInst->pBP_Instances[ii], 378 &pInst->pBP_Taps[ii], 379 &Coefficients); 380 break; 381 } 382 } 383 } 384 385 return(LVPSA_OK); 386 } 387 388 389 /************************************************************************************/ 390 /* */ 391 /* FUNCTION: LVPSA_SetQPFCoefficients */ 392 /* */ 393 /* DESCRIPTION: */ 394 /* Sets the quasi peak filters coefficients. This uses the chosen */ 395 /* LevelDetectionSpeed from the control parameters. */ 396 /* */ 397 /* PARAMETERS: */ 398 /* pInst Pointer to the instance */ 399 /* Params Control parameters */ 400 /* */ 401 /* RETURNS: */ 402 /* LVPSA_OK Always succeeds */ 403 /* */ 404 /* NOTES: */ 405 /* */ 406 /************************************************************************************/ 407 LVPSA_RETURN LVPSA_SetQPFCoefficients( LVPSA_InstancePr_t *pInst, 408 LVPSA_ControlParams_t *pParams ) 409 { 410 LVM_UINT16 ii; 411 LVM_Fs_en Fs = pParams->Fs; 412 QPD_C32_Coefs *pCoefficients; 413 extern QPD_C32_Coefs LVPSA_QPD_Coefs[]; 414 415 416 pCoefficients = &LVPSA_QPD_Coefs[(pParams->LevelDetectionSpeed * LVPSA_NR_SUPPORTED_RATE) + Fs]; 417 418 419 for (ii = 0; ii < pInst->nRelevantFilters; ii++) 420 { 421 LVPSA_QPD_Init (&pInst->pQPD_States[ii], 422 &pInst->pQPD_Taps[ii], 423 pCoefficients ); 424 } 425 426 return(LVPSA_OK); 427 428 } 429 430 /****************************************************************************************/ 431 /* */ 432 /* FUNCTION: LVPSA_BPSinglePrecCoefs */ 433 /* */ 434 /* DESCRIPTION: */ 435 /* Calculate single precision coefficients for a band pass filter */ 436 /* */ 437 /* PARAMETERS: */ 438 /* Fs Sampling frequency index */ 439 /* pFilterParams Pointer to the filter definition */ 440 /* pCoefficients Pointer to the coefficients */ 441 /* */ 442 /* RETURNS: */ 443 /* LVPSA_OK Always succeeds */ 444 /* */ 445 /* NOTES: */ 446 /* 1. The equations used are as follows: */ 447 /* */ 448 /* t0 = 2 * Pi * Fc / Fs */ 449 /* */ 450 /* b2 = -0.5 * (2Q - t0) / (2Q + t0) */ 451 /* b1 = (0.5 - b2) * cos(t0) */ 452 /* a0 = (0.5 + b2) / 2 */ 453 /* */ 454 /* Where: */ 455 /* Fc is the centre frequency, DC to Nyquist */ 456 /* Fs is the sample frequency, 8000 to 48000 in descrete steps */ 457 /* Q is the Q factor, 0.25 to 12 */ 458 /* */ 459 /* 2. This function is entirely based on the LVEQNB_SinglePrecCoefs function */ 460 /* of the n bands equalizer (LVEQNB */ 461 /* */ 462 /****************************************************************************************/ 463 LVPSA_RETURN LVPSA_BPSinglePrecCoefs( LVM_UINT16 Fs, 464 LVPSA_FilterParam_t *pFilterParams, 465 BP_C16_Coefs_t *pCoefficients) 466 { 467 468 extern LVM_INT16 LVPSA_TwoPiOnFsTable[]; 469 extern LVM_INT16 LVPSA_CosCoef[]; 470 471 472 /* 473 * Intermediate variables and temporary values 474 */ 475 LVM_INT32 T0; 476 LVM_INT16 D; 477 LVM_INT32 A0; 478 LVM_INT32 B1; 479 LVM_INT32 B2; 480 LVM_INT32 Dt0; 481 LVM_INT32 B2_Den; 482 LVM_INT32 B2_Num; 483 LVM_INT32 COS_T0; 484 LVM_INT16 coef; 485 LVM_INT32 factor; 486 LVM_INT16 t0; 487 LVM_INT16 i; 488 489 490 /* 491 * Get the filter definition 492 */ 493 LVM_UINT16 Frequency = pFilterParams->CenterFrequency; 494 LVM_UINT16 QFactor = pFilterParams->QFactor; 495 496 497 /* 498 * Calculating the intermediate values 499 */ 500 T0 = (LVM_INT32)Frequency * LVPSA_TwoPiOnFsTable[Fs]; /* T0 = 2 * Pi * Fc / Fs */ 501 D = 3200; /* Floating point value 1.000000 (1*100*2^5) */ 502 /* Force D = 1 : the function was originally used for a peaking filter. 503 The D parameter do not exist for a BandPass filter coefficients */ 504 505 /* 506 * Calculate the B2 coefficient 507 */ 508 Dt0 = D * (T0 >> 10); 509 B2_Den = (LVM_INT32)(((LVM_UINT32)QFactor << 19) + (LVM_UINT32)(Dt0 >> 2)); 510 B2_Num = (LVM_INT32)((LVM_UINT32)(Dt0 >> 3) - ((LVM_UINT32)QFactor << 18)); 511 B2 = (B2_Num / (B2_Den >> 16)) << 15; 512 513 /* 514 * Calculate the cosine by a polynomial expansion using the equation: 515 * 516 * Cos += coef(n) * t0^n For n = 0 to 6 517 */ 518 T0 = (T0 >> 10) * 20859; /* Scale to 1.0 in 16-bit for range 0 to fs/2 */ 519 t0 = (LVM_INT16)(T0 >> 16); 520 factor = 0x7fff; /* Initialise to 1.0 for the a0 coefficient */ 521 COS_T0 = 0; /* Initialise the error to zero */ 522 for (i=1; i<7; i++) 523 { 524 coef = LVPSA_CosCoef[i]; /* Get the nth coefficient */ 525 COS_T0 += (factor * coef) >> 5; /* The nth partial sum */ 526 factor = (factor * t0) >> 15; /* Calculate t0^n */ 527 } 528 COS_T0 = COS_T0 << (LVPSA_CosCoef[0]+6); /* Correct the scaling */ 529 530 531 B1 = ((0x40000000 - B2) >> 16) * (COS_T0 >> 16); /* B1 = (0.5 - b2) * cos(t0) */ 532 A0 = (0x40000000 + B2) >> 1; /* A0 = (0.5 + b2) / 2 */ 533 534 /* 535 * Write coeff into the data structure 536 */ 537 pCoefficients->A0 = (LVM_INT16)(A0>>16); 538 pCoefficients->B1 = (LVM_INT16)(B1>>15); 539 pCoefficients->B2 = (LVM_INT16)(B2>>16); 540 541 542 return(LVPSA_OK); 543 } 544 545 /****************************************************************************************/ 546 /* */ 547 /* FUNCTION: LVPSA_BPDoublePrecCoefs */ 548 /* */ 549 /* DESCRIPTION: */ 550 /* Calculate double precision coefficients for a band pass filter */ 551 /* */ 552 /* PARAMETERS: */ 553 /* Fs Sampling frequency index */ 554 /* pFilterParams Pointer to the filter definition */ 555 /* pCoefficients Pointer to the coefficients */ 556 /* */ 557 /* RETURNS: */ 558 /* LVPSA_OK Always succeeds */ 559 /* */ 560 /* NOTES: */ 561 /* 1. The equations used are as follows: */ 562 /* */ 563 /* t0 = 2 * Pi * Fc / Fs */ 564 /* */ 565 /* b2 = -0.5 * (2Q - t0) / (2Q + t0) */ 566 /* b1 = (0.5 - b2) * (1 - coserr(t0)) */ 567 /* a0 = (0.5 + b2) / 2 */ 568 /* */ 569 /* Where: */ 570 /* Fc is the centre frequency, DC to Fs/50 */ 571 /* Fs is the sample frequency, 8000 to 48000 in descrete steps */ 572 /* Q is the Q factor, 0.25 to 12 (represented by 25 to 1200) */ 573 /* */ 574 /* 2. The double precision coefficients are only used when fc is less than fs/85, so */ 575 /* the cosine of t0 is always close to 1.0. Instead of calculating the cosine */ 576 /* itself the difference from the value 1.0 is calculated, this can be done with */ 577 /* lower precision maths. */ 578 /* */ 579 /* 3. The value of the B2 coefficient is only calculated as a single precision value, */ 580 /* small errors in this value have a combined effect on the Q and Gain but not the */ 581 /* the frequency of the filter. */ 582 /* */ 583 /* 4. This function is entirely based on the LVEQNB_DoublePrecCoefs function */ 584 /* of the n bands equalizer (LVEQNB */ 585 /* */ 586 /****************************************************************************************/ 587 LVPSA_RETURN LVPSA_BPDoublePrecCoefs( LVM_UINT16 Fs, 588 LVPSA_FilterParam_t *pFilterParams, 589 BP_C32_Coefs_t *pCoefficients) 590 { 591 592 extern LVM_INT16 LVPSA_TwoPiOnFsTable[]; 593 extern LVM_INT16 LVPSA_DPCosCoef[]; 594 595 /* 596 * Intermediate variables and temporary values 597 */ 598 LVM_INT32 T0; 599 LVM_INT16 D; 600 LVM_INT32 A0; 601 LVM_INT32 B1; 602 LVM_INT32 B2; 603 LVM_INT32 Dt0; 604 LVM_INT32 B2_Den; 605 LVM_INT32 B2_Num; 606 LVM_INT32 CosErr; 607 LVM_INT16 coef; 608 LVM_INT32 factor; 609 LVM_INT16 t0; 610 LVM_INT16 i; 611 612 /* 613 * Get the filter definition 614 */ 615 LVM_UINT16 Frequency = pFilterParams->CenterFrequency; 616 LVM_UINT16 QFactor = pFilterParams->QFactor; 617 618 619 /* 620 * Calculating the intermediate values 621 */ 622 T0 = (LVM_INT32)Frequency * LVPSA_TwoPiOnFsTable[Fs]; /* T0 = 2 * Pi * Fc / Fs */ 623 D = 3200; /* Floating point value 1.000000 (1*100*2^5) */ 624 /* Force D = 1 : the function was originally used for a peaking filter. 625 The D parameter do not exist for a BandPass filter coefficients */ 626 627 /* 628 * Calculate the B2 coefficient 629 */ 630 Dt0 = D * (T0 >> 10); 631 B2_Den = (LVM_INT32)(((LVM_UINT32)QFactor << 19) + (LVM_UINT32)(Dt0 >> 2)); 632 B2_Num = (LVM_INT32)((LVM_UINT32)(Dt0 >> 3) - ((LVM_UINT32)QFactor << 18)); 633 B2 = (B2_Num / (B2_Den >> 16)) << 15; 634 635 /* 636 * Calculate the cosine error by a polynomial expansion using the equation: 637 * 638 * CosErr += coef(n) * t0^n For n = 0 to 4 639 */ 640 T0 = (T0 >> 6) * 0x7f53; /* Scale to 1.0 in 16-bit for range 0 to fs/50 */ 641 t0 = (LVM_INT16)(T0 >> 16); 642 factor = 0x7fff; /* Initialise to 1.0 for the a0 coefficient */ 643 CosErr = 0; /* Initialise the error to zero */ 644 for (i=1; i<5; i++) 645 { 646 coef = LVPSA_DPCosCoef[i]; /* Get the nth coefficient */ 647 CosErr += (factor * coef) >> 5; /* The nth partial sum */ 648 factor = (factor * t0) >> 15; /* Calculate t0^n */ 649 } 650 CosErr = CosErr << (LVPSA_DPCosCoef[0]); /* Correct the scaling */ 651 652 /* 653 * Calculate the B1 and A0 coefficients 654 */ 655 B1 = (0x40000000 - B2); /* B1 = (0.5 - b2) */ 656 A0 = ((B1 >> 16) * (CosErr >> 10)) >> 6; /* Temporary storage for (0.5 - b2) * coserr(t0) */ 657 B1 -= A0; /* B1 = (0.5 - b2) * (1 - coserr(t0)) */ 658 A0 = (0x40000000 + B2) >> 1; /* A0 = (0.5 + b2) / 2 */ 659 660 /* 661 * Write coeff into the data structure 662 */ 663 pCoefficients->A0 = A0; 664 pCoefficients->B1 = B1; 665 pCoefficients->B2 = B2; 666 667 return(LVPSA_OK); 668 } 669 670 /************************************************************************************/ 671 /* */ 672 /* FUNCTION: LVPSA_ClearFilterHistory */ 673 /* */ 674 /* DESCRIPTION: */ 675 /* Clears the filters' data history */ 676 /* */ 677 /* PARAMETERS: */ 678 /* pInst Pointer to the instance */ 679 /* */ 680 /* RETURNS: */ 681 /* LVPSA_OK Always succeeds */ 682 /* */ 683 /* NOTES: */ 684 /* */ 685 /************************************************************************************/ 686 LVPSA_RETURN LVPSA_ClearFilterHistory(LVPSA_InstancePr_t *pInst) 687 { 688 LVM_INT8 *pTapAddress; 689 LVM_UINT32 i; 690 691 /* Band Pass filters taps */ 692 pTapAddress = (LVM_INT8 *)pInst->pBP_Taps; 693 for(i = 0; i < pInst->nBands * sizeof(Biquad_1I_Order2_Taps_t); i++) 694 { 695 pTapAddress[i] = 0; 696 } 697 698 /* Quasi-peak filters taps */ 699 pTapAddress = (LVM_INT8 *)pInst->pQPD_Taps; 700 for(i = 0; i < pInst->nBands * sizeof(QPD_Taps_t); i++) 701 { 702 pTapAddress[i] = 0; 703 } 704 705 return(LVPSA_OK); 706 } 707 708