No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

effect_freeverb.cpp 17KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480
  1. /* Audio Library for Teensy 3.X
  2. * Copyright (c) 2018, Paul Stoffregen, paul@pjrc.com
  3. *
  4. * Development of this audio library was funded by PJRC.COM, LLC by sales of
  5. * Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop
  6. * open source software by purchasing Teensy or other PJRC products.
  7. *
  8. * Permission is hereby granted, free of charge, to any person obtaining a copy
  9. * of this software and associated documentation files (the "Software"), to deal
  10. * in the Software without restriction, including without limitation the rights
  11. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12. * copies of the Software, and to permit persons to whom the Software is
  13. * furnished to do so, subject to the following conditions:
  14. *
  15. * The above copyright notice, development funding notice, and this permission
  16. * notice shall be included in all copies or substantial portions of the Software.
  17. *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  24. * THE SOFTWARE.
  25. */
  26. // A fixed point implementation of Freeverb by Jezar at Dreampoint
  27. // http://blog.bjornroche.com/2012/06/freeverb-original-public-domain-code-by.html
  28. // https://music.columbia.edu/pipermail/music-dsp/2001-October/045433.html
  29. #include <Arduino.h>
  30. #include "effect_freeverb.h"
  31. #include "utility/dspinst.h"
  32. AudioEffectFreeverb::AudioEffectFreeverb() : AudioStream(1, inputQueueArray)
  33. {
  34. memset(comb1buf, 0, sizeof(comb1buf));
  35. memset(comb2buf, 0, sizeof(comb2buf));
  36. memset(comb3buf, 0, sizeof(comb3buf));
  37. memset(comb4buf, 0, sizeof(comb4buf));
  38. memset(comb5buf, 0, sizeof(comb5buf));
  39. memset(comb6buf, 0, sizeof(comb6buf));
  40. memset(comb7buf, 0, sizeof(comb7buf));
  41. memset(comb8buf, 0, sizeof(comb8buf));
  42. comb1index = 0;
  43. comb2index = 0;
  44. comb3index = 0;
  45. comb4index = 0;
  46. comb5index = 0;
  47. comb6index = 0;
  48. comb7index = 0;
  49. comb8index = 0;
  50. comb1filter = 0;
  51. comb2filter = 0;
  52. comb3filter = 0;
  53. comb4filter = 0;
  54. comb5filter = 0;
  55. comb6filter = 0;
  56. comb7filter = 0;
  57. comb8filter = 0;
  58. combdamp1 = 6553;
  59. combdamp2 = 26215;
  60. combfeeback = 27524;
  61. memset(allpass1buf, 0, sizeof(allpass1buf));
  62. memset(allpass2buf, 0, sizeof(allpass2buf));
  63. memset(allpass3buf, 0, sizeof(allpass3buf));
  64. memset(allpass4buf, 0, sizeof(allpass4buf));
  65. allpass1index = 0;
  66. allpass2index = 0;
  67. allpass3index = 0;
  68. allpass4index = 0;
  69. }
  70. #if 1
  71. #define sat16(n, rshift) signed_saturate_rshift((n), 16, (rshift))
  72. #else
  73. static int16_t sat16(int32_t n, int rshift)
  74. {
  75. n = n >> rshift;
  76. if (n > 32767) {
  77. return 32767;
  78. }
  79. if (n < -32768) {
  80. return -32768;
  81. }
  82. return n;
  83. }
  84. #endif
  85. // TODO: move this to one of the data files, use in output_adat.cpp, output_tdm.cpp, etc
  86. static const audio_block_t zeroblock = {
  87. 0, 0, 0, {
  88. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  89. #if AUDIO_BLOCK_SAMPLES > 16
  90. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  91. #endif
  92. #if AUDIO_BLOCK_SAMPLES > 32
  93. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  94. #endif
  95. #if AUDIO_BLOCK_SAMPLES > 48
  96. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  97. #endif
  98. #if AUDIO_BLOCK_SAMPLES > 64
  99. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  100. #endif
  101. #if AUDIO_BLOCK_SAMPLES > 80
  102. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  103. #endif
  104. #if AUDIO_BLOCK_SAMPLES > 96
  105. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  106. #endif
  107. #if AUDIO_BLOCK_SAMPLES > 112
  108. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  109. #endif
  110. } };
  111. void AudioEffectFreeverb::update()
  112. {
  113. #if defined(KINETISK)
  114. const audio_block_t *block;
  115. audio_block_t *outblock;
  116. int i;
  117. int16_t input, bufout, output;
  118. int32_t sum;
  119. outblock = allocate();
  120. if (!outblock) {
  121. audio_block_t *tmp = receiveReadOnly(0);
  122. if (tmp) release(tmp);
  123. return;
  124. }
  125. block = receiveReadOnly(0);
  126. if (!block) block = &zeroblock;
  127. for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
  128. // TODO: scale numerical range depending on roomsize & damping
  129. input = sat16(block->data[i] * 8738, 17); // for numerical headroom
  130. sum = 0;
  131. bufout = comb1buf[comb1index];
  132. sum += bufout;
  133. comb1filter = sat16(bufout * combdamp2 + comb1filter * combdamp1, 15);
  134. comb1buf[comb1index] = sat16(input + sat16(comb1filter * combfeeback, 15), 0);
  135. if (++comb1index >= sizeof(comb1buf)/sizeof(int16_t)) comb1index = 0;
  136. bufout = comb2buf[comb2index];
  137. sum += bufout;
  138. comb2filter = sat16(bufout * combdamp2 + comb2filter * combdamp1, 15);
  139. comb2buf[comb2index] = sat16(input + sat16(comb2filter * combfeeback, 15), 0);
  140. if (++comb2index >= sizeof(comb2buf)/sizeof(int16_t)) comb2index = 0;
  141. bufout = comb3buf[comb3index];
  142. sum += bufout;
  143. comb3filter = sat16(bufout * combdamp2 + comb3filter * combdamp1, 15);
  144. comb3buf[comb3index] = sat16(input + sat16(comb3filter * combfeeback, 15), 0);
  145. if (++comb3index >= sizeof(comb3buf)/sizeof(int16_t)) comb3index = 0;
  146. bufout = comb4buf[comb4index];
  147. sum += bufout;
  148. comb4filter = sat16(bufout * combdamp2 + comb4filter * combdamp1, 15);
  149. comb4buf[comb4index] = sat16(input + sat16(comb4filter * combfeeback, 15), 0);
  150. if (++comb4index >= sizeof(comb4buf)/sizeof(int16_t)) comb4index = 0;
  151. bufout = comb5buf[comb5index];
  152. sum += bufout;
  153. comb5filter = sat16(bufout * combdamp2 + comb5filter * combdamp1, 15);
  154. comb5buf[comb5index] = sat16(input + sat16(comb5filter * combfeeback, 15), 0);
  155. if (++comb5index >= sizeof(comb5buf)/sizeof(int16_t)) comb5index = 0;
  156. bufout = comb6buf[comb6index];
  157. sum += bufout;
  158. comb6filter = sat16(bufout * combdamp2 + comb6filter * combdamp1, 15);
  159. comb6buf[comb6index] = sat16(input + sat16(comb6filter * combfeeback, 15), 0);
  160. if (++comb6index >= sizeof(comb6buf)/sizeof(int16_t)) comb6index = 0;
  161. bufout = comb7buf[comb7index];
  162. sum += bufout;
  163. comb7filter = sat16(bufout * combdamp2 + comb7filter * combdamp1, 15);
  164. comb7buf[comb7index] = sat16(input + sat16(comb7filter * combfeeback, 15), 0);
  165. if (++comb7index >= sizeof(comb7buf)/sizeof(int16_t)) comb7index = 0;
  166. bufout = comb8buf[comb8index];
  167. sum += bufout;
  168. comb8filter = sat16(bufout * combdamp2 + comb8filter * combdamp1, 15);
  169. comb8buf[comb8index] = sat16(input + sat16(comb8filter * combfeeback, 15), 0);
  170. if (++comb8index >= sizeof(comb8buf)/sizeof(int16_t)) comb8index = 0;
  171. output = sat16(sum * 31457, 17);
  172. bufout = allpass1buf[allpass1index];
  173. allpass1buf[allpass1index] = output + (bufout >> 1);
  174. output = sat16(bufout - output, 1);
  175. if (++allpass1index >= sizeof(allpass1buf)/sizeof(int16_t)) allpass1index = 0;
  176. bufout = allpass2buf[allpass2index];
  177. allpass2buf[allpass2index] = output + (bufout >> 1);
  178. output = sat16(bufout - output, 1);
  179. if (++allpass2index >= sizeof(allpass2buf)/sizeof(int16_t)) allpass2index = 0;
  180. bufout = allpass3buf[allpass3index];
  181. allpass3buf[allpass3index] = output + (bufout >> 1);
  182. output = sat16(bufout - output, 1);
  183. if (++allpass3index >= sizeof(allpass3buf)/sizeof(int16_t)) allpass3index = 0;
  184. bufout = allpass4buf[allpass4index];
  185. allpass4buf[allpass4index] = output + (bufout >> 1);
  186. output = sat16(bufout - output, 1);
  187. if (++allpass4index >= sizeof(allpass4buf)/sizeof(int16_t)) allpass4index = 0;
  188. outblock->data[i] = sat16(output * 30, 0);
  189. }
  190. transmit(outblock);
  191. release(outblock);
  192. if (block != &zeroblock) release((audio_block_t *)block);
  193. #elif defined(KINETISL)
  194. audio_block_t *block;
  195. block = receiveReadOnly(0);
  196. if (block) release(block);
  197. #endif
  198. }
  199. AudioEffectFreeverbStereo::AudioEffectFreeverbStereo() : AudioStream(1, inputQueueArray)
  200. {
  201. memset(comb1bufL, 0, sizeof(comb1bufL));
  202. memset(comb2bufL, 0, sizeof(comb2bufL));
  203. memset(comb3bufL, 0, sizeof(comb3bufL));
  204. memset(comb4bufL, 0, sizeof(comb4bufL));
  205. memset(comb5bufL, 0, sizeof(comb5bufL));
  206. memset(comb6bufL, 0, sizeof(comb6bufL));
  207. memset(comb7bufL, 0, sizeof(comb7bufL));
  208. memset(comb8bufL, 0, sizeof(comb8bufL));
  209. comb1indexL = 0;
  210. comb2indexL = 0;
  211. comb3indexL = 0;
  212. comb4indexL = 0;
  213. comb5indexL = 0;
  214. comb6indexL = 0;
  215. comb7indexL = 0;
  216. comb8indexL = 0;
  217. comb1filterL = 0;
  218. comb2filterL = 0;
  219. comb3filterL = 0;
  220. comb4filterL = 0;
  221. comb5filterL = 0;
  222. comb6filterL = 0;
  223. comb7filterL = 0;
  224. comb8filterL = 0;
  225. memset(comb1bufR, 0, sizeof(comb1bufR));
  226. memset(comb2bufR, 0, sizeof(comb2bufR));
  227. memset(comb3bufR, 0, sizeof(comb3bufR));
  228. memset(comb4bufR, 0, sizeof(comb4bufR));
  229. memset(comb5bufR, 0, sizeof(comb5bufR));
  230. memset(comb6bufR, 0, sizeof(comb6bufR));
  231. memset(comb7bufR, 0, sizeof(comb7bufR));
  232. memset(comb8bufR, 0, sizeof(comb8bufR));
  233. comb1indexR = 0;
  234. comb2indexR = 0;
  235. comb3indexR = 0;
  236. comb4indexR = 0;
  237. comb5indexR = 0;
  238. comb6indexR = 0;
  239. comb7indexR = 0;
  240. comb8indexR = 0;
  241. comb1filterR = 0;
  242. comb2filterR = 0;
  243. comb3filterR = 0;
  244. comb4filterR = 0;
  245. comb5filterR = 0;
  246. comb6filterR = 0;
  247. comb7filterR = 0;
  248. comb8filterR = 0;
  249. combdamp1 = 6553;
  250. combdamp2 = 26215;
  251. combfeeback = 27524;
  252. memset(allpass1bufL, 0, sizeof(allpass1bufL));
  253. memset(allpass2bufL, 0, sizeof(allpass2bufL));
  254. memset(allpass3bufL, 0, sizeof(allpass3bufL));
  255. memset(allpass4bufL, 0, sizeof(allpass4bufL));
  256. allpass1indexL = 0;
  257. allpass2indexL = 0;
  258. allpass3indexL = 0;
  259. allpass4indexL = 0;
  260. memset(allpass1bufR, 0, sizeof(allpass1bufR));
  261. memset(allpass2bufR, 0, sizeof(allpass2bufR));
  262. memset(allpass3bufR, 0, sizeof(allpass3bufR));
  263. memset(allpass4bufR, 0, sizeof(allpass4bufR));
  264. allpass1indexR = 0;
  265. allpass2indexR = 0;
  266. allpass3indexR = 0;
  267. allpass4indexR = 0;
  268. }
  269. void AudioEffectFreeverbStereo::update()
  270. {
  271. #if defined(KINETISK)
  272. const audio_block_t *block;
  273. audio_block_t *outblockL;
  274. audio_block_t *outblockR;
  275. int i;
  276. int16_t input, bufout, outputL, outputR;
  277. int32_t sum;
  278. block = receiveReadOnly(0);
  279. outblockL = allocate();
  280. outblockR = allocate();
  281. if (!outblockL || !outblockR) {
  282. if (outblockL) release(outblockL);
  283. if (outblockR) release(outblockR);
  284. if (block) release((audio_block_t *)block);
  285. return;
  286. }
  287. if (!block) block = &zeroblock;
  288. for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
  289. // TODO: scale numerical range depending on roomsize & damping
  290. input = sat16(block->data[i] * 8738, 17); // for numerical headroom
  291. sum = 0;
  292. bufout = comb1bufL[comb1indexL];
  293. sum += bufout;
  294. comb1filterL = sat16(bufout * combdamp2 + comb1filterL * combdamp1, 15);
  295. comb1bufL[comb1indexL] = sat16(input + sat16(comb1filterL * combfeeback, 15), 0);
  296. if (++comb1indexL >= sizeof(comb1bufL)/sizeof(int16_t)) comb1indexL = 0;
  297. bufout = comb2bufL[comb2indexL];
  298. sum += bufout;
  299. comb2filterL = sat16(bufout * combdamp2 + comb2filterL * combdamp1, 15);
  300. comb2bufL[comb2indexL] = sat16(input + sat16(comb2filterL * combfeeback, 15), 0);
  301. if (++comb2indexL >= sizeof(comb2bufL)/sizeof(int16_t)) comb2indexL = 0;
  302. bufout = comb3bufL[comb3indexL];
  303. sum += bufout;
  304. comb3filterL = sat16(bufout * combdamp2 + comb3filterL * combdamp1, 15);
  305. comb3bufL[comb3indexL] = sat16(input + sat16(comb3filterL * combfeeback, 15), 0);
  306. if (++comb3indexL >= sizeof(comb3bufL)/sizeof(int16_t)) comb3indexL = 0;
  307. bufout = comb4bufL[comb4indexL];
  308. sum += bufout;
  309. comb4filterL = sat16(bufout * combdamp2 + comb4filterL * combdamp1, 15);
  310. comb4bufL[comb4indexL] = sat16(input + sat16(comb4filterL * combfeeback, 15), 0);
  311. if (++comb4indexL >= sizeof(comb4bufL)/sizeof(int16_t)) comb4indexL = 0;
  312. bufout = comb5bufL[comb5indexL];
  313. sum += bufout;
  314. comb5filterL = sat16(bufout * combdamp2 + comb5filterL * combdamp1, 15);
  315. comb5bufL[comb5indexL] = sat16(input + sat16(comb5filterL * combfeeback, 15), 0);
  316. if (++comb5indexL >= sizeof(comb5bufL)/sizeof(int16_t)) comb5indexL = 0;
  317. bufout = comb6bufL[comb6indexL];
  318. sum += bufout;
  319. comb6filterL = sat16(bufout * combdamp2 + comb6filterL * combdamp1, 15);
  320. comb6bufL[comb6indexL] = sat16(input + sat16(comb6filterL * combfeeback, 15), 0);
  321. if (++comb6indexL >= sizeof(comb6bufL)/sizeof(int16_t)) comb6indexL = 0;
  322. bufout = comb7bufL[comb7indexL];
  323. sum += bufout;
  324. comb7filterL = sat16(bufout * combdamp2 + comb7filterL * combdamp1, 15);
  325. comb7bufL[comb7indexL] = sat16(input + sat16(comb7filterL * combfeeback, 15), 0);
  326. if (++comb7indexL >= sizeof(comb7bufL)/sizeof(int16_t)) comb7indexL = 0;
  327. bufout = comb8bufL[comb8indexL];
  328. sum += bufout;
  329. comb8filterL = sat16(bufout * combdamp2 + comb8filterL * combdamp1, 15);
  330. comb8bufL[comb8indexL] = sat16(input + sat16(comb8filterL * combfeeback, 15), 0);
  331. if (++comb8indexL >= sizeof(comb8bufL)/sizeof(int16_t)) comb8indexL = 0;
  332. outputL = sat16(sum * 31457, 17);
  333. sum = 0;
  334. bufout = comb1bufR[comb1indexR];
  335. sum += bufout;
  336. comb1filterR = sat16(bufout * combdamp2 + comb1filterR * combdamp1, 15);
  337. comb1bufR[comb1indexR] = sat16(input + sat16(comb1filterR * combfeeback, 15), 0);
  338. if (++comb1indexR >= sizeof(comb1bufR)/sizeof(int16_t)) comb1indexR = 0;
  339. bufout = comb2bufR[comb2indexR];
  340. sum += bufout;
  341. comb2filterR = sat16(bufout * combdamp2 + comb2filterR * combdamp1, 15);
  342. comb2bufR[comb2indexR] = sat16(input + sat16(comb2filterR * combfeeback, 15), 0);
  343. if (++comb2indexR >= sizeof(comb2bufR)/sizeof(int16_t)) comb2indexR = 0;
  344. bufout = comb3bufR[comb3indexR];
  345. sum += bufout;
  346. comb3filterR = sat16(bufout * combdamp2 + comb3filterR * combdamp1, 15);
  347. comb3bufR[comb3indexR] = sat16(input + sat16(comb3filterR * combfeeback, 15), 0);
  348. if (++comb3indexR >= sizeof(comb3bufR)/sizeof(int16_t)) comb3indexR = 0;
  349. bufout = comb4bufR[comb4indexR];
  350. sum += bufout;
  351. comb4filterR = sat16(bufout * combdamp2 + comb4filterR * combdamp1, 15);
  352. comb4bufR[comb4indexR] = sat16(input + sat16(comb4filterR * combfeeback, 15), 0);
  353. if (++comb4indexR >= sizeof(comb4bufR)/sizeof(int16_t)) comb4indexR = 0;
  354. bufout = comb5bufR[comb5indexR];
  355. sum += bufout;
  356. comb5filterR = sat16(bufout * combdamp2 + comb5filterR * combdamp1, 15);
  357. comb5bufR[comb5indexR] = sat16(input + sat16(comb5filterR * combfeeback, 15), 0);
  358. if (++comb5indexR >= sizeof(comb5bufR)/sizeof(int16_t)) comb5indexR = 0;
  359. bufout = comb6bufR[comb6indexR];
  360. sum += bufout;
  361. comb6filterR = sat16(bufout * combdamp2 + comb6filterR * combdamp1, 15);
  362. comb6bufR[comb6indexR] = sat16(input + sat16(comb6filterR * combfeeback, 15), 0);
  363. if (++comb6indexR >= sizeof(comb6bufR)/sizeof(int16_t)) comb6indexR = 0;
  364. bufout = comb7bufR[comb7indexR];
  365. sum += bufout;
  366. comb7filterR = sat16(bufout * combdamp2 + comb7filterR * combdamp1, 15);
  367. comb7bufR[comb7indexR] = sat16(input + sat16(comb7filterR * combfeeback, 15), 0);
  368. if (++comb7indexR >= sizeof(comb7bufR)/sizeof(int16_t)) comb7indexR = 0;
  369. bufout = comb8bufR[comb8indexR];
  370. sum += bufout;
  371. comb8filterR = sat16(bufout * combdamp2 + comb8filterR * combdamp1, 15);
  372. comb8bufR[comb8indexR] = sat16(input + sat16(comb8filterR * combfeeback, 15), 0);
  373. if (++comb8indexR >= sizeof(comb8bufR)/sizeof(int16_t)) comb8indexR = 0;
  374. outputR = sat16(sum * 31457, 17);
  375. bufout = allpass1bufL[allpass1indexL];
  376. allpass1bufL[allpass1indexL] = outputL + (bufout >> 1);
  377. outputL = sat16(bufout - outputL, 1);
  378. if (++allpass1indexL >= sizeof(allpass1bufL)/sizeof(int16_t)) allpass1indexL = 0;
  379. bufout = allpass2bufL[allpass2indexL];
  380. allpass2bufL[allpass2indexL] = outputL + (bufout >> 1);
  381. outputL = sat16(bufout - outputL, 1);
  382. if (++allpass2indexL >= sizeof(allpass2bufL)/sizeof(int16_t)) allpass2indexL = 0;
  383. bufout = allpass3bufL[allpass3indexL];
  384. allpass3bufL[allpass3indexL] = outputL + (bufout >> 1);
  385. outputL = sat16(bufout - outputL, 1);
  386. if (++allpass3indexL >= sizeof(allpass3bufL)/sizeof(int16_t)) allpass3indexL = 0;
  387. bufout = allpass4bufL[allpass4indexL];
  388. allpass4bufL[allpass4indexL] = outputL + (bufout >> 1);
  389. outputL = sat16(bufout - outputL, 1);
  390. if (++allpass4indexL >= sizeof(allpass4bufL)/sizeof(int16_t)) allpass4indexL = 0;
  391. outblockL->data[i] = sat16(outputL * 30, 0);
  392. bufout = allpass1bufR[allpass1indexR];
  393. allpass1bufR[allpass1indexR] = outputR + (bufout >> 1);
  394. outputR = sat16(bufout - outputR, 1);
  395. if (++allpass1indexR >= sizeof(allpass1bufR)/sizeof(int16_t)) allpass1indexR = 0;
  396. bufout = allpass2bufR[allpass2indexR];
  397. allpass2bufR[allpass2indexR] = outputR + (bufout >> 1);
  398. outputR = sat16(bufout - outputR, 1);
  399. if (++allpass2indexR >= sizeof(allpass2bufR)/sizeof(int16_t)) allpass2indexR = 0;
  400. bufout = allpass3bufR[allpass3indexR];
  401. allpass3bufR[allpass3indexR] = outputR + (bufout >> 1);
  402. outputR = sat16(bufout - outputR, 1);
  403. if (++allpass3indexR >= sizeof(allpass3bufR)/sizeof(int16_t)) allpass3indexR = 0;
  404. bufout = allpass4bufR[allpass4indexR];
  405. allpass4bufR[allpass4indexR] = outputR + (bufout >> 1);
  406. outputR = sat16(bufout - outputR, 1);
  407. if (++allpass4indexR >= sizeof(allpass4bufR)/sizeof(int16_t)) allpass4indexR = 0;
  408. outblockR->data[i] = sat16(outputL * 30, 0);
  409. }
  410. transmit(outblockL, 0);
  411. transmit(outblockR, 1);
  412. release(outblockL);
  413. release(outblockR);
  414. if (block != &zeroblock) release((audio_block_t *)block);
  415. #elif defined(KINETISL)
  416. audio_block_t *block;
  417. block = receiveReadOnly(0);
  418. if (block) release(block);
  419. #endif
  420. }