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.

288 lines
8.0KB

  1. /*
  2. ZynAddSubFX - a software synthesizer
  3. Chorus.cpp - Chorus and Flange effects
  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 <cmath>
  12. #include <rtosc/ports.h>
  13. #include <rtosc/port-sugar.h>
  14. #include "../Misc/Allocator.h"
  15. #include "Chorus.h"
  16. #include <iostream>
  17. using namespace std;
  18. #define rObject Chorus
  19. #define rBegin [](const char *, rtosc::RtData &) {
  20. #define rEnd }
  21. rtosc::Ports Chorus::ports = {
  22. {"preset::i", rOptions(Alienwah 1, Alienwah 2, Alienwah 3, Alienwah 4)
  23. rDoc("Instrument Presets"), 0,
  24. rBegin;
  25. rEnd},
  26. //Pvolume/Ppanning are common
  27. rEffPar(Pfreq, 2, rShort("freq"), "Effect Frequency"),
  28. rEffPar(Pfreqrnd, 3, rShort("rand"), "Frequency Randomness"),
  29. rEffPar(PLFOtype, 4, rShort("shape"), "LFO Shape"),
  30. rEffParTF(PStereo,5, rShort("stereo"), "Stereo/Mono Mode"),
  31. rEffPar(Pdepth, 6, rShort("depth"), "LFO Depth"),
  32. rEffPar(Pdelay, 7, rShort("delay"), "Delay"),
  33. rEffPar(Pfeedback,8, rShort("fb"), "Feedback"),
  34. rEffPar(Plrcross, 9, rShort("l/r"), "Left/Right Crossover"),
  35. rEffParTF(Pflangemode, 10, rShort("flange"), "Flange Mode"),
  36. rEffParTF(Poutsub, 11, rShort("sub"), "Output Subtraction"),
  37. };
  38. #undef rBegin
  39. #undef rEnd
  40. #undef rObject
  41. Chorus::Chorus(EffectParams pars)
  42. :Effect(pars),
  43. lfo(pars.srate, pars.bufsize),
  44. maxdelay((int)(MAX_CHORUS_DELAY / 1000.0f * samplerate_f)),
  45. delaySample(memory.valloc<float>(maxdelay), memory.valloc<float>(maxdelay))
  46. {
  47. dlk = 0;
  48. drk = 0;
  49. setpreset(Ppreset);
  50. changepar(1, 64);
  51. lfo.effectlfoout(&lfol, &lfor);
  52. dl2 = getdelay(lfol);
  53. dr2 = getdelay(lfor);
  54. cleanup();
  55. }
  56. Chorus::~Chorus()
  57. {
  58. memory.devalloc(delaySample.l);
  59. memory.devalloc(delaySample.r);
  60. }
  61. //get the delay value in samples; xlfo is the current lfo value
  62. float Chorus::getdelay(float xlfo)
  63. {
  64. float result =
  65. (Pflangemode) ? 0 : (delay + xlfo * depth) * samplerate_f;
  66. //check if delay is too big (caused by bad setdelay() and setdepth()
  67. if((result + 0.5f) >= maxdelay) {
  68. cerr
  69. <<
  70. "WARNING: Chorus.cpp::getdelay(..) too big delay (see setdelay and setdepth funcs.)"
  71. << endl;
  72. result = maxdelay - 1.0f;
  73. }
  74. return result;
  75. }
  76. //Apply the effect
  77. void Chorus::out(const Stereo<float *> &input)
  78. {
  79. dl1 = dl2;
  80. dr1 = dr2;
  81. lfo.effectlfoout(&lfol, &lfor);
  82. dl2 = getdelay(lfol);
  83. dr2 = getdelay(lfor);
  84. for(int i = 0; i < buffersize; ++i) {
  85. float inL = input.l[i];
  86. float inR = input.r[i];
  87. //LRcross
  88. Stereo<float> tmpc(inL, inR);
  89. inL = tmpc.l * (1.0f - lrcross) + tmpc.r * lrcross;
  90. inR = tmpc.r * (1.0f - lrcross) + tmpc.l * lrcross;
  91. //Left channel
  92. //compute the delay in samples using linear interpolation between the lfo delays
  93. float mdel =
  94. (dl1 * (buffersize - i) + dl2 * i) / buffersize_f;
  95. if(++dlk >= maxdelay)
  96. dlk = 0;
  97. float tmp = dlk - mdel + maxdelay * 2.0f; //where should I get the sample from
  98. dlhi = (int) tmp;
  99. dlhi %= maxdelay;
  100. float dlhi2 = (dlhi - 1 + maxdelay) % maxdelay;
  101. float dllo = 1.0f + floorf(tmp) - tmp;
  102. efxoutl[i] = cinterpolate(delaySample.l, maxdelay, dlhi2) * dllo
  103. + cinterpolate(delaySample.l, maxdelay,
  104. dlhi) * (1.0f - dllo);
  105. delaySample.l[dlk] = inL + efxoutl[i] * fb;
  106. //Right channel
  107. //compute the delay in samples using linear interpolation between the lfo delays
  108. mdel = (dr1 * (buffersize - i) + dr2 * i) / buffersize_f;
  109. if(++drk >= maxdelay)
  110. drk = 0;
  111. tmp = drk * 1.0f - mdel + maxdelay * 2.0f; //where should I get the sample from
  112. dlhi = (int) tmp;
  113. dlhi %= maxdelay;
  114. dlhi2 = (dlhi - 1 + maxdelay) % maxdelay;
  115. dllo = 1.0f + floorf(tmp) - tmp;
  116. efxoutr[i] = cinterpolate(delaySample.r, maxdelay, dlhi2) * dllo
  117. + cinterpolate(delaySample.r, maxdelay,
  118. dlhi) * (1.0f - dllo);
  119. delaySample.r[dlk] = inR + efxoutr[i] * fb;
  120. }
  121. if(Poutsub)
  122. for(int i = 0; i < buffersize; ++i) {
  123. efxoutl[i] *= -1.0f;
  124. efxoutr[i] *= -1.0f;
  125. }
  126. for(int i = 0; i < buffersize; ++i) {
  127. efxoutl[i] *= pangainL;
  128. efxoutr[i] *= pangainR;
  129. }
  130. }
  131. //Cleanup the effect
  132. void Chorus::cleanup(void)
  133. {
  134. memset(delaySample.l, 0, maxdelay * sizeof(float));
  135. memset(delaySample.r, 0, maxdelay * sizeof(float));
  136. }
  137. //Parameter control
  138. void Chorus::setdepth(unsigned char _Pdepth)
  139. {
  140. Pdepth = _Pdepth;
  141. depth = (powf(8.0f, (Pdepth / 127.0f) * 2.0f) - 1.0f) / 1000.0f; //seconds
  142. }
  143. void Chorus::setdelay(unsigned char _Pdelay)
  144. {
  145. Pdelay = _Pdelay;
  146. delay = (powf(10.0f, (Pdelay / 127.0f) * 2.0f) - 1.0f) / 1000.0f; //seconds
  147. }
  148. void Chorus::setfb(unsigned char _Pfb)
  149. {
  150. Pfb = _Pfb;
  151. fb = (Pfb - 64.0f) / 64.1f;
  152. }
  153. void Chorus::setvolume(unsigned char _Pvolume)
  154. {
  155. Pvolume = _Pvolume;
  156. outvolume = Pvolume / 127.0f;
  157. volume = (!insertion) ? 1.0f : outvolume;
  158. }
  159. void Chorus::setpreset(unsigned char npreset)
  160. {
  161. const int PRESET_SIZE = 12;
  162. const int NUM_PRESETS = 10;
  163. unsigned char presets[NUM_PRESETS][PRESET_SIZE] = {
  164. //Chorus1
  165. {64, 64, 50, 0, 0, 90, 40, 85, 64, 119, 0, 0},
  166. //Chorus2
  167. {64, 64, 45, 0, 0, 98, 56, 90, 64, 19, 0, 0},
  168. //Chorus3
  169. {64, 64, 29, 0, 1, 42, 97, 95, 90, 127, 0, 0},
  170. //Celeste1
  171. {64, 64, 26, 0, 0, 42, 115, 18, 90, 127, 0, 0},
  172. //Celeste2
  173. {64, 64, 29, 117, 0, 50, 115, 9, 31, 127, 0, 1},
  174. //Flange1
  175. {64, 64, 57, 0, 0, 60, 23, 3, 62, 0, 0, 0},
  176. //Flange2
  177. {64, 64, 33, 34, 1, 40, 35, 3, 109, 0, 0, 0},
  178. //Flange3
  179. {64, 64, 53, 34, 1, 94, 35, 3, 54, 0, 0, 1},
  180. //Flange4
  181. {64, 64, 40, 0, 1, 62, 12, 19, 97, 0, 0, 0},
  182. //Flange5
  183. {64, 64, 55, 105, 0, 24, 39, 19, 17, 0, 0, 1}
  184. };
  185. if(npreset >= NUM_PRESETS)
  186. npreset = NUM_PRESETS - 1;
  187. for(int n = 0; n < PRESET_SIZE; ++n)
  188. changepar(n, presets[npreset][n]);
  189. Ppreset = npreset;
  190. }
  191. void Chorus::changepar(int npar, unsigned char value)
  192. {
  193. switch(npar) {
  194. case 0:
  195. setvolume(value);
  196. break;
  197. case 1:
  198. setpanning(value);
  199. break;
  200. case 2:
  201. lfo.Pfreq = value;
  202. lfo.updateparams();
  203. break;
  204. case 3:
  205. lfo.Prandomness = value;
  206. lfo.updateparams();
  207. break;
  208. case 4:
  209. lfo.PLFOtype = value;
  210. lfo.updateparams();
  211. break;
  212. case 5:
  213. lfo.Pstereo = value;
  214. lfo.updateparams();
  215. break;
  216. case 6:
  217. setdepth(value);
  218. break;
  219. case 7:
  220. setdelay(value);
  221. break;
  222. case 8:
  223. setfb(value);
  224. break;
  225. case 9:
  226. setlrcross(value);
  227. break;
  228. case 10:
  229. Pflangemode = (value > 1) ? 1 : value;
  230. break;
  231. case 11:
  232. Poutsub = (value > 1) ? 1 : value;
  233. break;
  234. }
  235. }
  236. unsigned char Chorus::getpar(int npar) const
  237. {
  238. switch(npar) {
  239. case 0: return Pvolume;
  240. case 1: return Ppanning;
  241. case 2: return lfo.Pfreq;
  242. case 3: return lfo.Prandomness;
  243. case 4: return lfo.PLFOtype;
  244. case 5: return lfo.Pstereo;
  245. case 6: return Pdepth;
  246. case 7: return Pdelay;
  247. case 8: return Pfb;
  248. case 9: return Plrcross;
  249. case 10: return Pflangemode;
  250. case 11: return Poutsub;
  251. default: return 0;
  252. }
  253. }