• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
ReverbInit(EAS_DATA_HANDLE pEASData,EAS_VOID_PTR * pInstData)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 */
ReverbProcess(EAS_VOID_PTR pInstData,EAS_PCM * pSrc,EAS_PCM * pDst,EAS_I32 numSamples)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 */
ReverbUpdateXfade(S_REVERB_OBJECT * pReverbData,EAS_INT nNumSamplesToAdd)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 */
ReverbCalculateNoise(EAS_U16 nMaxExcursion,EAS_I16 * pnNoise)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 */
ReverbCalculateSinCos(EAS_I16 nPhase,EAS_I16 * pnSin,EAS_I16 * pnCos)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 */
Reverb(S_REVERB_OBJECT * pReverbData,EAS_INT nNumSamplesToAdd,EAS_PCM * pOutputBuffer,EAS_PCM * pInputBuffer)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 */
ReverbShutdown(EAS_DATA_HANDLE pEASData,EAS_VOID_PTR pInstData)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 */
ReverbGetParam(EAS_VOID_PTR pInstData,EAS_I32 param,EAS_I32 * pValue)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 */
ReverbSetParam(EAS_VOID_PTR pInstData,EAS_I32 param,EAS_I32 value)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 */
ReverbUpdateRoom(S_REVERB_OBJECT * pReverbData)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 */
ReverbReadInPresets(S_REVERB_OBJECT * pReverbData)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