eas_reverb.c revision e442bb7cd6a085b33a4dd52c0e20a157ada7feb1
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