eas_reverb.c revision 56c99cd2c2c1e6ab038dac5fced5b92ccf11ff6c
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 */
46static EAS_RESULT ReverbInit (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData);
47static void ReverbProcess (EAS_VOID_PTR pInstData, EAS_PCM *pSrc, EAS_PCM *pDst, EAS_I32 numSamples);
48static EAS_RESULT ReverbShutdown (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData);
49static EAS_RESULT ReverbGetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
50static EAS_RESULT ReverbSetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
51
52/* common effects interface for configuration module */
53const 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*/
75static 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*/
275static 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*/
328static 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*/
432static 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*/
464static 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*/
525static 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*/
793static 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*/
819static 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*/
864static 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*/
914static 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*/
968static 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