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 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542
  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
  7. modify it under the terms of the GNU General Public License
  8. as published by the Free Software Foundation; either version 2
  9. of the License, or (at your option) any later version.
  10. */
  11. #include "Reverb.h"
  12. #include "../Misc/Util.h"
  13. #include "../Misc/Allocator.h"
  14. #include "../DSP/AnalogFilter.h"
  15. #include "../DSP/Unison.h"
  16. #include <cmath>
  17. #include <rtosc/ports.h>
  18. #include <rtosc/port-sugar.h>
  19. namespace zyncarla {
  20. #define rObject Reverb
  21. #define rBegin [](const char *msg, rtosc::RtData &d) {
  22. #define rEnd }
  23. rtosc::Ports Reverb::ports = {
  24. {"preset::i", rOptions(Cathedral1, Cathedral2, Cathedral3,
  25. Hall1, Hall2, Room1, Room2, Basement,
  26. Tunnel, Echoed1, Echoed2, VeryLong1, VeryLong2)
  27. rProp(parameter)
  28. rDoc("Instrument Presets"), 0,
  29. rBegin;
  30. rObject *o = (rObject*)d.obj;
  31. if(rtosc_narguments(msg))
  32. o->setpreset(rtosc_argument(msg, 0).i);
  33. else
  34. d.reply(d.loc, "i", o->Ppreset);
  35. rEnd},
  36. rEffParVol(rDefault(90), rPresets(80, 80, 80),
  37. rPresetsAt(5, 100, 100, 110, 85, 95)),
  38. rEffParPan(rPreset(8, 80)),
  39. rEffPar(Ptime, 2, rShort("time"),
  40. rPresets(63, 69, 69, 51, 53, 33, 21, 14, 84, 26, 40, 93, 111),
  41. "Length of Reverb"),
  42. rEffPar(Pidelay, 3, rShort("i.time"),
  43. rPresets(24, 35, 24, 10, 20, 0, 26, 0, 20, 60, 88, 15, 30),
  44. "Delay for first impulse"),
  45. rEffPar(Pidelayfb,4, rShort("i.fb"), rPresetsAt(8, 42, 71, 71), rDefault(0),
  46. "Feedback for first impulse"),
  47. rEffPar(Plpf, 7, rShort("lpf"),
  48. rPreset(1, 85), rPresetsAt(62, 127, 51, 114, 114, 114),
  49. rDefault(127), "Low pass filter"),
  50. rEffPar(Phpf, 8, rShort("hpf"),
  51. rPresets(5), rPresetsAt(2, 75, 21, 75), rPreset(7, 50),
  52. rPreset(12, 90), rDefault(0), "High pass filter"),
  53. rEffPar(Plohidamp,9, rShort("damp"), rDefault(0),
  54. rPresets(83, 71, 78, 78, 71, 106, 77, 71, 78, 64, 88, 77, 74)
  55. "Dampening"),
  56. //Todo make this a selector
  57. rEffPar(Ptype, 10, rShort("type"),
  58. rOptions(Random, Freeverb, Bandwidth),
  59. rPresets(Freeverb, Random, Freeverb, Freeverb, Freeverb, Random,
  60. Freeverb, Random, Freeverb, Freeverb, Freeverb, Random,
  61. Freeverb)
  62. rDefault(Random), "Type"),
  63. rEffPar(Proomsize,11,rShort("size"),
  64. rPreset(2, 85), rPresetsAt(5, 30, 45, 25, 105),
  65. rPresetsAt(11, 95, 80), rDefault(64),
  66. "Room Size"),
  67. rEffPar(Pbandwidth,12,rShort("bw"), rDefault(20), "Bandwidth"),
  68. };
  69. #undef rBegin
  70. #undef rEnd
  71. #undef rObject
  72. Reverb::Reverb(EffectParams pars)
  73. :Effect(pars),
  74. // defaults
  75. Pvolume(48),
  76. Ptime(64),
  77. Pidelay(40),
  78. Pidelayfb(0),
  79. Plpf(127),
  80. Phpf(0),
  81. Plohidamp(80),
  82. Ptype(1),
  83. Proomsize(64),
  84. Pbandwidth(30),
  85. idelaylen(0),
  86. roomsize(1.0f),
  87. rs(1.0f),
  88. bandwidth(NULL),
  89. idelay(NULL),
  90. lpf(NULL),
  91. hpf(NULL) // no filter
  92. {
  93. for(int i = 0; i < REV_COMBS * 2; ++i) {
  94. comblen[i] = 800 + (int)(RND * 1400.0f);
  95. combk[i] = 0;
  96. lpcomb[i] = 0;
  97. combfb[i] = -0.97f;
  98. comb[i] = NULL;
  99. }
  100. for(int i = 0; i < REV_APS * 2; ++i) {
  101. aplen[i] = 500 + (int)(RND * 500.0f);
  102. apk[i] = 0;
  103. ap[i] = NULL;
  104. }
  105. setpreset(Ppreset);
  106. cleanup(); //do not call this before the comb initialisation
  107. }
  108. Reverb::~Reverb()
  109. {
  110. memory.devalloc(idelay);
  111. memory.dealloc(hpf);
  112. memory.dealloc(lpf);
  113. for(int i = 0; i < REV_APS * 2; ++i)
  114. memory.devalloc(ap[i]);
  115. for(int i = 0; i < REV_COMBS * 2; ++i)
  116. memory.devalloc(comb[i]);
  117. memory.dealloc(bandwidth);
  118. }
  119. //Cleanup the effect
  120. void Reverb::cleanup(void)
  121. {
  122. for(int i = 0; i < REV_COMBS * 2; ++i) {
  123. lpcomb[i] = 0.0f;
  124. for(int j = 0; j < comblen[i]; ++j)
  125. comb[i][j] = 0.0f;
  126. }
  127. for(int i = 0; i < REV_APS * 2; ++i)
  128. for(int j = 0; j < aplen[i]; ++j)
  129. ap[i][j] = 0.0f;
  130. if(idelay)
  131. for(int i = 0; i < idelaylen; ++i)
  132. idelay[i] = 0.0f;
  133. if(hpf)
  134. hpf->cleanup();
  135. if(lpf)
  136. lpf->cleanup();
  137. }
  138. //Process one channel; 0=left, 1=right
  139. void Reverb::processmono(int ch, float *output, float *inputbuf)
  140. {
  141. //todo: implement the high part from lohidamp
  142. for(int j = REV_COMBS * ch; j < REV_COMBS * (ch + 1); ++j) {
  143. int &ck = combk[j];
  144. const int comblength = comblen[j];
  145. float &lpcombj = lpcomb[j];
  146. for(int i = 0; i < buffersize; ++i) {
  147. float fbout = comb[j][ck] * combfb[j];
  148. fbout = fbout * (1.0f - lohifb) + lpcombj * lohifb;
  149. lpcombj = fbout;
  150. comb[j][ck] = inputbuf[i] + fbout;
  151. output[i] += fbout;
  152. if((++ck) >= comblength)
  153. ck = 0;
  154. }
  155. }
  156. for(int j = REV_APS * ch; j < REV_APS * (1 + ch); ++j) {
  157. int &ak = apk[j];
  158. const int aplength = aplen[j];
  159. for(int i = 0; i < buffersize; ++i) {
  160. float tmp = ap[j][ak];
  161. ap[j][ak] = 0.7f * tmp + output[i];
  162. output[i] = tmp - 0.7f * ap[j][ak];
  163. if((++ak) >= aplength)
  164. ak = 0;
  165. }
  166. }
  167. }
  168. //Effect output
  169. void Reverb::out(const Stereo<float *> &smp)
  170. {
  171. if(!Pvolume && insertion)
  172. return;
  173. float inputbuf[buffersize];
  174. for(int i = 0; i < buffersize; ++i)
  175. inputbuf[i] = (smp.l[i] + smp.r[i]) / 2.0f;
  176. if(idelay)
  177. for(int i = 0; i < buffersize; ++i) {
  178. //Initial delay r
  179. float tmp = inputbuf[i] + idelay[idelayk] * idelayfb;
  180. inputbuf[i] = idelay[idelayk];
  181. idelay[idelayk] = tmp;
  182. idelayk++;
  183. if(idelayk >= idelaylen)
  184. idelayk = 0;
  185. }
  186. if(bandwidth)
  187. bandwidth->process(buffersize, inputbuf);
  188. if(lpf)
  189. lpf->filterout(inputbuf);
  190. if(hpf)
  191. hpf->filterout(inputbuf);
  192. processmono(0, efxoutl, inputbuf); //left
  193. processmono(1, efxoutr, inputbuf); //right
  194. float lvol = rs / REV_COMBS * pangainL;
  195. float rvol = rs / REV_COMBS * pangainR;
  196. if(insertion != 0) {
  197. lvol *= 2.0f;
  198. rvol *= 2.0f;
  199. }
  200. for(int i = 0; i < buffersize; ++i) {
  201. efxoutl[i] *= lvol;
  202. efxoutr[i] *= rvol;
  203. }
  204. }
  205. //Parameter control
  206. void Reverb::setvolume(unsigned char _Pvolume)
  207. {
  208. Pvolume = _Pvolume;
  209. if(!insertion) {
  210. if (Pvolume == 0) {
  211. outvolume = 0.0f;
  212. } else {
  213. outvolume = powf(0.01f, (1.0f - Pvolume / 127.0f)) * 4.0f;
  214. }
  215. volume = 1.0f;
  216. }
  217. else {
  218. volume = outvolume = Pvolume / 127.0f;
  219. if(Pvolume == 0)
  220. cleanup();
  221. }
  222. }
  223. void Reverb::settime(unsigned char _Ptime)
  224. {
  225. Ptime = _Ptime;
  226. float t = powf(60.0f, Ptime / 127.0f) - 0.97f;
  227. for(int i = 0; i < REV_COMBS * 2; ++i)
  228. combfb[i] =
  229. -expf((float)comblen[i] / samplerate_f * logf(0.001f) / t);
  230. //the feedback is negative because it removes the DC
  231. }
  232. void Reverb::setlohidamp(unsigned char _Plohidamp)
  233. {
  234. Plohidamp = (_Plohidamp < 64) ? 64 : _Plohidamp;
  235. //remove this when the high part from lohidamp is added
  236. if(Plohidamp == 64) {
  237. lohidamptype = 0;
  238. lohifb = 0.0f;
  239. }
  240. else {
  241. if(Plohidamp < 64)
  242. lohidamptype = 1;
  243. if(Plohidamp > 64)
  244. lohidamptype = 2;
  245. float x = fabsf((float)(Plohidamp - 64) / 64.1f);
  246. lohifb = x * x;
  247. }
  248. }
  249. void Reverb::setidelay(unsigned char _Pidelay)
  250. {
  251. Pidelay = _Pidelay;
  252. float delay = powf(50.0f * Pidelay / 127.0f, 2.0f) - 1.0f;
  253. int newDelayLen = (int) (samplerate_f * delay / 1000);
  254. if(newDelayLen == idelaylen)
  255. return;
  256. memory.devalloc(idelay);
  257. idelaylen = newDelayLen;
  258. if(idelaylen > 1) {
  259. idelayk = 0;
  260. idelay = memory.valloc<float>(idelaylen);
  261. memset(idelay, 0, idelaylen * sizeof(float));
  262. }
  263. }
  264. void Reverb::setidelayfb(unsigned char _Pidelayfb)
  265. {
  266. Pidelayfb = _Pidelayfb;
  267. idelayfb = Pidelayfb / 128.0f;
  268. }
  269. void Reverb::sethpf(unsigned char _Phpf)
  270. {
  271. Phpf = _Phpf;
  272. if(Phpf == 0) { //No HighPass
  273. memory.dealloc(hpf);
  274. } else {
  275. float fr = expf(sqrtf(Phpf / 127.0f) * logf(10000.0f)) + 20.0f;
  276. if(hpf == NULL)
  277. hpf = memory.alloc<AnalogFilter>(3, fr, 1, 0, samplerate, buffersize);
  278. else
  279. hpf->setfreq(fr);
  280. }
  281. }
  282. void Reverb::setlpf(unsigned char _Plpf)
  283. {
  284. Plpf = _Plpf;
  285. if(Plpf == 127) { //No LowPass
  286. memory.dealloc(lpf);
  287. } else {
  288. float fr = expf(sqrtf(Plpf / 127.0f) * logf(25000.0f)) + 40.0f;
  289. if(!lpf)
  290. lpf = memory.alloc<AnalogFilter>(2, fr, 1, 0, samplerate, buffersize);
  291. else
  292. lpf->setfreq(fr);
  293. }
  294. }
  295. void Reverb::settype(unsigned char _Ptype)
  296. {
  297. Ptype = _Ptype;
  298. const int NUM_TYPES = 3;
  299. const int combtunings[NUM_TYPES][REV_COMBS] = {
  300. //this is unused (for random)
  301. {0, 0, 0, 0, 0, 0, 0, 0 },
  302. //Freeverb by Jezar at Dreampoint
  303. {1116, 1188, 1277, 1356, 1422, 1491, 1557, 1617 },
  304. //duplicate of Freeverb by Jezar at Dreampoint
  305. {1116, 1188, 1277, 1356, 1422, 1491, 1557, 1617 }
  306. };
  307. const int aptunings[NUM_TYPES][REV_APS] = {
  308. //this is unused (for random)
  309. {0, 0, 0, 0 },
  310. //Freeverb by Jezar at Dreampoint
  311. {225, 341, 441, 556 },
  312. //duplicate of Freeverb by Jezar at Dreampoint
  313. {225, 341, 441, 556 }
  314. };
  315. if(Ptype >= NUM_TYPES)
  316. Ptype = NUM_TYPES - 1;
  317. // adjust the combs according to the samplerate
  318. float samplerate_adjust = samplerate_f / 44100.0f;
  319. float tmp;
  320. for(int i = 0; i < REV_COMBS * 2; ++i) {
  321. if(Ptype == 0)
  322. tmp = 800.0f + (int)(RND * 1400.0f);
  323. else
  324. tmp = combtunings[Ptype][i % REV_COMBS];
  325. tmp *= roomsize;
  326. if(i > REV_COMBS)
  327. tmp += 23.0f;
  328. tmp *= samplerate_adjust; //adjust the combs according to the samplerate
  329. if(tmp < 10.0f)
  330. tmp = 10.0f;
  331. combk[i] = 0;
  332. lpcomb[i] = 0;
  333. if(comblen[i] != (int)tmp || comb[i] == NULL) {
  334. comblen[i] = (int) tmp;
  335. memory.devalloc(comb[i]);
  336. comb[i] = memory.valloc<float>(comblen[i]);
  337. }
  338. }
  339. for(int i = 0; i < REV_APS * 2; ++i) {
  340. if(Ptype == 0)
  341. tmp = 500 + (int)(RND * 500.0f);
  342. else
  343. tmp = aptunings[Ptype][i % REV_APS];
  344. tmp *= roomsize;
  345. if(i > REV_APS)
  346. tmp += 23.0f;
  347. tmp *= samplerate_adjust; //adjust the combs according to the samplerate
  348. if(tmp < 10)
  349. tmp = 10;
  350. apk[i] = 0;
  351. if(aplen[i] != (int)tmp || ap[i] == NULL) {
  352. aplen[i] = (int) tmp;
  353. memory.devalloc(ap[i]);
  354. ap[i] = memory.valloc<float>(aplen[i]);
  355. }
  356. }
  357. memory.dealloc(bandwidth);
  358. if(Ptype == 2) { //bandwidth
  359. //TODO the size of the unison buffer may be too small, though this has
  360. //not been verified yet.
  361. //As this cannot be resized in a RT context, a good upper bound should
  362. //be found
  363. bandwidth = memory.alloc<Unison>(&memory, buffersize / 4 + 1, 2.0f, samplerate_f);
  364. bandwidth->setSize(50);
  365. bandwidth->setBaseFrequency(1.0f);
  366. }
  367. settime(Ptime);
  368. cleanup();
  369. }
  370. void Reverb::setroomsize(unsigned char _Proomsize)
  371. {
  372. Proomsize = _Proomsize;
  373. if(!Proomsize)
  374. this->Proomsize = 64; //this is because the older versions consider roomsize=0
  375. roomsize = (this->Proomsize - 64.0f) / 64.0f;
  376. if(roomsize > 0.0f)
  377. roomsize *= 2.0f;
  378. roomsize = powf(10.0f, roomsize);
  379. rs = sqrtf(roomsize);
  380. settype(Ptype);
  381. }
  382. void Reverb::setbandwidth(unsigned char _Pbandwidth)
  383. {
  384. Pbandwidth = _Pbandwidth;
  385. float v = Pbandwidth / 127.0f;
  386. if(bandwidth)
  387. bandwidth->setBandwidth(powf(v, 2.0f) * 200.0f);
  388. }
  389. void Reverb::setpreset(unsigned char npreset)
  390. {
  391. const int PRESET_SIZE = 13;
  392. const int NUM_PRESETS = 13;
  393. unsigned char presets[NUM_PRESETS][PRESET_SIZE] = {
  394. //Cathedral1
  395. {80, 64, 63, 24, 0, 0, 0, 85, 5, 83, 1, 64, 20},
  396. //Cathedral2
  397. {80, 64, 69, 35, 0, 0, 0, 127, 0, 71, 0, 64, 20},
  398. //Cathedral3
  399. {80, 64, 69, 24, 0, 0, 0, 127, 75, 78, 1, 85, 20},
  400. //Hall1
  401. {90, 64, 51, 10, 0, 0, 0, 127, 21, 78, 1, 64, 20},
  402. //Hall2
  403. {90, 64, 53, 20, 0, 0, 0, 127, 75, 71, 1, 64, 20},
  404. //Room1
  405. {100, 64, 33, 0, 0, 0, 0, 127, 0, 106, 0, 30, 20},
  406. //Room2
  407. {100, 64, 21, 26, 0, 0, 0, 62, 0, 77, 1, 45, 20},
  408. //Basement
  409. {110, 64, 14, 0, 0, 0, 0, 127, 5, 71, 0, 25, 20},
  410. //Tunnel
  411. {85, 80, 84, 20, 42, 0, 0, 51, 0, 78, 1, 105, 20},
  412. //Echoed1
  413. {95, 64, 26, 60, 71, 0, 0, 114, 0, 64, 1, 64, 20},
  414. //Echoed2
  415. {90, 64, 40, 88, 71, 0, 0, 114, 0, 88, 1, 64, 20},
  416. //VeryLong1
  417. {90, 64, 93, 15, 0, 0, 0, 114, 0, 77, 0, 95, 20},
  418. //VeryLong2
  419. {90, 64, 111, 30, 0, 0, 0, 114, 90, 74, 1, 80, 20}
  420. };
  421. if(npreset >= NUM_PRESETS)
  422. npreset = NUM_PRESETS - 1;
  423. for(int n = 0; n < PRESET_SIZE; ++n)
  424. changepar(n, presets[npreset][n]);
  425. if(insertion)
  426. changepar(0, presets[npreset][0] / 2); //lower the volume if reverb is insertion effect
  427. Ppreset = npreset;
  428. }
  429. void Reverb::changepar(int npar, unsigned char value)
  430. {
  431. switch(npar) {
  432. case 0:
  433. setvolume(value);
  434. break;
  435. case 1:
  436. setpanning(value);
  437. break;
  438. case 2:
  439. settime(value);
  440. break;
  441. case 3:
  442. setidelay(value);
  443. break;
  444. case 4:
  445. setidelayfb(value);
  446. break;
  447. // case 5:
  448. // setrdelay(value);
  449. // break;
  450. // case 6:
  451. // seterbalance(value);
  452. // break;
  453. case 7:
  454. setlpf(value);
  455. break;
  456. case 8:
  457. sethpf(value);
  458. break;
  459. case 9:
  460. setlohidamp(value);
  461. break;
  462. case 10:
  463. settype(value);
  464. break;
  465. case 11:
  466. setroomsize(value);
  467. break;
  468. case 12:
  469. setbandwidth(value);
  470. break;
  471. }
  472. }
  473. unsigned char Reverb::getpar(int npar) const
  474. {
  475. switch(npar) {
  476. case 0: return Pvolume;
  477. case 1: return Ppanning;
  478. case 2: return Ptime;
  479. case 3: return Pidelay;
  480. case 4: return Pidelayfb;
  481. case 7: return Plpf;
  482. case 8: return Phpf;
  483. case 9: return Plohidamp;
  484. case 10: return Ptype;
  485. case 11: return Proomsize;
  486. case 12: return Pbandwidth;
  487. default: return 0;
  488. }
  489. }
  490. }