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.

246 lines
6.3KB

  1. /*
  2. ZynAddSubFX - a software synthesizer
  3. Distorsion.cpp - Distorsion 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 "Distorsion.h"
  18. #include "../DSP/AnalogFilter.h"
  19. #include "../Misc/WaveShapeSmps.h"
  20. #include <cmath>
  21. Distorsion::Distorsion(bool insertion_, float *efxoutl_, float *efxoutr_)
  22. :Effect(insertion_, efxoutl_, efxoutr_, NULL, 0),
  23. Pvolume(50),
  24. Pdrive(90),
  25. Plevel(64),
  26. Ptype(0),
  27. Pnegate(0),
  28. Plpf(127),
  29. Phpf(0),
  30. Pstereo(0),
  31. Pprefiltering(0)
  32. {
  33. lpfl = new AnalogFilter(2, 22000, 1, 0);
  34. lpfr = new AnalogFilter(2, 22000, 1, 0);
  35. hpfl = new AnalogFilter(3, 20, 1, 0);
  36. hpfr = new AnalogFilter(3, 20, 1, 0);
  37. setpreset(Ppreset);
  38. cleanup();
  39. }
  40. Distorsion::~Distorsion()
  41. {
  42. delete lpfl;
  43. delete lpfr;
  44. delete hpfl;
  45. delete hpfr;
  46. }
  47. //Cleanup the effect
  48. void Distorsion::cleanup(void)
  49. {
  50. lpfl->cleanup();
  51. hpfl->cleanup();
  52. lpfr->cleanup();
  53. hpfr->cleanup();
  54. }
  55. //Apply the filters
  56. void Distorsion::applyfilters(float *efxoutl, float *efxoutr)
  57. {
  58. lpfl->filterout(efxoutl);
  59. hpfl->filterout(efxoutl);
  60. if(Pstereo != 0) { //stereo
  61. lpfr->filterout(efxoutr);
  62. hpfr->filterout(efxoutr);
  63. }
  64. }
  65. //Effect output
  66. void Distorsion::out(const Stereo<float *> &smp)
  67. {
  68. float inputvol = powf(5.0f, (Pdrive - 32.0f) / 127.0f);
  69. if(Pnegate)
  70. inputvol *= -1.0f;
  71. if(Pstereo) //Stereo
  72. for(int i = 0; i < synth->buffersize; ++i) {
  73. efxoutl[i] = smp.l[i] * inputvol * pangainL;
  74. efxoutr[i] = smp.r[i] * inputvol * pangainR;
  75. }
  76. else //Mono
  77. for(int i = 0; i < synth->buffersize; ++i)
  78. efxoutl[i] = (smp.l[i] * pangainL + smp.r[i] * pangainR) * inputvol;
  79. if(Pprefiltering)
  80. applyfilters(efxoutl, efxoutr);
  81. waveShapeSmps(synth->buffersize, efxoutl, Ptype + 1, Pdrive);
  82. if(Pstereo)
  83. waveShapeSmps(synth->buffersize, efxoutr, Ptype + 1, Pdrive);
  84. if(!Pprefiltering)
  85. applyfilters(efxoutl, efxoutr);
  86. if(!Pstereo)
  87. memcpy(efxoutr, efxoutl, synth->bufferbytes);
  88. float level = dB2rap(60.0f * Plevel / 127.0f - 40.0f);
  89. for(int i = 0; i < synth->buffersize; ++i) {
  90. float lout = efxoutl[i];
  91. float rout = efxoutr[i];
  92. float l = lout * (1.0f - lrcross) + rout * lrcross;
  93. float r = rout * (1.0f - lrcross) + lout * lrcross;
  94. lout = l;
  95. rout = r;
  96. efxoutl[i] = lout * 2.0f * level;
  97. efxoutr[i] = rout * 2.0f * level;
  98. }
  99. }
  100. //Parameter control
  101. void Distorsion::setvolume(unsigned char _Pvolume)
  102. {
  103. Pvolume = _Pvolume;
  104. if(insertion == 0) {
  105. outvolume = powf(0.01f, (1.0f - Pvolume / 127.0f)) * 4.0f;
  106. volume = 1.0f;
  107. }
  108. else
  109. volume = outvolume = Pvolume / 127.0f;
  110. if(Pvolume == 0)
  111. cleanup();
  112. }
  113. void Distorsion::setlpf(unsigned char _Plpf)
  114. {
  115. Plpf = _Plpf;
  116. float fr = expf(powf(Plpf / 127.0f, 0.5f) * logf(25000.0f)) + 40.0f;
  117. lpfl->setfreq(fr);
  118. lpfr->setfreq(fr);
  119. }
  120. void Distorsion::sethpf(unsigned char _Phpf)
  121. {
  122. Phpf = _Phpf;
  123. float fr = expf(powf(Phpf / 127.0f, 0.5f) * logf(25000.0f)) + 20.0f;
  124. hpfl->setfreq(fr);
  125. hpfr->setfreq(fr);
  126. }
  127. void Distorsion::setpreset(unsigned char npreset)
  128. {
  129. const int PRESET_SIZE = 11;
  130. const int NUM_PRESETS = 6;
  131. unsigned char presets[NUM_PRESETS][PRESET_SIZE] = {
  132. //Overdrive 1
  133. {127, 64, 35, 56, 70, 0, 0, 96, 0, 0, 0},
  134. //Overdrive 2
  135. {127, 64, 35, 29, 75, 1, 0, 127, 0, 0, 0},
  136. //A. Exciter 1
  137. {64, 64, 35, 75, 80, 5, 0, 127, 105, 1, 0},
  138. //A. Exciter 2
  139. {64, 64, 35, 85, 62, 1, 0, 127, 118, 1, 0},
  140. //Guitar Amp
  141. {127, 64, 35, 63, 75, 2, 0, 55, 0, 0, 0},
  142. //Quantisize
  143. {127, 64, 35, 88, 75, 4, 0, 127, 0, 1, 0}
  144. };
  145. if(npreset >= NUM_PRESETS)
  146. npreset = NUM_PRESETS - 1;
  147. for(int n = 0; n < PRESET_SIZE; ++n)
  148. changepar(n, presets[npreset][n]);
  149. if(!insertion) //lower the volume if this is system effect
  150. changepar(0, (int) (presets[npreset][0] / 1.5f));
  151. Ppreset = npreset;
  152. cleanup();
  153. }
  154. void Distorsion::changepar(int npar, unsigned char value)
  155. {
  156. switch(npar) {
  157. case 0:
  158. setvolume(value);
  159. break;
  160. case 1:
  161. setpanning(value);
  162. break;
  163. case 2:
  164. setlrcross(value);
  165. break;
  166. case 3:
  167. Pdrive = value;
  168. break;
  169. case 4:
  170. Plevel = value;
  171. break;
  172. case 5:
  173. if(value > 13)
  174. Ptype = 13; //this must be increased if more distorsion types are added
  175. else
  176. Ptype = value;
  177. break;
  178. case 6:
  179. if(value > 1)
  180. Pnegate = 1;
  181. else
  182. Pnegate = value;
  183. break;
  184. case 7:
  185. setlpf(value);
  186. break;
  187. case 8:
  188. sethpf(value);
  189. break;
  190. case 9:
  191. Pstereo = (value > 1) ? 1 : value;
  192. break;
  193. case 10:
  194. Pprefiltering = value;
  195. break;
  196. }
  197. }
  198. unsigned char Distorsion::getpar(int npar) const
  199. {
  200. switch(npar) {
  201. case 0: return Pvolume;
  202. case 1: return Ppanning;
  203. case 2: return Plrcross;
  204. case 3: return Pdrive;
  205. case 4: return Plevel;
  206. case 5: return Ptype;
  207. case 6: return Pnegate;
  208. case 7: return Plpf;
  209. case 8: return Phpf;
  210. case 9: return Pstereo;
  211. case 10: return Pprefiltering;
  212. default: return 0; //in case of bogus parameter number
  213. }
  214. }