Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

487 lines
17KB

  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. // cleaner sat16 by http://www.moseleyinstruments.com/
  71. static int16_t sat16(int32_t n, int rshift) {
  72. // we should always round towards 0
  73. // to avoid recirculating round-off noise
  74. //
  75. // a 2s complement positive number is always
  76. // rounded down, so we only need to take
  77. // care of negative numbers
  78. if (n < 0) {
  79. n = n + (~(0xFFFFFFFFUL << rshift));
  80. }
  81. n = n >> rshift;
  82. if (n > 32767) {
  83. return 32767;
  84. }
  85. if (n < -32768) {
  86. return -32768;
  87. }
  88. return n;
  89. }
  90. // TODO: move this to one of the data files, use in output_adat.cpp, output_tdm.cpp, etc
  91. static const audio_block_t zeroblock = {
  92. 0, 0, 0, {
  93. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  94. #if AUDIO_BLOCK_SAMPLES > 16
  95. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  96. #endif
  97. #if AUDIO_BLOCK_SAMPLES > 32
  98. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  99. #endif
  100. #if AUDIO_BLOCK_SAMPLES > 48
  101. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  102. #endif
  103. #if AUDIO_BLOCK_SAMPLES > 64
  104. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  105. #endif
  106. #if AUDIO_BLOCK_SAMPLES > 80
  107. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  108. #endif
  109. #if AUDIO_BLOCK_SAMPLES > 96
  110. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  111. #endif
  112. #if AUDIO_BLOCK_SAMPLES > 112
  113. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  114. #endif
  115. } };
  116. void AudioEffectFreeverb::update()
  117. {
  118. #if defined(__ARM_ARCH_7EM__)
  119. const audio_block_t *block;
  120. audio_block_t *outblock;
  121. int i;
  122. int16_t input, bufout, output;
  123. int32_t sum;
  124. outblock = allocate();
  125. if (!outblock) {
  126. audio_block_t *tmp = receiveReadOnly(0);
  127. if (tmp) release(tmp);
  128. return;
  129. }
  130. block = receiveReadOnly(0);
  131. if (!block) block = &zeroblock;
  132. for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
  133. // TODO: scale numerical range depending on roomsize & damping
  134. input = sat16(block->data[i] * 8738, 17); // for numerical headroom
  135. sum = 0;
  136. bufout = comb1buf[comb1index];
  137. sum += bufout;
  138. comb1filter = sat16(bufout * combdamp2 + comb1filter * combdamp1, 15);
  139. comb1buf[comb1index] = sat16(input + sat16(comb1filter * combfeeback, 15), 0);
  140. if (++comb1index >= sizeof(comb1buf)/sizeof(int16_t)) comb1index = 0;
  141. bufout = comb2buf[comb2index];
  142. sum += bufout;
  143. comb2filter = sat16(bufout * combdamp2 + comb2filter * combdamp1, 15);
  144. comb2buf[comb2index] = sat16(input + sat16(comb2filter * combfeeback, 15), 0);
  145. if (++comb2index >= sizeof(comb2buf)/sizeof(int16_t)) comb2index = 0;
  146. bufout = comb3buf[comb3index];
  147. sum += bufout;
  148. comb3filter = sat16(bufout * combdamp2 + comb3filter * combdamp1, 15);
  149. comb3buf[comb3index] = sat16(input + sat16(comb3filter * combfeeback, 15), 0);
  150. if (++comb3index >= sizeof(comb3buf)/sizeof(int16_t)) comb3index = 0;
  151. bufout = comb4buf[comb4index];
  152. sum += bufout;
  153. comb4filter = sat16(bufout * combdamp2 + comb4filter * combdamp1, 15);
  154. comb4buf[comb4index] = sat16(input + sat16(comb4filter * combfeeback, 15), 0);
  155. if (++comb4index >= sizeof(comb4buf)/sizeof(int16_t)) comb4index = 0;
  156. bufout = comb5buf[comb5index];
  157. sum += bufout;
  158. comb5filter = sat16(bufout * combdamp2 + comb5filter * combdamp1, 15);
  159. comb5buf[comb5index] = sat16(input + sat16(comb5filter * combfeeback, 15), 0);
  160. if (++comb5index >= sizeof(comb5buf)/sizeof(int16_t)) comb5index = 0;
  161. bufout = comb6buf[comb6index];
  162. sum += bufout;
  163. comb6filter = sat16(bufout * combdamp2 + comb6filter * combdamp1, 15);
  164. comb6buf[comb6index] = sat16(input + sat16(comb6filter * combfeeback, 15), 0);
  165. if (++comb6index >= sizeof(comb6buf)/sizeof(int16_t)) comb6index = 0;
  166. bufout = comb7buf[comb7index];
  167. sum += bufout;
  168. comb7filter = sat16(bufout * combdamp2 + comb7filter * combdamp1, 15);
  169. comb7buf[comb7index] = sat16(input + sat16(comb7filter * combfeeback, 15), 0);
  170. if (++comb7index >= sizeof(comb7buf)/sizeof(int16_t)) comb7index = 0;
  171. bufout = comb8buf[comb8index];
  172. sum += bufout;
  173. comb8filter = sat16(bufout * combdamp2 + comb8filter * combdamp1, 15);
  174. comb8buf[comb8index] = sat16(input + sat16(comb8filter * combfeeback, 15), 0);
  175. if (++comb8index >= sizeof(comb8buf)/sizeof(int16_t)) comb8index = 0;
  176. output = sat16(sum * 31457, 17);
  177. bufout = allpass1buf[allpass1index];
  178. allpass1buf[allpass1index] = output + (bufout >> 1);
  179. output = sat16(bufout - output, 1);
  180. if (++allpass1index >= sizeof(allpass1buf)/sizeof(int16_t)) allpass1index = 0;
  181. bufout = allpass2buf[allpass2index];
  182. allpass2buf[allpass2index] = output + (bufout >> 1);
  183. output = sat16(bufout - output, 1);
  184. if (++allpass2index >= sizeof(allpass2buf)/sizeof(int16_t)) allpass2index = 0;
  185. bufout = allpass3buf[allpass3index];
  186. allpass3buf[allpass3index] = output + (bufout >> 1);
  187. output = sat16(bufout - output, 1);
  188. if (++allpass3index >= sizeof(allpass3buf)/sizeof(int16_t)) allpass3index = 0;
  189. bufout = allpass4buf[allpass4index];
  190. allpass4buf[allpass4index] = output + (bufout >> 1);
  191. output = sat16(bufout - output, 1);
  192. if (++allpass4index >= sizeof(allpass4buf)/sizeof(int16_t)) allpass4index = 0;
  193. outblock->data[i] = sat16(output * 30, 0);
  194. }
  195. transmit(outblock);
  196. release(outblock);
  197. if (block != &zeroblock) release((audio_block_t *)block);
  198. #elif defined(KINETISL)
  199. audio_block_t *block;
  200. block = receiveReadOnly(0);
  201. if (block) release(block);
  202. #endif
  203. }
  204. AudioEffectFreeverbStereo::AudioEffectFreeverbStereo() : AudioStream(1, inputQueueArray)
  205. {
  206. memset(comb1bufL, 0, sizeof(comb1bufL));
  207. memset(comb2bufL, 0, sizeof(comb2bufL));
  208. memset(comb3bufL, 0, sizeof(comb3bufL));
  209. memset(comb4bufL, 0, sizeof(comb4bufL));
  210. memset(comb5bufL, 0, sizeof(comb5bufL));
  211. memset(comb6bufL, 0, sizeof(comb6bufL));
  212. memset(comb7bufL, 0, sizeof(comb7bufL));
  213. memset(comb8bufL, 0, sizeof(comb8bufL));
  214. comb1indexL = 0;
  215. comb2indexL = 0;
  216. comb3indexL = 0;
  217. comb4indexL = 0;
  218. comb5indexL = 0;
  219. comb6indexL = 0;
  220. comb7indexL = 0;
  221. comb8indexL = 0;
  222. comb1filterL = 0;
  223. comb2filterL = 0;
  224. comb3filterL = 0;
  225. comb4filterL = 0;
  226. comb5filterL = 0;
  227. comb6filterL = 0;
  228. comb7filterL = 0;
  229. comb8filterL = 0;
  230. memset(comb1bufR, 0, sizeof(comb1bufR));
  231. memset(comb2bufR, 0, sizeof(comb2bufR));
  232. memset(comb3bufR, 0, sizeof(comb3bufR));
  233. memset(comb4bufR, 0, sizeof(comb4bufR));
  234. memset(comb5bufR, 0, sizeof(comb5bufR));
  235. memset(comb6bufR, 0, sizeof(comb6bufR));
  236. memset(comb7bufR, 0, sizeof(comb7bufR));
  237. memset(comb8bufR, 0, sizeof(comb8bufR));
  238. comb1indexR = 0;
  239. comb2indexR = 0;
  240. comb3indexR = 0;
  241. comb4indexR = 0;
  242. comb5indexR = 0;
  243. comb6indexR = 0;
  244. comb7indexR = 0;
  245. comb8indexR = 0;
  246. comb1filterR = 0;
  247. comb2filterR = 0;
  248. comb3filterR = 0;
  249. comb4filterR = 0;
  250. comb5filterR = 0;
  251. comb6filterR = 0;
  252. comb7filterR = 0;
  253. comb8filterR = 0;
  254. combdamp1 = 6553;
  255. combdamp2 = 26215;
  256. combfeeback = 27524;
  257. memset(allpass1bufL, 0, sizeof(allpass1bufL));
  258. memset(allpass2bufL, 0, sizeof(allpass2bufL));
  259. memset(allpass3bufL, 0, sizeof(allpass3bufL));
  260. memset(allpass4bufL, 0, sizeof(allpass4bufL));
  261. allpass1indexL = 0;
  262. allpass2indexL = 0;
  263. allpass3indexL = 0;
  264. allpass4indexL = 0;
  265. memset(allpass1bufR, 0, sizeof(allpass1bufR));
  266. memset(allpass2bufR, 0, sizeof(allpass2bufR));
  267. memset(allpass3bufR, 0, sizeof(allpass3bufR));
  268. memset(allpass4bufR, 0, sizeof(allpass4bufR));
  269. allpass1indexR = 0;
  270. allpass2indexR = 0;
  271. allpass3indexR = 0;
  272. allpass4indexR = 0;
  273. }
  274. void AudioEffectFreeverbStereo::update()
  275. {
  276. #if defined(__ARM_ARCH_7EM__)
  277. const audio_block_t *block;
  278. audio_block_t *outblockL;
  279. audio_block_t *outblockR;
  280. int i;
  281. int16_t input, bufout, outputL, outputR;
  282. int32_t sum;
  283. block = receiveReadOnly(0);
  284. outblockL = allocate();
  285. outblockR = allocate();
  286. if (!outblockL || !outblockR) {
  287. if (outblockL) release(outblockL);
  288. if (outblockR) release(outblockR);
  289. if (block) release((audio_block_t *)block);
  290. return;
  291. }
  292. if (!block) block = &zeroblock;
  293. for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
  294. // TODO: scale numerical range depending on roomsize & damping
  295. input = sat16(block->data[i] * 8738, 17); // for numerical headroom
  296. sum = 0;
  297. bufout = comb1bufL[comb1indexL];
  298. sum += bufout;
  299. comb1filterL = sat16(bufout * combdamp2 + comb1filterL * combdamp1, 15);
  300. comb1bufL[comb1indexL] = sat16(input + sat16(comb1filterL * combfeeback, 15), 0);
  301. if (++comb1indexL >= sizeof(comb1bufL)/sizeof(int16_t)) comb1indexL = 0;
  302. bufout = comb2bufL[comb2indexL];
  303. sum += bufout;
  304. comb2filterL = sat16(bufout * combdamp2 + comb2filterL * combdamp1, 15);
  305. comb2bufL[comb2indexL] = sat16(input + sat16(comb2filterL * combfeeback, 15), 0);
  306. if (++comb2indexL >= sizeof(comb2bufL)/sizeof(int16_t)) comb2indexL = 0;
  307. bufout = comb3bufL[comb3indexL];
  308. sum += bufout;
  309. comb3filterL = sat16(bufout * combdamp2 + comb3filterL * combdamp1, 15);
  310. comb3bufL[comb3indexL] = sat16(input + sat16(comb3filterL * combfeeback, 15), 0);
  311. if (++comb3indexL >= sizeof(comb3bufL)/sizeof(int16_t)) comb3indexL = 0;
  312. bufout = comb4bufL[comb4indexL];
  313. sum += bufout;
  314. comb4filterL = sat16(bufout * combdamp2 + comb4filterL * combdamp1, 15);
  315. comb4bufL[comb4indexL] = sat16(input + sat16(comb4filterL * combfeeback, 15), 0);
  316. if (++comb4indexL >= sizeof(comb4bufL)/sizeof(int16_t)) comb4indexL = 0;
  317. bufout = comb5bufL[comb5indexL];
  318. sum += bufout;
  319. comb5filterL = sat16(bufout * combdamp2 + comb5filterL * combdamp1, 15);
  320. comb5bufL[comb5indexL] = sat16(input + sat16(comb5filterL * combfeeback, 15), 0);
  321. if (++comb5indexL >= sizeof(comb5bufL)/sizeof(int16_t)) comb5indexL = 0;
  322. bufout = comb6bufL[comb6indexL];
  323. sum += bufout;
  324. comb6filterL = sat16(bufout * combdamp2 + comb6filterL * combdamp1, 15);
  325. comb6bufL[comb6indexL] = sat16(input + sat16(comb6filterL * combfeeback, 15), 0);
  326. if (++comb6indexL >= sizeof(comb6bufL)/sizeof(int16_t)) comb6indexL = 0;
  327. bufout = comb7bufL[comb7indexL];
  328. sum += bufout;
  329. comb7filterL = sat16(bufout * combdamp2 + comb7filterL * combdamp1, 15);
  330. comb7bufL[comb7indexL] = sat16(input + sat16(comb7filterL * combfeeback, 15), 0);
  331. if (++comb7indexL >= sizeof(comb7bufL)/sizeof(int16_t)) comb7indexL = 0;
  332. bufout = comb8bufL[comb8indexL];
  333. sum += bufout;
  334. comb8filterL = sat16(bufout * combdamp2 + comb8filterL * combdamp1, 15);
  335. comb8bufL[comb8indexL] = sat16(input + sat16(comb8filterL * combfeeback, 15), 0);
  336. if (++comb8indexL >= sizeof(comb8bufL)/sizeof(int16_t)) comb8indexL = 0;
  337. outputL = sat16(sum * 31457, 17);
  338. sum = 0;
  339. bufout = comb1bufR[comb1indexR];
  340. sum += bufout;
  341. comb1filterR = sat16(bufout * combdamp2 + comb1filterR * combdamp1, 15);
  342. comb1bufR[comb1indexR] = sat16(input + sat16(comb1filterR * combfeeback, 15), 0);
  343. if (++comb1indexR >= sizeof(comb1bufR)/sizeof(int16_t)) comb1indexR = 0;
  344. bufout = comb2bufR[comb2indexR];
  345. sum += bufout;
  346. comb2filterR = sat16(bufout * combdamp2 + comb2filterR * combdamp1, 15);
  347. comb2bufR[comb2indexR] = sat16(input + sat16(comb2filterR * combfeeback, 15), 0);
  348. if (++comb2indexR >= sizeof(comb2bufR)/sizeof(int16_t)) comb2indexR = 0;
  349. bufout = comb3bufR[comb3indexR];
  350. sum += bufout;
  351. comb3filterR = sat16(bufout * combdamp2 + comb3filterR * combdamp1, 15);
  352. comb3bufR[comb3indexR] = sat16(input + sat16(comb3filterR * combfeeback, 15), 0);
  353. if (++comb3indexR >= sizeof(comb3bufR)/sizeof(int16_t)) comb3indexR = 0;
  354. bufout = comb4bufR[comb4indexR];
  355. sum += bufout;
  356. comb4filterR = sat16(bufout * combdamp2 + comb4filterR * combdamp1, 15);
  357. comb4bufR[comb4indexR] = sat16(input + sat16(comb4filterR * combfeeback, 15), 0);
  358. if (++comb4indexR >= sizeof(comb4bufR)/sizeof(int16_t)) comb4indexR = 0;
  359. bufout = comb5bufR[comb5indexR];
  360. sum += bufout;
  361. comb5filterR = sat16(bufout * combdamp2 + comb5filterR * combdamp1, 15);
  362. comb5bufR[comb5indexR] = sat16(input + sat16(comb5filterR * combfeeback, 15), 0);
  363. if (++comb5indexR >= sizeof(comb5bufR)/sizeof(int16_t)) comb5indexR = 0;
  364. bufout = comb6bufR[comb6indexR];
  365. sum += bufout;
  366. comb6filterR = sat16(bufout * combdamp2 + comb6filterR * combdamp1, 15);
  367. comb6bufR[comb6indexR] = sat16(input + sat16(comb6filterR * combfeeback, 15), 0);
  368. if (++comb6indexR >= sizeof(comb6bufR)/sizeof(int16_t)) comb6indexR = 0;
  369. bufout = comb7bufR[comb7indexR];
  370. sum += bufout;
  371. comb7filterR = sat16(bufout * combdamp2 + comb7filterR * combdamp1, 15);
  372. comb7bufR[comb7indexR] = sat16(input + sat16(comb7filterR * combfeeback, 15), 0);
  373. if (++comb7indexR >= sizeof(comb7bufR)/sizeof(int16_t)) comb7indexR = 0;
  374. bufout = comb8bufR[comb8indexR];
  375. sum += bufout;
  376. comb8filterR = sat16(bufout * combdamp2 + comb8filterR * combdamp1, 15);
  377. comb8bufR[comb8indexR] = sat16(input + sat16(comb8filterR * combfeeback, 15), 0);
  378. if (++comb8indexR >= sizeof(comb8bufR)/sizeof(int16_t)) comb8indexR = 0;
  379. outputR = sat16(sum * 31457, 17);
  380. bufout = allpass1bufL[allpass1indexL];
  381. allpass1bufL[allpass1indexL] = outputL + (bufout >> 1);
  382. outputL = sat16(bufout - outputL, 1);
  383. if (++allpass1indexL >= sizeof(allpass1bufL)/sizeof(int16_t)) allpass1indexL = 0;
  384. bufout = allpass2bufL[allpass2indexL];
  385. allpass2bufL[allpass2indexL] = outputL + (bufout >> 1);
  386. outputL = sat16(bufout - outputL, 1);
  387. if (++allpass2indexL >= sizeof(allpass2bufL)/sizeof(int16_t)) allpass2indexL = 0;
  388. bufout = allpass3bufL[allpass3indexL];
  389. allpass3bufL[allpass3indexL] = outputL + (bufout >> 1);
  390. outputL = sat16(bufout - outputL, 1);
  391. if (++allpass3indexL >= sizeof(allpass3bufL)/sizeof(int16_t)) allpass3indexL = 0;
  392. bufout = allpass4bufL[allpass4indexL];
  393. allpass4bufL[allpass4indexL] = outputL + (bufout >> 1);
  394. outputL = sat16(bufout - outputL, 1);
  395. if (++allpass4indexL >= sizeof(allpass4bufL)/sizeof(int16_t)) allpass4indexL = 0;
  396. outblockL->data[i] = sat16(outputL * 30, 0);
  397. bufout = allpass1bufR[allpass1indexR];
  398. allpass1bufR[allpass1indexR] = outputR + (bufout >> 1);
  399. outputR = sat16(bufout - outputR, 1);
  400. if (++allpass1indexR >= sizeof(allpass1bufR)/sizeof(int16_t)) allpass1indexR = 0;
  401. bufout = allpass2bufR[allpass2indexR];
  402. allpass2bufR[allpass2indexR] = outputR + (bufout >> 1);
  403. outputR = sat16(bufout - outputR, 1);
  404. if (++allpass2indexR >= sizeof(allpass2bufR)/sizeof(int16_t)) allpass2indexR = 0;
  405. bufout = allpass3bufR[allpass3indexR];
  406. allpass3bufR[allpass3indexR] = outputR + (bufout >> 1);
  407. outputR = sat16(bufout - outputR, 1);
  408. if (++allpass3indexR >= sizeof(allpass3bufR)/sizeof(int16_t)) allpass3indexR = 0;
  409. bufout = allpass4bufR[allpass4indexR];
  410. allpass4bufR[allpass4indexR] = outputR + (bufout >> 1);
  411. outputR = sat16(bufout - outputR, 1);
  412. if (++allpass4indexR >= sizeof(allpass4bufR)/sizeof(int16_t)) allpass4indexR = 0;
  413. outblockR->data[i] = sat16(outputL * 30, 0);
  414. }
  415. transmit(outblockL, 0);
  416. transmit(outblockR, 1);
  417. release(outblockL);
  418. release(outblockR);
  419. if (block != &zeroblock) release((audio_block_t *)block);
  420. #elif defined(KINETISL)
  421. audio_block_t *block;
  422. block = receiveReadOnly(0);
  423. if (block) release(block);
  424. #endif
  425. }