reverb_sw.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542
  1. /*************************************************************************/
  2. /* reverb_sw.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
  9. /* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
  10. /* */
  11. /* Permission is hereby granted, free of charge, to any person obtaining */
  12. /* a copy of this software and associated documentation files (the */
  13. /* "Software"), to deal in the Software without restriction, including */
  14. /* without limitation the rights to use, copy, modify, merge, publish, */
  15. /* distribute, sublicense, and/or sell copies of the Software, and to */
  16. /* permit persons to whom the Software is furnished to do so, subject to */
  17. /* the following conditions: */
  18. /* */
  19. /* The above copyright notice and this permission notice shall be */
  20. /* included in all copies or substantial portions of the Software. */
  21. /* */
  22. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  23. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  24. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
  25. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  26. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  27. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  28. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  29. /*************************************************************************/
  30. #include "reverb_sw.h"
  31. #include "core/print_string.h"
  32. #include <stdlib.h>
  33. #define SETMIN(x, y) (x) = MIN((x), (y))
  34. #define rangeloop(c, min, max) \
  35. for ((c) = (min); (c) < (max); (c)++)
  36. #define ABSDIFF(x, y) \
  37. (((x) < (y)) ? ((y) - (x)) : ((x) - (y)))
  38. #define MULSHIFT_S32(Factor1, Factor2, Bits) \
  39. ((int)(((int64_t)(Factor1) * (Factor2)) >> (Bits)))
  40. struct ReverbParamsSW {
  41. unsigned int BufferSize; // Required buffer size
  42. int gLPF; // Coefficient
  43. int gEcho0; // Coefficient
  44. int gEcho1; // Coefficient
  45. int gEcho2; // Coefficient
  46. int gEcho3; // Coefficient
  47. int gWall; // Coefficient
  48. int gReva; // Coefficient
  49. int gRevb; // Coefficient
  50. int gInputL; // Coefficient
  51. int gInputR; // Coefficient
  52. unsigned int nRevaOldL; // Offset
  53. unsigned int nRevaOldR; // Offset
  54. unsigned int nRevbOldL; // Offset
  55. unsigned int nRevbOldR; // Offset
  56. unsigned int nLwlNew; // Offset
  57. unsigned int nRwrNew; // Offset
  58. unsigned int nEcho0L; // Offset
  59. unsigned int nEcho0R; // Offset
  60. unsigned int nEcho1L; // Offset
  61. unsigned int nEcho1R; // Offset
  62. unsigned int nLwlOld; // Offset
  63. unsigned int nRwrOld; // Offset
  64. unsigned int nLwrNew; // Offset
  65. unsigned int nRwlNew; // Offset
  66. unsigned int nEcho2L; // Offset
  67. unsigned int nEcho2R; // Offset
  68. unsigned int nEcho3L; // Offset
  69. unsigned int nEcho3R; // Offset
  70. unsigned int nLwrOld; // Offset
  71. unsigned int nRwlOld; // Offset
  72. unsigned int nRevaNewL; // Offset
  73. unsigned int nRevaNewR; // Offset
  74. unsigned int nRevbNewL; // Offset
  75. unsigned int nRevbNewR; // Offset
  76. };
  77. static ReverbParamsSW reverb_params_Room = {
  78. 0x26C0 / 2,
  79. //gLPF gEcho0 gEcho1 gEcho2 gEcho3 gWall
  80. 0x6D80, 0x54B8, -0x4130, 0x0000, 0x0000, -0x4580,
  81. //gReva gRevb gInputL gInputR
  82. 0x5800, 0x5300, -0x8000, -0x8000,
  83. //nRevaOldL nRevaOldR nRevbOldL nRevbOldR
  84. 0x01B4 - 0x007D, 0x0136 - 0x007D, 0x00B8 - 0x005B, 0x005C - 0x005B,
  85. //nLwlNew nRwrNew nEcho0L nEcho0R nEcho1L nEcho1R
  86. 0x04D6, 0x0333, 0x03F0, 0x0227, 0x0374, 0x01EF,
  87. //nLwlOld nRwrOld nLwrNew nRwlNew nEcho2L nEcho2R nEcho3L nEcho3R
  88. 0x0334, 0x01B5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  89. //nLwrOld nRwlOld nRevaNewL nRevaNewR nRevbNewL nRevbNewR
  90. 0x0000, 0x0000, 0x01B4, 0x0136, 0x00B8, 0x005C
  91. };
  92. static ReverbParamsSW reverb_params_StudioSmall = {
  93. 0x1F40 / 2,
  94. //gLPF gEcho0 gEcho1 gEcho2 gEcho3 gWall
  95. 0x70F0, 0x4FA8, -0x4320, 0x4410, -0x3F10, -0x6400,
  96. //gReva gRevb gInputL gInputR
  97. 0x5280, 0x4EC0, -0x8000, -0x8000,
  98. //nRevaOldL nRevaOldR nRevbOldL nRevbOldR
  99. 0x00B4 - 0x0033, 0x0080 - 0x0033, 0x004C - 0x0025, 0x0026 - 0x0025,
  100. //nLwlNew nRwrNew nEcho0L nEcho0R nEcho1L nEcho1R
  101. 0x03E4, 0x031B, 0x03A4, 0x02AF, 0x0372, 0x0266,
  102. //nLwlOld nRwrOld nLwrNew nRwlNew nEcho2L nEcho2R nEcho3L nEcho3R
  103. 0x031C, 0x025D, 0x025C, 0x018E, 0x022F, 0x0135, 0x01D2, 0x00B7,
  104. //nLwrOld nRwlOld nRevaNewL nRevaNewR nRevbNewL nRevbNewR
  105. 0x018F, 0x00B5, 0x00B4, 0x0080, 0x004C, 0x0026
  106. };
  107. static ReverbParamsSW reverb_params_StudioMedium = {
  108. 0x4840 / 2,
  109. //gLPF gEcho0 gEcho1 gEcho2 gEcho3 gWall
  110. 0x70F0, 0x4FA8, -0x4320, 0x4510, -0x4110, -0x4B40,
  111. //gReva gRevb gInputL gInputR
  112. 0x5280, 0x4EC0, -0x8000, -0x8000,
  113. //nRevaOldL nRevaOldR nRevbOldL nRevbOldR
  114. 0x0264 - 0x00B1, 0x01B2 - 0x00B1, 0x0100 - 0x007F, 0x0080 - 0x007F,
  115. //nLwlNew nRwrNew nEcho0L nEcho0R nEcho1L nEcho1R
  116. 0x0904, 0x076B, 0x0824, 0x065F, 0x07A2, 0x0616,
  117. //nLwlOld nRwrOld nLwrNew nRwlNew nEcho2L nEcho2R nEcho3L nEcho3R
  118. 0x076C, 0x05ED, 0x05EC, 0x042E, 0x050F, 0x0305, 0x0462, 0x02B7,
  119. //nLwrOld nRwlOld nRevaNewL nRevaNewR nRevbNewL nRevbNewR
  120. 0x042F, 0x0265, 0x0264, 0x01B2, 0x0100, 0x0080
  121. };
  122. static ReverbParamsSW reverb_params_StudioLarge = {
  123. 0x6FE0 / 2,
  124. //gLPF gEcho0 gEcho1 gEcho2 gEcho3 gWall
  125. 0x6F60, 0x4FA8, -0x4320, 0x4510, -0x4110, -0x5980,
  126. //gReva gRevb gInputL gInputR
  127. 0x5680, 0x52C0, -0x8000, -0x8000,
  128. //nRevaOldL nRevaOldR nRevbOldL nRevbOldR
  129. 0x031C - 0x00E3, 0x0238 - 0x00E3, 0x0154 - 0x00A9, 0x00AA - 0x00A9,
  130. //nLwlNew nRwrNew nEcho0L nEcho0R nEcho1L nEcho1R
  131. 0x0DFB, 0x0B58, 0x0D09, 0x0A3C, 0x0BD9, 0x0973,
  132. //nLwlOld nRwrOld nLwrNew nRwlNew nEcho2L nEcho2R nEcho3L nEcho3R
  133. 0x0B59, 0x08DA, 0x08D9, 0x05E9, 0x07EC, 0x04B0, 0x06EF, 0x03D2,
  134. //nLwrOld nRwlOld nRevaNewL nRevaNewR nRevbNewL nRevbNewR
  135. 0x05EA, 0x031D, 0x031C, 0x0238, 0x0154, 0x00AA
  136. };
  137. static ReverbParamsSW reverb_params_Hall = {
  138. 0xADE0 / 2,
  139. //gLPF gEcho0 gEcho1 gEcho2 gEcho3 gWall
  140. 0x6000, 0x5000, 0x4C00, -0x4800, -0x4400, -0x4000,
  141. //gReva gRevb gInputL gInputR
  142. 0x6000, 0x5C00, -0x8000, -0x8000,
  143. //nRevaOldL nRevaOldR nRevbOldL nRevbOldR
  144. 0x05C0 - 0x01A5, 0x041A - 0x01A5, 0x0274 - 0x0139, 0x013A - 0x0139,
  145. //nLwlNew nRwrNew nEcho0L nEcho0R nEcho1L nEcho1R
  146. 0x15BA, 0x11BB, 0x14C2, 0x10BD, 0x11BC, 0x0DC1,
  147. //nLwlOld nRwrOld nLwrNew nRwlNew nEcho2L nEcho2R nEcho3L nEcho3R
  148. 0x11C0, 0x0DC3, 0x0DC0, 0x09C1, 0x0BC4, 0x07C1, 0x0A00, 0x06CD,
  149. //nLwrOld nRwlOld nRevaNewL nRevaNewR nRevbNewL nRevbNewR
  150. 0x09C2, 0x05C1, 0x05C0, 0x041A, 0x0274, 0x013A
  151. };
  152. static ReverbParamsSW reverb_params_SpaceEcho = {
  153. 0xF6C0 / 2,
  154. //gLPF gEcho0 gEcho1 gEcho2 gEcho3 gWall
  155. 0x7E00, 0x5000, -0x4C00, -0x5000, 0x4C00, -0x5000,
  156. //gReva gRevb gInputL gInputR
  157. 0x6000, 0x5400, -0x8000, -0x8000,
  158. //nRevaOldL nRevaOldR nRevbOldL nRevbOldR
  159. 0x0AE0 - 0x033D, 0x07A2 - 0x033D, 0x0464 - 0x0231, 0x0232 - 0x0231,
  160. //nLwlNew nRwrNew nEcho0L nEcho0R nEcho1L nEcho1R
  161. 0x1ED6, 0x1A31, 0x1D14, 0x183B, 0x1BC2, 0x16B2,
  162. //nLwlOld nRwrOld nLwrNew nRwlNew nEcho2L nEcho2R nEcho3L nEcho3R
  163. 0x1A32, 0x15EF, 0x15EE, 0x1055, 0x1334, 0x0F2D, 0x11F6, 0x0C5D,
  164. //nLwrOld nRwlOld nRevaNewL nRevaNewR nRevbNewL nRevbNewR
  165. 0x1056, 0x0AE1, 0x0AE0, 0x07A2, 0x0464, 0x0232
  166. };
  167. static ReverbParamsSW reverb_params_Echo = {
  168. 0x18040 / 2,
  169. //gLPF gEcho0 gEcho1 gEcho2 gEcho3 gWall
  170. 0x7FFF, 0x7FFF, 0x0000, 0x0000, 0x0000, -0x7F00,
  171. //gReva gRevb gInputL gInputR
  172. 0x0000, 0x0000, -0x8000, -0x8000,
  173. //nRevaOldL nRevaOldR nRevbOldL nRevbOldR
  174. 0x1004 - 0x0001, 0x1002 - 0x0001, 0x0004 - 0x0001, 0x0002 - 0x0001,
  175. //nLwlNew nRwrNew nEcho0L nEcho0R nEcho1L nEcho1R
  176. 0x1FFF, 0x0FFF, 0x1005, 0x0005, 0x0000, 0x0000,
  177. //nLwlOld nRwrOld nLwrNew nRwlNew nEcho2L nEcho2R nEcho3L nEcho3R
  178. 0x1005, 0x0005, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  179. //nLwrOld nRwlOld nRevaNewL nRevaNewR nRevbNewL nRevbNewR
  180. 0x0000, 0x0000, 0x1004, 0x1002, 0x0004, 0x0002
  181. };
  182. static ReverbParamsSW reverb_params_Delay = {
  183. 0x18040 / 2,
  184. //gLPF gEcho0 gEcho1 gEcho2 gEcho3 gWall
  185. 0x7FFF, 0x7FFF, 0x0000, 0x0000, 0x0000, 0x0000,
  186. //gReva gRevb gInputL gInputR
  187. 0x0000, 0x0000, -0x8000, -0x8000,
  188. //nRevaOldL nRevaOldR nRevbOldL nRevbOldR
  189. 0x1004 - 0x0001, 0x1002 - 0x0001, 0x0004 - 0x0001, 0x0002 - 0x0001,
  190. //nLwlNew nRwrNew nEcho0L nEcho0R nEcho1L nEcho1R
  191. 0x1FFF, 0x0FFF, 0x1005, 0x0005, 0x0000, 0x0000,
  192. //nLwlOld nRwrOld nLwrNew nRwlNew nEcho2L nEcho2R nEcho3L nEcho3R
  193. 0x1005, 0x0005, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  194. //nLwrOld nRwlOld nRevaNewL nRevaNewR nRevbNewL nRevbNewR
  195. 0x0000, 0x0000, 0x1004, 0x1002, 0x0004, 0x0002
  196. };
  197. static ReverbParamsSW reverb_params_HalfEcho = {
  198. 0x3C00 / 2,
  199. //gLPF gEcho0 gEcho1 gEcho2 gEcho3 gWall
  200. 0x70F0, 0x4FA8, -0x4320, 0x4510, -0x4110, -0x7B00,
  201. //gReva gRevb gInputL gInputR
  202. 0x5F80, 0x54C0, -0x8000, -0x8000,
  203. //nRevaOldL nRevaOldR nRevbOldL nRevbOldR
  204. 0x0058 - 0x0017, 0x0040 - 0x0017, 0x0028 - 0x0013, 0x0014 - 0x0013,
  205. //nLwlNew nRwrNew nEcho0L nEcho0R nEcho1L nEcho1R
  206. 0x0371, 0x02AF, 0x02E5, 0x01DF, 0x02B0, 0x01D7,
  207. //nLwlOld nRwrOld nLwrNew nRwlNew nEcho2L nEcho2R nEcho3L nEcho3R
  208. 0x0358, 0x026A, 0x01D6, 0x011E, 0x012D, 0x00B1, 0x011F, 0x0059,
  209. //nLwrOld nRwlOld nRevaNewL nRevaNewR nRevbNewL nRevbNewR
  210. 0x01A0, 0x00E3, 0x0058, 0x0040, 0x0028, 0x0014
  211. };
  212. static ReverbParamsSW *reverb_param_modes[] = {
  213. &reverb_params_Room,
  214. &reverb_params_StudioSmall,
  215. &reverb_params_StudioMedium,
  216. &reverb_params_StudioLarge,
  217. &reverb_params_Hall,
  218. &reverb_params_SpaceEcho,
  219. &reverb_params_Echo,
  220. &reverb_params_Delay,
  221. &reverb_params_HalfEcho,
  222. };
  223. bool ReverbSW::process(int *p_input, int *p_output, int p_frames, int p_stereo_stride) {
  224. // p_input must point to a non-looping buffer.
  225. // BOTH p_input and p_output must be touched (use ClearModuleBuffer).
  226. if (!reverb_buffer)
  227. return false;
  228. // LOCAL MACROS
  229. #undef LM_SETSRCOFFSET
  230. #define LM_SETSRCOFFSET(x) \
  231. (x) = current_params->x + Offset; \
  232. if ((x) >= reverb_buffer_size) { \
  233. (x) -= reverb_buffer_size; \
  234. } \
  235. SETMIN(aSample, reverb_buffer_size - (x));
  236. /*
  237. #undef LM_SETSRCOFFSET2
  238. #define LM_SETSRCOFFSET2(x,y) \
  239. (x) = ((y) << 3) >> HZShift; \
  240. (x) += Offset; \
  241. if ( (x) >= reverb_buffer_size ) { \
  242. (x) -= reverb_buffer_size; \
  243. } \
  244. SETMIN ( aSample, reverb_buffer_size - (x) );
  245. */
  246. #undef LM_SRCADVANCE
  247. #define LM_SRCADVANCE(x) \
  248. (x) += aSample;
  249. #undef LM_MUL
  250. #define LM_MUL(x, y) \
  251. MULSHIFT_S32(x, current_params->y, 15)
  252. #undef LM_REVERB
  253. #define LM_REVERB(x) reverb_buffer[(x) + cSample]
  254. // LOCAL VARIABLES
  255. unsigned int Offset;
  256. int lwl, lwr, rwl, rwr;
  257. //unsigned char HZShift;
  258. // CODE
  259. lwl = state.lwl;
  260. lwr = state.lwr;
  261. rwl = state.rwl;
  262. rwr = state.rwr;
  263. Offset = state.Offset;
  264. int max = 0;
  265. while (p_frames) {
  266. // Offsets
  267. unsigned int nLwlOld;
  268. unsigned int nRwrOld;
  269. unsigned int nLwlNew;
  270. unsigned int nRwrNew;
  271. unsigned int nLwrOld;
  272. unsigned int nRwlOld;
  273. unsigned int nLwrNew;
  274. unsigned int nRwlNew;
  275. unsigned int nEcho0L;
  276. unsigned int nEcho1L;
  277. unsigned int nEcho2L;
  278. unsigned int nEcho3L;
  279. unsigned int nEcho0R;
  280. unsigned int nEcho1R;
  281. unsigned int nEcho2R;
  282. unsigned int nEcho3R;
  283. unsigned int nRevaOldL;
  284. unsigned int nRevaOldR;
  285. unsigned int nRevbOldL;
  286. unsigned int nRevbOldR;
  287. unsigned int nRevaNewL;
  288. unsigned int nRevaNewR;
  289. unsigned int nRevbNewL;
  290. unsigned int nRevbNewR;
  291. // Other variables
  292. unsigned int aSample = p_frames;
  293. // Set initial offsets
  294. LM_SETSRCOFFSET(nLwlOld);
  295. LM_SETSRCOFFSET(nRwrOld);
  296. LM_SETSRCOFFSET(nLwlNew);
  297. LM_SETSRCOFFSET(nRwrNew);
  298. LM_SETSRCOFFSET(nLwrOld);
  299. LM_SETSRCOFFSET(nRwlOld);
  300. LM_SETSRCOFFSET(nLwrNew);
  301. LM_SETSRCOFFSET(nRwlNew);
  302. LM_SETSRCOFFSET(nEcho0L);
  303. LM_SETSRCOFFSET(nEcho1L);
  304. LM_SETSRCOFFSET(nEcho2L);
  305. LM_SETSRCOFFSET(nEcho3L);
  306. LM_SETSRCOFFSET(nEcho0R);
  307. LM_SETSRCOFFSET(nEcho1R);
  308. LM_SETSRCOFFSET(nEcho2R);
  309. LM_SETSRCOFFSET(nEcho3R);
  310. LM_SETSRCOFFSET(nRevaOldL);
  311. LM_SETSRCOFFSET(nRevaOldR);
  312. LM_SETSRCOFFSET(nRevbOldL);
  313. LM_SETSRCOFFSET(nRevbOldR);
  314. LM_SETSRCOFFSET(nRevaNewL);
  315. LM_SETSRCOFFSET(nRevaNewR);
  316. LM_SETSRCOFFSET(nRevbNewL);
  317. LM_SETSRCOFFSET(nRevbNewR);
  318. //SETMIN ( aSample, p_output.Size - p_output.Offset );
  319. for (unsigned int cSample = 0; cSample < aSample; cSample++) {
  320. int tempL0, tempL1, tempR0, tempR1;
  321. tempL1 = p_input[(cSample << p_stereo_stride)] >> 8;
  322. tempR1 = p_input[(cSample << p_stereo_stride) + 1] >> 8;
  323. tempL0 = LM_MUL(tempL1, gInputL);
  324. tempR0 = LM_MUL(tempR1, gInputR);
  325. /*
  326. Left -> Wall -> Left Reflection
  327. */
  328. tempL1 = tempL0 + LM_MUL(LM_REVERB(nLwlOld), gWall);
  329. tempR1 = tempR0 + LM_MUL(LM_REVERB(nRwrOld), gWall);
  330. lwl += LM_MUL(tempL1 - lwl, gLPF);
  331. rwr += LM_MUL(tempR1 - rwr, gLPF);
  332. LM_REVERB(nLwlNew) = lwl;
  333. LM_REVERB(nRwrNew) = rwr;
  334. /*
  335. Left -> Wall -> Right Reflection
  336. */
  337. tempL1 = tempL0 + LM_MUL(LM_REVERB(nRwlOld), gWall);
  338. tempR1 = tempR0 + LM_MUL(LM_REVERB(nLwrOld), gWall);
  339. lwr += LM_MUL(tempL1 - lwr, gLPF);
  340. rwl += LM_MUL(tempR1 - rwl, gLPF);
  341. LM_REVERB(nLwrNew) = lwr;
  342. LM_REVERB(nRwlNew) = rwl;
  343. /*
  344. Early Echo(Early Reflection)
  345. */
  346. tempL0 =
  347. LM_MUL(LM_REVERB(nEcho0L), gEcho0) +
  348. LM_MUL(LM_REVERB(nEcho1L), gEcho1) +
  349. LM_MUL(LM_REVERB(nEcho2L), gEcho2) +
  350. LM_MUL(LM_REVERB(nEcho3L), gEcho3);
  351. tempR0 =
  352. LM_MUL(LM_REVERB(nEcho0R), gEcho0) +
  353. LM_MUL(LM_REVERB(nEcho1R), gEcho1) +
  354. LM_MUL(LM_REVERB(nEcho2R), gEcho2) +
  355. LM_MUL(LM_REVERB(nEcho3R), gEcho3);
  356. /*
  357. Late Reverb
  358. */
  359. tempL1 = LM_REVERB(nRevaOldL);
  360. tempR1 = LM_REVERB(nRevaOldR);
  361. tempL0 -= LM_MUL(tempL1, gReva);
  362. tempR0 -= LM_MUL(tempR1, gReva);
  363. LM_REVERB(nRevaNewL) = tempL0;
  364. LM_REVERB(nRevaNewR) = tempR0;
  365. tempL0 = LM_MUL(tempL0, gReva) + tempL1;
  366. tempR0 = LM_MUL(tempR0, gReva) + tempR1;
  367. tempL1 = LM_REVERB(nRevbOldL);
  368. tempR1 = LM_REVERB(nRevbOldR);
  369. tempL0 -= LM_MUL(tempL1, gRevb);
  370. tempR0 -= LM_MUL(tempR1, gRevb);
  371. LM_REVERB(nRevbNewL) = tempL0;
  372. LM_REVERB(nRevbNewR) = tempR0;
  373. tempL0 = LM_MUL(tempL0, gRevb) + tempL1;
  374. tempR0 = LM_MUL(tempR0, gRevb) + tempR1;
  375. /*
  376. Output
  377. */
  378. max |= abs(tempL0);
  379. max |= abs(tempR0);
  380. p_output[(cSample << p_stereo_stride)] += tempL0 << 8;
  381. p_output[(cSample << p_stereo_stride) + 1] += tempR0 << 8;
  382. }
  383. // Advance offsets
  384. Offset += aSample;
  385. if (Offset >= reverb_buffer_size) {
  386. Offset -= reverb_buffer_size;
  387. }
  388. p_input += aSample << p_stereo_stride;
  389. p_output += aSample << p_stereo_stride;
  390. p_frames -= aSample;
  391. }
  392. state.lwl = lwl;
  393. state.lwr = lwr;
  394. state.rwl = rwl;
  395. state.rwr = rwr;
  396. state.Offset = Offset;
  397. return (max & 0x7FFFFF00) != 0; // audio was mixed?
  398. }
  399. void ReverbSW::adjust_current_params() {
  400. *current_params = *reverb_param_modes[mode];
  401. uint32_t maxofs = 0;
  402. #define LM_CONFIG_PARAM(x) \
  403. current_params->x = (int)(((int64_t)current_params->x * (int64_t)mix_rate * 8L) / (int64_t)44100); \
  404. if (current_params->x > maxofs) \
  405. maxofs = current_params->x;
  406. LM_CONFIG_PARAM(nLwlOld);
  407. LM_CONFIG_PARAM(nRwrOld);
  408. LM_CONFIG_PARAM(nLwlNew);
  409. LM_CONFIG_PARAM(nRwrNew);
  410. LM_CONFIG_PARAM(nLwrOld);
  411. LM_CONFIG_PARAM(nRwlOld);
  412. LM_CONFIG_PARAM(nLwrNew);
  413. LM_CONFIG_PARAM(nRwlNew);
  414. LM_CONFIG_PARAM(nEcho0L);
  415. LM_CONFIG_PARAM(nEcho1L);
  416. LM_CONFIG_PARAM(nEcho2L);
  417. LM_CONFIG_PARAM(nEcho3L);
  418. LM_CONFIG_PARAM(nEcho0R);
  419. LM_CONFIG_PARAM(nEcho1R);
  420. LM_CONFIG_PARAM(nEcho2R);
  421. LM_CONFIG_PARAM(nEcho3R);
  422. LM_CONFIG_PARAM(nRevaOldL);
  423. LM_CONFIG_PARAM(nRevaOldR);
  424. LM_CONFIG_PARAM(nRevbOldL);
  425. LM_CONFIG_PARAM(nRevbOldR);
  426. LM_CONFIG_PARAM(nRevaNewL);
  427. LM_CONFIG_PARAM(nRevaNewR);
  428. LM_CONFIG_PARAM(nRevbNewL);
  429. LM_CONFIG_PARAM(nRevbNewR);
  430. int needed_buffer_size = maxofs + 1;
  431. if (reverb_buffer)
  432. memdelete_arr(reverb_buffer);
  433. reverb_buffer = memnew_arr(int, needed_buffer_size);
  434. reverb_buffer_size = needed_buffer_size;
  435. for (uint32_t i = 0; i < reverb_buffer_size; i++)
  436. reverb_buffer[i] = 0;
  437. state.reset();
  438. }
  439. void ReverbSW::set_mode(ReverbMode p_mode) {
  440. if (mode == p_mode)
  441. return;
  442. mode = p_mode;
  443. adjust_current_params();
  444. }
  445. void ReverbSW::set_mix_rate(int p_mix_rate) {
  446. if (p_mix_rate == mix_rate)
  447. return;
  448. mix_rate = p_mix_rate;
  449. adjust_current_params();
  450. }
  451. ReverbSW::ReverbSW() {
  452. reverb_buffer = 0;
  453. reverb_buffer_size = 0;
  454. mode = REVERB_MODE_ROOM;
  455. mix_rate = 1;
  456. current_params = memnew(ReverbParamsSW);
  457. }
  458. ReverbSW::~ReverbSW() {
  459. if (reverb_buffer)
  460. memdelete_arr(reverb_buffer);
  461. memdelete(current_params);
  462. }