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.

479 lines
13KB

  1. /*
  2. ZynAddSubFX - a software synthesizer
  3. Phaser.cpp - Phasing and Approximate digital model of an analog JFET phaser.
  4. Analog modeling implemented by Ryan Billing aka Transmogrifox.
  5. DSP analog modeling theory & practice largely influenced by
  6. various CCRMA publications, particularly works by Julius O. Smith.
  7. Copyright (C) 2002-2005 Nasca Octavian Paul
  8. Copyright (C) 2009-2010 Ryan Billing
  9. Copyright (C) 2010-2010 Mark McCurry
  10. This program is free software; you can redistribute it and/or
  11. modify it under the terms of the GNU General Public License
  12. as published by the Free Software Foundation; either version 2
  13. of the License, or (at your option) any later version.
  14. */
  15. #include <cmath>
  16. #include <algorithm>
  17. #include <rtosc/ports.h>
  18. #include <rtosc/port-sugar.h>
  19. #include "../Misc/Allocator.h"
  20. #include "Phaser.h"
  21. using namespace std;
  22. #define rObject Phaser
  23. #define rBegin [](const char *, rtosc::RtData &) {
  24. #define rEnd }
  25. rtosc::Ports Phaser::ports = {
  26. {"preset::i", rOptions(Alienwah 1, Alienwah 2, Alienwah 3, Alienwah 4)
  27. rDoc("Instrument Presets"), 0,
  28. rBegin;
  29. rEnd},
  30. //Pvolume/Ppanning are common
  31. rEffPar(lfo.Pfreq, 2, ""),
  32. rEffPar(lfo.Prandomness, 3, ""),
  33. rEffPar(lfo.PLFOtype, 4, ""),
  34. rEffPar(lfo.Pstereo, 5, ""),
  35. rEffPar(Pdepth, 6, ""),
  36. rEffPar(Pfb, 7, ""),
  37. rEffPar(Pstages, 8, ""),
  38. rEffPar(Plrcross, 9, ""),
  39. rEffPar(Poffset, 9, ""),
  40. rEffParTF(Poutsub, 10, ""),
  41. rEffPar(Pphase, 11, ""),
  42. rEffPar(Pwidth, 11, ""),
  43. rEffPar(Phyper, 12, ""),
  44. rEffPar(Pdistortion, 13, ""),
  45. rEffPar(Panalog, 14, ""),
  46. };
  47. #undef rBegin
  48. #undef rEnd
  49. #undef rObject
  50. #define PHASER_LFO_SHAPE 2
  51. #define ONE_ 0.99999f // To prevent LFO ever reaching 1.0f for filter stability purposes
  52. #define ZERO_ 0.00001f // Same idea as above.
  53. Phaser::Phaser(EffectParams pars)
  54. :Effect(pars), lfo(pars.srate, pars.bufsize), old(NULL), xn1(NULL),
  55. yn1(NULL), diff(0.0f), oldgain(0.0f), fb(0.0f)
  56. {
  57. analog_setup();
  58. setpreset(Ppreset);
  59. cleanup();
  60. }
  61. void Phaser::analog_setup()
  62. {
  63. //model mismatch between JFET devices
  64. offset[0] = -0.2509303f;
  65. offset[1] = 0.9408924f;
  66. offset[2] = 0.998f;
  67. offset[3] = -0.3486182f;
  68. offset[4] = -0.2762545f;
  69. offset[5] = -0.5215785f;
  70. offset[6] = 0.2509303f;
  71. offset[7] = -0.9408924f;
  72. offset[8] = -0.998f;
  73. offset[9] = 0.3486182f;
  74. offset[10] = 0.2762545f;
  75. offset[11] = 0.5215785f;
  76. barber = 0; //Deactivate barber pole phasing by default
  77. mis = 1.0f;
  78. Rmin = 625.0f; // 2N5457 typical on resistance at Vgs = 0
  79. Rmax = 22000.0f; // Resistor parallel to FET
  80. Rmx = Rmin / Rmax;
  81. Rconst = 1.0f + Rmx; // Handle parallel resistor relationship
  82. C = 0.00000005f; // 50 nF
  83. CFs = 2.0f * samplerate_f * C;
  84. invperiod = 1.0f / buffersize_f;
  85. }
  86. Phaser::~Phaser()
  87. {
  88. memory.devalloc(old.l);
  89. memory.devalloc(old.r);
  90. memory.devalloc(xn1.l);
  91. memory.devalloc(xn1.r);
  92. memory.devalloc(yn1.l);
  93. memory.devalloc(yn1.r);
  94. }
  95. /*
  96. * Effect output
  97. */
  98. void Phaser::out(const Stereo<float *> &input)
  99. {
  100. if(Panalog)
  101. AnalogPhase(input);
  102. else
  103. normalPhase(input);
  104. }
  105. void Phaser::AnalogPhase(const Stereo<float *> &input)
  106. {
  107. Stereo<float> gain(0.0f), lfoVal(0.0f), mod(0.0f), g(0.0f), b(0.0f), hpf(
  108. 0.0f);
  109. lfo.effectlfoout(&lfoVal.l, &lfoVal.r);
  110. mod.l = lfoVal.l * width + (depth - 0.5f);
  111. mod.r = lfoVal.r * width + (depth - 0.5f);
  112. mod.l = limit(mod.l, ZERO_, ONE_);
  113. mod.r = limit(mod.r, ZERO_, ONE_);
  114. if(Phyper) {
  115. //Triangle wave squared is approximately sin on bottom, tri on top
  116. //Result is exponential sweep more akin to filter in synth with
  117. //exponential generator circuitry.
  118. mod.l *= mod.l;
  119. mod.r *= mod.r;
  120. }
  121. //g.l,g.r is Vp - Vgs. Typical FET drain-source resistance follows constant/[1-sqrt(Vp - Vgs)]
  122. mod.l = sqrtf(1.0f - mod.l);
  123. mod.r = sqrtf(1.0f - mod.r);
  124. diff.r = (mod.r - oldgain.r) * invperiod;
  125. diff.l = (mod.l - oldgain.l) * invperiod;
  126. g = oldgain;
  127. oldgain = mod;
  128. for(int i = 0; i < buffersize; ++i) {
  129. g.l += diff.l; // Linear interpolation between LFO samples
  130. g.r += diff.r;
  131. Stereo<float> xn(input.l[i] * pangainL, input.r[i] * pangainR);
  132. if(barber) {
  133. g.l += 0.25;
  134. g.l -= floorf(g.l);
  135. g.r += 0.25;
  136. g.r -= floorf(g.r);
  137. }
  138. xn.l = applyPhase(xn.l, g.l, fb.l, hpf.l, yn1.l, xn1.l);
  139. xn.r = applyPhase(xn.r, g.r, fb.r, hpf.r, yn1.r, xn1.r);
  140. fb.l = xn.l * feedback;
  141. fb.r = xn.r * feedback;
  142. efxoutl[i] = xn.l;
  143. efxoutr[i] = xn.r;
  144. }
  145. if(Poutsub) {
  146. invSignal(efxoutl, buffersize);
  147. invSignal(efxoutr, buffersize);
  148. }
  149. }
  150. float Phaser::applyPhase(float x, float g, float fb,
  151. float &hpf, float *yn1, float *xn1)
  152. {
  153. for(int j = 0; j < Pstages; ++j) { //Phasing routine
  154. mis = 1.0f + offsetpct * offset[j];
  155. //This is symmetrical.
  156. //FET is not, so this deviates slightly, however sym dist. is
  157. //better sounding than a real FET.
  158. float d = (1.0f + 2.0f * (0.25f + g) * hpf * hpf * distortion) * mis;
  159. Rconst = 1.0f + mis * Rmx;
  160. // This is 1/R. R is being modulated to control filter fc.
  161. float b = (Rconst - g) / (d * Rmin);
  162. float gain = (CFs - b) / (CFs + b);
  163. yn1[j] = gain * (x + yn1[j]) - xn1[j];
  164. //high pass filter:
  165. //Distortion depends on the high-pass part of the AP stage.
  166. hpf = yn1[j] + (1.0f - gain) * xn1[j];
  167. xn1[j] = x;
  168. x = yn1[j];
  169. if(j == 1)
  170. x += fb; //Insert feedback after first phase stage
  171. }
  172. return x;
  173. }
  174. void Phaser::normalPhase(const Stereo<float *> &input)
  175. {
  176. Stereo<float> gain(0.0f), lfoVal(0.0f);
  177. lfo.effectlfoout(&lfoVal.l, &lfoVal.r);
  178. gain.l =
  179. (expf(lfoVal.l
  180. * PHASER_LFO_SHAPE) - 1) / (expf(PHASER_LFO_SHAPE) - 1.0f);
  181. gain.r =
  182. (expf(lfoVal.r
  183. * PHASER_LFO_SHAPE) - 1) / (expf(PHASER_LFO_SHAPE) - 1.0f);
  184. gain.l = 1.0f - phase * (1.0f - depth) - (1.0f - phase) * gain.l * depth;
  185. gain.r = 1.0f - phase * (1.0f - depth) - (1.0f - phase) * gain.r * depth;
  186. gain.l = limit(gain.l, ZERO_, ONE_);
  187. gain.r = limit(gain.r, ZERO_, ONE_);
  188. for(int i = 0; i < buffersize; ++i) {
  189. float x = (float) i / buffersize_f;
  190. float x1 = 1.0f - x;
  191. //TODO think about making panning an external feature
  192. Stereo<float> xn(input.l[i] * pangainL + fb.l,
  193. input.r[i] * pangainR + fb.r);
  194. Stereo<float> g(gain.l * x + oldgain.l * x1,
  195. gain.r * x + oldgain.r * x1);
  196. xn.l = applyPhase(xn.l, g.l, old.l);
  197. xn.r = applyPhase(xn.r, g.r, old.r);
  198. //Left/Right crossing
  199. crossover(xn.l, xn.r, lrcross);
  200. fb.l = xn.l * feedback;
  201. fb.r = xn.r * feedback;
  202. efxoutl[i] = xn.l;
  203. efxoutr[i] = xn.r;
  204. }
  205. oldgain = gain;
  206. if(Poutsub) {
  207. invSignal(efxoutl, buffersize);
  208. invSignal(efxoutr, buffersize);
  209. }
  210. }
  211. float Phaser::applyPhase(float x, float g, float *old)
  212. {
  213. for(int j = 0; j < Pstages * 2; ++j) { //Phasing routine
  214. float tmp = old[j];
  215. old[j] = g * tmp + x;
  216. x = tmp - g * old[j];
  217. }
  218. return x;
  219. }
  220. /*
  221. * Cleanup the effect
  222. */
  223. void Phaser::cleanup()
  224. {
  225. fb = oldgain = Stereo<float>(0.0f);
  226. for(int i = 0; i < Pstages * 2; ++i) {
  227. old.l[i] = 0.0f;
  228. old.r[i] = 0.0f;
  229. }
  230. for(int i = 0; i < Pstages; ++i) {
  231. xn1.l[i] = 0.0f;
  232. yn1.l[i] = 0.0f;
  233. xn1.r[i] = 0.0f;
  234. yn1.r[i] = 0.0f;
  235. }
  236. }
  237. /*
  238. * Parameter control
  239. */
  240. void Phaser::setwidth(unsigned char Pwidth)
  241. {
  242. this->Pwidth = Pwidth;
  243. width = ((float)Pwidth / 127.0f);
  244. }
  245. void Phaser::setfb(unsigned char Pfb)
  246. {
  247. this->Pfb = Pfb;
  248. feedback = (float) (Pfb - 64) / 64.2f;
  249. }
  250. void Phaser::setvolume(unsigned char Pvolume)
  251. {
  252. this->Pvolume = Pvolume;
  253. outvolume = Pvolume / 127.0f;
  254. if(insertion == 0)
  255. volume = 1.0f;
  256. else
  257. volume = outvolume;
  258. }
  259. void Phaser::setdistortion(unsigned char Pdistortion)
  260. {
  261. this->Pdistortion = Pdistortion;
  262. distortion = (float)Pdistortion / 127.0f;
  263. }
  264. void Phaser::setoffset(unsigned char Poffset)
  265. {
  266. this->Poffset = Poffset;
  267. offsetpct = (float)Poffset / 127.0f;
  268. }
  269. void Phaser::setstages(unsigned char Pstages)
  270. {
  271. memory.devalloc(old.l);
  272. memory.devalloc(old.r);
  273. memory.devalloc(xn1.l);
  274. memory.devalloc(xn1.r);
  275. memory.devalloc(yn1.l);
  276. memory.devalloc(yn1.r);
  277. this->Pstages = min(MAX_PHASER_STAGES, (int)Pstages);
  278. old = Stereo<float *>(memory.valloc<float>(Pstages * 2),
  279. memory.valloc<float>(Pstages * 2));
  280. xn1 = Stereo<float *>(memory.valloc<float>(Pstages),
  281. memory.valloc<float>(Pstages));
  282. yn1 = Stereo<float *>(memory.valloc<float>(Pstages),
  283. memory.valloc<float>(Pstages));
  284. cleanup();
  285. }
  286. void Phaser::setphase(unsigned char Pphase)
  287. {
  288. this->Pphase = Pphase;
  289. phase = (Pphase / 127.0f);
  290. }
  291. void Phaser::setdepth(unsigned char Pdepth)
  292. {
  293. this->Pdepth = Pdepth;
  294. depth = (float)(Pdepth) / 127.0f;
  295. }
  296. void Phaser::setpreset(unsigned char npreset)
  297. {
  298. const int PRESET_SIZE = 15;
  299. const int NUM_PRESETS = 12;
  300. unsigned char presets[NUM_PRESETS][PRESET_SIZE] = {
  301. //Phaser
  302. //0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
  303. {64, 64, 36, 0, 0, 64, 110, 64, 1, 0, 0, 20,
  304. 0, 0,
  305. 0 },
  306. {64, 64, 35, 0, 0, 88, 40, 64, 3, 0, 0, 20, 0, 0,
  307. 0 },
  308. {64, 64, 31, 0, 0, 66, 68, 107, 2, 0, 0, 20, 0, 0,
  309. 0 },
  310. {39, 64, 22, 0, 0, 66, 67, 10, 5, 0, 1, 20, 0, 0,
  311. 0 },
  312. {64, 64, 20, 0, 1, 110, 67, 78, 10, 0, 0, 20, 0, 0,
  313. 0 },
  314. {64, 64, 53, 100, 0, 58, 37, 78, 3, 0, 0, 20, 0, 0,
  315. 0 },
  316. //APhaser
  317. //0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
  318. {64, 64, 14, 0, 1, 64, 64, 40, 4, 10, 0, 110,1, 20,
  319. 1 },
  320. {64, 64, 14, 5, 1, 64, 70, 40, 6, 10, 0, 110,1, 20,
  321. 1 },
  322. {64, 64, 9, 0, 0, 64, 60, 40, 8, 10, 0, 40, 0, 20,
  323. 1 },
  324. {64, 64, 14, 10, 0, 64, 45, 80, 7, 10, 1, 110,1, 20,
  325. 1 },
  326. {25, 64, 127, 10, 0, 64, 25, 16, 8, 100, 0, 25, 0, 20,
  327. 1 },
  328. {64, 64, 1, 10, 1, 64, 70, 40, 12, 10, 0, 110,1, 20,
  329. 1 }
  330. };
  331. if(npreset >= NUM_PRESETS)
  332. npreset = NUM_PRESETS - 1;
  333. for(int n = 0; n < PRESET_SIZE; ++n)
  334. changepar(n, presets[npreset][n]);
  335. Ppreset = npreset;
  336. }
  337. void Phaser::changepar(int npar, unsigned char value)
  338. {
  339. switch(npar) {
  340. case 0:
  341. setvolume(value);
  342. break;
  343. case 1:
  344. setpanning(value);
  345. break;
  346. case 2:
  347. lfo.Pfreq = value;
  348. lfo.updateparams();
  349. break;
  350. case 3:
  351. lfo.Prandomness = value;
  352. lfo.updateparams();
  353. break;
  354. case 4:
  355. lfo.PLFOtype = value;
  356. lfo.updateparams();
  357. barber = (2 == value);
  358. break;
  359. case 5:
  360. lfo.Pstereo = value;
  361. lfo.updateparams();
  362. break;
  363. case 6:
  364. setdepth(value);
  365. break;
  366. case 7:
  367. setfb(value);
  368. break;
  369. case 8:
  370. setstages(value);
  371. break;
  372. case 9:
  373. setlrcross(value);
  374. setoffset(value);
  375. break;
  376. case 10:
  377. Poutsub = min((int)value, 1);
  378. break;
  379. case 11:
  380. setphase(value);
  381. setwidth(value);
  382. break;
  383. case 12:
  384. Phyper = min((int)value, 1);
  385. break;
  386. case 13:
  387. setdistortion(value);
  388. break;
  389. case 14:
  390. Panalog = value;
  391. break;
  392. }
  393. }
  394. unsigned char Phaser::getpar(int npar) const
  395. {
  396. switch(npar) {
  397. case 0: return Pvolume;
  398. case 1: return Ppanning;
  399. case 2: return lfo.Pfreq;
  400. case 3: return lfo.Prandomness;
  401. case 4: return lfo.PLFOtype;
  402. case 5: return lfo.Pstereo;
  403. case 6: return Pdepth;
  404. case 7: return Pfb;
  405. case 8: return Pstages;
  406. case 9: return Plrcross;
  407. return Poffset; //same
  408. case 10: return Poutsub;
  409. case 11: return Pphase;
  410. return Pwidth; //same
  411. case 12: return Phyper;
  412. case 13: return Pdistortion;
  413. case 14: return Panalog;
  414. default: return 0;
  415. }
  416. }