1 /*---------------------------------------------------------------------------- 2 * 3 * File: 4 * eas_reverb.c 5 * 6 * Contents and purpose: 7 * Contains the implementation of the Reverb effect. 8 * 9 * 10 * Copyright Sonic Network Inc. 2006 11 12 * Licensed under the Apache License, Version 2.0 (the "License"); 13 * you may not use this file except in compliance with the License. 14 * You may obtain a copy of the License at 15 * 16 * http://www.apache.org/licenses/LICENSE-2.0 17 * 18 * Unless required by applicable law or agreed to in writing, software 19 * distributed under the License is distributed on an "AS IS" BASIS, 20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 * See the License for the specific language governing permissions and 22 * limitations under the License. 23 * 24 *---------------------------------------------------------------------------- 25 * Revision Control: 26 * $Revision: 510 $ 27 * $Date: 2006-12-19 01:47:33 -0800 (Tue, 19 Dec 2006) $ 28 *---------------------------------------------------------------------------- 29 */ 30 31 /*------------------------------------ 32 * includes 33 *------------------------------------ 34 */ 35 36 #include "eas_data.h" 37 #include "eas_effects.h" 38 #include "eas_math.h" 39 #include "eas_reverbdata.h" 40 #include "eas_reverb.h" 41 #include "eas_config.h" 42 #include "eas_host.h" 43 #include "eas_report.h" 44 45 /* prototypes for effects interface */ 46 static EAS_RESULT ReverbInit (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData); 47 static void ReverbProcess (EAS_VOID_PTR pInstData, EAS_PCM *pSrc, EAS_PCM *pDst, EAS_I32 numSamples); 48 static EAS_RESULT ReverbShutdown (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData); 49 static EAS_RESULT ReverbGetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue); 50 static EAS_RESULT ReverbSetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value); 51 52 /* common effects interface for configuration module */ 53 const S_EFFECTS_INTERFACE EAS_Reverb = 54 { 55 ReverbInit, 56 ReverbProcess, 57 ReverbShutdown, 58 ReverbGetParam, 59 ReverbSetParam 60 }; 61 62 63 64 /*---------------------------------------------------------------------------- 65 * InitializeReverb() 66 *---------------------------------------------------------------------------- 67 * Purpose: 68 * 69 * Inputs: 70 * 71 * Outputs: 72 * 73 *---------------------------------------------------------------------------- 74 */ 75 static EAS_RESULT ReverbInit(EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData) 76 { 77 EAS_I32 i; 78 EAS_U16 nOffset; 79 EAS_INT temp; 80 81 S_REVERB_OBJECT *pReverbData; 82 S_REVERB_PRESET *pPreset; 83 84 /* check Configuration Module for data allocation */ 85 if (pEASData->staticMemoryModel) 86 pReverbData = EAS_CMEnumFXData(EAS_MODULE_REVERB); 87 88 /* allocate dynamic memory */ 89 else 90 pReverbData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_REVERB_OBJECT)); 91 92 if (pReverbData == NULL) 93 { 94 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate Reverb memory\n"); */ } 95 return EAS_ERROR_MALLOC_FAILED; 96 } 97 98 /* clear the structure */ 99 EAS_HWMemSet(pReverbData, 0, sizeof(S_REVERB_OBJECT)); 100 101 ReverbReadInPresets(pReverbData); 102 103 pReverbData->m_nMinSamplesToAdd = REVERB_UPDATE_PERIOD_IN_SAMPLES; 104 105 pReverbData->m_nRevOutFbkR = 0; 106 pReverbData->m_nRevOutFbkL = 0; 107 108 pReverbData->m_sAp0.m_zApIn = AP0_IN; 109 pReverbData->m_sAp0.m_zApOut = AP0_IN + DEFAULT_AP0_LENGTH; 110 pReverbData->m_sAp0.m_nApGain = DEFAULT_AP0_GAIN; 111 112 pReverbData->m_zD0In = DELAY0_IN; 113 114 pReverbData->m_sAp1.m_zApIn = AP1_IN; 115 pReverbData->m_sAp1.m_zApOut = AP1_IN + DEFAULT_AP1_LENGTH; 116 pReverbData->m_sAp1.m_nApGain = DEFAULT_AP1_GAIN; 117 118 pReverbData->m_zD1In = DELAY1_IN; 119 120 pReverbData->m_zLpf0 = 0; 121 pReverbData->m_zLpf1 = 0; 122 pReverbData->m_nLpfFwd = 8837; 123 pReverbData->m_nLpfFbk = 6494; 124 125 pReverbData->m_nSin = 0; 126 pReverbData->m_nCos = 0; 127 pReverbData->m_nSinIncrement = 0; 128 pReverbData->m_nCosIncrement = 0; 129 130 // set xfade parameters 131 pReverbData->m_nXfadeInterval = (EAS_U16)REVERB_XFADE_PERIOD_IN_SAMPLES; 132 pReverbData->m_nXfadeCounter = pReverbData->m_nXfadeInterval + 1; // force update on first iteration 133 pReverbData->m_nPhase = -32768; 134 pReverbData->m_nPhaseIncrement = REVERB_XFADE_PHASE_INCREMENT; 135 136 pReverbData->m_nNoise = (EAS_I16)0xABCD; 137 138 pReverbData->m_nMaxExcursion = 0x007F; 139 140 // set delay tap lengths 141 nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, 142 &pReverbData->m_nNoise ); 143 144 pReverbData->m_zD1Cross = 145 DELAY1_OUT - pReverbData->m_nMaxExcursion + nOffset; 146 147 nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, 148 &pReverbData->m_nNoise ); 149 150 pReverbData->m_zD0Cross = 151 DELAY1_OUT - pReverbData->m_nMaxExcursion - nOffset; 152 153 nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, 154 &pReverbData->m_nNoise ); 155 156 pReverbData->m_zD0Self = 157 DELAY0_OUT - pReverbData->m_nMaxExcursion - nOffset; 158 159 nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, 160 &pReverbData->m_nNoise ); 161 162 pReverbData->m_zD1Self = 163 DELAY1_OUT - pReverbData->m_nMaxExcursion + nOffset; 164 165 // for debugging purposes, allow noise generator 166 pReverbData->m_bUseNoise = EAS_FALSE; 167 168 // for debugging purposes, allow bypass 169 pReverbData->m_bBypass = EAS_TRUE; //EAS_FALSE; 170 171 pReverbData->m_nNextRoom = 1; 172 173 pReverbData->m_nCurrentRoom = pReverbData->m_nNextRoom + 1; // force update on first iteration 174 175 pReverbData->m_nWet = REVERB_DEFAULT_WET; 176 177 pReverbData->m_nDry = REVERB_DEFAULT_DRY; 178 179 // set base index into circular buffer 180 pReverbData->m_nBaseIndex = 0; 181 182 // set the early reflections, L 183 pReverbData->m_sEarlyL.m_nLpfFbk = 4915; 184 pReverbData->m_sEarlyL.m_nLpfFwd = 27852; 185 pReverbData->m_sEarlyL.m_zLpf = 0; 186 187 for (i=0; i < REVERB_MAX_NUM_REFLECTIONS; i++) 188 { 189 pReverbData->m_sEarlyL.m_nGain[i] = 0; 190 pReverbData->m_sEarlyL.m_zDelay[i] = 0; 191 } 192 193 // set the early reflections, R 194 pReverbData->m_sEarlyR.m_nLpfFbk = 4915; 195 pReverbData->m_sEarlyR.m_nLpfFwd = 27852; 196 pReverbData->m_sEarlyR.m_zLpf = 0; 197 198 for (i=0; i < REVERB_MAX_NUM_REFLECTIONS; i++) 199 { 200 pReverbData->m_sEarlyR.m_nGain[i] = 0; 201 pReverbData->m_sEarlyR.m_zDelay[i] = 0; 202 } 203 204 // clear the reverb delay line 205 for (i=0; i < REVERB_BUFFER_SIZE_IN_SAMPLES; i++) 206 { 207 pReverbData->m_nDelayLine[i] = 0; 208 } 209 210 //////////////////////////////// 211 ///code from the EAS DEMO Reverb 212 //now copy from the new preset into the reverb 213 pPreset = &pReverbData->m_sPreset.m_sPreset[pReverbData->m_nNextRoom]; 214 215 pReverbData->m_nLpfFbk = pPreset->m_nLpfFbk; 216 pReverbData->m_nLpfFwd = pPreset->m_nLpfFwd; 217 218 pReverbData->m_nEarly = pPreset->m_nEarly; 219 pReverbData->m_nWet = pPreset->m_nWet; 220 pReverbData->m_nDry = pPreset->m_nDry; 221 222 pReverbData->m_nMaxExcursion = pPreset->m_nMaxExcursion; 223 //stored as time based, convert to sample based 224 temp = pPreset->m_nXfadeInterval; 225 /*lint -e{702} shift for performance */ 226 temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16; 227 pReverbData->m_nXfadeInterval = (EAS_U16) temp; 228 //gsReverbObject.m_nXfadeInterval = pPreset->m_nXfadeInterval; 229 230 pReverbData->m_sAp0.m_nApGain = pPreset->m_nAp0_ApGain; 231 //stored as time based, convert to absolute sample value 232 temp = pPreset->m_nAp0_ApOut; 233 /*lint -e{702} shift for performance */ 234 temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16; 235 pReverbData->m_sAp0.m_zApOut = (EAS_U16) (pReverbData->m_sAp0.m_zApIn + temp); 236 //gsReverbObject.m_sAp0.m_zApOut = pPreset->m_nAp0_ApOut; 237 238 pReverbData->m_sAp1.m_nApGain = pPreset->m_nAp1_ApGain; 239 //stored as time based, convert to absolute sample value 240 temp = pPreset->m_nAp1_ApOut; 241 /*lint -e{702} shift for performance */ 242 temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16; 243 pReverbData->m_sAp1.m_zApOut = (EAS_U16) (pReverbData->m_sAp1.m_zApIn + temp); 244 //gsReverbObject.m_sAp1.m_zApOut = pPreset->m_nAp1_ApOut; 245 ///code from the EAS DEMO Reverb 246 //////////////////////////////// 247 248 *pInstData = pReverbData; 249 250 return EAS_SUCCESS; 251 252 } /* end InitializeReverb */ 253 254 255 256 /*---------------------------------------------------------------------------- 257 * ReverbProcess() 258 *---------------------------------------------------------------------------- 259 * Purpose: 260 * Reverberate the requested number of samples (block based processing) 261 * 262 * Inputs: 263 * pInputBuffer - src buffer 264 * pOutputBuffer - dst buffer 265 * nNumSamplesToAdd - number of samples to write to buffer 266 * 267 * Outputs: 268 * number of samples actually written to buffer 269 * 270 * Side Effects: 271 * - samples are added to the presently free buffer 272 * 273 *---------------------------------------------------------------------------- 274 */ 275 static void ReverbProcess(EAS_VOID_PTR pInstData, EAS_PCM *pSrc, EAS_PCM *pDst, EAS_I32 numSamples) 276 { 277 S_REVERB_OBJECT *pReverbData; 278 279 pReverbData = (S_REVERB_OBJECT*) pInstData; 280 281 //if bypassed or the preset forces the signal to be completely dry 282 if (pReverbData->m_bBypass || 283 (pReverbData->m_nWet == 0 && pReverbData->m_nDry == 32767)) 284 { 285 if (pSrc != pDst) 286 EAS_HWMemCpy(pSrc, pDst, numSamples * NUM_OUTPUT_CHANNELS * (EAS_I32) sizeof(EAS_PCM)); 287 return; 288 } 289 290 if (pReverbData->m_nNextRoom != pReverbData->m_nCurrentRoom) 291 { 292 ReverbUpdateRoom(pReverbData); 293 } 294 295 ReverbUpdateXfade(pReverbData, numSamples); 296 297 Reverb(pReverbData, numSamples, pDst, pSrc); 298 299 /* check if update counter needs to be reset */ 300 if (pReverbData->m_nUpdateCounter >= REVERB_MODULO_UPDATE_PERIOD_IN_SAMPLES) 301 { 302 /* update interval has elapsed, so reset counter */ 303 pReverbData->m_nUpdateCounter = 0; 304 } /* end if m_nUpdateCounter >= update interval */ 305 306 /* increment update counter */ 307 pReverbData->m_nUpdateCounter += (EAS_I16)numSamples; 308 309 } /* end ComputeReverb */ 310 311 /*---------------------------------------------------------------------------- 312 * ReverbUpdateXfade 313 *---------------------------------------------------------------------------- 314 * Purpose: 315 * Update the xfade parameters as required 316 * 317 * Inputs: 318 * nNumSamplesToAdd - number of samples to write to buffer 319 * 320 * Outputs: 321 * 322 * 323 * Side Effects: 324 * - xfade parameters will be changed 325 * 326 *---------------------------------------------------------------------------- 327 */ 328 static EAS_RESULT ReverbUpdateXfade(S_REVERB_OBJECT *pReverbData, EAS_INT nNumSamplesToAdd) 329 { 330 EAS_U16 nOffset; 331 EAS_I16 tempCos; 332 EAS_I16 tempSin; 333 334 if (pReverbData->m_nXfadeCounter >= pReverbData->m_nXfadeInterval) 335 { 336 /* update interval has elapsed, so reset counter */ 337 pReverbData->m_nXfadeCounter = 0; 338 339 // Pin the sin,cos values to min / max values to ensure that the 340 // modulated taps' coefs are zero (thus no clicks) 341 if (pReverbData->m_nPhaseIncrement > 0) 342 { 343 // if phase increment > 0, then sin -> 1, cos -> 0 344 pReverbData->m_nSin = 32767; 345 pReverbData->m_nCos = 0; 346 347 // reset the phase to match the sin, cos values 348 pReverbData->m_nPhase = 32767; 349 350 // modulate the cross taps because their tap coefs are zero 351 nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, &pReverbData->m_nNoise ); 352 353 pReverbData->m_zD1Cross = 354 DELAY1_OUT - pReverbData->m_nMaxExcursion + nOffset; 355 356 nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, &pReverbData->m_nNoise ); 357 358 pReverbData->m_zD0Cross = 359 DELAY0_OUT - pReverbData->m_nMaxExcursion - nOffset; 360 } 361 else 362 { 363 // if phase increment < 0, then sin -> 0, cos -> 1 364 pReverbData->m_nSin = 0; 365 pReverbData->m_nCos = 32767; 366 367 // reset the phase to match the sin, cos values 368 pReverbData->m_nPhase = -32768; 369 370 // modulate the self taps because their tap coefs are zero 371 nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, &pReverbData->m_nNoise ); 372 373 pReverbData->m_zD0Self = 374 DELAY0_OUT - pReverbData->m_nMaxExcursion - nOffset; 375 376 nOffset = ReverbCalculateNoise( pReverbData->m_nMaxExcursion, &pReverbData->m_nNoise ); 377 378 pReverbData->m_zD1Self = 379 DELAY1_OUT - pReverbData->m_nMaxExcursion + nOffset; 380 381 } // end if-else (pReverbData->m_nPhaseIncrement > 0) 382 383 // Reverse the direction of the sin,cos so that the 384 // tap whose coef was previously increasing now decreases 385 // and vice versa 386 pReverbData->m_nPhaseIncrement = -pReverbData->m_nPhaseIncrement; 387 388 } // end if counter >= update interval 389 390 //compute what phase will be next time 391 pReverbData->m_nPhase += pReverbData->m_nPhaseIncrement; 392 393 //calculate what the new sin and cos need to reach by the next update 394 ReverbCalculateSinCos(pReverbData->m_nPhase, &tempSin, &tempCos); 395 396 //calculate the per-sample increment required to get there by the next update 397 /*lint -e{702} shift for performance */ 398 pReverbData->m_nSinIncrement = 399 (tempSin - pReverbData->m_nSin) >> REVERB_UPDATE_PERIOD_IN_BITS; 400 401 /*lint -e{702} shift for performance */ 402 pReverbData->m_nCosIncrement = 403 (tempCos - pReverbData->m_nCos) >> REVERB_UPDATE_PERIOD_IN_BITS; 404 405 406 /* increment update counter */ 407 pReverbData->m_nXfadeCounter += (EAS_U16) nNumSamplesToAdd; 408 409 return EAS_SUCCESS; 410 411 } /* end ReverbUpdateXfade */ 412 413 414 /*---------------------------------------------------------------------------- 415 * ReverbCalculateNoise 416 *---------------------------------------------------------------------------- 417 * Purpose: 418 * Calculate a noise sample and limit its value 419 * 420 * Inputs: 421 * nMaxExcursion - noise value is limited to this value 422 * pnNoise - return new noise sample in this (not limited) 423 * 424 * Outputs: 425 * new limited noise value 426 * 427 * Side Effects: 428 * - *pnNoise noise value is updated 429 * 430 *---------------------------------------------------------------------------- 431 */ 432 static EAS_U16 ReverbCalculateNoise(EAS_U16 nMaxExcursion, EAS_I16 *pnNoise) 433 { 434 // calculate new noise value 435 *pnNoise = (EAS_I16) (*pnNoise * 5 + 1); 436 437 #if 0 // 1xxx, test 438 *pnNoise = 0; 439 #endif // 1xxx, test 440 441 // return the limited noise value 442 return (nMaxExcursion & (*pnNoise)); 443 444 } /* end ReverbCalculateNoise */ 445 446 /*---------------------------------------------------------------------------- 447 * ReverbCalculateSinCos 448 *---------------------------------------------------------------------------- 449 * Purpose: 450 * Calculate a new sin and cosine value based on the given phase 451 * 452 * Inputs: 453 * nPhase - phase angle 454 * pnSin - input old value, output new value 455 * pnCos - input old value, output new value 456 * 457 * Outputs: 458 * 459 * Side Effects: 460 * - *pnSin, *pnCos are updated 461 * 462 *---------------------------------------------------------------------------- 463 */ 464 static EAS_RESULT ReverbCalculateSinCos(EAS_I16 nPhase, EAS_I16 *pnSin, EAS_I16 *pnCos) 465 { 466 EAS_I32 nTemp; 467 EAS_I32 nNetAngle; 468 469 // -1 <= nPhase < 1 470 // However, for the calculation, we need a value 471 // that ranges from -1/2 to +1/2, so divide the phase by 2 472 /*lint -e{702} shift for performance */ 473 nNetAngle = nPhase >> 1; 474 475 /* 476 Implement the following 477 sin(x) = (2-4*c)*x^2 + c + x 478 cos(x) = (2-4*c)*x^2 + c - x 479 480 where c = 1/sqrt(2) 481 using the a0 + x*(a1 + x*a2) approach 482 */ 483 484 /* limit the input "angle" to be between -0.5 and +0.5 */ 485 if (nNetAngle > EG1_HALF) 486 { 487 nNetAngle = EG1_HALF; 488 } 489 else if (nNetAngle < EG1_MINUS_HALF) 490 { 491 nNetAngle = EG1_MINUS_HALF; 492 } 493 494 /* calculate sin */ 495 nTemp = EG1_ONE + MULT_EG1_EG1(REVERB_PAN_G2, nNetAngle); 496 nTemp = REVERB_PAN_G0 + MULT_EG1_EG1(nTemp, nNetAngle); 497 *pnSin = (EAS_I16) SATURATE_EG1(nTemp); 498 499 /* calculate cos */ 500 nTemp = -EG1_ONE + MULT_EG1_EG1(REVERB_PAN_G2, nNetAngle); 501 nTemp = REVERB_PAN_G0 + MULT_EG1_EG1(nTemp, nNetAngle); 502 *pnCos = (EAS_I16) SATURATE_EG1(nTemp); 503 504 return EAS_SUCCESS; 505 } /* end ReverbCalculateSinCos */ 506 507 /*---------------------------------------------------------------------------- 508 * Reverb 509 *---------------------------------------------------------------------------- 510 * Purpose: 511 * apply reverb to the given signal 512 * 513 * Inputs: 514 * nNu 515 * pnSin - input old value, output new value 516 * pnCos - input old value, output new value 517 * 518 * Outputs: 519 * number of samples actually reverberated 520 * 521 * Side Effects: 522 * 523 *---------------------------------------------------------------------------- 524 */ 525 static EAS_RESULT Reverb(S_REVERB_OBJECT *pReverbData, EAS_INT nNumSamplesToAdd, EAS_PCM *pOutputBuffer, EAS_PCM *pInputBuffer) 526 { 527 EAS_I32 i; 528 EAS_I32 nDelayOut; 529 EAS_U16 nBase; 530 531 EAS_U32 nAddr; 532 EAS_I32 nTemp1; 533 EAS_I32 nTemp2; 534 EAS_I32 nApIn; 535 EAS_I32 nApOut; 536 537 EAS_I32 j; 538 EAS_I32 nEarlyOut; 539 540 EAS_I32 tempValue; 541 542 543 // get the base address 544 nBase = pReverbData->m_nBaseIndex; 545 546 for (i=0; i < nNumSamplesToAdd; i++) 547 { 548 // ********** Left Allpass - start 549 // left input = (left dry/4) + right feedback from previous period 550 /*lint -e{702} use shift for performance */ 551 nApIn = ((*pInputBuffer++)>>2) + pReverbData->m_nRevOutFbkR; 552 // nApIn = *pInputBuffer++; // 1xxx test and debug ap 553 554 // fetch allpass delay line out 555 //nAddr = CIRCULAR(nBase, psAp0->m_zApOut, REVERB_BUFFER_MASK); 556 nAddr = CIRCULAR(nBase, pReverbData->m_sAp0.m_zApOut, REVERB_BUFFER_MASK); 557 nDelayOut = pReverbData->m_nDelayLine[nAddr]; 558 559 // calculate allpass feedforward; subtract the feedforward result 560 nTemp1 = MULT_EG1_EG1(nApIn, pReverbData->m_sAp0.m_nApGain); 561 nApOut = SATURATE(nDelayOut - nTemp1); // allpass output 562 563 // calculate allpass feedback; add the feedback result 564 nTemp1 = MULT_EG1_EG1(nApOut, pReverbData->m_sAp0.m_nApGain); 565 nTemp1 = SATURATE(nApIn + nTemp1); 566 567 // inject into allpass delay 568 nAddr = CIRCULAR(nBase, pReverbData->m_sAp0.m_zApIn, REVERB_BUFFER_MASK); 569 pReverbData->m_nDelayLine[nAddr] = (EAS_PCM) nTemp1; 570 571 // inject allpass output into delay line 572 nAddr = CIRCULAR(nBase, pReverbData->m_zD0In, REVERB_BUFFER_MASK); 573 pReverbData->m_nDelayLine[nAddr] = (EAS_PCM) nApOut; 574 575 // ********** Left Allpass - end 576 577 // ********** Right Allpass - start 578 // right input = (right dry/4) + left feedback from previous period 579 /*lint -e{702} use shift for performance */ 580 nApIn = ((*pInputBuffer++)>>2) + pReverbData->m_nRevOutFbkL; 581 // nApIn = *pInputBuffer++; // 1xxx test and debug ap 582 583 // fetch allpass delay line out 584 nAddr = CIRCULAR(nBase, pReverbData->m_sAp1.m_zApOut, REVERB_BUFFER_MASK); 585 nDelayOut = pReverbData->m_nDelayLine[nAddr]; 586 587 // calculate allpass feedforward; subtract the feedforward result 588 nTemp1 = MULT_EG1_EG1(nApIn, pReverbData->m_sAp1.m_nApGain); 589 nApOut = SATURATE(nDelayOut - nTemp1); // allpass output 590 591 // calculate allpass feedback; add the feedback result 592 nTemp1 = MULT_EG1_EG1(nApOut, pReverbData->m_sAp1.m_nApGain); 593 nTemp1 = SATURATE(nApIn + nTemp1); 594 595 // inject into allpass delay 596 nAddr = CIRCULAR(nBase, pReverbData->m_sAp1.m_zApIn, REVERB_BUFFER_MASK); 597 pReverbData->m_nDelayLine[nAddr] = (EAS_PCM) nTemp1; 598 599 // inject allpass output into delay line 600 nAddr = CIRCULAR(nBase, pReverbData->m_zD1In, REVERB_BUFFER_MASK); 601 pReverbData->m_nDelayLine[nAddr] = (EAS_PCM) nApOut; 602 603 // ********** Right Allpass - end 604 605 // ********** D0 output - start 606 // fetch delay line self out 607 nAddr = CIRCULAR(nBase, pReverbData->m_zD0Self, REVERB_BUFFER_MASK); 608 nDelayOut = pReverbData->m_nDelayLine[nAddr]; 609 610 // calculate delay line self out 611 nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nSin); 612 613 // fetch delay line cross out 614 nAddr = CIRCULAR(nBase, pReverbData->m_zD1Cross, REVERB_BUFFER_MASK); 615 nDelayOut = pReverbData->m_nDelayLine[nAddr]; 616 617 // calculate delay line self out 618 nTemp2 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nCos); 619 620 // calculate unfiltered delay out 621 nDelayOut = SATURATE(nTemp1 + nTemp2); 622 623 // calculate lowpass filter (mixer scale factor included in LPF feedforward) 624 nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nLpfFwd); 625 626 nTemp2 = MULT_EG1_EG1(pReverbData->m_zLpf0, pReverbData->m_nLpfFbk); 627 628 // calculate filtered delay out and simultaneously update LPF state variable 629 // filtered delay output is stored in m_zLpf0 630 pReverbData->m_zLpf0 = (EAS_PCM) SATURATE(nTemp1 + nTemp2); 631 632 // ********** D0 output - end 633 634 // ********** D1 output - start 635 // fetch delay line self out 636 nAddr = CIRCULAR(nBase, pReverbData->m_zD1Self, REVERB_BUFFER_MASK); 637 nDelayOut = pReverbData->m_nDelayLine[nAddr]; 638 639 // calculate delay line self out 640 nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nSin); 641 642 // fetch delay line cross out 643 nAddr = CIRCULAR(nBase, pReverbData->m_zD0Cross, REVERB_BUFFER_MASK); 644 nDelayOut = pReverbData->m_nDelayLine[nAddr]; 645 646 // calculate delay line self out 647 nTemp2 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nCos); 648 649 // calculate unfiltered delay out 650 nDelayOut = SATURATE(nTemp1 + nTemp2); 651 652 // calculate lowpass filter (mixer scale factor included in LPF feedforward) 653 nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_nLpfFwd); 654 655 nTemp2 = MULT_EG1_EG1(pReverbData->m_zLpf1, pReverbData->m_nLpfFbk); 656 657 // calculate filtered delay out and simultaneously update LPF state variable 658 // filtered delay output is stored in m_zLpf1 659 pReverbData->m_zLpf1 = (EAS_PCM)SATURATE(nTemp1 + nTemp2); 660 661 // ********** D1 output - end 662 663 // ********** mixer and feedback - start 664 // sum is fedback to right input (R + L) 665 pReverbData->m_nRevOutFbkL = 666 (EAS_PCM)SATURATE((EAS_I32)pReverbData->m_zLpf1 + (EAS_I32)pReverbData->m_zLpf0); 667 668 // difference is feedback to left input (R - L) 669 /*lint -e{685} lint complains that it can't saturate negative */ 670 pReverbData->m_nRevOutFbkR = 671 (EAS_PCM)SATURATE((EAS_I32)pReverbData->m_zLpf1 - (EAS_I32)pReverbData->m_zLpf0); 672 673 // ********** mixer and feedback - end 674 675 // ********** start early reflection generator, left 676 //psEarly = &(pReverbData->m_sEarlyL); 677 678 nEarlyOut = 0; 679 680 for (j=0; j < REVERB_MAX_NUM_REFLECTIONS; j++) 681 { 682 // fetch delay line out 683 //nAddr = CIRCULAR(nBase, psEarly->m_zDelay[j], REVERB_BUFFER_MASK); 684 nAddr = CIRCULAR(nBase, pReverbData->m_sEarlyL.m_zDelay[j], REVERB_BUFFER_MASK); 685 686 nDelayOut = pReverbData->m_nDelayLine[nAddr]; 687 688 // calculate reflection 689 //nTemp1 = MULT_EG1_EG1(nDelayOut, psEarly->m_nGain[j]); 690 nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_sEarlyL.m_nGain[j]); 691 692 nEarlyOut = SATURATE(nEarlyOut + nTemp1); 693 694 } // end for (j=0; j < REVERB_MAX_NUM_REFLECTIONS; j++) 695 696 // apply lowpass to early reflections 697 //nTemp1 = MULT_EG1_EG1(nEarlyOut, psEarly->m_nLpfFwd); 698 nTemp1 = MULT_EG1_EG1(nEarlyOut, pReverbData->m_sEarlyL.m_nLpfFwd); 699 700 //nTemp2 = MULT_EG1_EG1(psEarly->m_zLpf, psEarly->m_nLpfFbk); 701 nTemp2 = MULT_EG1_EG1(pReverbData->m_sEarlyL.m_zLpf, pReverbData->m_sEarlyL.m_nLpfFbk); 702 703 704 // calculate filtered out and simultaneously update LPF state variable 705 // filtered output is stored in m_zLpf1 706 //psEarly->m_zLpf = SATURATE(nTemp1 + nTemp2); 707 pReverbData->m_sEarlyL.m_zLpf = (EAS_PCM) SATURATE(nTemp1 + nTemp2); 708 709 // combine filtered early and late reflections for output 710 //*pOutputBuffer++ = inL; 711 //tempValue = SATURATE(psEarly->m_zLpf + pReverbData->m_nRevOutFbkL); 712 tempValue = SATURATE((EAS_I32)pReverbData->m_sEarlyL.m_zLpf + (EAS_I32)pReverbData->m_nRevOutFbkL); 713 //scale reverb output by wet level 714 /*lint -e{701} use shift for performance */ 715 tempValue = MULT_EG1_EG1(tempValue, (pReverbData->m_nWet<<1)); 716 //sum with output buffer 717 tempValue += *pOutputBuffer; 718 *pOutputBuffer++ = (EAS_PCM)SATURATE(tempValue); 719 720 // ********** end early reflection generator, left 721 722 // ********** start early reflection generator, right 723 //psEarly = &(pReverbData->m_sEarlyR); 724 725 nEarlyOut = 0; 726 727 for (j=0; j < REVERB_MAX_NUM_REFLECTIONS; j++) 728 { 729 // fetch delay line out 730 nAddr = CIRCULAR(nBase, pReverbData->m_sEarlyR.m_zDelay[j], REVERB_BUFFER_MASK); 731 nDelayOut = pReverbData->m_nDelayLine[nAddr]; 732 733 // calculate reflection 734 nTemp1 = MULT_EG1_EG1(nDelayOut, pReverbData->m_sEarlyR.m_nGain[j]); 735 736 nEarlyOut = SATURATE(nEarlyOut + nTemp1); 737 738 } // end for (j=0; j < REVERB_MAX_NUM_REFLECTIONS; j++) 739 740 // apply lowpass to early reflections 741 nTemp1 = MULT_EG1_EG1(nEarlyOut, pReverbData->m_sEarlyR.m_nLpfFwd); 742 743 nTemp2 = MULT_EG1_EG1(pReverbData->m_sEarlyR.m_zLpf, pReverbData->m_sEarlyR.m_nLpfFbk); 744 745 // calculate filtered out and simultaneously update LPF state variable 746 // filtered output is stored in m_zLpf1 747 pReverbData->m_sEarlyR.m_zLpf = (EAS_PCM)SATURATE(nTemp1 + nTemp2); 748 749 // combine filtered early and late reflections for output 750 //*pOutputBuffer++ = inR; 751 tempValue = SATURATE((EAS_I32)pReverbData->m_sEarlyR.m_zLpf + (EAS_I32)pReverbData->m_nRevOutFbkR); 752 //scale reverb output by wet level 753 /*lint -e{701} use shift for performance */ 754 tempValue = MULT_EG1_EG1(tempValue, (pReverbData->m_nWet << 1)); 755 //sum with output buffer 756 tempValue = tempValue + *pOutputBuffer; 757 *pOutputBuffer++ = (EAS_PCM)SATURATE(tempValue); 758 759 // ********** end early reflection generator, right 760 761 // decrement base addr for next sample period 762 nBase--; 763 764 pReverbData->m_nSin += pReverbData->m_nSinIncrement; 765 pReverbData->m_nCos += pReverbData->m_nCosIncrement; 766 767 } // end for (i=0; i < nNumSamplesToAdd; i++) 768 769 // store the most up to date version 770 pReverbData->m_nBaseIndex = nBase; 771 772 return EAS_SUCCESS; 773 } /* end Reverb */ 774 775 776 777 /*---------------------------------------------------------------------------- 778 * ReverbShutdown() 779 *---------------------------------------------------------------------------- 780 * Purpose: 781 * Initializes the Reverb effect. 782 * 783 * Inputs: 784 * pInstData - handle to instance data 785 * 786 * Outputs: 787 * 788 * 789 * Side Effects: 790 * 791 *---------------------------------------------------------------------------- 792 */ 793 static EAS_RESULT ReverbShutdown (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData) 794 { 795 /* check Configuration Module for static memory allocation */ 796 if (!pEASData->staticMemoryModel) 797 EAS_HWFree(pEASData->hwInstData, pInstData); 798 return EAS_SUCCESS; 799 } /* end ReverbShutdown */ 800 801 /*---------------------------------------------------------------------------- 802 * ReverbGetParam() 803 *---------------------------------------------------------------------------- 804 * Purpose: 805 * Get a Reverb parameter 806 * 807 * Inputs: 808 * pInstData - handle to instance data 809 * param - parameter index 810 * *pValue - pointer to variable to hold retrieved value 811 * 812 * Outputs: 813 * 814 * 815 * Side Effects: 816 * 817 *---------------------------------------------------------------------------- 818 */ 819 static EAS_RESULT ReverbGetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue) 820 { 821 S_REVERB_OBJECT *p; 822 823 p = (S_REVERB_OBJECT*) pInstData; 824 825 switch (param) 826 { 827 case EAS_PARAM_REVERB_BYPASS: 828 *pValue = (EAS_I32) p->m_bBypass; 829 break; 830 case EAS_PARAM_REVERB_PRESET: 831 *pValue = (EAS_I8) p->m_nCurrentRoom; 832 break; 833 case EAS_PARAM_REVERB_WET: 834 *pValue = p->m_nWet; 835 break; 836 case EAS_PARAM_REVERB_DRY: 837 *pValue = p->m_nDry; 838 break; 839 default: 840 return EAS_ERROR_INVALID_PARAMETER; 841 } 842 return EAS_SUCCESS; 843 } /* end ReverbGetParam */ 844 845 846 /*---------------------------------------------------------------------------- 847 * ReverbSetParam() 848 *---------------------------------------------------------------------------- 849 * Purpose: 850 * Set a Reverb parameter 851 * 852 * Inputs: 853 * pInstData - handle to instance data 854 * param - parameter index 855 * *pValue - new paramter value 856 * 857 * Outputs: 858 * 859 * 860 * Side Effects: 861 * 862 *---------------------------------------------------------------------------- 863 */ 864 static EAS_RESULT ReverbSetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value) 865 { 866 S_REVERB_OBJECT *p; 867 868 p = (S_REVERB_OBJECT*) pInstData; 869 870 switch (param) 871 { 872 case EAS_PARAM_REVERB_BYPASS: 873 p->m_bBypass = (EAS_BOOL) value; 874 break; 875 case EAS_PARAM_REVERB_PRESET: 876 if(value!=EAS_PARAM_REVERB_LARGE_HALL && value!=EAS_PARAM_REVERB_HALL && 877 value!=EAS_PARAM_REVERB_CHAMBER && value!=EAS_PARAM_REVERB_ROOM) 878 return EAS_ERROR_INVALID_PARAMETER; 879 p->m_nNextRoom = (EAS_I16)value; 880 break; 881 case EAS_PARAM_REVERB_WET: 882 if(value>EAS_REVERB_WET_MAX || value<EAS_REVERB_WET_MIN) 883 return EAS_ERROR_INVALID_PARAMETER; 884 p->m_nWet = (EAS_I16)value; 885 break; 886 case EAS_PARAM_REVERB_DRY: 887 if(value>EAS_REVERB_DRY_MAX || value<EAS_REVERB_DRY_MIN) 888 return EAS_ERROR_INVALID_PARAMETER; 889 p->m_nDry = (EAS_I16)value; 890 break; 891 default: 892 return EAS_ERROR_INVALID_PARAMETER; 893 } 894 return EAS_SUCCESS; 895 } /* end ReverbSetParam */ 896 897 898 /*---------------------------------------------------------------------------- 899 * ReverbUpdateRoom 900 *---------------------------------------------------------------------------- 901 * Purpose: 902 * Update the room's preset parameters as required 903 * 904 * Inputs: 905 * 906 * Outputs: 907 * 908 * 909 * Side Effects: 910 * - reverb paramters (fbk, fwd, etc) will be changed 911 * - m_nCurrentRoom := m_nNextRoom 912 *---------------------------------------------------------------------------- 913 */ 914 static EAS_RESULT ReverbUpdateRoom(S_REVERB_OBJECT *pReverbData) 915 { 916 EAS_INT temp; 917 918 S_REVERB_PRESET *pPreset = &pReverbData->m_sPreset.m_sPreset[pReverbData->m_nNextRoom]; 919 920 pReverbData->m_nLpfFwd = pPreset->m_nLpfFwd; 921 pReverbData->m_nLpfFbk = pPreset->m_nLpfFbk; 922 923 pReverbData->m_nEarly = pPreset->m_nEarly; 924 pReverbData->m_nWet = pPreset->m_nWet; 925 pReverbData->m_nDry = pPreset->m_nDry; 926 927 928 pReverbData->m_nMaxExcursion = pPreset->m_nMaxExcursion; 929 //stored as time based, convert to sample based 930 temp = pPreset->m_nXfadeInterval; 931 /*lint -e{702} shift for performance */ 932 temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16; 933 pReverbData->m_nXfadeInterval = (EAS_U16) temp; 934 //gpsReverbObject->m_nXfadeInterval = pPreset->m_nXfadeInterval; 935 pReverbData->m_sAp0.m_nApGain = pPreset->m_nAp0_ApGain; 936 //stored as time based, convert to absolute sample value 937 temp = pPreset->m_nAp0_ApOut; 938 /*lint -e{702} shift for performance */ 939 temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16; 940 pReverbData->m_sAp0.m_zApOut = (EAS_U16) (pReverbData->m_sAp0.m_zApIn + temp); 941 //gpsReverbObject->m_sAp0.m_zApOut = pPreset->m_nAp0_ApOut; 942 pReverbData->m_sAp1.m_nApGain = pPreset->m_nAp1_ApGain; 943 //stored as time based, convert to absolute sample value 944 temp = pPreset->m_nAp1_ApOut; 945 /*lint -e{702} shift for performance */ 946 temp = (temp * _OUTPUT_SAMPLE_RATE) >> 16; 947 pReverbData->m_sAp1.m_zApOut = (EAS_U16) (pReverbData->m_sAp1.m_zApIn + temp); 948 //gpsReverbObject->m_sAp1.m_zApOut = pPreset->m_nAp1_ApOut; 949 950 pReverbData->m_nCurrentRoom = pReverbData->m_nNextRoom; 951 952 return EAS_SUCCESS; 953 954 } /* end ReverbUpdateRoom */ 955 956 957 /*---------------------------------------------------------------------------- 958 * ReverbReadInPresets() 959 *---------------------------------------------------------------------------- 960 * Purpose: sets global reverb preset bank to defaults 961 * 962 * Inputs: 963 * 964 * Outputs: 965 * 966 *---------------------------------------------------------------------------- 967 */ 968 static EAS_RESULT ReverbReadInPresets(S_REVERB_OBJECT *pReverbData) 969 { 970 971 int preset = 0; 972 int defaultPreset = 0; 973 974 //now init any remaining presets to defaults 975 for (defaultPreset = preset; defaultPreset < REVERB_MAX_ROOM_TYPE; defaultPreset++) 976 { 977 S_REVERB_PRESET *pPreset = &pReverbData->m_sPreset.m_sPreset[defaultPreset]; 978 if (defaultPreset == 0 || defaultPreset > REVERB_MAX_ROOM_TYPE-1) 979 { 980 pPreset->m_nLpfFbk = 8307; 981 pPreset->m_nLpfFwd = 14768; 982 pPreset->m_nEarly = 0; 983 pPreset->m_nWet = 27690; 984 pPreset->m_nDry = 32767; 985 pPreset->m_nEarlyL_LpfFbk = 3692; 986 pPreset->m_nEarlyL_LpfFwd = 29075; 987 pPreset->m_nEarlyL_Delay0 = 922; 988 pPreset->m_nEarlyL_Gain0 = 22152; 989 pPreset->m_nEarlyL_Delay1 = 1462; 990 pPreset->m_nEarlyL_Gain1 = 17537; 991 pPreset->m_nEarlyL_Delay2 = 0; 992 pPreset->m_nEarlyL_Gain2 = 14768; 993 pPreset->m_nEarlyL_Delay3 = 1221; 994 pPreset->m_nEarlyL_Gain3 = 14307; 995 pPreset->m_nEarlyL_Delay4 = 0; 996 pPreset->m_nEarlyL_Gain4 = 13384; 997 pPreset->m_nEarlyR_Delay0 = 502; 998 pPreset->m_nEarlyR_Gain0 = 20306; 999 pPreset->m_nEarlyR_Delay1 = 1762; 1000 pPreset->m_nEarlyR_Gain1 = 17537; 1001 pPreset->m_nEarlyR_Delay2 = 0; 1002 pPreset->m_nEarlyR_Gain2 = 14768; 1003 pPreset->m_nEarlyR_Delay3 = 0; 1004 pPreset->m_nEarlyR_Gain3 = 16153; 1005 pPreset->m_nEarlyR_Delay4 = 0; 1006 pPreset->m_nEarlyR_Gain4 = 13384; 1007 pPreset->m_nMaxExcursion = 127; 1008 pPreset->m_nXfadeInterval = 6388; 1009 pPreset->m_nAp0_ApGain = 15691; 1010 pPreset->m_nAp0_ApOut = 711; 1011 pPreset->m_nAp1_ApGain = 17999; 1012 pPreset->m_nAp1_ApOut = 1113; 1013 pPreset->m_rfu4 = 0; 1014 pPreset->m_rfu5 = 0; 1015 pPreset->m_rfu6 = 0; 1016 pPreset->m_rfu7 = 0; 1017 pPreset->m_rfu8 = 0; 1018 pPreset->m_rfu9 = 0; 1019 pPreset->m_rfu10 = 0; 1020 } 1021 else if (defaultPreset == 1) 1022 { 1023 pPreset->m_nLpfFbk = 6461; 1024 pPreset->m_nLpfFwd = 14307; 1025 pPreset->m_nEarly = 0; 1026 pPreset->m_nWet = 27690; 1027 pPreset->m_nDry = 32767; 1028 pPreset->m_nEarlyL_LpfFbk = 3692; 1029 pPreset->m_nEarlyL_LpfFwd = 29075; 1030 pPreset->m_nEarlyL_Delay0 = 922; 1031 pPreset->m_nEarlyL_Gain0 = 22152; 1032 pPreset->m_nEarlyL_Delay1 = 1462; 1033 pPreset->m_nEarlyL_Gain1 = 17537; 1034 pPreset->m_nEarlyL_Delay2 = 0; 1035 pPreset->m_nEarlyL_Gain2 = 14768; 1036 pPreset->m_nEarlyL_Delay3 = 1221; 1037 pPreset->m_nEarlyL_Gain3 = 14307; 1038 pPreset->m_nEarlyL_Delay4 = 0; 1039 pPreset->m_nEarlyL_Gain4 = 13384; 1040 pPreset->m_nEarlyR_Delay0 = 502; 1041 pPreset->m_nEarlyR_Gain0 = 20306; 1042 pPreset->m_nEarlyR_Delay1 = 1762; 1043 pPreset->m_nEarlyR_Gain1 = 17537; 1044 pPreset->m_nEarlyR_Delay2 = 0; 1045 pPreset->m_nEarlyR_Gain2 = 14768; 1046 pPreset->m_nEarlyR_Delay3 = 0; 1047 pPreset->m_nEarlyR_Gain3 = 16153; 1048 pPreset->m_nEarlyR_Delay4 = 0; 1049 pPreset->m_nEarlyR_Gain4 = 13384; 1050 pPreset->m_nMaxExcursion = 127; 1051 pPreset->m_nXfadeInterval = 6391; 1052 pPreset->m_nAp0_ApGain = 15230; 1053 pPreset->m_nAp0_ApOut = 708; 1054 pPreset->m_nAp1_ApGain = 9692; 1055 pPreset->m_nAp1_ApOut = 1113; 1056 pPreset->m_rfu4 = 0; 1057 pPreset->m_rfu5 = 0; 1058 pPreset->m_rfu6 = 0; 1059 pPreset->m_rfu7 = 0; 1060 pPreset->m_rfu8 = 0; 1061 pPreset->m_rfu9 = 0; 1062 pPreset->m_rfu10 = 0; 1063 } 1064 else if (defaultPreset == 2) 1065 { 1066 pPreset->m_nLpfFbk = 5077; 1067 pPreset->m_nLpfFwd = 12922; 1068 pPreset->m_nEarly = 0; 1069 pPreset->m_nWet = 24460; 1070 pPreset->m_nDry = 32767; 1071 pPreset->m_nEarlyL_LpfFbk = 3692; 1072 pPreset->m_nEarlyL_LpfFwd = 29075; 1073 pPreset->m_nEarlyL_Delay0 = 922; 1074 pPreset->m_nEarlyL_Gain0 = 22152; 1075 pPreset->m_nEarlyL_Delay1 = 1462; 1076 pPreset->m_nEarlyL_Gain1 = 17537; 1077 pPreset->m_nEarlyL_Delay2 = 0; 1078 pPreset->m_nEarlyL_Gain2 = 14768; 1079 pPreset->m_nEarlyL_Delay3 = 1221; 1080 pPreset->m_nEarlyL_Gain3 = 14307; 1081 pPreset->m_nEarlyL_Delay4 = 0; 1082 pPreset->m_nEarlyL_Gain4 = 13384; 1083 pPreset->m_nEarlyR_Delay0 = 502; 1084 pPreset->m_nEarlyR_Gain0 = 20306; 1085 pPreset->m_nEarlyR_Delay1 = 1762; 1086 pPreset->m_nEarlyR_Gain1 = 17537; 1087 pPreset->m_nEarlyR_Delay2 = 0; 1088 pPreset->m_nEarlyR_Gain2 = 14768; 1089 pPreset->m_nEarlyR_Delay3 = 0; 1090 pPreset->m_nEarlyR_Gain3 = 16153; 1091 pPreset->m_nEarlyR_Delay4 = 0; 1092 pPreset->m_nEarlyR_Gain4 = 13384; 1093 pPreset->m_nMaxExcursion = 127; 1094 pPreset->m_nXfadeInterval = 6449; 1095 pPreset->m_nAp0_ApGain = 15691; 1096 pPreset->m_nAp0_ApOut = 774; 1097 pPreset->m_nAp1_ApGain = 15691; 1098 pPreset->m_nAp1_ApOut = 1113; 1099 pPreset->m_rfu4 = 0; 1100 pPreset->m_rfu5 = 0; 1101 pPreset->m_rfu6 = 0; 1102 pPreset->m_rfu7 = 0; 1103 pPreset->m_rfu8 = 0; 1104 pPreset->m_rfu9 = 0; 1105 pPreset->m_rfu10 = 0; 1106 } 1107 else if (defaultPreset == 3) 1108 { 1109 pPreset->m_nLpfFbk = 5077; 1110 pPreset->m_nLpfFwd = 11076; 1111 pPreset->m_nEarly = 0; 1112 pPreset->m_nWet = 23075; 1113 pPreset->m_nDry = 32767; 1114 pPreset->m_nEarlyL_LpfFbk = 3692; 1115 pPreset->m_nEarlyL_LpfFwd = 29075; 1116 pPreset->m_nEarlyL_Delay0 = 922; 1117 pPreset->m_nEarlyL_Gain0 = 22152; 1118 pPreset->m_nEarlyL_Delay1 = 1462; 1119 pPreset->m_nEarlyL_Gain1 = 17537; 1120 pPreset->m_nEarlyL_Delay2 = 0; 1121 pPreset->m_nEarlyL_Gain2 = 14768; 1122 pPreset->m_nEarlyL_Delay3 = 1221; 1123 pPreset->m_nEarlyL_Gain3 = 14307; 1124 pPreset->m_nEarlyL_Delay4 = 0; 1125 pPreset->m_nEarlyL_Gain4 = 13384; 1126 pPreset->m_nEarlyR_Delay0 = 502; 1127 pPreset->m_nEarlyR_Gain0 = 20306; 1128 pPreset->m_nEarlyR_Delay1 = 1762; 1129 pPreset->m_nEarlyR_Gain1 = 17537; 1130 pPreset->m_nEarlyR_Delay2 = 0; 1131 pPreset->m_nEarlyR_Gain2 = 14768; 1132 pPreset->m_nEarlyR_Delay3 = 0; 1133 pPreset->m_nEarlyR_Gain3 = 16153; 1134 pPreset->m_nEarlyR_Delay4 = 0; 1135 pPreset->m_nEarlyR_Gain4 = 13384; 1136 pPreset->m_nMaxExcursion = 127; 1137 pPreset->m_nXfadeInterval = 6470; //6483; 1138 pPreset->m_nAp0_ApGain = 14768; 1139 pPreset->m_nAp0_ApOut = 792; 1140 pPreset->m_nAp1_ApGain = 15783; 1141 pPreset->m_nAp1_ApOut = 1113; 1142 pPreset->m_rfu4 = 0; 1143 pPreset->m_rfu5 = 0; 1144 pPreset->m_rfu6 = 0; 1145 pPreset->m_rfu7 = 0; 1146 pPreset->m_rfu8 = 0; 1147 pPreset->m_rfu9 = 0; 1148 pPreset->m_rfu10 = 0; 1149 1150 } 1151 } 1152 1153 return EAS_SUCCESS; 1154 } 1155