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.

578 lines
17KB

  1. /*
  2. ZynAddSubFX - a software synthesizer
  3. SUBnote.cpp - The "subtractive" synthesizer
  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 <cstdlib>
  19. #include <cstdio>
  20. #include <cassert>
  21. #include "../globals.h"
  22. #include "SUBnote.h"
  23. #include "../Misc/Util.h"
  24. SUBnote::SUBnote(SUBnoteParameters *parameters,
  25. Controller *ctl_,
  26. float freq,
  27. float velocity,
  28. int portamento_,
  29. int midinote,
  30. bool besilent)
  31. :SynthNote(freq, velocity, portamento_, midinote, besilent)
  32. {
  33. pars = parameters;
  34. ctl = ctl_;
  35. NoteEnabled = ON;
  36. setup(freq, velocity, portamento_, midinote);
  37. }
  38. void SUBnote::setup(float freq,
  39. float velocity,
  40. int portamento_,
  41. int midinote,
  42. bool legato)
  43. {
  44. portamento = portamento_;
  45. NoteEnabled = ON;
  46. volume = powf(0.1f, 3.0f * (1.0f - pars->PVolume / 96.0f)); //-60 dB .. 0 dB
  47. volume *= VelF(velocity, pars->PAmpVelocityScaleFunction);
  48. if(pars->PPanning != 0)
  49. panning = pars->PPanning / 127.0f;
  50. else
  51. panning = RND;
  52. if(!legato) {
  53. numstages = pars->Pnumstages;
  54. stereo = pars->Pstereo;
  55. start = pars->Pstart;
  56. firsttick = 1;
  57. }
  58. int pos[MAX_SUB_HARMONICS];
  59. if(pars->Pfixedfreq == 0)
  60. basefreq = freq;
  61. else {
  62. basefreq = 440.0f;
  63. int fixedfreqET = pars->PfixedfreqET;
  64. if(fixedfreqET != 0) { //if the frequency varies according the keyboard note
  65. float tmp =
  66. (midinote
  67. - 69.0f) / 12.0f
  68. * (powf(2.0f, (fixedfreqET - 1) / 63.0f) - 1.0f);
  69. if(fixedfreqET <= 64)
  70. basefreq *= powf(2.0f, tmp);
  71. else
  72. basefreq *= powf(3.0f, tmp);
  73. }
  74. }
  75. float detune = getdetune(pars->PDetuneType,
  76. pars->PCoarseDetune,
  77. pars->PDetune);
  78. basefreq *= powf(2.0f, detune / 1200.0f); //detune
  79. // basefreq*=ctl->pitchwheel.relfreq;//pitch wheel
  80. //global filter
  81. GlobalFilterCenterPitch = pars->GlobalFilter->getfreq() //center freq
  82. + (pars->PGlobalFilterVelocityScale / 127.0f
  83. * 6.0f) //velocity sensing
  84. * (VelF(velocity,
  85. pars->PGlobalFilterVelocityScaleFunction)
  86. - 1);
  87. if(!legato) {
  88. GlobalFilterL = NULL;
  89. GlobalFilterR = NULL;
  90. GlobalFilterEnvelope = NULL;
  91. }
  92. //select only harmonics that desire to compute
  93. int harmonics = 0;
  94. for(int n = 0; n < MAX_SUB_HARMONICS; ++n) {
  95. if(pars->Phmag[n] == 0)
  96. continue;
  97. if(n * basefreq > synth->samplerate_f / 2.0f)
  98. break; //remove the freqs above the Nyquist freq
  99. pos[harmonics++] = n;
  100. }
  101. if(!legato)
  102. firstnumharmonics = numharmonics = harmonics;
  103. else {
  104. if(harmonics > firstnumharmonics)
  105. numharmonics = firstnumharmonics;
  106. else
  107. numharmonics = harmonics;
  108. }
  109. if(numharmonics == 0) {
  110. NoteEnabled = OFF;
  111. return;
  112. }
  113. if(!legato) {
  114. lfilter = new bpfilter[numstages * numharmonics];
  115. if(stereo != 0)
  116. rfilter = new bpfilter[numstages * numharmonics];
  117. }
  118. //how much the amplitude is normalised (because the harmonics)
  119. float reduceamp = 0.0f;
  120. for(int n = 0; n < numharmonics; ++n) {
  121. float freq = basefreq * (pos[n] + 1);
  122. //the bandwidth is not absolute(Hz); it is relative to frequency
  123. float bw =
  124. powf(10, (pars->Pbandwidth - 127.0f) / 127.0f * 4) * numstages;
  125. //Bandwidth Scale
  126. bw *= powf(1000 / freq, (pars->Pbwscale - 64.0f) / 64.0f * 3.0f);
  127. //Relative BandWidth
  128. bw *= powf(100, (pars->Phrelbw[pos[n]] - 64.0f) / 64.0f);
  129. if(bw > 25.0f)
  130. bw = 25.0f;
  131. //try to keep same amplitude on all freqs and bw. (empirically)
  132. float gain = sqrt(1500.0f / (bw * freq));
  133. float hmagnew = 1.0f - pars->Phmag[pos[n]] / 127.0f;
  134. float hgain;
  135. switch(pars->Phmagtype) {
  136. case 1:
  137. hgain = expf(hmagnew * logf(0.01f));
  138. break;
  139. case 2:
  140. hgain = expf(hmagnew * logf(0.001f));
  141. break;
  142. case 3:
  143. hgain = expf(hmagnew * logf(0.0001f));
  144. break;
  145. case 4:
  146. hgain = expf(hmagnew * logf(0.00001f));
  147. break;
  148. default:
  149. hgain = 1.0f - hmagnew;
  150. }
  151. gain *= hgain;
  152. reduceamp += hgain;
  153. for(int nph = 0; nph < numstages; ++nph) {
  154. float amp = 1.0f;
  155. if(nph == 0)
  156. amp = gain;
  157. initfilter(lfilter[nph + n * numstages], freq, bw, amp, hgain);
  158. if(stereo != 0)
  159. initfilter(rfilter[nph + n * numstages], freq, bw, amp, hgain);
  160. }
  161. }
  162. if(reduceamp < 0.001f)
  163. reduceamp = 1.0f;
  164. volume /= reduceamp;
  165. oldpitchwheel = 0;
  166. oldbandwidth = 64;
  167. if(!legato) {
  168. if(pars->Pfixedfreq == 0)
  169. initparameters(basefreq);
  170. else
  171. initparameters(basefreq / 440.0f * freq);
  172. }
  173. else {
  174. if(pars->Pfixedfreq == 0)
  175. freq = basefreq;
  176. else
  177. freq *= basefreq / 440.0f;
  178. if(pars->PGlobalFilterEnabled != 0) {
  179. globalfiltercenterq = pars->GlobalFilter->getq();
  180. GlobalFilterFreqTracking = pars->GlobalFilter->getfreqtracking(
  181. basefreq);
  182. }
  183. }
  184. oldamplitude = newamplitude;
  185. }
  186. void SUBnote::legatonote(float freq, float velocity, int portamento_,
  187. int midinote, bool externcall)
  188. {
  189. // Manage legato stuff
  190. if(legato.update(freq, velocity, portamento_, midinote, externcall))
  191. return;
  192. setup(freq, velocity, portamento_, midinote, true);
  193. }
  194. SUBnote::~SUBnote()
  195. {
  196. if(NoteEnabled != OFF)
  197. KillNote();
  198. }
  199. /*
  200. * Kill the note
  201. */
  202. void SUBnote::KillNote()
  203. {
  204. if(NoteEnabled != OFF) {
  205. delete [] lfilter;
  206. lfilter = NULL;
  207. if(stereo != 0)
  208. delete [] rfilter;
  209. rfilter = NULL;
  210. delete AmpEnvelope;
  211. delete FreqEnvelope;
  212. delete BandWidthEnvelope;
  213. delete GlobalFilterL;
  214. delete GlobalFilterR;
  215. delete GlobalFilterEnvelope;
  216. NoteEnabled = OFF;
  217. }
  218. }
  219. /*
  220. * Compute the filters coefficients
  221. */
  222. void SUBnote::computefiltercoefs(bpfilter &filter,
  223. float freq,
  224. float bw,
  225. float gain)
  226. {
  227. if(freq > synth->samplerate_f / 2.0f - 200.0f)
  228. freq = synth->samplerate_f / 2.0f - 200.0f;
  229. float omega = 2.0f * PI * freq / synth->samplerate_f;
  230. float sn = sinf(omega);
  231. float cs = cosf(omega);
  232. float alpha = sn * sinh(LOG_2 / 2.0f * bw * omega / sn);
  233. if(alpha > 1)
  234. alpha = 1;
  235. if(alpha > bw)
  236. alpha = bw;
  237. filter.b0 = alpha / (1.0f + alpha) * filter.amp * gain;
  238. filter.b2 = -alpha / (1.0f + alpha) * filter.amp * gain;
  239. filter.a1 = -2.0f * cs / (1.0f + alpha);
  240. filter.a2 = (1.0f - alpha) / (1.0f + alpha);
  241. }
  242. /*
  243. * Initialise the filters
  244. */
  245. void SUBnote::initfilter(bpfilter &filter,
  246. float freq,
  247. float bw,
  248. float amp,
  249. float mag)
  250. {
  251. filter.xn1 = 0.0f;
  252. filter.xn2 = 0.0f;
  253. if(start == 0) {
  254. filter.yn1 = 0.0f;
  255. filter.yn2 = 0.0f;
  256. }
  257. else {
  258. float a = 0.1f * mag; //empirically
  259. float p = RND * 2.0f * PI;
  260. if(start == 1)
  261. a *= RND;
  262. filter.yn1 = a * cosf(p);
  263. filter.yn2 = a * cosf(p + freq * 2.0f * PI / synth->samplerate_f);
  264. //correct the error of computation the start amplitude
  265. //at very high frequencies
  266. if(freq > synth->samplerate_f * 0.96f) {
  267. filter.yn1 = 0.0f;
  268. filter.yn2 = 0.0f;
  269. }
  270. }
  271. filter.amp = amp;
  272. filter.freq = freq;
  273. filter.bw = bw;
  274. computefiltercoefs(filter, freq, bw, 1.0f);
  275. }
  276. /*
  277. * Do the filtering
  278. */
  279. inline float SUBnote::SubFilter(bpfilter &filter, const float input) const
  280. {
  281. const float out = input * filter.b0 + filter.b2 * filter.xn2
  282. - filter.a1 * filter.yn1 - filter.a2 * filter.yn2;
  283. filter.xn2 = filter.xn1;
  284. filter.xn1 = input;
  285. filter.yn2 = filter.yn1;
  286. filter.yn1 = out;
  287. return out;
  288. }
  289. void SUBnote::filter(bpfilter &filter, float *smps)
  290. {
  291. assert(synth->buffersize % 8 == 0);
  292. for(int i = 0; i < synth->buffersize; i += 8) {
  293. smps[i] = SubFilter(filter, smps[i]);
  294. smps[i + 1] = SubFilter(filter, smps[i + 1]);
  295. smps[i + 2] = SubFilter(filter, smps[i + 2]);
  296. smps[i + 3] = SubFilter(filter, smps[i + 3]);
  297. smps[i + 4] = SubFilter(filter, smps[i + 4]);
  298. smps[i + 5] = SubFilter(filter, smps[i + 5]);
  299. smps[i + 6] = SubFilter(filter, smps[i + 6]);
  300. smps[i + 7] = SubFilter(filter, smps[i + 7]);
  301. }
  302. }
  303. /*
  304. * Init Parameters
  305. */
  306. void SUBnote::initparameters(float freq)
  307. {
  308. AmpEnvelope = new Envelope(pars->AmpEnvelope, freq);
  309. if(pars->PFreqEnvelopeEnabled != 0)
  310. FreqEnvelope = new Envelope(pars->FreqEnvelope, freq);
  311. else
  312. FreqEnvelope = NULL;
  313. if(pars->PBandWidthEnvelopeEnabled != 0)
  314. BandWidthEnvelope = new Envelope(pars->BandWidthEnvelope, freq);
  315. else
  316. BandWidthEnvelope = NULL;
  317. if(pars->PGlobalFilterEnabled != 0) {
  318. globalfiltercenterq = pars->GlobalFilter->getq();
  319. GlobalFilterL = Filter::generate(pars->GlobalFilter);
  320. if(stereo)
  321. GlobalFilterR = Filter::generate(pars->GlobalFilter);
  322. GlobalFilterEnvelope = new Envelope(pars->GlobalFilterEnvelope,
  323. freq);
  324. GlobalFilterFreqTracking = pars->GlobalFilter->getfreqtracking(basefreq);
  325. }
  326. computecurrentparameters();
  327. }
  328. /*
  329. * Compute Parameters of SUBnote for each tick
  330. */
  331. void SUBnote::computecurrentparameters()
  332. {
  333. if((FreqEnvelope != NULL) || (BandWidthEnvelope != NULL)
  334. || (oldpitchwheel != ctl->pitchwheel.data)
  335. || (oldbandwidth != ctl->bandwidth.data)
  336. || (portamento != 0)) {
  337. float envfreq = 1.0f;
  338. float envbw = 1.0f;
  339. float gain = 1.0f;
  340. if(FreqEnvelope != NULL) {
  341. envfreq = FreqEnvelope->envout() / 1200;
  342. envfreq = powf(2.0f, envfreq);
  343. }
  344. envfreq *= ctl->pitchwheel.relfreq; //pitch wheel
  345. if(portamento != 0) { //portamento is used
  346. envfreq *= ctl->portamento.freqrap;
  347. if(ctl->portamento.used == 0) //the portamento has finished
  348. portamento = 0; //this note is no longer "portamented"
  349. ;
  350. }
  351. if(BandWidthEnvelope != NULL) {
  352. envbw = BandWidthEnvelope->envout();
  353. envbw = powf(2, envbw);
  354. }
  355. envbw *= ctl->bandwidth.relbw; //bandwidth controller
  356. float tmpgain = 1.0f / sqrt(envbw * envfreq);
  357. for(int n = 0; n < numharmonics; ++n)
  358. for(int nph = 0; nph < numstages; ++nph) {
  359. if(nph == 0)
  360. gain = tmpgain;
  361. else
  362. gain = 1.0f;
  363. computefiltercoefs(lfilter[nph + n * numstages],
  364. lfilter[nph + n * numstages].freq * envfreq,
  365. lfilter[nph + n * numstages].bw * envbw,
  366. gain);
  367. }
  368. if(stereo != 0)
  369. for(int n = 0; n < numharmonics; ++n)
  370. for(int nph = 0; nph < numstages; ++nph) {
  371. if(nph == 0)
  372. gain = tmpgain;
  373. else
  374. gain = 1.0f;
  375. computefiltercoefs(
  376. rfilter[nph + n * numstages],
  377. rfilter[nph + n
  378. * numstages].freq * envfreq,
  379. rfilter[nph + n * numstages].bw * envbw,
  380. gain);
  381. }
  382. oldbandwidth = ctl->bandwidth.data;
  383. oldpitchwheel = ctl->pitchwheel.data;
  384. }
  385. newamplitude = volume * AmpEnvelope->envout_dB() * 2.0f;
  386. //Filter
  387. if(GlobalFilterL != NULL) {
  388. float globalfilterpitch = GlobalFilterCenterPitch
  389. + GlobalFilterEnvelope->envout();
  390. float filterfreq = globalfilterpitch + ctl->filtercutoff.relfreq
  391. + GlobalFilterFreqTracking;
  392. filterfreq = Filter::getrealfreq(filterfreq);
  393. GlobalFilterL->setfreq_and_q(filterfreq,
  394. globalfiltercenterq * ctl->filterq.relq);
  395. if(GlobalFilterR != NULL)
  396. GlobalFilterR->setfreq_and_q(
  397. filterfreq,
  398. globalfiltercenterq
  399. * ctl->filterq.relq);
  400. }
  401. }
  402. /*
  403. * Note Output
  404. */
  405. int SUBnote::noteout(float *outl, float *outr)
  406. {
  407. memcpy(outl, denormalkillbuf, synth->bufferbytes);
  408. memcpy(outr, denormalkillbuf, synth->bufferbytes);
  409. if(NoteEnabled == OFF)
  410. return 0;
  411. float *tmprnd = getTmpBuffer();
  412. float *tmpsmp = getTmpBuffer();
  413. //left channel
  414. for(int i = 0; i < synth->buffersize; ++i)
  415. tmprnd[i] = RND * 2.0f - 1.0f;
  416. for(int n = 0; n < numharmonics; ++n) {
  417. memcpy(tmpsmp, tmprnd, synth->bufferbytes);
  418. for(int nph = 0; nph < numstages; ++nph)
  419. filter(lfilter[nph + n * numstages], tmpsmp);
  420. for(int i = 0; i < synth->buffersize; ++i)
  421. outl[i] += tmpsmp[i];
  422. }
  423. if(GlobalFilterL != NULL)
  424. GlobalFilterL->filterout(&outl[0]);
  425. //right channel
  426. if(stereo != 0) {
  427. for(int i = 0; i < synth->buffersize; ++i)
  428. tmprnd[i] = RND * 2.0f - 1.0f;
  429. for(int n = 0; n < numharmonics; ++n) {
  430. memcpy(tmpsmp, tmprnd, synth->bufferbytes);
  431. for(int nph = 0; nph < numstages; ++nph)
  432. filter(rfilter[nph + n * numstages], tmpsmp);
  433. for(int i = 0; i < synth->buffersize; ++i)
  434. outr[i] += tmpsmp[i];
  435. }
  436. if(GlobalFilterR != NULL)
  437. GlobalFilterR->filterout(&outr[0]);
  438. }
  439. else
  440. memcpy(outr, outl, synth->bufferbytes);
  441. returnTmpBuffer(tmprnd);
  442. returnTmpBuffer(tmpsmp);
  443. if(firsttick != 0) {
  444. int n = 10;
  445. if(n > synth->buffersize)
  446. n = synth->buffersize;
  447. for(int i = 0; i < n; ++i) {
  448. float ampfadein = 0.5f - 0.5f * cosf(
  449. (float) i / (float) n * PI);
  450. outl[i] *= ampfadein;
  451. outr[i] *= ampfadein;
  452. }
  453. firsttick = 0;
  454. }
  455. if(ABOVE_AMPLITUDE_THRESHOLD(oldamplitude, newamplitude))
  456. // Amplitude interpolation
  457. for(int i = 0; i < synth->buffersize; ++i) {
  458. float tmpvol = INTERPOLATE_AMPLITUDE(oldamplitude,
  459. newamplitude,
  460. i,
  461. synth->buffersize);
  462. outl[i] *= tmpvol * panning;
  463. outr[i] *= tmpvol * (1.0f - panning);
  464. }
  465. else
  466. for(int i = 0; i < synth->buffersize; ++i) {
  467. outl[i] *= newamplitude * panning;
  468. outr[i] *= newamplitude * (1.0f - panning);
  469. }
  470. oldamplitude = newamplitude;
  471. computecurrentparameters();
  472. // Apply legato-specific sound signal modifications
  473. legato.apply(*this, outl, outr);
  474. // Check if the note needs to be computed more
  475. if(AmpEnvelope->finished() != 0) {
  476. for(int i = 0; i < synth->buffersize; ++i) { //fade-out
  477. float tmp = 1.0f - (float)i / synth->buffersize_f;
  478. outl[i] *= tmp;
  479. outr[i] *= tmp;
  480. }
  481. KillNote();
  482. }
  483. return 1;
  484. }
  485. /*
  486. * Relase Key (Note Off)
  487. */
  488. void SUBnote::relasekey()
  489. {
  490. AmpEnvelope->relasekey();
  491. if(FreqEnvelope)
  492. FreqEnvelope->relasekey();
  493. if(BandWidthEnvelope)
  494. BandWidthEnvelope->relasekey();
  495. if(GlobalFilterEnvelope)
  496. GlobalFilterEnvelope->relasekey();
  497. }
  498. /*
  499. * Check if the note is finished
  500. */
  501. int SUBnote::finished() const
  502. {
  503. if(NoteEnabled == OFF)
  504. return 1;
  505. else
  506. return 0;
  507. }