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.

Chorus.cpp 7.5KB

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