Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Reverb.cpp 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  1. /*
  2. ZynAddSubFX - a software synthesizer
  3. Reverb.cpp - Reverberation effect
  4. Copyright (C) 2002-2005 Nasca Octavian Paul
  5. Author: Nasca Octavian Paul
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of version 2 of the GNU General Public License
  8. as published by the Free Software Foundation.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License (version 2 or later) for more details.
  13. You should have received a copy of the GNU General Public License (version 2)
  14. along with this program; if not, write to the Free Software Foundation,
  15. Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  16. */
  17. #include "Reverb.h"
  18. #include "../Misc/Util.h"
  19. #include "../DSP/AnalogFilter.h"
  20. #include "../DSP/Unison.h"
  21. #include <cmath>
  22. //todo: EarlyReflections, Prdelay, Perbalance
  23. Reverb::Reverb(bool insertion_, float *efxoutl_, float *efxoutr_)
  24. :Effect(insertion_, efxoutl_, efxoutr_, NULL, 0),
  25. // defaults
  26. Pvolume(48),
  27. Ptime(64),
  28. Pidelay(40),
  29. Pidelayfb(0),
  30. Prdelay(0),
  31. Perbalance(64),
  32. Plpf(127),
  33. Phpf(0),
  34. Plohidamp(80),
  35. Ptype(1),
  36. Proomsize(64),
  37. Pbandwidth(30),
  38. roomsize(1.0f),
  39. rs(1.0f),
  40. bandwidth(NULL),
  41. idelay(NULL),
  42. lpf(NULL),
  43. hpf(NULL) // no filter
  44. {
  45. for(int i = 0; i < REV_COMBS * 2; ++i) {
  46. comblen[i] = 800 + (int)(RND * 1400.0f);
  47. combk[i] = 0;
  48. lpcomb[i] = 0;
  49. combfb[i] = -0.97f;
  50. comb[i] = NULL;
  51. }
  52. for(int i = 0; i < REV_APS * 2; ++i) {
  53. aplen[i] = 500 + (int)(RND * 500.0f);
  54. apk[i] = 0;
  55. ap[i] = NULL;
  56. }
  57. setpreset(Ppreset);
  58. cleanup(); //do not call this before the comb initialisation
  59. }
  60. Reverb::~Reverb()
  61. {
  62. delete [] idelay;
  63. delete hpf;
  64. delete lpf;
  65. for(int i = 0; i < REV_APS * 2; ++i)
  66. delete [] ap[i];
  67. for(int i = 0; i < REV_COMBS * 2; ++i)
  68. delete [] comb[i];
  69. if(bandwidth)
  70. delete bandwidth;
  71. }
  72. //Cleanup the effect
  73. void Reverb::cleanup(void)
  74. {
  75. int i, j;
  76. for(i = 0; i < REV_COMBS * 2; ++i) {
  77. lpcomb[i] = 0.0f;
  78. for(j = 0; j < comblen[i]; ++j)
  79. comb[i][j] = 0.0f;
  80. }
  81. for(i = 0; i < REV_APS * 2; ++i)
  82. for(j = 0; j < aplen[i]; ++j)
  83. ap[i][j] = 0.0f;
  84. if(idelay)
  85. for(i = 0; i < idelaylen; ++i)
  86. idelay[i] = 0.0f;
  87. if(hpf)
  88. hpf->cleanup();
  89. if(lpf)
  90. lpf->cleanup();
  91. }
  92. //Process one channel; 0=left, 1=right
  93. void Reverb::processmono(int ch, float *output, float *inputbuf)
  94. {
  95. //todo: implement the high part from lohidamp
  96. for(int j = REV_COMBS * ch; j < REV_COMBS * (ch + 1); ++j) {
  97. int &ck = combk[j];
  98. const int comblength = comblen[j];
  99. float &lpcombj = lpcomb[j];
  100. for(int i = 0; i < synth->buffersize; ++i) {
  101. float fbout = comb[j][ck] * combfb[j];
  102. fbout = fbout * (1.0f - lohifb) + lpcombj * lohifb;
  103. lpcombj = fbout;
  104. comb[j][ck] = inputbuf[i] + fbout;
  105. output[i] += fbout;
  106. if((++ck) >= comblength)
  107. ck = 0;
  108. }
  109. }
  110. for(int j = REV_APS * ch; j < REV_APS * (1 + ch); ++j) {
  111. int &ak = apk[j];
  112. const int aplength = aplen[j];
  113. for(int i = 0; i < synth->buffersize; ++i) {
  114. float tmp = ap[j][ak];
  115. ap[j][ak] = 0.7f * tmp + output[i];
  116. output[i] = tmp - 0.7f * ap[j][ak];
  117. if((++ak) >= aplength)
  118. ak = 0;
  119. }
  120. }
  121. }
  122. //Effect output
  123. void Reverb::out(const Stereo<float *> &smp)
  124. {
  125. if(!Pvolume && insertion)
  126. return;
  127. float *inputbuf = getTmpBuffer();
  128. for(int i = 0; i < synth->buffersize; ++i)
  129. inputbuf[i] = (smp.l[i] + smp.r[i]) / 2.0f;
  130. if(idelay)
  131. for(int i = 0; i < synth->buffersize; ++i) {
  132. //Initial delay r
  133. float tmp = inputbuf[i] + idelay[idelayk] * idelayfb;
  134. inputbuf[i] = idelay[idelayk];
  135. idelay[idelayk] = tmp;
  136. idelayk++;
  137. if(idelayk >= idelaylen)
  138. idelayk = 0;
  139. }
  140. if(bandwidth)
  141. bandwidth->process(synth->buffersize, inputbuf);
  142. if(lpf)
  143. lpf->filterout(inputbuf);
  144. if(hpf)
  145. hpf->filterout(inputbuf);
  146. processmono(0, efxoutl, inputbuf); //left
  147. processmono(1, efxoutr, inputbuf); //right
  148. returnTmpBuffer(inputbuf);
  149. float lvol = rs / REV_COMBS * pangainL;
  150. float rvol = rs / REV_COMBS * pangainR;
  151. if(insertion != 0) {
  152. lvol *= 2.0f;
  153. rvol *= 2.0f;
  154. }
  155. for(int i = 0; i < synth->buffersize; ++i) {
  156. efxoutl[i] *= lvol;
  157. efxoutr[i] *= rvol;
  158. }
  159. }
  160. //Parameter control
  161. void Reverb::setvolume(unsigned char _Pvolume)
  162. {
  163. Pvolume = _Pvolume;
  164. if(!insertion) {
  165. outvolume = powf(0.01f, (1.0f - Pvolume / 127.0f)) * 4.0f;
  166. volume = 1.0f;
  167. }
  168. else {
  169. volume = outvolume = Pvolume / 127.0f;
  170. if(Pvolume == 0)
  171. cleanup();
  172. }
  173. }
  174. void Reverb::settime(unsigned char _Ptime)
  175. {
  176. Ptime = _Ptime;
  177. float t = powf(60.0f, Ptime / 127.0f) - 0.97f;
  178. for(int i = 0; i < REV_COMBS * 2; ++i)
  179. combfb[i] =
  180. -expf((float)comblen[i] / synth->samplerate_f * logf(0.001f) / t);
  181. //the feedback is negative because it removes the DC
  182. }
  183. void Reverb::setlohidamp(unsigned char _Plohidamp)
  184. {
  185. Plohidamp = (_Plohidamp < 64) ? 64 : _Plohidamp;
  186. //remove this when the high part from lohidamp is added
  187. if(Plohidamp == 64) {
  188. lohidamptype = 0;
  189. lohifb = 0.0f;
  190. }
  191. else {
  192. if(Plohidamp < 64)
  193. lohidamptype = 1;
  194. if(Plohidamp > 64)
  195. lohidamptype = 2;
  196. float x = fabsf((float)(Plohidamp - 64) / 64.1f);
  197. lohifb = x * x;
  198. }
  199. }
  200. void Reverb::setidelay(unsigned char _Pidelay)
  201. {
  202. Pidelay = _Pidelay;
  203. float delay = powf(50.0f * Pidelay / 127.0f, 2.0f) - 1.0f;
  204. if(idelay)
  205. delete [] idelay;
  206. idelay = NULL;
  207. idelaylen = (int) (synth->samplerate_f * delay / 1000);
  208. if(idelaylen > 1) {
  209. idelayk = 0;
  210. idelay = new float[idelaylen];
  211. memset(idelay, 0, idelaylen * sizeof(float));
  212. }
  213. }
  214. void Reverb::setidelayfb(unsigned char _Pidelayfb)
  215. {
  216. Pidelayfb = _Pidelayfb;
  217. idelayfb = Pidelayfb / 128.0f;
  218. }
  219. void Reverb::sethpf(unsigned char _Phpf)
  220. {
  221. Phpf = _Phpf;
  222. if(Phpf == 0) { //No HighPass
  223. if(hpf)
  224. delete hpf;
  225. hpf = NULL;
  226. }
  227. else {
  228. float fr = expf(powf(Phpf / 127.0f, 0.5f) * logf(10000.0f)) + 20.0f;
  229. if(hpf == NULL)
  230. hpf = new AnalogFilter(3, fr, 1, 0);
  231. else
  232. hpf->setfreq(fr);
  233. }
  234. }
  235. void Reverb::setlpf(unsigned char _Plpf)
  236. {
  237. Plpf = _Plpf;
  238. if(Plpf == 127) { //No LowPass
  239. if(lpf)
  240. delete lpf;
  241. lpf = NULL;
  242. }
  243. else {
  244. float fr = expf(powf(Plpf / 127.0f, 0.5f) * logf(25000.0f)) + 40.0f;
  245. if(!lpf)
  246. lpf = new AnalogFilter(2, fr, 1, 0);
  247. else
  248. lpf->setfreq(fr);
  249. }
  250. }
  251. void Reverb::settype(unsigned char _Ptype)
  252. {
  253. Ptype = _Ptype;
  254. const int NUM_TYPES = 3;
  255. const int combtunings[NUM_TYPES][REV_COMBS] = {
  256. //this is unused (for random)
  257. {0, 0, 0, 0, 0, 0, 0, 0 },
  258. //Freeverb by Jezar at Dreampoint
  259. {1116, 1188, 1277, 1356, 1422, 1491, 1557, 1617 },
  260. //duplicate of Freeverb by Jezar at Dreampoint
  261. {1116, 1188, 1277, 1356, 1422, 1491, 1557, 1617 }
  262. };
  263. const int aptunings[NUM_TYPES][REV_APS] = {
  264. //this is unused (for random)
  265. {0, 0, 0, 0 },
  266. //Freeverb by Jezar at Dreampoint
  267. {225, 341, 441, 556 },
  268. //duplicate of Freeverb by Jezar at Dreampoint
  269. {225, 341, 441, 556 }
  270. };
  271. if(Ptype >= NUM_TYPES)
  272. Ptype = NUM_TYPES - 1;
  273. // adjust the combs according to the samplerate
  274. float samplerate_adjust = synth->samplerate_f / 44100.0f;
  275. float tmp;
  276. for(int i = 0; i < REV_COMBS * 2; ++i) {
  277. if(Ptype == 0)
  278. tmp = 800.0f + (int)(RND * 1400.0f);
  279. else
  280. tmp = combtunings[Ptype][i % REV_COMBS];
  281. tmp *= roomsize;
  282. if(i > REV_COMBS)
  283. tmp += 23.0f;
  284. tmp *= samplerate_adjust; //adjust the combs according to the samplerate
  285. if(tmp < 10.0f)
  286. tmp = 10.0f;
  287. comblen[i] = (int) tmp;
  288. combk[i] = 0;
  289. lpcomb[i] = 0;
  290. if(comb[i])
  291. delete [] comb[i];
  292. comb[i] = new float[comblen[i]];
  293. }
  294. for(int i = 0; i < REV_APS * 2; ++i) {
  295. if(Ptype == 0)
  296. tmp = 500 + (int)(RND * 500.0f);
  297. else
  298. tmp = aptunings[Ptype][i % REV_APS];
  299. tmp *= roomsize;
  300. if(i > REV_APS)
  301. tmp += 23.0f;
  302. tmp *= samplerate_adjust; //adjust the combs according to the samplerate
  303. if(tmp < 10)
  304. tmp = 10;
  305. aplen[i] = (int) tmp;
  306. apk[i] = 0;
  307. if(ap[i])
  308. delete [] ap[i];
  309. ap[i] = new float[aplen[i]];
  310. }
  311. delete bandwidth;
  312. bandwidth = NULL;
  313. if(Ptype == 2) { //bandwidth
  314. //TODO the size of the unison buffer may be too small, though this has
  315. //not been verified yet.
  316. //As this cannot be resized in a RT context, a good upper bound should
  317. //be found
  318. bandwidth = new Unison(synth->buffersize / 4 + 1, 2.0f);
  319. bandwidth->setSize(50);
  320. bandwidth->setBaseFrequency(1.0f);
  321. }
  322. settime(Ptime);
  323. cleanup();
  324. }
  325. void Reverb::setroomsize(unsigned char _Proomsize)
  326. {
  327. Proomsize = _Proomsize;
  328. if(!Proomsize)
  329. this->Proomsize = 64; //this is because the older versions consider roomsize=0
  330. roomsize = (this->Proomsize - 64.0f) / 64.0f;
  331. if(roomsize > 0.0f)
  332. roomsize *= 2.0f;
  333. roomsize = powf(10.0f, roomsize);
  334. rs = sqrtf(roomsize);
  335. settype(Ptype);
  336. }
  337. void Reverb::setbandwidth(unsigned char _Pbandwidth)
  338. {
  339. Pbandwidth = _Pbandwidth;
  340. float v = Pbandwidth / 127.0f;
  341. if(bandwidth)
  342. bandwidth->setBandwidth(powf(v, 2.0f) * 200.0f);
  343. }
  344. void Reverb::setpreset(unsigned char npreset)
  345. {
  346. const int PRESET_SIZE = 13;
  347. const int NUM_PRESETS = 13;
  348. unsigned char presets[NUM_PRESETS][PRESET_SIZE] = {
  349. //Cathedral1
  350. {80, 64, 63, 24, 0, 0, 0, 85, 5, 83, 1, 64, 20},
  351. //Cathedral2
  352. {80, 64, 69, 35, 0, 0, 0, 127, 0, 71, 0, 64, 20},
  353. //Cathedral3
  354. {80, 64, 69, 24, 0, 0, 0, 127, 75, 78, 1, 85, 20},
  355. //Hall1
  356. {90, 64, 51, 10, 0, 0, 0, 127, 21, 78, 1, 64, 20},
  357. //Hall2
  358. {90, 64, 53, 20, 0, 0, 0, 127, 75, 71, 1, 64, 20},
  359. //Room1
  360. {100, 64, 33, 0, 0, 0, 0, 127, 0, 106, 0, 30, 20},
  361. //Room2
  362. {100, 64, 21, 26, 0, 0, 0, 62, 0, 77, 1, 45, 20},
  363. //Basement
  364. {110, 64, 14, 0, 0, 0, 0, 127, 5, 71, 0, 25, 20},
  365. //Tunnel
  366. {85, 80, 84, 20, 42, 0, 0, 51, 0, 78, 1, 105, 20},
  367. //Echoed1
  368. {95, 64, 26, 60, 71, 0, 0, 114, 0, 64, 1, 64, 20},
  369. //Echoed2
  370. {90, 64, 40, 88, 71, 0, 0, 114, 0, 88, 1, 64, 20},
  371. //VeryLong1
  372. {90, 64, 93, 15, 0, 0, 0, 114, 0, 77, 0, 95, 20},
  373. //VeryLong2
  374. {90, 64, 111, 30, 0, 0, 0, 114, 90, 74, 1, 80, 20}
  375. };
  376. if(npreset >= NUM_PRESETS)
  377. npreset = NUM_PRESETS - 1;
  378. for(int n = 0; n < PRESET_SIZE; ++n)
  379. changepar(n, presets[npreset][n]);
  380. if(insertion)
  381. changepar(0, presets[npreset][0] / 2); //lower the volume if reverb is insertion effect
  382. Ppreset = npreset;
  383. }
  384. void Reverb::changepar(int npar, unsigned char value)
  385. {
  386. switch(npar) {
  387. case 0:
  388. setvolume(value);
  389. break;
  390. case 1:
  391. setpanning(value);
  392. break;
  393. case 2:
  394. settime(value);
  395. break;
  396. case 3:
  397. setidelay(value);
  398. break;
  399. case 4:
  400. setidelayfb(value);
  401. break;
  402. // case 5:
  403. // setrdelay(value);
  404. // break;
  405. // case 6:
  406. // seterbalance(value);
  407. // break;
  408. case 7:
  409. setlpf(value);
  410. break;
  411. case 8:
  412. sethpf(value);
  413. break;
  414. case 9:
  415. setlohidamp(value);
  416. break;
  417. case 10:
  418. settype(value);
  419. break;
  420. case 11:
  421. setroomsize(value);
  422. break;
  423. case 12:
  424. setbandwidth(value);
  425. break;
  426. }
  427. }
  428. unsigned char Reverb::getpar(int npar) const
  429. {
  430. switch(npar) {
  431. case 0: return Pvolume;
  432. case 1: return Ppanning;
  433. case 2: return Ptime;
  434. case 3: return Pidelay;
  435. case 4: return Pidelayfb;
  436. // case 5: return Prdelay;
  437. // case 6: return Perbalance;
  438. case 7: return Plpf;
  439. case 8: return Phpf;
  440. case 9: return Plohidamp;
  441. case 10: return Ptype;
  442. case 11: return Proomsize;
  443. case 12: return Pbandwidth;
  444. default: return 0;
  445. }
  446. }