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.

247 lines
6.4KB

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