eas_reverb.c 39 KB

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