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.

614 lines
18KB

  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 "Envelope.h"
  24. #include "../Params/Controller.h"
  25. #include "../Params/SUBnoteParameters.h"
  26. #include "../Params/FilterParams.h"
  27. #include "../Misc/Util.h"
  28. #include "../Misc/Allocator.h"
  29. SUBnote::SUBnote(const SUBnoteParameters *parameters, SynthParams &spars)
  30. :SynthNote(spars), pars(*parameters)
  31. {
  32. NoteEnabled = ON;
  33. setup(spars.frequency, spars.velocity, spars.portamento, spars.note);
  34. }
  35. void SUBnote::setup(float freq,
  36. float velocity,
  37. int portamento_,
  38. int midinote,
  39. bool legato)
  40. {
  41. this->velocity = velocity;
  42. portamento = portamento_;
  43. NoteEnabled = ON;
  44. volume = powf(0.1f, 3.0f * (1.0f - pars.PVolume / 96.0f)); //-60 dB .. 0 dB
  45. volume *= VelF(velocity, pars.PAmpVelocityScaleFunction);
  46. if(pars.PPanning != 0)
  47. panning = pars.PPanning / 127.0f;
  48. else
  49. panning = RND;
  50. if(!legato) {
  51. numstages = pars.Pnumstages;
  52. stereo = pars.Pstereo;
  53. start = pars.Pstart;
  54. firsttick = 1;
  55. }
  56. int pos[MAX_SUB_HARMONICS];
  57. if(pars.Pfixedfreq == 0)
  58. basefreq = freq;
  59. else {
  60. basefreq = 440.0f;
  61. int fixedfreqET = pars.PfixedfreqET;
  62. if(fixedfreqET) { //if the frequency varies according the keyboard note
  63. float tmp = (midinote - 69.0f) / 12.0f
  64. * (powf(2.0f, (fixedfreqET - 1) / 63.0f) - 1.0f);
  65. if(fixedfreqET <= 64)
  66. basefreq *= powf(2.0f, tmp);
  67. else
  68. basefreq *= powf(3.0f, tmp);
  69. }
  70. }
  71. float detune = getdetune(pars.PDetuneType,
  72. pars.PCoarseDetune,
  73. pars.PDetune);
  74. basefreq *= powf(2.0f, detune / 1200.0f); //detune
  75. // basefreq*=ctl.pitchwheel.relfreq;//pitch wheel
  76. //global filter
  77. GlobalFilterCenterPitch = pars.GlobalFilter->getfreq() //center freq
  78. + (pars.PGlobalFilterVelocityScale / 127.0f
  79. * 6.0f) //velocity sensing
  80. * (VelF(velocity,
  81. pars.PGlobalFilterVelocityScaleFunction)
  82. - 1);
  83. if(!legato) {
  84. GlobalFilterL = NULL;
  85. GlobalFilterR = NULL;
  86. GlobalFilterEnvelope = NULL;
  87. }
  88. int harmonics = 0;
  89. //select only harmonics that desire to compute
  90. for(int n = 0; n < MAX_SUB_HARMONICS; ++n) {
  91. if(pars.Phmag[n] == 0)
  92. continue;
  93. pos[harmonics++] = n;
  94. }
  95. if(!legato)
  96. firstnumharmonics = numharmonics = harmonics;
  97. else {
  98. if(harmonics > firstnumharmonics)
  99. numharmonics = firstnumharmonics;
  100. else
  101. numharmonics = harmonics;
  102. }
  103. if(numharmonics == 0) {
  104. NoteEnabled = OFF;
  105. return;
  106. }
  107. if(!legato) {
  108. lfilter = memory.valloc<bpfilter>(numstages * numharmonics);
  109. if(stereo)
  110. rfilter = memory.valloc<bpfilter>(numstages * numharmonics);
  111. }
  112. //how much the amplitude is normalised (because the harmonics)
  113. float reduceamp = 0.0f;
  114. for(int n = 0; n < numharmonics; ++n) {
  115. float freq = basefreq * pars.POvertoneFreqMult[pos[n]];
  116. overtone_freq[n] = freq;
  117. overtone_rolloff[n] = computerolloff(freq);
  118. //the bandwidth is not absolute(Hz); it is relative to frequency
  119. float bw =
  120. powf(10, (pars.Pbandwidth - 127.0f) / 127.0f * 4) * numstages;
  121. //Bandwidth Scale
  122. bw *= powf(1000 / freq, (pars.Pbwscale - 64.0f) / 64.0f * 3.0f);
  123. //Relative BandWidth
  124. bw *= powf(100, (pars.Phrelbw[pos[n]] - 64.0f) / 64.0f);
  125. if(bw > 25.0f)
  126. bw = 25.0f;
  127. //try to keep same amplitude on all freqs and bw. (empirically)
  128. float gain = sqrt(1500.0f / (bw * freq));
  129. float hmagnew = 1.0f - pars.Phmag[pos[n]] / 127.0f;
  130. float hgain;
  131. switch(pars.Phmagtype) {
  132. case 1:
  133. hgain = expf(hmagnew * logf(0.01f));
  134. break;
  135. case 2:
  136. hgain = expf(hmagnew * logf(0.001f));
  137. break;
  138. case 3:
  139. hgain = expf(hmagnew * logf(0.0001f));
  140. break;
  141. case 4:
  142. hgain = expf(hmagnew * logf(0.00001f));
  143. break;
  144. default:
  145. hgain = 1.0f - hmagnew;
  146. }
  147. gain *= hgain;
  148. reduceamp += hgain;
  149. for(int nph = 0; nph < numstages; ++nph) {
  150. float amp = 1.0f;
  151. if(nph == 0)
  152. amp = gain;
  153. initfilter(lfilter[nph + n * numstages], freq, bw, amp, hgain);
  154. if(stereo)
  155. initfilter(rfilter[nph + n * numstages], freq, bw, amp, hgain);
  156. }
  157. }
  158. if(reduceamp < 0.001f)
  159. reduceamp = 1.0f;
  160. volume /= reduceamp;
  161. oldpitchwheel = 0;
  162. oldbandwidth = 64;
  163. if(!legato) {
  164. if(pars.Pfixedfreq == 0)
  165. initparameters(basefreq);
  166. else
  167. initparameters(basefreq / 440.0f * freq);
  168. }
  169. else {
  170. if(pars.Pfixedfreq == 0)
  171. freq = basefreq;
  172. else
  173. freq *= basefreq / 440.0f;
  174. if(pars.PGlobalFilterEnabled) {
  175. globalfiltercenterq = pars.GlobalFilter->getq();
  176. GlobalFilterFreqTracking = pars.GlobalFilter->getfreqtracking(
  177. basefreq);
  178. }
  179. }
  180. oldamplitude = newamplitude;
  181. }
  182. SynthNote *SUBnote::cloneLegato(void)
  183. {
  184. SynthParams sp{memory, ctl, synth, time, legato.param.freq, velocity,
  185. (bool)portamento, legato.param.midinote, true};
  186. return memory.alloc<SUBnote>(&pars, sp);
  187. }
  188. void SUBnote::legatonote(LegatoParams pars)
  189. {
  190. // Manage legato stuff
  191. if(legato.update(pars))
  192. return;
  193. setup(pars.frequency, pars.velocity, pars.portamento, pars.midinote,
  194. true);
  195. }
  196. SUBnote::~SUBnote()
  197. {
  198. if(NoteEnabled != OFF)
  199. KillNote();
  200. }
  201. /*
  202. * Kill the note
  203. */
  204. void SUBnote::KillNote()
  205. {
  206. if(NoteEnabled != OFF) {
  207. memory.devalloc(numstages * numharmonics, lfilter);
  208. if(stereo)
  209. memory.devalloc(numstages * numharmonics, rfilter);
  210. memory.dealloc(AmpEnvelope);
  211. memory.dealloc(FreqEnvelope);
  212. memory.dealloc(BandWidthEnvelope);
  213. memory.dealloc(GlobalFilterL);
  214. memory.dealloc(GlobalFilterR);
  215. memory.dealloc(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 void SubFilterA(const float coeff[4], float &src, float work[4])
  280. {
  281. work[3] = src*coeff[0]+work[1]*coeff[1]+work[2]*coeff[2]+work[3]*coeff[3];
  282. work[1] = src;
  283. src = work[3];
  284. }
  285. inline void SubFilterB(const float coeff[4], float &src, float work[4])
  286. {
  287. work[2] = src*coeff[0]+work[0]*coeff[1]+work[3]*coeff[2]+work[2]*coeff[3];
  288. work[0] = src;
  289. src = work[2];
  290. }
  291. //This dance is designed to minimize unneeded memory operations which can result
  292. //in quite a bit of wasted time
  293. void SUBnote::filter(bpfilter &filter, float *smps)
  294. {
  295. assert(synth.buffersize % 8 == 0);
  296. float coeff[4] = {filter.b0, filter.b2, -filter.a1, -filter.a2};
  297. float work[4] = {filter.xn1, filter.xn2, filter.yn1, filter.yn2};
  298. for(int i = 0; i < synth.buffersize; i += 8) {
  299. SubFilterA(coeff, smps[i + 0], work);
  300. SubFilterB(coeff, smps[i + 1], work);
  301. SubFilterA(coeff, smps[i + 2], work);
  302. SubFilterB(coeff, smps[i + 3], work);
  303. SubFilterA(coeff, smps[i + 4], work);
  304. SubFilterB(coeff, smps[i + 5], work);
  305. SubFilterA(coeff, smps[i + 6], work);
  306. SubFilterB(coeff, smps[i + 7], work);
  307. }
  308. filter.xn1 = work[0];
  309. filter.xn2 = work[1];
  310. filter.yn1 = work[2];
  311. filter.yn2 = work[3];
  312. }
  313. /*
  314. * Init Parameters
  315. */
  316. void SUBnote::initparameters(float freq)
  317. {
  318. AmpEnvelope = memory.alloc<Envelope>(*pars.AmpEnvelope, freq, synth.dt());
  319. if(pars.PFreqEnvelopeEnabled)
  320. FreqEnvelope = memory.alloc<Envelope>(*pars.FreqEnvelope, freq, synth.dt());
  321. else
  322. FreqEnvelope = NULL;
  323. if(pars.PBandWidthEnvelopeEnabled)
  324. BandWidthEnvelope = memory.alloc<Envelope>(*pars.BandWidthEnvelope, freq, synth.dt());
  325. else
  326. BandWidthEnvelope = NULL;
  327. if(pars.PGlobalFilterEnabled) {
  328. globalfiltercenterq = pars.GlobalFilter->getq();
  329. GlobalFilterL = Filter::generate(memory, pars.GlobalFilter,
  330. synth.samplerate, synth.buffersize);
  331. if(stereo)
  332. GlobalFilterR = Filter::generate(memory, pars.GlobalFilter,
  333. synth.samplerate, synth.buffersize);
  334. GlobalFilterEnvelope = memory.alloc<Envelope>(*pars.GlobalFilterEnvelope, freq, synth.dt());
  335. GlobalFilterFreqTracking = pars.GlobalFilter->getfreqtracking(basefreq);
  336. }
  337. computecurrentparameters();
  338. }
  339. /*
  340. * Compute how much to reduce amplitude near nyquist or subaudible frequencies.
  341. */
  342. float SUBnote::computerolloff(float freq)
  343. {
  344. const float lower_limit = 10.0f;
  345. const float lower_width = 10.0f;
  346. const float upper_width = 200.0f;
  347. float upper_limit = synth.samplerate / 2.0f;
  348. if (freq > lower_limit + lower_width &&
  349. freq < upper_limit - upper_width)
  350. return 1.0f;
  351. if (freq <= lower_limit || freq >= upper_limit)
  352. return 0.0f;
  353. if (freq <= lower_limit + lower_width)
  354. return (1.0f - cosf(M_PI * (freq - lower_limit) / lower_width)) / 2.0f;
  355. return (1.0f - cosf(M_PI * (freq - upper_limit) / upper_width)) / 2.0f;
  356. }
  357. /*
  358. * Compute Parameters of SUBnote for each tick
  359. */
  360. void SUBnote::computecurrentparameters()
  361. {
  362. if(FreqEnvelope || BandWidthEnvelope
  363. || (oldpitchwheel != ctl.pitchwheel.data)
  364. || (oldbandwidth != ctl.bandwidth.data)
  365. || portamento) {
  366. float envfreq = 1.0f;
  367. float envbw = 1.0f;
  368. float gain = 1.0f;
  369. if(FreqEnvelope) {
  370. envfreq = FreqEnvelope->envout() / 1200;
  371. envfreq = powf(2.0f, envfreq);
  372. }
  373. envfreq *= ctl.pitchwheel.relfreq; //pitch wheel
  374. if(portamento) { //portamento is used
  375. envfreq *= ctl.portamento.freqrap;
  376. if(!ctl.portamento.used) //the portamento has finished
  377. portamento = false; //this note is no longer "portamented"
  378. }
  379. if(BandWidthEnvelope) {
  380. envbw = BandWidthEnvelope->envout();
  381. envbw = powf(2, envbw);
  382. }
  383. envbw *= ctl.bandwidth.relbw; //bandwidth controller
  384. float tmpgain = 1.0f / sqrt(envbw * envfreq);
  385. for(int n = 0; n < numharmonics; ++n) {
  386. overtone_rolloff[n] = computerolloff(overtone_freq[n] * envfreq);
  387. }
  388. for(int n = 0; n < numharmonics; ++n)
  389. for(int nph = 0; nph < numstages; ++nph) {
  390. if(nph == 0)
  391. gain = tmpgain;
  392. else
  393. gain = 1.0f;
  394. computefiltercoefs(lfilter[nph + n * numstages],
  395. lfilter[nph + n * numstages].freq * envfreq,
  396. lfilter[nph + n * numstages].bw * envbw,
  397. gain);
  398. }
  399. if(stereo)
  400. for(int n = 0; n < numharmonics; ++n)
  401. for(int nph = 0; nph < numstages; ++nph) {
  402. if(nph == 0)
  403. gain = tmpgain;
  404. else
  405. gain = 1.0f;
  406. computefiltercoefs(
  407. rfilter[nph + n * numstages],
  408. rfilter[nph + n * numstages].freq * envfreq,
  409. rfilter[nph + n * numstages].bw * envbw,
  410. gain);
  411. }
  412. oldbandwidth = ctl.bandwidth.data;
  413. oldpitchwheel = ctl.pitchwheel.data;
  414. }
  415. newamplitude = volume * AmpEnvelope->envout_dB() * 2.0f;
  416. //Filter
  417. if(GlobalFilterL != NULL) {
  418. float globalfilterpitch = GlobalFilterCenterPitch
  419. + GlobalFilterEnvelope->envout();
  420. float filterfreq = globalfilterpitch + ctl.filtercutoff.relfreq
  421. + GlobalFilterFreqTracking;
  422. filterfreq = Filter::getrealfreq(filterfreq);
  423. GlobalFilterL->setfreq_and_q(filterfreq,
  424. globalfiltercenterq * ctl.filterq.relq);
  425. if(GlobalFilterR != NULL)
  426. GlobalFilterR->setfreq_and_q(
  427. filterfreq,
  428. globalfiltercenterq
  429. * ctl.filterq.relq);
  430. }
  431. }
  432. /*
  433. * Note Output
  434. */
  435. int SUBnote::noteout(float *outl, float *outr)
  436. {
  437. memcpy(outl, synth.denormalkillbuf, synth.bufferbytes);
  438. memcpy(outr, synth.denormalkillbuf, synth.bufferbytes);
  439. if(NoteEnabled == OFF)
  440. return 0;
  441. float tmprnd[synth.buffersize];
  442. float tmpsmp[synth.buffersize];
  443. //left channel
  444. for(int i = 0; i < synth.buffersize; ++i)
  445. tmprnd[i] = RND * 2.0f - 1.0f;
  446. for(int n = 0; n < numharmonics; ++n) {
  447. float rolloff = overtone_rolloff[n];
  448. memcpy(tmpsmp, tmprnd, synth.bufferbytes);
  449. for(int nph = 0; nph < numstages; ++nph)
  450. filter(lfilter[nph + n * numstages], tmpsmp);
  451. for(int i = 0; i < synth.buffersize; ++i)
  452. outl[i] += tmpsmp[i] * rolloff;
  453. }
  454. if(GlobalFilterL != NULL)
  455. GlobalFilterL->filterout(&outl[0]);
  456. //right channel
  457. if(stereo) {
  458. for(int i = 0; i < synth.buffersize; ++i)
  459. tmprnd[i] = RND * 2.0f - 1.0f;
  460. for(int n = 0; n < numharmonics; ++n) {
  461. float rolloff = overtone_rolloff[n];
  462. memcpy(tmpsmp, tmprnd, synth.bufferbytes);
  463. for(int nph = 0; nph < numstages; ++nph)
  464. filter(rfilter[nph + n * numstages], tmpsmp);
  465. for(int i = 0; i < synth.buffersize; ++i)
  466. outr[i] += tmpsmp[i] * rolloff;
  467. }
  468. if(GlobalFilterR != NULL)
  469. GlobalFilterR->filterout(&outr[0]);
  470. }
  471. else
  472. memcpy(outr, outl, synth.bufferbytes);
  473. if(firsttick != 0) {
  474. int n = 10;
  475. if(n > synth.buffersize)
  476. n = synth.buffersize;
  477. for(int i = 0; i < n; ++i) {
  478. float ampfadein = 0.5f - 0.5f * cosf(
  479. (float) i / (float) n * PI);
  480. outl[i] *= ampfadein;
  481. outr[i] *= ampfadein;
  482. }
  483. firsttick = 0;
  484. }
  485. if(ABOVE_AMPLITUDE_THRESHOLD(oldamplitude, newamplitude))
  486. // Amplitude interpolation
  487. for(int i = 0; i < synth.buffersize; ++i) {
  488. float tmpvol = INTERPOLATE_AMPLITUDE(oldamplitude,
  489. newamplitude,
  490. i,
  491. synth.buffersize);
  492. outl[i] *= tmpvol * panning;
  493. outr[i] *= tmpvol * (1.0f - panning);
  494. }
  495. else
  496. for(int i = 0; i < synth.buffersize; ++i) {
  497. outl[i] *= newamplitude * panning;
  498. outr[i] *= newamplitude * (1.0f - panning);
  499. }
  500. oldamplitude = newamplitude;
  501. computecurrentparameters();
  502. // Apply legato-specific sound signal modifications
  503. legato.apply(*this, outl, outr);
  504. // Check if the note needs to be computed more
  505. if(AmpEnvelope->finished() != 0) {
  506. for(int i = 0; i < synth.buffersize; ++i) { //fade-out
  507. float tmp = 1.0f - (float)i / synth.buffersize_f;
  508. outl[i] *= tmp;
  509. outr[i] *= tmp;
  510. }
  511. KillNote();
  512. }
  513. return 1;
  514. }
  515. /*
  516. * Release Key (Note Off)
  517. */
  518. void SUBnote::releasekey()
  519. {
  520. AmpEnvelope->releasekey();
  521. if(FreqEnvelope)
  522. FreqEnvelope->releasekey();
  523. if(BandWidthEnvelope)
  524. BandWidthEnvelope->releasekey();
  525. if(GlobalFilterEnvelope)
  526. GlobalFilterEnvelope->releasekey();
  527. }
  528. /*
  529. * Check if the note is finished
  530. */
  531. int SUBnote::finished() const
  532. {
  533. if(NoteEnabled == OFF)
  534. return 1;
  535. else
  536. return 0;
  537. }