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.

238 lines
6.0KB

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