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.

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