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 #include "LVREV_Private.h" 24 #include "Filter.h" 25 26 /****************************************************************************************/ 27 /* */ 28 /* FUNCTION: LVREV_ApplyNewSettings */ 29 /* */ 30 /* DESCRIPTION: */ 31 /* Applies the new control parameters */ 32 /* */ 33 /* PARAMETERS: */ 34 /* pPrivate Pointer to the instance private parameters */ 35 /* */ 36 /* RETURNS: */ 37 /* LVREV_Success Succeeded */ 38 /* LVREV_NULLADDRESS When pPrivate is NULL */ 39 /* */ 40 /* NOTES: */ 41 /* */ 42 /****************************************************************************************/ 43 44 #ifndef BUILD_FLOAT 45 LVREV_ReturnStatus_en LVREV_ApplyNewSettings (LVREV_Instance_st *pPrivate) 46 { 47 48 LVM_Mode_en OperatingMode; 49 LVM_INT32 NumberOfDelayLines; 50 51 52 /* Check for NULL pointer */ 53 if(pPrivate == LVM_NULL) 54 { 55 return LVREV_NULLADDRESS; 56 } 57 58 OperatingMode = pPrivate->NewParams.OperatingMode; 59 60 if(pPrivate->InstanceParams.NumDelays == LVREV_DELAYLINES_4) 61 { 62 NumberOfDelayLines = 4; 63 } 64 else if(pPrivate->InstanceParams.NumDelays == LVREV_DELAYLINES_2) 65 { 66 NumberOfDelayLines = 2; 67 } 68 else 69 { 70 NumberOfDelayLines = 1; 71 } 72 73 /* 74 * Update the high pass filter coefficients 75 */ 76 if((pPrivate->NewParams.HPF != pPrivate->CurrentParams.HPF) || 77 (pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) || 78 (pPrivate->bFirstControl == LVM_TRUE)) 79 { 80 LVM_INT32 Omega; 81 FO_C32_Coefs_t Coeffs; 82 83 Omega = LVM_GetOmega(pPrivate->NewParams.HPF, pPrivate->NewParams.SampleRate); 84 LVM_FO_HPF(Omega, &Coeffs); 85 FO_1I_D32F32Cll_TRC_WRA_01_Init( &pPrivate->pFastCoef->HPCoefs, &pPrivate->pFastData->HPTaps, &Coeffs); 86 LoadConst_32(0, 87 (void *)&pPrivate->pFastData->HPTaps, /* Destination Cast to void: no dereferencing in function*/ 88 sizeof(Biquad_1I_Order1_Taps_t)/sizeof(LVM_INT32)); 89 } 90 91 92 /* 93 * Update the low pass filter coefficients 94 */ 95 if((pPrivate->NewParams.LPF != pPrivate->CurrentParams.LPF) || 96 (pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) || 97 (pPrivate->bFirstControl == LVM_TRUE)) 98 { 99 LVM_INT32 Omega; 100 FO_C32_Coefs_t Coeffs; 101 102 103 Coeffs.A0 = 0x7FFFFFFF; 104 Coeffs.A1 = 0; 105 Coeffs.B1 = 0; 106 if(pPrivate->NewParams.LPF <= (LVM_FsTable[pPrivate->NewParams.SampleRate] >> 1)) 107 { 108 Omega = LVM_GetOmega(pPrivate->NewParams.LPF, pPrivate->NewParams.SampleRate); 109 110 /* 111 * Do not apply filter if w =2*pi*fc/fs >= 2.9 112 */ 113 if(Omega<=LVREV_2_9_INQ29) 114 { 115 LVM_FO_LPF(Omega, &Coeffs); 116 } 117 } 118 FO_1I_D32F32Cll_TRC_WRA_01_Init( &pPrivate->pFastCoef->LPCoefs, &pPrivate->pFastData->LPTaps, &Coeffs); 119 LoadConst_32(0, 120 (void *)&pPrivate->pFastData->LPTaps, /* Destination Cast to void: no dereferencing in function*/ 121 sizeof(Biquad_1I_Order1_Taps_t)/sizeof(LVM_INT32)); 122 } 123 124 125 /* 126 * Calculate the room size parameter 127 */ 128 if( pPrivate->NewParams.RoomSize != pPrivate->CurrentParams.RoomSize) 129 { 130 /* Room size range is 10ms to 200ms 131 * 0% -- 10ms 132 * 50% -- 65ms 133 * 100% -- 120ms 134 */ 135 pPrivate->RoomSizeInms = 10 + (((pPrivate->NewParams.RoomSize*11) + 5)/10); 136 } 137 138 139 /* 140 * Update the T delay number of samples and the all pass delay number of samples 141 */ 142 if( (pPrivate->NewParams.RoomSize != pPrivate->CurrentParams.RoomSize) || 143 (pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) || 144 (pPrivate->bFirstControl == LVM_TRUE)) 145 { 146 147 LVM_UINT32 Temp; 148 LVM_INT32 APDelaySize; 149 LVM_INT32 Fs = LVM_GetFsFromTable(pPrivate->NewParams.SampleRate); 150 LVM_UINT32 DelayLengthSamples = (LVM_UINT32)(Fs * pPrivate->RoomSizeInms); 151 LVM_INT16 i; 152 LVM_INT16 ScaleTable[] = {LVREV_T_3_Power_minus0_on_4, LVREV_T_3_Power_minus1_on_4, LVREV_T_3_Power_minus2_on_4, LVREV_T_3_Power_minus3_on_4}; 153 LVM_INT16 MaxT_Delay[] = {LVREV_MAX_T0_DELAY, LVREV_MAX_T1_DELAY, LVREV_MAX_T2_DELAY, LVREV_MAX_T3_DELAY}; 154 LVM_INT16 MaxAP_Delay[] = {LVREV_MAX_AP0_DELAY, LVREV_MAX_AP1_DELAY, LVREV_MAX_AP2_DELAY, LVREV_MAX_AP3_DELAY}; 155 156 157 /* 158 * For each delay line 159 */ 160 for (i=0; i<NumberOfDelayLines; i++) 161 { 162 if (i != 0) 163 { 164 LVM_INT32 Temp1; /* to avoid QAC warning on type conversion */ 165 LVM_INT32 Temp2; /* to avoid QAC warning on type conversion */ 166 167 Temp2=(LVM_INT32)DelayLengthSamples; 168 MUL32x16INTO32(Temp2, ScaleTable[i], Temp1, 15) 169 Temp=(LVM_UINT32)Temp1; 170 } 171 else 172 { 173 Temp = DelayLengthSamples; 174 } 175 APDelaySize = Temp / 1500; 176 177 178 /* 179 * Set the fixed delay 180 */ 181 Temp = (MaxT_Delay[i] - MaxAP_Delay[i]) * Fs / 48000; 182 pPrivate->Delay_AP[i] = pPrivate->T[i] - Temp; 183 184 185 /* 186 * Set the tap selection 187 */ 188 if (pPrivate->AB_Selection) 189 { 190 /* Smooth from tap A to tap B */ 191 pPrivate->pOffsetB[i] = &pPrivate->pDelay_T[i][pPrivate->T[i] - Temp - APDelaySize]; 192 pPrivate->B_DelaySize[i] = APDelaySize; 193 pPrivate->Mixer_APTaps[i].Target1 = 0; 194 pPrivate->Mixer_APTaps[i].Target2 = 0x7fffffff; 195 } 196 else 197 { 198 /* Smooth from tap B to tap A */ 199 pPrivate->pOffsetA[i] = &pPrivate->pDelay_T[i][pPrivate->T[i] - Temp - APDelaySize]; 200 pPrivate->A_DelaySize[i] = APDelaySize; 201 pPrivate->Mixer_APTaps[i].Target2 = 0; 202 pPrivate->Mixer_APTaps[i].Target1 = 0x7fffffff; 203 } 204 205 /* 206 * Set the maximum block size to the smallest delay size 207 */ 208 pPrivate->MaxBlkLen = Temp; 209 if (pPrivate->MaxBlkLen > pPrivate->A_DelaySize[i]) 210 { 211 pPrivate->MaxBlkLen = pPrivate->A_DelaySize[i]; 212 } 213 if (pPrivate->MaxBlkLen > pPrivate->B_DelaySize[i]) 214 { 215 pPrivate->MaxBlkLen = pPrivate->B_DelaySize[i]; 216 } 217 } 218 if (pPrivate->AB_Selection) 219 { 220 pPrivate->AB_Selection = 0; 221 } 222 else 223 { 224 pPrivate->AB_Selection = 1; 225 } 226 227 228 /* 229 * Limit the maximum block length 230 */ 231 pPrivate->MaxBlkLen=pPrivate->MaxBlkLen-2; /* Just as a precausion, but no problem if we remove this line */ 232 if(pPrivate->MaxBlkLen > pPrivate->InstanceParams.MaxBlockSize) 233 { 234 pPrivate->MaxBlkLen = (LVM_INT32)pPrivate->InstanceParams.MaxBlockSize; 235 } 236 } 237 238 239 /* 240 * Update the low pass filter coefficient 241 */ 242 if( (pPrivate->NewParams.Damping != pPrivate->CurrentParams.Damping) || 243 (pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) || 244 (pPrivate->bFirstControl == LVM_TRUE)) 245 { 246 247 LVM_INT32 Temp; 248 LVM_INT32 Omega; 249 FO_C32_Coefs_t Coeffs; 250 LVM_INT16 i; 251 LVM_INT16 Damping = (LVM_INT16)((pPrivate->NewParams.Damping * 100) + 1000); 252 LVM_INT32 ScaleTable[] = {LVREV_T_3_Power_0_on_4, LVREV_T_3_Power_1_on_4, LVREV_T_3_Power_2_on_4, LVREV_T_3_Power_3_on_4}; 253 254 255 /* 256 * For each filter 257 */ 258 for (i=0; i<NumberOfDelayLines; i++) 259 { 260 if (i != 0) 261 { 262 MUL32x16INTO32(ScaleTable[i], Damping, Temp, 15) 263 } 264 else 265 { 266 Temp = Damping; 267 } 268 if(Temp <= (LVM_FsTable[pPrivate->NewParams.SampleRate] >> 1)) 269 { 270 Omega = LVM_GetOmega((LVM_UINT16)Temp, pPrivate->NewParams.SampleRate); 271 LVM_FO_LPF(Omega, &Coeffs); 272 } 273 else 274 { 275 Coeffs.A0 = 0x7FF00000; 276 Coeffs.A1 = 0; 277 Coeffs.B1 = 0; 278 } 279 FO_1I_D32F32Cll_TRC_WRA_01_Init(&pPrivate->pFastCoef->RevLPCoefs[i], &pPrivate->pFastData->RevLPTaps[i], &Coeffs); 280 } 281 } 282 283 284 /* 285 * Update All-pass filter mixer time constants 286 */ 287 if( (pPrivate->NewParams.RoomSize != pPrivate->CurrentParams.RoomSize) || 288 (pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) || 289 (pPrivate->NewParams.Density != pPrivate->CurrentParams.Density)) 290 { 291 LVM_INT16 i; 292 LVM_INT32 Alpha = (LVM_INT32)LVM_Mixer_TimeConstant(LVREV_ALLPASS_TC, LVM_GetFsFromTable(pPrivate->NewParams.SampleRate), 1); 293 LVM_INT32 AlphaTap = (LVM_INT32)LVM_Mixer_TimeConstant(LVREV_ALLPASS_TAP_TC, LVM_GetFsFromTable(pPrivate->NewParams.SampleRate), 1); 294 295 for (i=0; i<4; i++) 296 { 297 pPrivate->Mixer_APTaps[i].Alpha1 = AlphaTap; 298 pPrivate->Mixer_APTaps[i].Alpha2 = AlphaTap; 299 pPrivate->Mixer_SGFeedback[i].Alpha = Alpha; 300 pPrivate->Mixer_SGFeedforward[i].Alpha = Alpha; 301 } 302 } 303 304 305 /* 306 * Update the feed back gain 307 */ 308 if( (pPrivate->NewParams.RoomSize != pPrivate->CurrentParams.RoomSize) || 309 (pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) || 310 (pPrivate->NewParams.T60 != pPrivate->CurrentParams.T60) || 311 (pPrivate->bFirstControl == LVM_TRUE)) 312 { 313 314 LVM_INT32 G[4]; /* Feedback gain (Q7.24) */ 315 316 if(pPrivate->NewParams.T60 == 0) 317 { 318 G[3] = 0; 319 G[2] = 0; 320 G[1] = 0; 321 G[0] = 0; 322 } 323 else 324 { 325 LVM_INT32 Temp1; 326 LVM_INT32 Temp2; 327 LVM_INT16 i; 328 LVM_INT16 ScaleTable[] = {LVREV_T_3_Power_minus0_on_4, LVREV_T_3_Power_minus1_on_4, LVREV_T_3_Power_minus2_on_4, LVREV_T_3_Power_minus3_on_4}; 329 330 331 /* 332 * For each delay line 333 */ 334 for (i=0; i<NumberOfDelayLines; i++) 335 { 336 Temp1 = (3 * pPrivate->RoomSizeInms * ScaleTable[i]) / pPrivate->NewParams.T60; 337 if(Temp1 >= (4 << 15)) 338 { 339 G[i] = 0; 340 } 341 else if((Temp1 >= (2 << 15))) 342 { 343 Temp2 = LVM_Power10(-(Temp1 << 14)); 344 Temp1 = LVM_Power10(-(Temp1 << 14)); 345 MUL32x32INTO32(Temp1,Temp2,Temp1,24) 346 } 347 else 348 { 349 Temp1 = LVM_Power10(-(Temp1 << 15)); 350 } 351 if (NumberOfDelayLines == 1) 352 { 353 G[i] = Temp1; 354 } 355 else 356 { 357 LVM_INT32 TempG; 358 MUL32x16INTO32(Temp1,ONE_OVER_SQRT_TWO,TempG,15) 359 G[i]=TempG; 360 } 361 } 362 } 363 364 /* Set up the feedback mixers for four delay lines */ 365 pPrivate->FeedbackMixer[0].Target=G[0]<<7; 366 pPrivate->FeedbackMixer[1].Target=G[1]<<7; 367 pPrivate->FeedbackMixer[2].Target=G[2]<<7; 368 pPrivate->FeedbackMixer[3].Target=G[3]<<7; 369 } 370 371 372 /* 373 * Calculate the gain correction 374 */ 375 if((pPrivate->NewParams.RoomSize != pPrivate->CurrentParams.RoomSize) || 376 (pPrivate->NewParams.Level != pPrivate->CurrentParams.Level) || 377 (pPrivate->NewParams.T60 != pPrivate->CurrentParams.T60) ) 378 { 379 LVM_INT32 Index=0; 380 LVM_INT32 i=0; 381 LVM_INT32 Gain=0; 382 LVM_INT32 RoomSize=0; 383 LVM_INT32 T60; 384 LVM_INT32 Coefs[5]; 385 386 if(pPrivate->NewParams.RoomSize==0) 387 { 388 RoomSize=1; 389 } 390 else 391 { 392 RoomSize=(LVM_INT32)pPrivate->NewParams.RoomSize; 393 } 394 395 if(pPrivate->NewParams.T60<100) 396 { 397 T60 = 100 * LVREV_T60_SCALE; 398 } 399 else 400 { 401 T60 = pPrivate->NewParams.T60 * LVREV_T60_SCALE; 402 } 403 404 /* Find the nearest room size in table */ 405 for(i=0;i<24;i++) 406 { 407 if(RoomSize<= LVREV_GainPolyTable[i][0]) 408 { 409 Index=i; 410 break; 411 } 412 } 413 414 415 if(RoomSize==LVREV_GainPolyTable[Index][0]) 416 { 417 /* Take table values if the room size is in table */ 418 for(i=1;i<5;i++) 419 { 420 Coefs[i-1]=LVREV_GainPolyTable[Index][i]; 421 } 422 Coefs[4]=0; 423 Gain=LVM_Polynomial(3,Coefs,T60); /* Q.24 result */ 424 } 425 else 426 { 427 /* Interpolate the gain between nearest room sizes */ 428 429 LVM_INT32 Gain1,Gain2; 430 LVM_INT32 Tot_Dist,Dist; 431 432 Tot_Dist=LVREV_GainPolyTable[Index][0]-LVREV_GainPolyTable[Index-1][0]; 433 Dist=RoomSize-LVREV_GainPolyTable[Index-1][0]; 434 435 436 /* Get gain for first */ 437 for(i=1;i<5;i++) 438 { 439 Coefs[i-1]=LVREV_GainPolyTable[Index-1][i]; 440 } 441 Coefs[4]=0; 442 443 Gain1=LVM_Polynomial(3,Coefs,T60); /* Q.24 result */ 444 445 /* Get gain for second */ 446 for(i=1;i<5;i++) 447 { 448 Coefs[i-1]=LVREV_GainPolyTable[Index][i]; 449 } 450 Coefs[4]=0; 451 452 Gain2=LVM_Polynomial(3,Coefs,T60); /* Q.24 result */ 453 454 /* Linear Interpolate the gain */ 455 Gain = Gain1+ (((Gain2-Gain1)*Dist)/(Tot_Dist)); 456 } 457 458 459 /* 460 * Get the inverse of gain: Q.15 461 * Gain is mostly above one except few cases, take only gains above 1 462 */ 463 if(Gain < 16777216L) 464 { 465 pPrivate->Gain= 32767; 466 } 467 else 468 { 469 pPrivate->Gain=(LVM_INT16)(LVM_MAXINT_32/(Gain>>8)); 470 } 471 472 473 Index=((32767*100)/(100+pPrivate->NewParams.Level)); 474 pPrivate->Gain=(LVM_INT16)((pPrivate->Gain*Index)>>15); 475 pPrivate->GainMixer.Target = pPrivate->Gain*Index; 476 } 477 478 479 /* 480 * Update the all pass comb filter coefficient 481 */ 482 if( (pPrivate->NewParams.Density != pPrivate->CurrentParams.Density) || 483 (pPrivate->bFirstControl == LVM_TRUE)) 484 { 485 LVM_INT16 i; 486 LVM_INT32 b = pPrivate->NewParams.Density * LVREV_B_8_on_1000; 487 488 for (i=0;i<4; i++) 489 { 490 pPrivate->Mixer_SGFeedback[i].Target = b; 491 pPrivate->Mixer_SGFeedforward[i].Target = b; 492 } 493 } 494 495 496 /* 497 * Update the bypass mixer time constant 498 */ 499 if((pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) || 500 (pPrivate->bFirstControl == LVM_TRUE)) 501 { 502 LVM_UINT16 NumChannels = 1; /* Assume MONO format */ 503 LVM_INT32 Alpha; 504 505 Alpha = (LVM_INT32)LVM_Mixer_TimeConstant(LVREV_FEEDBACKMIXER_TC, LVM_GetFsFromTable(pPrivate->NewParams.SampleRate), NumChannels); 506 pPrivate->FeedbackMixer[0].Alpha=Alpha; 507 pPrivate->FeedbackMixer[1].Alpha=Alpha; 508 pPrivate->FeedbackMixer[2].Alpha=Alpha; 509 pPrivate->FeedbackMixer[3].Alpha=Alpha; 510 511 NumChannels = 2; /* Always stereo output */ 512 pPrivate->BypassMixer.Alpha1 = (LVM_INT32)LVM_Mixer_TimeConstant(LVREV_BYPASSMIXER_TC, LVM_GetFsFromTable(pPrivate->NewParams.SampleRate), NumChannels); 513 pPrivate->BypassMixer.Alpha2 = pPrivate->BypassMixer.Alpha1; 514 pPrivate->GainMixer.Alpha = pPrivate->BypassMixer.Alpha1; 515 } 516 517 518 /* 519 * Update the bypass mixer targets 520 */ 521 if( (pPrivate->NewParams.Level != pPrivate->CurrentParams.Level) && 522 (pPrivate->NewParams.OperatingMode == LVM_MODE_ON)) 523 { 524 pPrivate->BypassMixer.Target2 = ((LVM_INT32)(pPrivate->NewParams.Level * 32767)/100)<<16; 525 pPrivate->BypassMixer.Target1 = 0x00000000; 526 if ((pPrivate->NewParams.Level == 0) && (pPrivate->bFirstControl == LVM_FALSE)) 527 { 528 pPrivate->BypassMixer.CallbackSet2 = LVM_TRUE; 529 } 530 if (pPrivate->NewParams.Level != 0) 531 { 532 pPrivate->bDisableReverb = LVM_FALSE; 533 } 534 } 535 536 if(pPrivate->NewParams.OperatingMode != pPrivate->CurrentParams.OperatingMode) 537 { 538 if(pPrivate->NewParams.OperatingMode == LVM_MODE_ON) 539 { 540 pPrivate->BypassMixer.Target2 = ((LVM_INT32)(pPrivate->NewParams.Level * 32767)/100)<<16; 541 pPrivate->BypassMixer.Target1 = 0x00000000; 542 543 pPrivate->BypassMixer.CallbackSet2 = LVM_FALSE; 544 OperatingMode = LVM_MODE_ON; 545 if (pPrivate->NewParams.Level == 0) 546 { 547 pPrivate->bDisableReverb = LVM_TRUE; 548 } 549 else 550 { 551 pPrivate->bDisableReverb = LVM_FALSE; 552 } 553 } 554 else if (pPrivate->bFirstControl == LVM_FALSE) 555 { 556 pPrivate->BypassMixer.Target2 = 0x00000000; 557 pPrivate->BypassMixer.Target1 = 0x00000000; 558 pPrivate->BypassMixer.CallbackSet2 = LVM_TRUE; 559 pPrivate->GainMixer.Target = 0x03FFFFFF; 560 OperatingMode = LVM_MODE_ON; 561 } 562 else 563 { 564 OperatingMode = LVM_MODE_OFF; 565 } 566 } 567 568 569 /* 570 * If it is the first call to ApplyNew settings force the current to the target to begin immediate playback of the effect 571 */ 572 if(pPrivate->bFirstControl == LVM_TRUE) 573 { 574 pPrivate->BypassMixer.Current1 = pPrivate->BypassMixer.Target1; 575 pPrivate->BypassMixer.Current2 = pPrivate->BypassMixer.Target2; 576 } 577 578 579 /* 580 * Copy the new parameters 581 */ 582 pPrivate->CurrentParams = pPrivate->NewParams; 583 pPrivate->CurrentParams.OperatingMode = OperatingMode; 584 585 586 /* 587 * Update flag 588 */ 589 if(pPrivate->bFirstControl == LVM_TRUE) 590 { 591 pPrivate->bFirstControl = LVM_FALSE; 592 } 593 594 595 return LVREV_SUCCESS; 596 } 597 #else /* BUILD_FLOAT*/ 598 LVREV_ReturnStatus_en LVREV_ApplyNewSettings (LVREV_Instance_st *pPrivate) 599 { 600 601 LVM_Mode_en OperatingMode; 602 LVM_INT32 NumberOfDelayLines; 603 604 605 /* Check for NULL pointer */ 606 if(pPrivate == LVM_NULL) 607 { 608 return LVREV_NULLADDRESS; 609 } 610 611 OperatingMode = pPrivate->NewParams.OperatingMode; 612 613 if(pPrivate->InstanceParams.NumDelays == LVREV_DELAYLINES_4) 614 { 615 NumberOfDelayLines = 4; 616 } 617 else if(pPrivate->InstanceParams.NumDelays == LVREV_DELAYLINES_2) 618 { 619 NumberOfDelayLines = 2; 620 } 621 else 622 { 623 NumberOfDelayLines = 1; 624 } 625 626 /* 627 * Update the high pass filter coefficients 628 */ 629 if((pPrivate->NewParams.HPF != pPrivate->CurrentParams.HPF) || 630 (pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) || 631 (pPrivate->bFirstControl == LVM_TRUE)) 632 { 633 LVM_FLOAT Omega; 634 FO_FLOAT_Coefs_t Coeffs; 635 636 Omega = LVM_GetOmega(pPrivate->NewParams.HPF, pPrivate->NewParams.SampleRate); 637 LVM_FO_HPF(Omega, &Coeffs); 638 FO_1I_D32F32Cll_TRC_WRA_01_Init( &pPrivate->pFastCoef->HPCoefs, 639 &pPrivate->pFastData->HPTaps, &Coeffs); 640 LoadConst_Float(0, 641 (void *)&pPrivate->pFastData->HPTaps, /* Destination Cast to void: \ 642 no dereferencing in function*/ 643 sizeof(Biquad_1I_Order1_FLOAT_Taps_t) / sizeof(LVM_FLOAT)); 644 } 645 646 647 /* 648 * Update the low pass filter coefficients 649 */ 650 if((pPrivate->NewParams.LPF != pPrivate->CurrentParams.LPF) || 651 (pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) || 652 (pPrivate->bFirstControl == LVM_TRUE)) 653 { 654 LVM_FLOAT Omega; 655 FO_FLOAT_Coefs_t Coeffs; 656 657 Coeffs.A0 = 1; 658 Coeffs.A1 = 0; 659 Coeffs.B1 = 0; 660 if(pPrivate->NewParams.LPF <= (LVM_FsTable[pPrivate->NewParams.SampleRate] >> 1)) 661 { 662 Omega = LVM_GetOmega(pPrivate->NewParams.LPF, pPrivate->NewParams.SampleRate); 663 664 /* 665 * Do not apply filter if w =2*pi*fc/fs >= 2.9 666 */ 667 if(Omega <= (LVM_FLOAT)LVREV_2_9_INQ29) 668 { 669 LVM_FO_LPF(Omega, &Coeffs); 670 } 671 } 672 FO_1I_D32F32Cll_TRC_WRA_01_Init( &pPrivate->pFastCoef->LPCoefs, 673 &pPrivate->pFastData->LPTaps, &Coeffs); 674 LoadConst_Float(0, 675 (void *)&pPrivate->pFastData->LPTaps, /* Destination Cast to void: \ 676 no dereferencing in function*/ 677 sizeof(Biquad_1I_Order1_FLOAT_Taps_t) / sizeof(LVM_FLOAT)); 678 } 679 680 681 /* 682 * Calculate the room size parameter 683 */ 684 if( pPrivate->NewParams.RoomSize != pPrivate->CurrentParams.RoomSize) 685 { 686 /* Room size range is 10ms to 200ms 687 * 0% -- 10ms 688 * 50% -- 65ms 689 * 100% -- 120ms 690 */ 691 pPrivate->RoomSizeInms = 10 + (((pPrivate->NewParams.RoomSize*11) + 5) / 10); 692 } 693 694 695 /* 696 * Update the T delay number of samples and the all pass delay number of samples 697 */ 698 if( (pPrivate->NewParams.RoomSize != pPrivate->CurrentParams.RoomSize) || 699 (pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) || 700 (pPrivate->bFirstControl == LVM_TRUE)) 701 { 702 703 LVM_UINT32 Temp; 704 LVM_INT32 APDelaySize; 705 LVM_INT32 Fs = LVM_GetFsFromTable(pPrivate->NewParams.SampleRate); 706 LVM_UINT32 DelayLengthSamples = (LVM_UINT32)(Fs * pPrivate->RoomSizeInms); 707 LVM_INT16 i; 708 LVM_FLOAT ScaleTable[] = {LVREV_T_3_Power_minus0_on_4, LVREV_T_3_Power_minus1_on_4, \ 709 LVREV_T_3_Power_minus2_on_4, LVREV_T_3_Power_minus3_on_4}; 710 LVM_INT16 MaxT_Delay[] = {LVREV_MAX_T0_DELAY, LVREV_MAX_T1_DELAY, \ 711 LVREV_MAX_T2_DELAY, LVREV_MAX_T3_DELAY}; 712 LVM_INT16 MaxAP_Delay[] = {LVREV_MAX_AP0_DELAY, LVREV_MAX_AP1_DELAY, \ 713 LVREV_MAX_AP2_DELAY, LVREV_MAX_AP3_DELAY}; 714 715 716 /* 717 * For each delay line 718 */ 719 for (i = 0; i < NumberOfDelayLines; i++) 720 { 721 if (i != 0) 722 { 723 LVM_FLOAT Temp1; /* to avoid QAC warning on type conversion */ 724 725 Temp1=(LVM_FLOAT)DelayLengthSamples; 726 Temp = (LVM_UINT32)(Temp1 * ScaleTable[i]); 727 } 728 else 729 { 730 Temp = DelayLengthSamples; 731 } 732 APDelaySize = Temp / 1500; 733 734 735 /* 736 * Set the fixed delay 737 */ 738 739 #ifdef HIGHER_FS 740 Temp = (MaxT_Delay[i] - MaxAP_Delay[i]) * Fs / 192000; 741 #else 742 Temp = (MaxT_Delay[i] - MaxAP_Delay[i]) * Fs / 48000; 743 #endif 744 pPrivate->Delay_AP[i] = pPrivate->T[i] - Temp; 745 746 747 /* 748 * Set the tap selection 749 */ 750 if (pPrivate->AB_Selection) 751 { 752 /* Smooth from tap A to tap B */ 753 pPrivate->pOffsetB[i] = &pPrivate->pDelay_T[i][pPrivate->T[i] - \ 754 Temp - APDelaySize]; 755 pPrivate->B_DelaySize[i] = APDelaySize; 756 pPrivate->Mixer_APTaps[i].Target1 = 0; 757 pPrivate->Mixer_APTaps[i].Target2 = 1.0f; 758 } 759 else 760 { 761 /* Smooth from tap B to tap A */ 762 pPrivate->pOffsetA[i] = &pPrivate->pDelay_T[i][pPrivate->T[i] - \ 763 Temp - APDelaySize]; 764 pPrivate->A_DelaySize[i] = APDelaySize; 765 pPrivate->Mixer_APTaps[i].Target2 = 0; 766 pPrivate->Mixer_APTaps[i].Target1 = 1.0f; 767 } 768 769 /* 770 * Set the maximum block size to the smallest delay size 771 */ 772 pPrivate->MaxBlkLen = Temp; 773 if (pPrivate->MaxBlkLen > pPrivate->A_DelaySize[i]) 774 { 775 pPrivate->MaxBlkLen = pPrivate->A_DelaySize[i]; 776 } 777 if (pPrivate->MaxBlkLen > pPrivate->B_DelaySize[i]) 778 { 779 pPrivate->MaxBlkLen = pPrivate->B_DelaySize[i]; 780 } 781 } 782 if (pPrivate->AB_Selection) 783 { 784 pPrivate->AB_Selection = 0; 785 } 786 else 787 { 788 pPrivate->AB_Selection = 1; 789 } 790 791 792 /* 793 * Limit the maximum block length 794 */ 795 /* Just as a precausion, but no problem if we remove this line */ 796 pPrivate->MaxBlkLen = pPrivate->MaxBlkLen - 2; 797 if(pPrivate->MaxBlkLen > pPrivate->InstanceParams.MaxBlockSize) 798 { 799 pPrivate->MaxBlkLen = (LVM_INT32)pPrivate->InstanceParams.MaxBlockSize; 800 } 801 } 802 803 804 805 /* 806 * Update the low pass filter coefficient 807 */ 808 if( (pPrivate->NewParams.Damping != pPrivate->CurrentParams.Damping) || 809 (pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) || 810 (pPrivate->bFirstControl == LVM_TRUE)) 811 { 812 813 LVM_INT32 Temp; 814 LVM_FLOAT Omega; 815 FO_FLOAT_Coefs_t Coeffs; 816 LVM_INT16 i; 817 LVM_INT16 Damping = (LVM_INT16)((pPrivate->NewParams.Damping * 100) + 1000); 818 LVM_FLOAT ScaleTable[] = {LVREV_T_3_Power_0_on_4, LVREV_T_3_Power_1_on_4, 819 LVREV_T_3_Power_2_on_4, LVREV_T_3_Power_3_on_4}; 820 821 822 /* 823 * For each filter 824 */ 825 for (i = 0; i < NumberOfDelayLines; i++) 826 { 827 if (i != 0) 828 { 829 Temp = (LVM_INT32)(ScaleTable[i] * Damping); 830 } 831 else 832 { 833 Temp = Damping; 834 } 835 if(Temp <= (LVM_INT32)(LVM_FsTable[pPrivate->NewParams.SampleRate] >> 1)) 836 { 837 Omega = LVM_GetOmega(Temp, pPrivate->NewParams.SampleRate); 838 LVM_FO_LPF(Omega, &Coeffs); 839 } 840 else 841 { 842 Coeffs.A0 = 1; 843 Coeffs.A1 = 0; 844 Coeffs.B1 = 0; 845 } 846 FO_1I_D32F32Cll_TRC_WRA_01_Init(&pPrivate->pFastCoef->RevLPCoefs[i], 847 &pPrivate->pFastData->RevLPTaps[i], &Coeffs); 848 } 849 } 850 851 852 /* 853 * Update All-pass filter mixer time constants 854 */ 855 if( (pPrivate->NewParams.RoomSize != pPrivate->CurrentParams.RoomSize) || 856 (pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) || 857 (pPrivate->NewParams.Density != pPrivate->CurrentParams.Density)) 858 { 859 LVM_INT16 i; 860 LVM_FLOAT Alpha; 861 LVM_FLOAT AlphaTap; 862 863 Alpha = LVM_Mixer_TimeConstant(LVREV_ALLPASS_TC, 864 LVM_GetFsFromTable(pPrivate->NewParams.SampleRate), 865 1); 866 867 AlphaTap = LVM_Mixer_TimeConstant(LVREV_ALLPASS_TAP_TC, 868 LVM_GetFsFromTable(pPrivate->NewParams.SampleRate), 869 1); 870 871 for (i = 0; i < 4; i++) 872 { 873 pPrivate->Mixer_APTaps[i].Alpha1 = AlphaTap; 874 pPrivate->Mixer_APTaps[i].Alpha2 = AlphaTap; 875 pPrivate->Mixer_SGFeedback[i].Alpha = Alpha; 876 pPrivate->Mixer_SGFeedforward[i].Alpha = Alpha; 877 } 878 } 879 880 881 /* 882 * Update the feed back gain 883 */ 884 if( (pPrivate->NewParams.RoomSize != pPrivate->CurrentParams.RoomSize) || 885 (pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) || 886 (pPrivate->NewParams.T60 != pPrivate->CurrentParams.T60) || 887 (pPrivate->bFirstControl == LVM_TRUE)) 888 { 889 890 LVM_FLOAT G[4]; /* Feedback gain (Q7.24) */ 891 892 if(pPrivate->NewParams.T60 == 0) 893 { 894 G[3] = 0; 895 G[2] = 0; 896 G[1] = 0; 897 G[0] = 0; 898 } 899 else 900 { 901 LVM_FLOAT Temp1; 902 LVM_FLOAT Temp2; 903 LVM_INT16 i; 904 LVM_FLOAT ScaleTable[] = {LVREV_T_3_Power_minus0_on_4, LVREV_T_3_Power_minus1_on_4, 905 LVREV_T_3_Power_minus2_on_4, LVREV_T_3_Power_minus3_on_4}; 906 907 908 /* 909 * For each delay line 910 */ 911 for (i = 0; i < NumberOfDelayLines; i++) 912 { 913 Temp1 = (3 * pPrivate->RoomSizeInms * ScaleTable[i]) / pPrivate->NewParams.T60; 914 if(Temp1 >= (4)) 915 { 916 G[i] = 0; 917 } 918 else if((Temp1 >= (2))) 919 { 920 Temp2 = LVM_Power10(-(Temp1 / 2.0f)); 921 Temp1 = LVM_Power10(-(Temp1 / 2.0f)); 922 Temp1 = Temp1 * Temp2; 923 } 924 else 925 { 926 Temp1 = LVM_Power10(-(Temp1)); 927 } 928 if (NumberOfDelayLines == 1) 929 { 930 G[i] = Temp1; 931 } 932 else 933 { 934 LVM_FLOAT TempG; 935 TempG = Temp1 * ONE_OVER_SQRT_TWO; 936 G[i]=TempG; 937 } 938 } 939 } 940 941 /* Set up the feedback mixers for four delay lines */ 942 pPrivate->FeedbackMixer[0].Target=G[0]; 943 pPrivate->FeedbackMixer[1].Target=G[1]; 944 pPrivate->FeedbackMixer[2].Target=G[2]; 945 pPrivate->FeedbackMixer[3].Target=G[3]; 946 } 947 948 949 /* 950 * Calculate the gain correction 951 */ 952 if((pPrivate->NewParams.RoomSize != pPrivate->CurrentParams.RoomSize) || 953 (pPrivate->NewParams.Level != pPrivate->CurrentParams.Level) || 954 (pPrivate->NewParams.T60 != pPrivate->CurrentParams.T60) ) 955 { 956 LVM_INT32 Index=0; 957 LVM_FLOAT Index_FLOAT; 958 LVM_INT32 i=0; 959 LVM_FLOAT Gain=0; 960 LVM_INT32 RoomSize=0; 961 LVM_FLOAT T60; 962 LVM_FLOAT Coefs[5]; 963 964 965 if(pPrivate->NewParams.RoomSize == 0) 966 { 967 RoomSize = 1; 968 } 969 else 970 { 971 RoomSize = (LVM_INT32)pPrivate->NewParams.RoomSize; 972 } 973 974 975 if(pPrivate->NewParams.T60 < 100) 976 { 977 T60 = 100 * LVREV_T60_SCALE; 978 } 979 else 980 { 981 T60 = pPrivate->NewParams.T60 * LVREV_T60_SCALE; 982 } 983 984 /* Find the nearest room size in table */ 985 for(i = 0; i < 24; i++) 986 { 987 if(RoomSize <= LVREV_GainPolyTable[i][0]) 988 { 989 Index = i; 990 break; 991 } 992 } 993 994 995 if(RoomSize == LVREV_GainPolyTable[Index][0]) 996 { 997 /* Take table values if the room size is in table */ 998 for(i = 1; i < 5; i++) 999 { 1000 Coefs[i-1] = LVREV_GainPolyTable[Index][i]; 1001 } 1002 Coefs[4] = 0; 1003 Gain = LVM_Polynomial(3, Coefs, T60); /* Q.24 result */ 1004 } 1005 else 1006 { 1007 /* Interpolate the gain between nearest room sizes */ 1008 1009 LVM_FLOAT Gain1,Gain2; 1010 LVM_INT32 Tot_Dist,Dist; 1011 1012 Tot_Dist = (LVM_UINT32)LVREV_GainPolyTable[Index][0] - \ 1013 (LVM_UINT32)LVREV_GainPolyTable[Index-1][0]; 1014 Dist = RoomSize - (LVM_UINT32)LVREV_GainPolyTable[Index - 1][0]; 1015 1016 1017 /* Get gain for first */ 1018 for(i = 1; i < 5; i++) 1019 { 1020 Coefs[i-1] = LVREV_GainPolyTable[Index-1][i]; 1021 } 1022 Coefs[4] = 0; 1023 1024 Gain1 = LVM_Polynomial(3, Coefs, T60); /* Q.24 result */ 1025 1026 /* Get gain for second */ 1027 for(i = 1; i < 5; i++) 1028 { 1029 Coefs[i-1] = LVREV_GainPolyTable[Index][i]; 1030 } 1031 Coefs[4] = 0; 1032 1033 Gain2 = LVM_Polynomial(3, Coefs, T60); /* Q.24 result */ 1034 1035 /* Linear Interpolate the gain */ 1036 Gain = Gain1 + (((Gain2 - Gain1) * Dist) / (Tot_Dist)); 1037 } 1038 1039 1040 /* 1041 * Get the inverse of gain: Q.15 1042 * Gain is mostly above one except few cases, take only gains above 1 1043 */ 1044 if(Gain < 1) 1045 { 1046 pPrivate->Gain = 1; 1047 } 1048 else 1049 { 1050 pPrivate->Gain = 1 / Gain; 1051 } 1052 1053 Index_FLOAT = 100.0f / (LVM_FLOAT)(100 + pPrivate->NewParams.Level); 1054 pPrivate->Gain = pPrivate->Gain * Index_FLOAT; 1055 pPrivate->GainMixer.Target = (pPrivate->Gain*Index_FLOAT) / 2; 1056 } 1057 1058 1059 /* 1060 * Update the all pass comb filter coefficient 1061 */ 1062 if( (pPrivate->NewParams.Density != pPrivate->CurrentParams.Density) || 1063 (pPrivate->bFirstControl == LVM_TRUE)) 1064 { 1065 LVM_INT16 i; 1066 LVM_FLOAT b = (LVM_FLOAT)pPrivate->NewParams.Density * LVREV_B_8_on_1000; 1067 1068 for (i = 0; i < 4; i++) 1069 { 1070 pPrivate->Mixer_SGFeedback[i].Target = b; 1071 pPrivate->Mixer_SGFeedforward[i].Target = b; 1072 } 1073 } 1074 1075 1076 /* 1077 * Update the bypass mixer time constant 1078 */ 1079 if((pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) || 1080 (pPrivate->bFirstControl == LVM_TRUE)) 1081 { 1082 LVM_UINT16 NumChannels = 1; /* Assume MONO format */ 1083 LVM_FLOAT Alpha; 1084 1085 Alpha = LVM_Mixer_TimeConstant(LVREV_FEEDBACKMIXER_TC, 1086 LVM_GetFsFromTable(pPrivate->NewParams.SampleRate), 1087 NumChannels); 1088 pPrivate->FeedbackMixer[0].Alpha = Alpha; 1089 pPrivate->FeedbackMixer[1].Alpha = Alpha; 1090 pPrivate->FeedbackMixer[2].Alpha = Alpha; 1091 pPrivate->FeedbackMixer[3].Alpha = Alpha; 1092 1093 NumChannels = 2; /* Always stereo output */ 1094 pPrivate->BypassMixer.Alpha1 = LVM_Mixer_TimeConstant(LVREV_BYPASSMIXER_TC, 1095 LVM_GetFsFromTable(pPrivate->NewParams.SampleRate), NumChannels); 1096 pPrivate->BypassMixer.Alpha2 = pPrivate->BypassMixer.Alpha1; 1097 pPrivate->GainMixer.Alpha = pPrivate->BypassMixer.Alpha1; 1098 } 1099 1100 1101 /* 1102 * Update the bypass mixer targets 1103 */ 1104 if( (pPrivate->NewParams.Level != pPrivate->CurrentParams.Level) && 1105 (pPrivate->NewParams.OperatingMode == LVM_MODE_ON)) 1106 { 1107 pPrivate->BypassMixer.Target2 = (LVM_FLOAT)(pPrivate->NewParams.Level ) / 100.0f; 1108 pPrivate->BypassMixer.Target1 = 0x00000000; 1109 if ((pPrivate->NewParams.Level == 0) && (pPrivate->bFirstControl == LVM_FALSE)) 1110 { 1111 pPrivate->BypassMixer.CallbackSet2 = LVM_TRUE; 1112 } 1113 if (pPrivate->NewParams.Level != 0) 1114 { 1115 pPrivate->bDisableReverb = LVM_FALSE; 1116 } 1117 } 1118 1119 if(pPrivate->NewParams.OperatingMode != pPrivate->CurrentParams.OperatingMode) 1120 { 1121 if(pPrivate->NewParams.OperatingMode == LVM_MODE_ON) 1122 { 1123 pPrivate->BypassMixer.Target2 = (LVM_FLOAT)(pPrivate->NewParams.Level ) / 100.0f; 1124 pPrivate->BypassMixer.Target1 = 0x00000000; 1125 1126 pPrivate->BypassMixer.CallbackSet2 = LVM_FALSE; 1127 OperatingMode = LVM_MODE_ON; 1128 if (pPrivate->NewParams.Level == 0) 1129 { 1130 pPrivate->bDisableReverb = LVM_TRUE; 1131 } 1132 else 1133 { 1134 pPrivate->bDisableReverb = LVM_FALSE; 1135 } 1136 } 1137 else if (pPrivate->bFirstControl == LVM_FALSE) 1138 { 1139 pPrivate->BypassMixer.Target2 = 0x00000000; 1140 pPrivate->BypassMixer.Target1 = 0x00000000; 1141 pPrivate->BypassMixer.CallbackSet2 = LVM_TRUE; 1142 pPrivate->GainMixer.Target = 0.03125f; 1143 OperatingMode = LVM_MODE_ON; 1144 } 1145 else 1146 { 1147 OperatingMode = LVM_MODE_OFF; 1148 } 1149 } 1150 1151 1152 /* If it is the first call to ApplyNew settings force the current to the target \ 1153 to begin immediate playback of the effect */ 1154 if(pPrivate->bFirstControl == LVM_TRUE) 1155 { 1156 pPrivate->BypassMixer.Current1 = pPrivate->BypassMixer.Target1; 1157 pPrivate->BypassMixer.Current2 = pPrivate->BypassMixer.Target2; 1158 } 1159 1160 1161 /* 1162 * Copy the new parameters 1163 */ 1164 pPrivate->CurrentParams = pPrivate->NewParams; 1165 pPrivate->CurrentParams.OperatingMode = OperatingMode; 1166 1167 1168 /* 1169 * Update flag 1170 */ 1171 if(pPrivate->bFirstControl == LVM_TRUE) 1172 { 1173 pPrivate->bFirstControl = LVM_FALSE; 1174 } 1175 1176 1177 return LVREV_SUCCESS; 1178 } 1179 #endif /*BUILD_FLOAT*/ 1180 /****************************************************************************************/ 1181 /* */ 1182 /* FUNCTION: BypassMixer_Callback */ 1183 /* */ 1184 /* DESCRIPTION: */ 1185 /* Controls the On to Off operating mode transition */ 1186 /* */ 1187 /* PARAMETERS: */ 1188 /* pPrivate Pointer to the instance private parameters */ 1189 /* */ 1190 /* RETURNS: */ 1191 /* LVREV_Success Succeeded */ 1192 /* LVREV_NULLADDRESS When pPrivate is NULL */ 1193 /* */ 1194 /* NOTES: */ 1195 /* */ 1196 /****************************************************************************************/ 1197 LVM_INT32 BypassMixer_Callback (void *pCallbackData, 1198 void *pGeneralPurpose, 1199 LVM_INT16 GeneralPurpose ) 1200 { 1201 1202 LVREV_Instance_st *pLVREV_Private = (LVREV_Instance_st *)pCallbackData; 1203 1204 1205 /* 1206 * Avoid build warnings 1207 */ 1208 (void)pGeneralPurpose; 1209 (void)GeneralPurpose; 1210 1211 1212 /* 1213 * Turn off 1214 */ 1215 pLVREV_Private->CurrentParams.OperatingMode = LVM_MODE_OFF; 1216 pLVREV_Private->bDisableReverb = LVM_TRUE; 1217 LVREV_ClearAudioBuffers((LVREV_Handle_t)pCallbackData); 1218 1219 1220 return 0; 1221 } 1222 1223 /* End of file */ 1224 1225