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.

1820 lines
66KB

  1. /*
  2. ZynAddSubFX - a software synthesizer
  3. ADnote.cpp - The "additive" 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 <cstring>
  21. #include <cassert>
  22. #include <stdint.h>
  23. #include "../globals.h"
  24. #include "../Misc/Util.h"
  25. #include "../DSP/Filter.h"
  26. #include "OscilGen.h"
  27. #include "ADnote.h"
  28. ADnote::ADnote(ADnoteParameters *pars,
  29. Controller *ctl_,
  30. float freq,
  31. float velocity,
  32. int portamento_,
  33. int midinote_,
  34. bool besilent)
  35. :SynthNote(freq, velocity, portamento_, midinote_, besilent)
  36. {
  37. tmpwavel = new float [synth->buffersize];
  38. tmpwaver = new float [synth->buffersize];
  39. bypassl = new float [synth->buffersize];
  40. bypassr = new float [synth->buffersize];
  41. partparams = pars;
  42. ctl = ctl_;
  43. portamento = portamento_;
  44. midinote = midinote_;
  45. NoteEnabled = ON;
  46. basefreq = freq;
  47. if(velocity > 1.0f)
  48. velocity = 1.0f;
  49. this->velocity = velocity;
  50. time = 0.0f;
  51. stereo = pars->GlobalPar.PStereo;
  52. NoteGlobalPar.Detune = getdetune(pars->GlobalPar.PDetuneType,
  53. pars->GlobalPar.PCoarseDetune,
  54. pars->GlobalPar.PDetune);
  55. bandwidthDetuneMultiplier = pars->getBandwidthDetuneMultiplier();
  56. if(pars->GlobalPar.PPanning == 0)
  57. NoteGlobalPar.Panning = RND;
  58. else
  59. NoteGlobalPar.Panning = pars->GlobalPar.PPanning / 128.0f;
  60. NoteGlobalPar.FilterCenterPitch = pars->GlobalPar.GlobalFilter->getfreq() //center freq
  61. + pars->GlobalPar.PFilterVelocityScale
  62. / 127.0f * 6.0f //velocity sensing
  63. * (VelF(velocity,
  64. pars->GlobalPar.
  65. PFilterVelocityScaleFunction) - 1);
  66. if(pars->GlobalPar.PPunchStrength != 0) {
  67. NoteGlobalPar.Punch.Enabled = 1;
  68. NoteGlobalPar.Punch.t = 1.0f; //start from 1.0f and to 0.0f
  69. NoteGlobalPar.Punch.initialvalue =
  70. ((powf(10, 1.5f * pars->GlobalPar.PPunchStrength / 127.0f) - 1.0f)
  71. * VelF(velocity,
  72. pars->GlobalPar.PPunchVelocitySensing));
  73. float time =
  74. powf(10, 3.0f * pars->GlobalPar.PPunchTime / 127.0f) / 10000.0f; //0.1f .. 100 ms
  75. float stretch = powf(440.0f / freq,
  76. pars->GlobalPar.PPunchStretch / 64.0f);
  77. NoteGlobalPar.Punch.dt = 1.0f / (time * synth->samplerate_f * stretch);
  78. }
  79. else
  80. NoteGlobalPar.Punch.Enabled = 0;
  81. for(int nvoice = 0; nvoice < NUM_VOICES; ++nvoice) {
  82. pars->VoicePar[nvoice].OscilSmp->newrandseed(prng());
  83. NoteVoicePar[nvoice].OscilSmp = NULL;
  84. NoteVoicePar[nvoice].FMSmp = NULL;
  85. NoteVoicePar[nvoice].VoiceOut = NULL;
  86. NoteVoicePar[nvoice].FMVoice = -1;
  87. unison_size[nvoice] = 1;
  88. if(pars->VoicePar[nvoice].Enabled == 0) {
  89. NoteVoicePar[nvoice].Enabled = OFF;
  90. continue; //the voice is disabled
  91. }
  92. unison_stereo_spread[nvoice] =
  93. pars->VoicePar[nvoice].Unison_stereo_spread / 127.0f;
  94. int unison = pars->VoicePar[nvoice].Unison_size;
  95. if(unison < 1)
  96. unison = 1;
  97. //compute unison
  98. unison_size[nvoice] = unison;
  99. unison_base_freq_rap[nvoice] = new float[unison];
  100. unison_freq_rap[nvoice] = new float[unison];
  101. unison_invert_phase[nvoice] = new bool[unison];
  102. float unison_spread = pars->getUnisonFrequencySpreadCents(
  103. nvoice);
  104. float unison_real_spread = powf(2.0f, (unison_spread * 0.5f) / 1200.0f);
  105. float unison_vibratto_a = pars->VoicePar[nvoice].Unison_vibratto
  106. / 127.0f; //0.0f .. 1.0f
  107. switch(unison) {
  108. case 1:
  109. unison_base_freq_rap[nvoice][0] = 1.0f; //if the unison is not used, always make the only subvoice to have the default note
  110. break;
  111. case 2: { //unison for 2 subvoices
  112. unison_base_freq_rap[nvoice][0] = 1.0f / unison_real_spread;
  113. unison_base_freq_rap[nvoice][1] = unison_real_spread;
  114. };
  115. break;
  116. default: { //unison for more than 2 subvoices
  117. float unison_values[unison];
  118. float min = -1e-6, max = 1e-6;
  119. for(int k = 0; k < unison; ++k) {
  120. float step = (k / (float) (unison - 1)) * 2.0f - 1.0f; //this makes the unison spread more uniform
  121. float val = step + (RND * 2.0f - 1.0f) / (unison - 1);
  122. unison_values[k] = val;
  123. if (min > val) {
  124. min = val;
  125. }
  126. if (max < val) {
  127. max = val;
  128. }
  129. }
  130. float diff = max - min;
  131. for(int k = 0; k < unison; ++k) {
  132. unison_values[k] =
  133. (unison_values[k] - (max + min) * 0.5f) / diff; //the lowest value will be -1 and the highest will be 1
  134. unison_base_freq_rap[nvoice][k] =
  135. powf(2.0f, (unison_spread * unison_values[k]) / 1200);
  136. }
  137. };
  138. }
  139. //unison vibrattos
  140. if(unison > 1)
  141. for(int k = 0; k < unison; ++k) //reduce the frequency difference for larger vibrattos
  142. unison_base_freq_rap[nvoice][k] = 1.0f
  143. + (unison_base_freq_rap[
  144. nvoice][k] - 1.0f)
  145. * (1.0f - unison_vibratto_a);
  146. unison_vibratto[nvoice].step = new float[unison];
  147. unison_vibratto[nvoice].position = new float[unison];
  148. unison_vibratto[nvoice].amplitude =
  149. (unison_real_spread - 1.0f) * unison_vibratto_a;
  150. float increments_per_second = synth->samplerate_f / synth->buffersize_f;
  151. float vibratto_base_period = 0.25f
  152. * powf(
  153. 2.0f,
  154. (1.0f
  155. - pars->VoicePar[nvoice].
  156. Unison_vibratto_speed
  157. / 127.0f) * 4.0f);
  158. for(int k = 0; k < unison; ++k) {
  159. unison_vibratto[nvoice].position[k] = RND * 1.8f - 0.9f;
  160. //make period to vary randomly from 50% to 200% vibratto base period
  161. float vibratto_period = vibratto_base_period
  162. * powf(2.0f, RND * 2.0f - 1.0f);
  163. float m = 4.0f / (vibratto_period * increments_per_second);
  164. if(RND < 0.5f)
  165. m = -m;
  166. unison_vibratto[nvoice].step[k] = m;
  167. }
  168. if(unison == 1) { //no vibratto for a single voice
  169. unison_vibratto[nvoice].step[0] = 0.0f;
  170. unison_vibratto[nvoice].position[0] = 0.0f;
  171. unison_vibratto[nvoice].amplitude = 0.0f;
  172. }
  173. //phase invert for unison
  174. unison_invert_phase[nvoice][0] = false;
  175. if(unison != 1) {
  176. int inv = pars->VoicePar[nvoice].Unison_invert_phase;
  177. switch(inv) {
  178. case 0: for(int k = 0; k < unison; ++k)
  179. unison_invert_phase[nvoice][k] = false;
  180. break;
  181. case 1: for(int k = 0; k < unison; ++k)
  182. unison_invert_phase[nvoice][k] = (RND > 0.5f);
  183. break;
  184. default: for(int k = 0; k < unison; ++k)
  185. unison_invert_phase[nvoice][k] =
  186. (k % inv == 0) ? true : false;
  187. break;
  188. }
  189. }
  190. oscfreqhi[nvoice] = new int[unison];
  191. oscfreqlo[nvoice] = new float[unison];
  192. oscfreqhiFM[nvoice] = new unsigned int[unison];
  193. oscfreqloFM[nvoice] = new float[unison];
  194. oscposhi[nvoice] = new int[unison];
  195. oscposlo[nvoice] = new float[unison];
  196. oscposhiFM[nvoice] = new unsigned int[unison];
  197. oscposloFM[nvoice] = new float[unison];
  198. NoteVoicePar[nvoice].Enabled = ON;
  199. NoteVoicePar[nvoice].fixedfreq = pars->VoicePar[nvoice].Pfixedfreq;
  200. NoteVoicePar[nvoice].fixedfreqET = pars->VoicePar[nvoice].PfixedfreqET;
  201. //use the Globalpars.detunetype if the detunetype is 0
  202. if(pars->VoicePar[nvoice].PDetuneType != 0) {
  203. NoteVoicePar[nvoice].Detune = getdetune(
  204. pars->VoicePar[nvoice].PDetuneType,
  205. pars->VoicePar[nvoice].
  206. PCoarseDetune,
  207. 8192); //coarse detune
  208. NoteVoicePar[nvoice].FineDetune = getdetune(
  209. pars->VoicePar[nvoice].PDetuneType,
  210. 0,
  211. pars->VoicePar[nvoice].PDetune); //fine detune
  212. }
  213. else {
  214. NoteVoicePar[nvoice].Detune = getdetune(
  215. pars->GlobalPar.PDetuneType,
  216. pars->VoicePar[nvoice].
  217. PCoarseDetune,
  218. 8192); //coarse detune
  219. NoteVoicePar[nvoice].FineDetune = getdetune(
  220. pars->GlobalPar.PDetuneType,
  221. 0,
  222. pars->VoicePar[nvoice].PDetune); //fine detune
  223. }
  224. if(pars->VoicePar[nvoice].PFMDetuneType != 0)
  225. NoteVoicePar[nvoice].FMDetune = getdetune(
  226. pars->VoicePar[nvoice].PFMDetuneType,
  227. pars->VoicePar[nvoice].
  228. PFMCoarseDetune,
  229. pars->VoicePar[nvoice].PFMDetune);
  230. else
  231. NoteVoicePar[nvoice].FMDetune = getdetune(
  232. pars->GlobalPar.PDetuneType,
  233. pars->VoicePar[nvoice].
  234. PFMCoarseDetune,
  235. pars->VoicePar[nvoice].PFMDetune);
  236. for(int k = 0; k < unison; ++k) {
  237. oscposhi[nvoice][k] = 0;
  238. oscposlo[nvoice][k] = 0.0f;
  239. oscposhiFM[nvoice][k] = 0;
  240. oscposloFM[nvoice][k] = 0.0f;
  241. }
  242. //the extra points contains the first point
  243. NoteVoicePar[nvoice].OscilSmp =
  244. new float[synth->oscilsize + OSCIL_SMP_EXTRA_SAMPLES];
  245. //Get the voice's oscil or external's voice oscil
  246. int vc = nvoice;
  247. if(pars->VoicePar[nvoice].Pextoscil != -1)
  248. vc = pars->VoicePar[nvoice].Pextoscil;
  249. if(!pars->GlobalPar.Hrandgrouping)
  250. pars->VoicePar[vc].OscilSmp->newrandseed(prng());
  251. int oscposhi_start =
  252. pars->VoicePar[vc].OscilSmp->get(NoteVoicePar[nvoice].OscilSmp,
  253. getvoicebasefreq(nvoice),
  254. pars->VoicePar[nvoice].Presonance);
  255. //I store the first elments to the last position for speedups
  256. for(int i = 0; i < OSCIL_SMP_EXTRA_SAMPLES; ++i)
  257. NoteVoicePar[nvoice].OscilSmp[synth->oscilsize
  258. + i] =
  259. NoteVoicePar[nvoice].OscilSmp[i];
  260. oscposhi_start +=
  261. (int)((pars->VoicePar[nvoice].Poscilphase
  262. - 64.0f) / 128.0f * synth->oscilsize + synth->oscilsize * 4);
  263. oscposhi_start %= synth->oscilsize;
  264. for(int k = 0; k < unison; ++k) {
  265. oscposhi[nvoice][k] = oscposhi_start;
  266. oscposhi_start = (int)(RND * (synth->oscilsize - 1)); //put random starting point for other subvoices
  267. }
  268. NoteVoicePar[nvoice].FreqLfo = NULL;
  269. NoteVoicePar[nvoice].FreqEnvelope = NULL;
  270. NoteVoicePar[nvoice].AmpLfo = NULL;
  271. NoteVoicePar[nvoice].AmpEnvelope = NULL;
  272. NoteVoicePar[nvoice].VoiceFilterL = NULL;
  273. NoteVoicePar[nvoice].VoiceFilterR = NULL;
  274. NoteVoicePar[nvoice].FilterEnvelope = NULL;
  275. NoteVoicePar[nvoice].FilterLfo = NULL;
  276. NoteVoicePar[nvoice].FilterCenterPitch =
  277. pars->VoicePar[nvoice].VoiceFilter->getfreq();
  278. NoteVoicePar[nvoice].filterbypass =
  279. pars->VoicePar[nvoice].Pfilterbypass;
  280. switch(pars->VoicePar[nvoice].PFMEnabled) {
  281. case 1:
  282. NoteVoicePar[nvoice].FMEnabled = MORPH;
  283. break;
  284. case 2:
  285. NoteVoicePar[nvoice].FMEnabled = RING_MOD;
  286. break;
  287. case 3:
  288. NoteVoicePar[nvoice].FMEnabled = PHASE_MOD;
  289. break;
  290. case 4:
  291. NoteVoicePar[nvoice].FMEnabled = FREQ_MOD;
  292. break;
  293. case 5:
  294. NoteVoicePar[nvoice].FMEnabled = PITCH_MOD;
  295. break;
  296. default:
  297. NoteVoicePar[nvoice].FMEnabled = NONE;
  298. }
  299. NoteVoicePar[nvoice].FMVoice = pars->VoicePar[nvoice].PFMVoice;
  300. NoteVoicePar[nvoice].FMFreqEnvelope = NULL;
  301. NoteVoicePar[nvoice].FMAmpEnvelope = NULL;
  302. //Compute the Voice's modulator volume (incl. damping)
  303. float fmvoldamp = powf(440.0f / getvoicebasefreq(
  304. nvoice),
  305. pars->VoicePar[nvoice].PFMVolumeDamp / 64.0f
  306. - 1.0f);
  307. switch(NoteVoicePar[nvoice].FMEnabled) {
  308. case PHASE_MOD:
  309. fmvoldamp =
  310. powf(440.0f / getvoicebasefreq(
  311. nvoice), pars->VoicePar[nvoice].PFMVolumeDamp
  312. / 64.0f);
  313. NoteVoicePar[nvoice].FMVolume =
  314. (expf(pars->VoicePar[nvoice].PFMVolume / 127.0f
  315. * FM_AMP_MULTIPLIER) - 1.0f) * fmvoldamp * 4.0f;
  316. break;
  317. case FREQ_MOD:
  318. NoteVoicePar[nvoice].FMVolume =
  319. (expf(pars->VoicePar[nvoice].PFMVolume / 127.0f
  320. * FM_AMP_MULTIPLIER) - 1.0f) * fmvoldamp * 4.0f;
  321. break;
  322. // case PITCH_MOD:NoteVoicePar[nvoice].FMVolume=(pars->VoicePar[nvoice].PFMVolume/127.0f*8.0f)*fmvoldamp;//???????????
  323. // break;
  324. default:
  325. if(fmvoldamp > 1.0f)
  326. fmvoldamp = 1.0f;
  327. NoteVoicePar[nvoice].FMVolume =
  328. pars->VoicePar[nvoice].PFMVolume
  329. / 127.0f * fmvoldamp;
  330. }
  331. //Voice's modulator velocity sensing
  332. NoteVoicePar[nvoice].FMVolume *=
  333. VelF(velocity,
  334. partparams->VoicePar[nvoice].PFMVelocityScaleFunction);
  335. FMoldsmp[nvoice] = new float [unison];
  336. for(int k = 0; k < unison; ++k)
  337. FMoldsmp[nvoice][k] = 0.0f; //this is for FM (integration)
  338. firsttick[nvoice] = 1;
  339. NoteVoicePar[nvoice].DelayTicks =
  340. (int)((expf(pars->VoicePar[nvoice].PDelay / 127.0f
  341. * logf(50.0f))
  342. - 1.0f) / synth->buffersize_f / 10.0f * synth->samplerate_f);
  343. }
  344. max_unison = 1;
  345. for(int nvoice = 0; nvoice < NUM_VOICES; ++nvoice)
  346. if(unison_size[nvoice] > max_unison)
  347. max_unison = unison_size[nvoice];
  348. tmpwave_unison = new float *[max_unison];
  349. for(int k = 0; k < max_unison; ++k) {
  350. tmpwave_unison[k] = new float[synth->buffersize];
  351. memset(tmpwave_unison[k], 0, synth->bufferbytes);
  352. }
  353. initparameters();
  354. }
  355. // ADlegatonote: This function is (mostly) a copy of ADnote(...) and
  356. // initparameters() stuck together with some lines removed so that it
  357. // only alter the already playing note (to perform legato). It is
  358. // possible I left stuff that is not required for this.
  359. void ADnote::legatonote(float freq, float velocity, int portamento_,
  360. int midinote_, bool externcall)
  361. {
  362. ADnoteParameters *pars = partparams;
  363. // Manage legato stuff
  364. if(legato.update(freq, velocity, portamento_, midinote_, externcall))
  365. return;
  366. portamento = portamento_;
  367. midinote = midinote_;
  368. basefreq = freq;
  369. if(velocity > 1.0f)
  370. velocity = 1.0f;
  371. this->velocity = velocity;
  372. NoteGlobalPar.Detune = getdetune(pars->GlobalPar.PDetuneType,
  373. pars->GlobalPar.PCoarseDetune,
  374. pars->GlobalPar.PDetune);
  375. bandwidthDetuneMultiplier = pars->getBandwidthDetuneMultiplier();
  376. if(pars->GlobalPar.PPanning == 0)
  377. NoteGlobalPar.Panning = RND;
  378. else
  379. NoteGlobalPar.Panning = pars->GlobalPar.PPanning / 128.0f;
  380. //center freq
  381. NoteGlobalPar.FilterCenterPitch = pars->GlobalPar.GlobalFilter->getfreq()
  382. + pars->GlobalPar.PFilterVelocityScale
  383. / 127.0f * 6.0f //velocity sensing
  384. * (VelF(velocity,
  385. pars->GlobalPar.
  386. PFilterVelocityScaleFunction) - 1);
  387. for(int nvoice = 0; nvoice < NUM_VOICES; ++nvoice) {
  388. if(NoteVoicePar[nvoice].Enabled == OFF)
  389. continue; //(gf) Stay the same as first note in legato.
  390. NoteVoicePar[nvoice].fixedfreq = pars->VoicePar[nvoice].Pfixedfreq;
  391. NoteVoicePar[nvoice].fixedfreqET = pars->VoicePar[nvoice].PfixedfreqET;
  392. //use the Globalpars.detunetype if the detunetype is 0
  393. if(pars->VoicePar[nvoice].PDetuneType != 0) {
  394. NoteVoicePar[nvoice].Detune = getdetune(
  395. pars->VoicePar[nvoice].PDetuneType,
  396. pars->VoicePar[nvoice].PCoarseDetune,
  397. 8192); //coarse detune
  398. NoteVoicePar[nvoice].FineDetune = getdetune(
  399. pars->VoicePar[nvoice].PDetuneType,
  400. 0,
  401. pars->VoicePar[nvoice].PDetune); //fine detune
  402. }
  403. else {
  404. NoteVoicePar[nvoice].Detune = getdetune(
  405. pars->GlobalPar.PDetuneType,
  406. pars->VoicePar[nvoice].PCoarseDetune,
  407. 8192); //coarse detune
  408. NoteVoicePar[nvoice].FineDetune = getdetune(
  409. pars->GlobalPar.PDetuneType,
  410. 0,
  411. pars->VoicePar[nvoice].PDetune); //fine detune
  412. }
  413. if(pars->VoicePar[nvoice].PFMDetuneType != 0)
  414. NoteVoicePar[nvoice].FMDetune = getdetune(
  415. pars->VoicePar[nvoice].PFMDetuneType,
  416. pars->VoicePar[nvoice].PFMCoarseDetune,
  417. pars->VoicePar[nvoice].PFMDetune);
  418. else
  419. NoteVoicePar[nvoice].FMDetune = getdetune(
  420. pars->GlobalPar.PDetuneType,
  421. pars->VoicePar[nvoice].PFMCoarseDetune,
  422. pars->VoicePar[nvoice].PFMDetune);
  423. //Get the voice's oscil or external's voice oscil
  424. int vc = nvoice;
  425. if(pars->VoicePar[nvoice].Pextoscil != -1)
  426. vc = pars->VoicePar[nvoice].Pextoscil;
  427. if(!pars->GlobalPar.Hrandgrouping)
  428. pars->VoicePar[vc].OscilSmp->newrandseed(prng());
  429. pars->VoicePar[vc].OscilSmp->get(NoteVoicePar[nvoice].OscilSmp,
  430. getvoicebasefreq(nvoice),
  431. pars->VoicePar[nvoice].Presonance); //(gf)Modif of the above line.
  432. //I store the first elments to the last position for speedups
  433. for(int i = 0; i < OSCIL_SMP_EXTRA_SAMPLES; ++i)
  434. NoteVoicePar[nvoice].OscilSmp[synth->oscilsize
  435. + i] =
  436. NoteVoicePar[nvoice].OscilSmp[i];
  437. NoteVoicePar[nvoice].FilterCenterPitch =
  438. pars->VoicePar[nvoice].VoiceFilter->getfreq();
  439. NoteVoicePar[nvoice].filterbypass =
  440. pars->VoicePar[nvoice].Pfilterbypass;
  441. NoteVoicePar[nvoice].FMVoice = pars->VoicePar[nvoice].PFMVoice;
  442. //Compute the Voice's modulator volume (incl. damping)
  443. float fmvoldamp = powf(440.0f / getvoicebasefreq(nvoice),
  444. pars->VoicePar[nvoice].PFMVolumeDamp / 64.0f
  445. - 1.0f);
  446. switch(NoteVoicePar[nvoice].FMEnabled) {
  447. case PHASE_MOD:
  448. fmvoldamp =
  449. powf(440.0f / getvoicebasefreq(
  450. nvoice), pars->VoicePar[nvoice].PFMVolumeDamp
  451. / 64.0f);
  452. NoteVoicePar[nvoice].FMVolume =
  453. (expf(pars->VoicePar[nvoice].PFMVolume / 127.0f
  454. * FM_AMP_MULTIPLIER) - 1.0f) * fmvoldamp * 4.0f;
  455. break;
  456. case FREQ_MOD:
  457. NoteVoicePar[nvoice].FMVolume =
  458. (expf(pars->VoicePar[nvoice].PFMVolume / 127.0f
  459. * FM_AMP_MULTIPLIER) - 1.0f) * fmvoldamp * 4.0f;
  460. break;
  461. // case PITCH_MOD:NoteVoicePar[nvoice].FMVolume=(pars->VoicePar[nvoice].PFMVolume/127.0f*8.0f)*fmvoldamp;//???????????
  462. // break;
  463. default:
  464. if(fmvoldamp > 1.0f)
  465. fmvoldamp = 1.0f;
  466. NoteVoicePar[nvoice].FMVolume =
  467. pars->VoicePar[nvoice].PFMVolume
  468. / 127.0f * fmvoldamp;
  469. }
  470. //Voice's modulator velocity sensing
  471. NoteVoicePar[nvoice].FMVolume *=
  472. VelF(velocity,
  473. partparams->VoicePar[nvoice].PFMVelocityScaleFunction);
  474. NoteVoicePar[nvoice].DelayTicks =
  475. (int)((expf(pars->VoicePar[nvoice].PDelay / 127.0f
  476. * logf(50.0f))
  477. - 1.0f) / synth->buffersize_f / 10.0f * synth->samplerate_f);
  478. }
  479. /// initparameters();
  480. ///////////////
  481. // Altered content of initparameters():
  482. int tmp[NUM_VOICES];
  483. NoteGlobalPar.Volume = 4.0f
  484. * powf(0.1f, 3.0f
  485. * (1.0f - partparams->GlobalPar.PVolume
  486. / 96.0f)) //-60 dB .. 0 dB
  487. * VelF(
  488. velocity,
  489. partparams->GlobalPar.
  490. PAmpVelocityScaleFunction); //velocity sensing
  491. globalnewamplitude = NoteGlobalPar.Volume
  492. * NoteGlobalPar.AmpEnvelope->envout_dB()
  493. * NoteGlobalPar.AmpLfo->amplfoout();
  494. NoteGlobalPar.FilterQ = partparams->GlobalPar.GlobalFilter->getq();
  495. NoteGlobalPar.FilterFreqTracking =
  496. partparams->GlobalPar.GlobalFilter->getfreqtracking(basefreq);
  497. // Forbids the Modulation Voice to be greater or equal than voice
  498. for(int i = 0; i < NUM_VOICES; ++i)
  499. if(NoteVoicePar[i].FMVoice >= i)
  500. NoteVoicePar[i].FMVoice = -1;
  501. // Voice Parameter init
  502. for(unsigned nvoice = 0; nvoice < NUM_VOICES; ++nvoice) {
  503. if(NoteVoicePar[nvoice].Enabled == 0)
  504. continue;
  505. NoteVoicePar[nvoice].noisetype = partparams->VoicePar[nvoice].Type;
  506. /* Voice Amplitude Parameters Init */
  507. NoteVoicePar[nvoice].Volume =
  508. powf(0.1f, 3.0f
  509. * (1.0f - partparams->VoicePar[nvoice].PVolume / 127.0f)) // -60 dB .. 0 dB
  510. * VelF(velocity,
  511. partparams->VoicePar[nvoice].PAmpVelocityScaleFunction); //velocity
  512. if(partparams->VoicePar[nvoice].PVolumeminus != 0)
  513. NoteVoicePar[nvoice].Volume = -NoteVoicePar[nvoice].Volume;
  514. if(partparams->VoicePar[nvoice].PPanning == 0)
  515. NoteVoicePar[nvoice].Panning = RND; // random panning
  516. else
  517. NoteVoicePar[nvoice].Panning =
  518. partparams->VoicePar[nvoice].PPanning / 128.0f;
  519. newamplitude[nvoice] = 1.0f;
  520. if((partparams->VoicePar[nvoice].PAmpEnvelopeEnabled != 0)
  521. && (NoteVoicePar[nvoice].AmpEnvelope != NULL))
  522. newamplitude[nvoice] *= NoteVoicePar[nvoice].AmpEnvelope->envout_dB();
  523. if((partparams->VoicePar[nvoice].PAmpLfoEnabled != 0)
  524. && (NoteVoicePar[nvoice].AmpLfo != NULL))
  525. newamplitude[nvoice] *= NoteVoicePar[nvoice].AmpLfo->amplfoout();
  526. NoteVoicePar[nvoice].FilterFreqTracking =
  527. partparams->VoicePar[nvoice].VoiceFilter->getfreqtracking(basefreq);
  528. /* Voice Modulation Parameters Init */
  529. if((NoteVoicePar[nvoice].FMEnabled != NONE)
  530. && (NoteVoicePar[nvoice].FMVoice < 0)) {
  531. partparams->VoicePar[nvoice].FMSmp->newrandseed(prng());
  532. //Perform Anti-aliasing only on MORPH or RING MODULATION
  533. int vc = nvoice;
  534. if(partparams->VoicePar[nvoice].PextFMoscil != -1)
  535. vc = partparams->VoicePar[nvoice].PextFMoscil;
  536. if(!partparams->GlobalPar.Hrandgrouping)
  537. partparams->VoicePar[vc].FMSmp->newrandseed(prng());
  538. for(int i = 0; i < OSCIL_SMP_EXTRA_SAMPLES; ++i)
  539. NoteVoicePar[nvoice].FMSmp[synth->oscilsize + i] =
  540. NoteVoicePar[nvoice].FMSmp[i];
  541. }
  542. FMnewamplitude[nvoice] = NoteVoicePar[nvoice].FMVolume
  543. * ctl->fmamp.relamp;
  544. if((partparams->VoicePar[nvoice].PFMAmpEnvelopeEnabled != 0)
  545. && (NoteVoicePar[nvoice].FMAmpEnvelope != NULL))
  546. FMnewamplitude[nvoice] *=
  547. NoteVoicePar[nvoice].FMAmpEnvelope->envout_dB();
  548. }
  549. for(int nvoice = 0; nvoice < NUM_VOICES; ++nvoice) {
  550. for(unsigned i = nvoice + 1; i < NUM_VOICES; ++i)
  551. tmp[i] = 0;
  552. for(unsigned i = nvoice + 1; i < NUM_VOICES; ++i)
  553. if((NoteVoicePar[i].FMVoice == nvoice) && (tmp[i] == 0))
  554. tmp[i] = 1;
  555. }
  556. }
  557. /*
  558. * Kill a voice of ADnote
  559. */
  560. void ADnote::KillVoice(int nvoice)
  561. {
  562. delete [] oscfreqhi[nvoice];
  563. delete [] oscfreqlo[nvoice];
  564. delete [] oscfreqhiFM[nvoice];
  565. delete [] oscfreqloFM[nvoice];
  566. delete [] oscposhi[nvoice];
  567. delete [] oscposlo[nvoice];
  568. delete [] oscposhiFM[nvoice];
  569. delete [] oscposloFM[nvoice];
  570. delete [] unison_base_freq_rap[nvoice];
  571. delete [] unison_freq_rap[nvoice];
  572. delete [] unison_invert_phase[nvoice];
  573. delete [] FMoldsmp[nvoice];
  574. delete [] unison_vibratto[nvoice].step;
  575. delete [] unison_vibratto[nvoice].position;
  576. NoteVoicePar[nvoice].kill();
  577. }
  578. /*
  579. * Kill the note
  580. */
  581. void ADnote::KillNote()
  582. {
  583. for(unsigned nvoice = 0; nvoice < NUM_VOICES; ++nvoice) {
  584. if(NoteVoicePar[nvoice].Enabled == ON)
  585. KillVoice(nvoice);
  586. if(NoteVoicePar[nvoice].VoiceOut)
  587. delete NoteVoicePar[nvoice].VoiceOut;
  588. NoteVoicePar[nvoice].VoiceOut = NULL;
  589. }
  590. NoteGlobalPar.kill();
  591. NoteEnabled = OFF;
  592. }
  593. ADnote::~ADnote()
  594. {
  595. if(NoteEnabled == ON)
  596. KillNote();
  597. delete [] tmpwavel;
  598. delete [] tmpwaver;
  599. delete [] bypassl;
  600. delete [] bypassr;
  601. for(int k = 0; k < max_unison; ++k)
  602. delete[] tmpwave_unison[k];
  603. delete[] tmpwave_unison;
  604. }
  605. /*
  606. * Init the parameters
  607. */
  608. void ADnote::initparameters()
  609. {
  610. int tmp[NUM_VOICES];
  611. // Global Parameters
  612. NoteGlobalPar.initparameters(partparams->GlobalPar, basefreq, velocity,
  613. stereo);
  614. NoteGlobalPar.AmpEnvelope->envout_dB(); //discard the first envelope output
  615. globalnewamplitude = NoteGlobalPar.Volume
  616. * NoteGlobalPar.AmpEnvelope->envout_dB()
  617. * NoteGlobalPar.AmpLfo->amplfoout();
  618. // Forbids the Modulation Voice to be greater or equal than voice
  619. for(int i = 0; i < NUM_VOICES; ++i)
  620. if(NoteVoicePar[i].FMVoice >= i)
  621. NoteVoicePar[i].FMVoice = -1;
  622. // Voice Parameter init
  623. for(int nvoice = 0; nvoice < NUM_VOICES; ++nvoice) {
  624. Voice &vce = NoteVoicePar[nvoice];
  625. ADnoteVoiceParam &param = partparams->VoicePar[nvoice];
  626. if(vce.Enabled == 0)
  627. continue;
  628. vce.noisetype = param.Type;
  629. /* Voice Amplitude Parameters Init */
  630. vce.Volume = powf(0.1f, 3.0f * (1.0f - param.PVolume / 127.0f)) // -60dB..0dB
  631. * VelF(velocity, param.PAmpVelocityScaleFunction);
  632. if(param.PVolumeminus)
  633. vce.Volume = -vce.Volume;
  634. if(param.PPanning == 0)
  635. vce.Panning = RND; // random panning
  636. else
  637. vce.Panning = param.PPanning / 128.0f;
  638. newamplitude[nvoice] = 1.0f;
  639. if(param.PAmpEnvelopeEnabled) {
  640. vce.AmpEnvelope = new Envelope(param.AmpEnvelope, basefreq);
  641. vce.AmpEnvelope->envout_dB(); //discard the first envelope sample
  642. newamplitude[nvoice] *= vce.AmpEnvelope->envout_dB();
  643. }
  644. if(param.PAmpLfoEnabled) {
  645. vce.AmpLfo = new LFO(param.AmpLfo, basefreq);
  646. newamplitude[nvoice] *= vce.AmpLfo->amplfoout();
  647. }
  648. /* Voice Frequency Parameters Init */
  649. if(param.PFreqEnvelopeEnabled != 0)
  650. vce.FreqEnvelope = new Envelope(param.FreqEnvelope, basefreq);
  651. if(param.PFreqLfoEnabled != 0)
  652. vce.FreqLfo = new LFO(param.FreqLfo, basefreq);
  653. /* Voice Filter Parameters Init */
  654. if(param.PFilterEnabled != 0) {
  655. vce.VoiceFilterL = Filter::generate(param.VoiceFilter);
  656. vce.VoiceFilterR = Filter::generate(param.VoiceFilter);
  657. }
  658. if(param.PFilterEnvelopeEnabled != 0)
  659. vce.FilterEnvelope = new Envelope(param.FilterEnvelope, basefreq);
  660. if(param.PFilterLfoEnabled != 0)
  661. vce.FilterLfo = new LFO(param.FilterLfo, basefreq);
  662. vce.FilterFreqTracking =
  663. param.VoiceFilter->getfreqtracking(basefreq);
  664. /* Voice Modulation Parameters Init */
  665. if((vce.FMEnabled != NONE) && (vce.FMVoice < 0)) {
  666. param.FMSmp->newrandseed(prng());
  667. vce.FMSmp = new float[synth->oscilsize + OSCIL_SMP_EXTRA_SAMPLES];
  668. //Perform Anti-aliasing only on MORPH or RING MODULATION
  669. int vc = nvoice;
  670. if(param.PextFMoscil != -1)
  671. vc = param.PextFMoscil;
  672. float tmp = 1.0f;
  673. if((partparams->VoicePar[vc].FMSmp->Padaptiveharmonics != 0)
  674. || (vce.FMEnabled == MORPH)
  675. || (vce.FMEnabled == RING_MOD))
  676. tmp = getFMvoicebasefreq(nvoice);
  677. if(!partparams->GlobalPar.Hrandgrouping)
  678. partparams->VoicePar[vc].FMSmp->newrandseed(prng());
  679. for(int k = 0; k < unison_size[nvoice]; ++k)
  680. oscposhiFM[nvoice][k] = (oscposhi[nvoice][k]
  681. + partparams->VoicePar[vc].FMSmp->get(
  682. vce.FMSmp, tmp))
  683. % synth->oscilsize;
  684. for(int i = 0; i < OSCIL_SMP_EXTRA_SAMPLES; ++i)
  685. vce.FMSmp[synth->oscilsize + i] = vce.FMSmp[i];
  686. int oscposhiFM_add =
  687. (int)((param.PFMoscilphase
  688. - 64.0f) / 128.0f * synth->oscilsize
  689. + synth->oscilsize * 4);
  690. for(int k = 0; k < unison_size[nvoice]; ++k) {
  691. oscposhiFM[nvoice][k] += oscposhiFM_add;
  692. oscposhiFM[nvoice][k] %= synth->oscilsize;
  693. }
  694. }
  695. if(param.PFMFreqEnvelopeEnabled != 0)
  696. vce.FMFreqEnvelope = new Envelope(param.FMFreqEnvelope, basefreq);
  697. FMnewamplitude[nvoice] = vce.FMVolume * ctl->fmamp.relamp;
  698. if(param.PFMAmpEnvelopeEnabled != 0) {
  699. vce.FMAmpEnvelope = new Envelope(param.FMAmpEnvelope,
  700. basefreq);
  701. FMnewamplitude[nvoice] *= vce.FMAmpEnvelope->envout_dB();
  702. }
  703. }
  704. for(int nvoice = 0; nvoice < NUM_VOICES; ++nvoice) {
  705. for(int i = nvoice + 1; i < NUM_VOICES; ++i)
  706. tmp[i] = 0;
  707. for(int i = nvoice + 1; i < NUM_VOICES; ++i)
  708. if((NoteVoicePar[i].FMVoice == nvoice) && (tmp[i] == 0)) {
  709. NoteVoicePar[nvoice].VoiceOut = new float[synth->buffersize];
  710. tmp[i] = 1;
  711. }
  712. if(NoteVoicePar[nvoice].VoiceOut)
  713. memset(NoteVoicePar[nvoice].VoiceOut, 0, synth->bufferbytes);
  714. }
  715. }
  716. /*
  717. * Computes the relative frequency of each unison voice and it's vibratto
  718. * This must be called before setfreq* functions
  719. */
  720. void ADnote::compute_unison_freq_rap(int nvoice) {
  721. if(unison_size[nvoice] == 1) { //no unison
  722. unison_freq_rap[nvoice][0] = 1.0f;
  723. return;
  724. }
  725. float relbw = ctl->bandwidth.relbw * bandwidthDetuneMultiplier;
  726. for(int k = 0; k < unison_size[nvoice]; ++k) {
  727. float pos = unison_vibratto[nvoice].position[k];
  728. float step = unison_vibratto[nvoice].step[k];
  729. pos += step;
  730. if(pos <= -1.0f) {
  731. pos = -1.0f;
  732. step = -step;
  733. }
  734. if(pos >= 1.0f) {
  735. pos = 1.0f;
  736. step = -step;
  737. }
  738. float vibratto_val = (pos - 0.333333333f * pos * pos * pos) * 1.5f; //make the vibratto lfo smoother
  739. unison_freq_rap[nvoice][k] = 1.0f
  740. + ((unison_base_freq_rap[nvoice][k]
  741. - 1.0f) + vibratto_val
  742. * unison_vibratto[nvoice].amplitude)
  743. * relbw;
  744. unison_vibratto[nvoice].position[k] = pos;
  745. step = unison_vibratto[nvoice].step[k] = step;
  746. }
  747. }
  748. /*
  749. * Computes the frequency of an oscillator
  750. */
  751. void ADnote::setfreq(int nvoice, float in_freq)
  752. {
  753. for(int k = 0; k < unison_size[nvoice]; ++k) {
  754. float freq = fabs(in_freq) * unison_freq_rap[nvoice][k];
  755. float speed = freq * synth->oscilsize_f / synth->samplerate_f;
  756. if(speed > synth->oscilsize_f)
  757. speed = synth->oscilsize_f;
  758. F2I(speed, oscfreqhi[nvoice][k]);
  759. oscfreqlo[nvoice][k] = speed - floor(speed);
  760. }
  761. }
  762. /*
  763. * Computes the frequency of an modullator oscillator
  764. */
  765. void ADnote::setfreqFM(int nvoice, float in_freq)
  766. {
  767. for(int k = 0; k < unison_size[nvoice]; ++k) {
  768. float freq = fabs(in_freq) * unison_freq_rap[nvoice][k];
  769. float speed = freq * synth->oscilsize_f / synth->samplerate_f;
  770. if(speed > synth->samplerate_f)
  771. speed = synth->samplerate_f;
  772. F2I(speed, oscfreqhiFM[nvoice][k]);
  773. oscfreqloFM[nvoice][k] = speed - floor(speed);
  774. }
  775. }
  776. /*
  777. * Get Voice base frequency
  778. */
  779. float ADnote::getvoicebasefreq(int nvoice) const
  780. {
  781. float detune = NoteVoicePar[nvoice].Detune / 100.0f
  782. + NoteVoicePar[nvoice].FineDetune / 100.0f
  783. * ctl->bandwidth.relbw * bandwidthDetuneMultiplier
  784. + NoteGlobalPar.Detune / 100.0f;
  785. if(NoteVoicePar[nvoice].fixedfreq == 0)
  786. return this->basefreq * powf(2, detune / 12.0f);
  787. else { //the fixed freq is enabled
  788. float fixedfreq = 440.0f;
  789. int fixedfreqET = NoteVoicePar[nvoice].fixedfreqET;
  790. if(fixedfreqET != 0) { //if the frequency varies according the keyboard note
  791. float tmp =
  792. (midinote
  793. - 69.0f) / 12.0f
  794. * (powf(2.0f, (fixedfreqET - 1) / 63.0f) - 1.0f);
  795. if(fixedfreqET <= 64)
  796. fixedfreq *= powf(2.0f, tmp);
  797. else
  798. fixedfreq *= powf(3.0f, tmp);
  799. }
  800. return fixedfreq * powf(2.0f, detune / 12.0f);
  801. }
  802. }
  803. /*
  804. * Get Voice's Modullator base frequency
  805. */
  806. float ADnote::getFMvoicebasefreq(int nvoice) const
  807. {
  808. float detune = NoteVoicePar[nvoice].FMDetune / 100.0f;
  809. return getvoicebasefreq(nvoice) * powf(2, detune / 12.0f);
  810. }
  811. /*
  812. * Computes all the parameters for each tick
  813. */
  814. void ADnote::computecurrentparameters()
  815. {
  816. int nvoice;
  817. float voicefreq, voicepitch, filterpitch, filterfreq, FMfreq,
  818. FMrelativepitch, globalpitch, globalfilterpitch;
  819. globalpitch = 0.01f * (NoteGlobalPar.FreqEnvelope->envout()
  820. + NoteGlobalPar.FreqLfo->lfoout()
  821. * ctl->modwheel.relmod);
  822. globaloldamplitude = globalnewamplitude;
  823. globalnewamplitude = NoteGlobalPar.Volume
  824. * NoteGlobalPar.AmpEnvelope->envout_dB()
  825. * NoteGlobalPar.AmpLfo->amplfoout();
  826. globalfilterpitch = NoteGlobalPar.FilterEnvelope->envout()
  827. + NoteGlobalPar.FilterLfo->lfoout()
  828. + NoteGlobalPar.FilterCenterPitch;
  829. float tmpfilterfreq = globalfilterpitch + ctl->filtercutoff.relfreq
  830. + NoteGlobalPar.FilterFreqTracking;
  831. tmpfilterfreq = Filter::getrealfreq(tmpfilterfreq);
  832. float globalfilterq = NoteGlobalPar.FilterQ * ctl->filterq.relq;
  833. NoteGlobalPar.GlobalFilterL->setfreq_and_q(tmpfilterfreq, globalfilterq);
  834. if(stereo != 0)
  835. NoteGlobalPar.GlobalFilterR->setfreq_and_q(tmpfilterfreq, globalfilterq);
  836. //compute the portamento, if it is used by this note
  837. float portamentofreqrap = 1.0f;
  838. if(portamento != 0) { //this voice use portamento
  839. portamentofreqrap = ctl->portamento.freqrap;
  840. if(ctl->portamento.used == 0) //the portamento has finished
  841. portamento = 0; //this note is no longer "portamented"
  842. }
  843. //compute parameters for all voices
  844. for(nvoice = 0; nvoice < NUM_VOICES; ++nvoice) {
  845. if(NoteVoicePar[nvoice].Enabled != ON)
  846. continue;
  847. NoteVoicePar[nvoice].DelayTicks -= 1;
  848. if(NoteVoicePar[nvoice].DelayTicks > 0)
  849. continue;
  850. compute_unison_freq_rap(nvoice);
  851. /*******************/
  852. /* Voice Amplitude */
  853. /*******************/
  854. oldamplitude[nvoice] = newamplitude[nvoice];
  855. newamplitude[nvoice] = 1.0f;
  856. if(NoteVoicePar[nvoice].AmpEnvelope != NULL)
  857. newamplitude[nvoice] *= NoteVoicePar[nvoice].AmpEnvelope->envout_dB();
  858. if(NoteVoicePar[nvoice].AmpLfo != NULL)
  859. newamplitude[nvoice] *= NoteVoicePar[nvoice].AmpLfo->amplfoout();
  860. /****************/
  861. /* Voice Filter */
  862. /****************/
  863. if(NoteVoicePar[nvoice].VoiceFilterL != NULL) {
  864. filterpitch = NoteVoicePar[nvoice].FilterCenterPitch;
  865. if(NoteVoicePar[nvoice].FilterEnvelope != NULL)
  866. filterpitch += NoteVoicePar[nvoice].FilterEnvelope->envout();
  867. if(NoteVoicePar[nvoice].FilterLfo != NULL)
  868. filterpitch += NoteVoicePar[nvoice].FilterLfo->lfoout();
  869. filterfreq = filterpitch + NoteVoicePar[nvoice].FilterFreqTracking;
  870. filterfreq = Filter::getrealfreq(filterfreq);
  871. NoteVoicePar[nvoice].VoiceFilterL->setfreq(filterfreq);
  872. if(stereo && NoteVoicePar[nvoice].VoiceFilterR)
  873. NoteVoicePar[nvoice].VoiceFilterR->setfreq(filterfreq);
  874. }
  875. if(NoteVoicePar[nvoice].noisetype == 0) { //compute only if the voice isn't noise
  876. /*******************/
  877. /* Voice Frequency */
  878. /*******************/
  879. voicepitch = 0.0f;
  880. if(NoteVoicePar[nvoice].FreqLfo != NULL)
  881. voicepitch += NoteVoicePar[nvoice].FreqLfo->lfoout() / 100.0f
  882. * ctl->bandwidth.relbw;
  883. if(NoteVoicePar[nvoice].FreqEnvelope != NULL)
  884. voicepitch += NoteVoicePar[nvoice].FreqEnvelope->envout()
  885. / 100.0f;
  886. voicefreq = getvoicebasefreq(nvoice)
  887. * powf(2, (voicepitch + globalpitch) / 12.0f); //Hz frequency
  888. voicefreq *= ctl->pitchwheel.relfreq; //change the frequency by the controller
  889. setfreq(nvoice, voicefreq * portamentofreqrap);
  890. /***************/
  891. /* Modulator */
  892. /***************/
  893. if(NoteVoicePar[nvoice].FMEnabled != NONE) {
  894. FMrelativepitch = NoteVoicePar[nvoice].FMDetune / 100.0f;
  895. if(NoteVoicePar[nvoice].FMFreqEnvelope != NULL)
  896. FMrelativepitch +=
  897. NoteVoicePar[nvoice].FMFreqEnvelope->envout() / 100;
  898. FMfreq =
  899. powf(2.0f, FMrelativepitch
  900. / 12.0f) * voicefreq * portamentofreqrap;
  901. setfreqFM(nvoice, FMfreq);
  902. FMoldamplitude[nvoice] = FMnewamplitude[nvoice];
  903. FMnewamplitude[nvoice] = NoteVoicePar[nvoice].FMVolume
  904. * ctl->fmamp.relamp;
  905. if(NoteVoicePar[nvoice].FMAmpEnvelope != NULL)
  906. FMnewamplitude[nvoice] *=
  907. NoteVoicePar[nvoice].FMAmpEnvelope->envout_dB();
  908. }
  909. }
  910. }
  911. time += synth->buffersize_f / synth->samplerate_f;
  912. }
  913. /*
  914. * Fadein in a way that removes clicks but keep sound "punchy"
  915. */
  916. inline void ADnote::fadein(float *smps) const
  917. {
  918. int zerocrossings = 0;
  919. for(int i = 1; i < synth->buffersize; ++i)
  920. if((smps[i - 1] < 0.0f) && (smps[i] > 0.0f))
  921. zerocrossings++; //this is only the possitive crossings
  922. float tmp = (synth->buffersize_f - 1.0f) / (zerocrossings + 1) / 3.0f;
  923. if(tmp < 8.0f)
  924. tmp = 8.0f;
  925. int n;
  926. F2I(tmp, n); //how many samples is the fade-in
  927. if(n > synth->buffersize)
  928. n = synth->buffersize;
  929. for(int i = 0; i < n; ++i) { //fade-in
  930. float tmp = 0.5f - cosf((float)i / (float) n * PI) * 0.5f;
  931. smps[i] *= tmp;
  932. }
  933. }
  934. /*
  935. * Computes the Oscillator (Without Modulation) - LinearInterpolation
  936. */
  937. /* As the code here is a bit odd due to optimization, here is what happens
  938. * First the current possition and frequency are retrieved from the running
  939. * state. These are broken up into high and low portions to indicate how many
  940. * samples are skipped in one step and how many fractional samples are skipped.
  941. * Outside of this method the fractional samples are just handled with floating
  942. * point code, but that's a bit slower than it needs to be. In this code the low
  943. * portions are known to exist between 0.0 and 1.0 and it is known that they are
  944. * stored in single precision floating point IEEE numbers. This implies that
  945. * a maximum of 24 bits are significant. The below code does your standard
  946. * linear interpolation that you'll see throughout this codebase, but by
  947. * sticking to integers for tracking the overflow of the low portion, around 15%
  948. * of the execution time was shaved off in the ADnote test.
  949. */
  950. inline void ADnote::ComputeVoiceOscillator_LinearInterpolation(int nvoice)
  951. {
  952. for(int k = 0; k < unison_size[nvoice]; ++k) {
  953. int poshi = oscposhi[nvoice][k];
  954. int poslo = oscposlo[nvoice][k] * (1<<24);
  955. int freqhi = oscfreqhi[nvoice][k];
  956. int freqlo = oscfreqlo[nvoice][k] * (1<<24);
  957. float *smps = NoteVoicePar[nvoice].OscilSmp;
  958. float *tw = tmpwave_unison[k];
  959. assert(oscfreqlo[nvoice][k] < 1.0f);
  960. for(int i = 0; i < synth->buffersize; ++i) {
  961. tw[i] = (smps[poshi] * ((1<<24) - poslo) + smps[poshi + 1] * poslo)/(1.0f*(1<<24));
  962. poslo += freqlo;
  963. poshi += freqhi + (poslo>>24);
  964. poslo &= 0xffffff;
  965. poshi &= synth->oscilsize - 1;
  966. }
  967. oscposhi[nvoice][k] = poshi;
  968. oscposlo[nvoice][k] = poslo/(1.0f*(1<<24));
  969. }
  970. }
  971. /*
  972. * Computes the Oscillator (Without Modulation) - CubicInterpolation
  973. *
  974. The differences from the Linear are to little to deserve to be used. This is because I am using a large synth->oscilsize (>512)
  975. inline void ADnote::ComputeVoiceOscillator_CubicInterpolation(int nvoice){
  976. int i,poshi;
  977. float poslo;
  978. poshi=oscposhi[nvoice];
  979. poslo=oscposlo[nvoice];
  980. float *smps=NoteVoicePar[nvoice].OscilSmp;
  981. float xm1,x0,x1,x2,a,b,c;
  982. for (i=0;i<synth->buffersize;i++){
  983. xm1=smps[poshi];
  984. x0=smps[poshi+1];
  985. x1=smps[poshi+2];
  986. x2=smps[poshi+3];
  987. a=(3.0f * (x0-x1) - xm1 + x2) / 2.0f;
  988. b = 2.0f*x1 + xm1 - (5.0f*x0 + x2) / 2.0f;
  989. c = (x1 - xm1) / 2.0f;
  990. tmpwave[i]=(((a * poslo) + b) * poslo + c) * poslo + x0;
  991. printf("a\n");
  992. //tmpwave[i]=smps[poshi]*(1.0f-poslo)+smps[poshi+1]*poslo;
  993. poslo+=oscfreqlo[nvoice];
  994. if (poslo>=1.0f) {
  995. poslo-=1.0f;
  996. poshi++;
  997. };
  998. poshi+=oscfreqhi[nvoice];
  999. poshi&=synth->oscilsize-1;
  1000. };
  1001. oscposhi[nvoice]=poshi;
  1002. oscposlo[nvoice]=poslo;
  1003. };
  1004. */
  1005. /*
  1006. * Computes the Oscillator (Morphing)
  1007. */
  1008. inline void ADnote::ComputeVoiceOscillatorMorph(int nvoice)
  1009. {
  1010. int i;
  1011. float amp;
  1012. ComputeVoiceOscillator_LinearInterpolation(nvoice);
  1013. if(FMnewamplitude[nvoice] > 1.0f)
  1014. FMnewamplitude[nvoice] = 1.0f;
  1015. if(FMoldamplitude[nvoice] > 1.0f)
  1016. FMoldamplitude[nvoice] = 1.0f;
  1017. if(NoteVoicePar[nvoice].FMVoice >= 0) {
  1018. //if I use VoiceOut[] as modullator
  1019. int FMVoice = NoteVoicePar[nvoice].FMVoice;
  1020. for(int k = 0; k < unison_size[nvoice]; ++k) {
  1021. float *tw = tmpwave_unison[k];
  1022. for(i = 0; i < synth->buffersize; ++i) {
  1023. amp = INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice],
  1024. FMnewamplitude[nvoice],
  1025. i,
  1026. synth->buffersize);
  1027. tw[i] = tw[i]
  1028. * (1.0f
  1029. - amp) + amp * NoteVoicePar[FMVoice].VoiceOut[i];
  1030. }
  1031. }
  1032. }
  1033. else
  1034. for(int k = 0; k < unison_size[nvoice]; ++k) {
  1035. int poshiFM = oscposhiFM[nvoice][k];
  1036. float posloFM = oscposloFM[nvoice][k];
  1037. int freqhiFM = oscfreqhiFM[nvoice][k];
  1038. float freqloFM = oscfreqloFM[nvoice][k];
  1039. float *tw = tmpwave_unison[k];
  1040. for(i = 0; i < synth->buffersize; ++i) {
  1041. amp = INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice],
  1042. FMnewamplitude[nvoice],
  1043. i,
  1044. synth->buffersize);
  1045. tw[i] = tw[i] * (1.0f - amp) + amp
  1046. * (NoteVoicePar[nvoice].FMSmp[poshiFM] * (1 - posloFM)
  1047. + NoteVoicePar[nvoice].FMSmp[poshiFM + 1] * posloFM);
  1048. posloFM += freqloFM;
  1049. if(posloFM >= 1.0f) {
  1050. posloFM -= 1.0f;
  1051. poshiFM++;
  1052. }
  1053. poshiFM += freqhiFM;
  1054. poshiFM &= synth->oscilsize - 1;
  1055. }
  1056. oscposhiFM[nvoice][k] = poshiFM;
  1057. oscposloFM[nvoice][k] = posloFM;
  1058. }
  1059. }
  1060. /*
  1061. * Computes the Oscillator (Ring Modulation)
  1062. */
  1063. inline void ADnote::ComputeVoiceOscillatorRingModulation(int nvoice)
  1064. {
  1065. int i;
  1066. float amp;
  1067. ComputeVoiceOscillator_LinearInterpolation(nvoice);
  1068. if(FMnewamplitude[nvoice] > 1.0f)
  1069. FMnewamplitude[nvoice] = 1.0f;
  1070. if(FMoldamplitude[nvoice] > 1.0f)
  1071. FMoldamplitude[nvoice] = 1.0f;
  1072. if(NoteVoicePar[nvoice].FMVoice >= 0)
  1073. // if I use VoiceOut[] as modullator
  1074. for(int k = 0; k < unison_size[nvoice]; ++k) {
  1075. float *tw = tmpwave_unison[k];
  1076. for(i = 0; i < synth->buffersize; ++i) {
  1077. amp = INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice],
  1078. FMnewamplitude[nvoice],
  1079. i,
  1080. synth->buffersize);
  1081. int FMVoice = NoteVoicePar[nvoice].FMVoice;
  1082. tw[i] *= (1.0f - amp) + amp * NoteVoicePar[FMVoice].VoiceOut[i];
  1083. }
  1084. }
  1085. else
  1086. for(int k = 0; k < unison_size[nvoice]; ++k) {
  1087. int poshiFM = oscposhiFM[nvoice][k];
  1088. float posloFM = oscposloFM[nvoice][k];
  1089. int freqhiFM = oscfreqhiFM[nvoice][k];
  1090. float freqloFM = oscfreqloFM[nvoice][k];
  1091. float *tw = tmpwave_unison[k];
  1092. for(i = 0; i < synth->buffersize; ++i) {
  1093. amp = INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice],
  1094. FMnewamplitude[nvoice],
  1095. i,
  1096. synth->buffersize);
  1097. tw[i] *= (NoteVoicePar[nvoice].FMSmp[poshiFM] * (1.0f - posloFM)
  1098. + NoteVoicePar[nvoice].FMSmp[poshiFM
  1099. + 1] * posloFM) * amp
  1100. + (1.0f - amp);
  1101. posloFM += freqloFM;
  1102. if(posloFM >= 1.0f) {
  1103. posloFM -= 1.0f;
  1104. poshiFM++;
  1105. }
  1106. poshiFM += freqhiFM;
  1107. poshiFM &= synth->oscilsize - 1;
  1108. }
  1109. oscposhiFM[nvoice][k] = poshiFM;
  1110. oscposloFM[nvoice][k] = posloFM;
  1111. }
  1112. }
  1113. /*
  1114. * Computes the Oscillator (Phase Modulation or Frequency Modulation)
  1115. */
  1116. inline void ADnote::ComputeVoiceOscillatorFrequencyModulation(int nvoice,
  1117. int FMmode)
  1118. {
  1119. int carposhi = 0;
  1120. int i, FMmodfreqhi = 0;
  1121. float FMmodfreqlo = 0, carposlo = 0;
  1122. if(NoteVoicePar[nvoice].FMVoice >= 0)
  1123. //if I use VoiceOut[] as modulator
  1124. for(int k = 0; k < unison_size[nvoice]; ++k) {
  1125. float *tw = tmpwave_unison[k];
  1126. memcpy(tw, NoteVoicePar[NoteVoicePar[nvoice].FMVoice].VoiceOut,
  1127. synth->bufferbytes);
  1128. }
  1129. else
  1130. //Compute the modulator and store it in tmpwave_unison[][]
  1131. for(int k = 0; k < unison_size[nvoice]; ++k) {
  1132. int poshiFM = oscposhiFM[nvoice][k];
  1133. float posloFM = oscposloFM[nvoice][k];
  1134. int freqhiFM = oscfreqhiFM[nvoice][k];
  1135. float freqloFM = oscfreqloFM[nvoice][k];
  1136. float *tw = tmpwave_unison[k];
  1137. for(i = 0; i < synth->buffersize; ++i) {
  1138. tw[i] =
  1139. (NoteVoicePar[nvoice].FMSmp[poshiFM] * (1.0f - posloFM)
  1140. + NoteVoicePar[nvoice].FMSmp[poshiFM + 1] * posloFM);
  1141. posloFM += freqloFM;
  1142. if(posloFM >= 1.0f) {
  1143. posloFM = fmod(posloFM, 1.0f);
  1144. poshiFM++;
  1145. }
  1146. poshiFM += freqhiFM;
  1147. poshiFM &= synth->oscilsize - 1;
  1148. }
  1149. oscposhiFM[nvoice][k] = poshiFM;
  1150. oscposloFM[nvoice][k] = posloFM;
  1151. }
  1152. // Amplitude interpolation
  1153. if(ABOVE_AMPLITUDE_THRESHOLD(FMoldamplitude[nvoice],
  1154. FMnewamplitude[nvoice]))
  1155. for(int k = 0; k < unison_size[nvoice]; ++k) {
  1156. float *tw = tmpwave_unison[k];
  1157. for(i = 0; i < synth->buffersize; ++i)
  1158. tw[i] *= INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice],
  1159. FMnewamplitude[nvoice],
  1160. i,
  1161. synth->buffersize);
  1162. }
  1163. else
  1164. for(int k = 0; k < unison_size[nvoice]; ++k) {
  1165. float *tw = tmpwave_unison[k];
  1166. for(i = 0; i < synth->buffersize; ++i)
  1167. tw[i] *= FMnewamplitude[nvoice];
  1168. }
  1169. //normalize: makes all sample-rates, oscil_sizes to produce same sound
  1170. if(FMmode != 0) { //Frequency modulation
  1171. float normalize = synth->oscilsize_f / 262144.0f * 44100.0f
  1172. / synth->samplerate_f;
  1173. for(int k = 0; k < unison_size[nvoice]; ++k) {
  1174. float *tw = tmpwave_unison[k];
  1175. float fmold = FMoldsmp[nvoice][k];
  1176. for(i = 0; i < synth->buffersize; ++i) {
  1177. fmold = fmod(fmold + tw[i] * normalize, synth->oscilsize);
  1178. tw[i] = fmold;
  1179. }
  1180. FMoldsmp[nvoice][k] = fmold;
  1181. }
  1182. }
  1183. else { //Phase modulation
  1184. float normalize = synth->oscilsize_f / 262144.0f;
  1185. for(int k = 0; k < unison_size[nvoice]; ++k) {
  1186. float *tw = tmpwave_unison[k];
  1187. for(i = 0; i < synth->buffersize; ++i)
  1188. tw[i] *= normalize;
  1189. }
  1190. }
  1191. //do the modulation
  1192. for(int k = 0; k < unison_size[nvoice]; ++k) {
  1193. float *tw = tmpwave_unison[k];
  1194. int poshi = oscposhi[nvoice][k];
  1195. float poslo = oscposlo[nvoice][k];
  1196. int freqhi = oscfreqhi[nvoice][k];
  1197. float freqlo = oscfreqlo[nvoice][k];
  1198. for(i = 0; i < synth->buffersize; ++i) {
  1199. F2I(tw[i], FMmodfreqhi);
  1200. FMmodfreqlo = fmod(tw[i] + 0.0000000001f, 1.0f);
  1201. if(FMmodfreqhi < 0)
  1202. FMmodfreqlo++;
  1203. //carrier
  1204. carposhi = poshi + FMmodfreqhi;
  1205. carposlo = poslo + FMmodfreqlo;
  1206. if(carposlo >= 1.0f) {
  1207. carposhi++;
  1208. carposlo = fmod(carposlo, 1.0f);
  1209. }
  1210. carposhi &= (synth->oscilsize - 1);
  1211. tw[i] = NoteVoicePar[nvoice].OscilSmp[carposhi]
  1212. * (1.0f - carposlo)
  1213. + NoteVoicePar[nvoice].OscilSmp[carposhi
  1214. + 1] * carposlo;
  1215. poslo += freqlo;
  1216. if(poslo >= 1.0f) {
  1217. poslo = fmod(poslo, 1.0f);
  1218. poshi++;
  1219. }
  1220. poshi += freqhi;
  1221. poshi &= synth->oscilsize - 1;
  1222. }
  1223. oscposhi[nvoice][k] = poshi;
  1224. oscposlo[nvoice][k] = poslo;
  1225. }
  1226. }
  1227. /*Calculeaza Oscilatorul cu PITCH MODULATION*/
  1228. inline void ADnote::ComputeVoiceOscillatorPitchModulation(int /*nvoice*/)
  1229. {
  1230. //TODO
  1231. }
  1232. /*
  1233. * Computes the Noise
  1234. */
  1235. inline void ADnote::ComputeVoiceNoise(int nvoice)
  1236. {
  1237. for(int k = 0; k < unison_size[nvoice]; ++k) {
  1238. float *tw = tmpwave_unison[k];
  1239. for(int i = 0; i < synth->buffersize; ++i)
  1240. tw[i] = RND * 2.0f - 1.0f;
  1241. }
  1242. }
  1243. /*
  1244. * Compute the ADnote samples
  1245. * Returns 0 if the note is finished
  1246. */
  1247. int ADnote::noteout(float *outl, float *outr)
  1248. {
  1249. memcpy(outl, denormalkillbuf, synth->bufferbytes);
  1250. memcpy(outr, denormalkillbuf, synth->bufferbytes);
  1251. if(NoteEnabled == OFF)
  1252. return 0;
  1253. memset(bypassl, 0, synth->bufferbytes);
  1254. memset(bypassr, 0, synth->bufferbytes);
  1255. computecurrentparameters();
  1256. for(unsigned nvoice = 0; nvoice < NUM_VOICES; ++nvoice) {
  1257. if((NoteVoicePar[nvoice].Enabled != ON)
  1258. || (NoteVoicePar[nvoice].DelayTicks > 0))
  1259. continue;
  1260. if(NoteVoicePar[nvoice].noisetype == 0) //voice mode=sound
  1261. switch(NoteVoicePar[nvoice].FMEnabled) {
  1262. case MORPH:
  1263. ComputeVoiceOscillatorMorph(nvoice);
  1264. break;
  1265. case RING_MOD:
  1266. ComputeVoiceOscillatorRingModulation(nvoice);
  1267. break;
  1268. case PHASE_MOD:
  1269. ComputeVoiceOscillatorFrequencyModulation(nvoice, 0);
  1270. break;
  1271. case FREQ_MOD:
  1272. ComputeVoiceOscillatorFrequencyModulation(nvoice, 1);
  1273. break;
  1274. //case PITCH_MOD:ComputeVoiceOscillatorPitchModulation(nvoice);break;
  1275. default:
  1276. ComputeVoiceOscillator_LinearInterpolation(nvoice);
  1277. //if (config.cfg.Interpolation) ComputeVoiceOscillator_CubicInterpolation(nvoice);
  1278. }
  1279. else
  1280. ComputeVoiceNoise(nvoice);
  1281. // Voice Processing
  1282. //mix subvoices into voice
  1283. memset(tmpwavel, 0, synth->bufferbytes);
  1284. if(stereo)
  1285. memset(tmpwaver, 0, synth->bufferbytes);
  1286. for(int k = 0; k < unison_size[nvoice]; ++k) {
  1287. float *tw = tmpwave_unison[k];
  1288. if(stereo) {
  1289. float stereo_pos = 0;
  1290. if(unison_size[nvoice] > 1)
  1291. stereo_pos = k
  1292. / (float)(unison_size[nvoice]
  1293. - 1) * 2.0f - 1.0f;
  1294. float stereo_spread = unison_stereo_spread[nvoice] * 2.0f; //between 0 and 2.0f
  1295. if(stereo_spread > 1.0f) {
  1296. float stereo_pos_1 = (stereo_pos >= 0.0f) ? 1.0f : -1.0f;
  1297. stereo_pos =
  1298. (2.0f
  1299. - stereo_spread) * stereo_pos
  1300. + (stereo_spread - 1.0f) * stereo_pos_1;
  1301. }
  1302. else
  1303. stereo_pos *= stereo_spread;
  1304. if(unison_size[nvoice] == 1)
  1305. stereo_pos = 0.0f;
  1306. float panning = (stereo_pos + 1.0f) * 0.5f;
  1307. float lvol = (1.0f - panning) * 2.0f;
  1308. if(lvol > 1.0f)
  1309. lvol = 1.0f;
  1310. float rvol = panning * 2.0f;
  1311. if(rvol > 1.0f)
  1312. rvol = 1.0f;
  1313. if(unison_invert_phase[nvoice][k]) {
  1314. lvol = -lvol;
  1315. rvol = -rvol;
  1316. }
  1317. for(int i = 0; i < synth->buffersize; ++i)
  1318. tmpwavel[i] += tw[i] * lvol;
  1319. for(int i = 0; i < synth->buffersize; ++i)
  1320. tmpwaver[i] += tw[i] * rvol;
  1321. }
  1322. else
  1323. for(int i = 0; i < synth->buffersize; ++i)
  1324. tmpwavel[i] += tw[i];
  1325. }
  1326. float unison_amplitude = 1.0f / sqrt(unison_size[nvoice]); //reduce the amplitude for large unison sizes
  1327. // Amplitude
  1328. float oldam = oldamplitude[nvoice] * unison_amplitude;
  1329. float newam = newamplitude[nvoice] * unison_amplitude;
  1330. if(ABOVE_AMPLITUDE_THRESHOLD(oldam, newam)) {
  1331. int rest = synth->buffersize;
  1332. //test if the amplitude if raising and the difference is high
  1333. if((newam > oldam) && ((newam - oldam) > 0.25f)) {
  1334. rest = 10;
  1335. if(rest > synth->buffersize)
  1336. rest = synth->buffersize;
  1337. for(int i = 0; i < synth->buffersize - rest; ++i)
  1338. tmpwavel[i] *= oldam;
  1339. if(stereo)
  1340. for(int i = 0; i < synth->buffersize - rest; ++i)
  1341. tmpwaver[i] *= oldam;
  1342. }
  1343. // Amplitude interpolation
  1344. for(int i = 0; i < rest; ++i) {
  1345. float amp = INTERPOLATE_AMPLITUDE(oldam, newam, i, rest);
  1346. tmpwavel[i + (synth->buffersize - rest)] *= amp;
  1347. if(stereo)
  1348. tmpwaver[i + (synth->buffersize - rest)] *= amp;
  1349. }
  1350. }
  1351. else {
  1352. for(int i = 0; i < synth->buffersize; ++i)
  1353. tmpwavel[i] *= newam;
  1354. if(stereo)
  1355. for(int i = 0; i < synth->buffersize; ++i)
  1356. tmpwaver[i] *= newam;
  1357. }
  1358. // Fade in
  1359. if(firsttick[nvoice] != 0) {
  1360. fadein(&tmpwavel[0]);
  1361. if(stereo)
  1362. fadein(&tmpwaver[0]);
  1363. firsttick[nvoice] = 0;
  1364. }
  1365. // Filter
  1366. if(NoteVoicePar[nvoice].VoiceFilterL != NULL)
  1367. NoteVoicePar[nvoice].VoiceFilterL->filterout(&tmpwavel[0]);
  1368. if((stereo) && (NoteVoicePar[nvoice].VoiceFilterR != NULL))
  1369. NoteVoicePar[nvoice].VoiceFilterR->filterout(&tmpwaver[0]);
  1370. //check if the amplitude envelope is finished, if yes, the voice will be fadeout
  1371. if(NoteVoicePar[nvoice].AmpEnvelope != NULL)
  1372. if(NoteVoicePar[nvoice].AmpEnvelope->finished() != 0) {
  1373. for(int i = 0; i < synth->buffersize; ++i)
  1374. tmpwavel[i] *= 1.0f - (float)i / synth->buffersize_f;
  1375. if(stereo)
  1376. for(int i = 0; i < synth->buffersize; ++i)
  1377. tmpwaver[i] *= 1.0f - (float)i / synth->buffersize_f;
  1378. }
  1379. //the voice is killed later
  1380. // Put the ADnote samples in VoiceOut (without appling Global volume, because I wish to use this voice as a modullator)
  1381. if(NoteVoicePar[nvoice].VoiceOut != NULL) {
  1382. if(stereo)
  1383. for(int i = 0; i < synth->buffersize; ++i)
  1384. NoteVoicePar[nvoice].VoiceOut[i] = tmpwavel[i]
  1385. + tmpwaver[i];
  1386. else //mono
  1387. for(int i = 0; i < synth->buffersize; ++i)
  1388. NoteVoicePar[nvoice].VoiceOut[i] = tmpwavel[i];
  1389. }
  1390. // Add the voice that do not bypass the filter to out
  1391. if(NoteVoicePar[nvoice].filterbypass == 0) { //no bypass
  1392. if(stereo)
  1393. for(int i = 0; i < synth->buffersize; ++i) { //stereo
  1394. outl[i] += tmpwavel[i] * NoteVoicePar[nvoice].Volume
  1395. * NoteVoicePar[nvoice].Panning * 2.0f;
  1396. outr[i] += tmpwaver[i] * NoteVoicePar[nvoice].Volume
  1397. * (1.0f - NoteVoicePar[nvoice].Panning) * 2.0f;
  1398. }
  1399. else
  1400. for(int i = 0; i < synth->buffersize; ++i) //mono
  1401. outl[i] += tmpwavel[i] * NoteVoicePar[nvoice].Volume;
  1402. }
  1403. else { //bypass the filter
  1404. if(stereo)
  1405. for(int i = 0; i < synth->buffersize; ++i) { //stereo
  1406. bypassl[i] += tmpwavel[i] * NoteVoicePar[nvoice].Volume
  1407. * NoteVoicePar[nvoice].Panning * 2.0f;
  1408. bypassr[i] += tmpwaver[i] * NoteVoicePar[nvoice].Volume
  1409. * (1.0f
  1410. - NoteVoicePar[nvoice].Panning) * 2.0f;
  1411. }
  1412. else
  1413. for(int i = 0; i < synth->buffersize; ++i) //mono
  1414. bypassl[i] += tmpwavel[i] * NoteVoicePar[nvoice].Volume;
  1415. }
  1416. // chech if there is necesary to proces the voice longer (if the Amplitude envelope isn't finished)
  1417. if(NoteVoicePar[nvoice].AmpEnvelope != NULL)
  1418. if(NoteVoicePar[nvoice].AmpEnvelope->finished() != 0)
  1419. KillVoice(nvoice);
  1420. }
  1421. //Processing Global parameters
  1422. NoteGlobalPar.GlobalFilterL->filterout(&outl[0]);
  1423. if(stereo == 0) { //set the right channel=left channel
  1424. memcpy(outr, outl, synth->bufferbytes);
  1425. memcpy(bypassr, bypassl, synth->bufferbytes);
  1426. }
  1427. else
  1428. NoteGlobalPar.GlobalFilterR->filterout(&outr[0]);
  1429. for(int i = 0; i < synth->buffersize; ++i) {
  1430. outl[i] += bypassl[i];
  1431. outr[i] += bypassr[i];
  1432. }
  1433. if(ABOVE_AMPLITUDE_THRESHOLD(globaloldamplitude, globalnewamplitude))
  1434. // Amplitude Interpolation
  1435. for(int i = 0; i < synth->buffersize; ++i) {
  1436. float tmpvol = INTERPOLATE_AMPLITUDE(globaloldamplitude,
  1437. globalnewamplitude,
  1438. i,
  1439. synth->buffersize);
  1440. outl[i] *= tmpvol * NoteGlobalPar.Panning;
  1441. outr[i] *= tmpvol * (1.0f - NoteGlobalPar.Panning);
  1442. }
  1443. else
  1444. for(int i = 0; i < synth->buffersize; ++i) {
  1445. outl[i] *= globalnewamplitude * NoteGlobalPar.Panning;
  1446. outr[i] *= globalnewamplitude * (1.0f - NoteGlobalPar.Panning);
  1447. }
  1448. //Apply the punch
  1449. if(NoteGlobalPar.Punch.Enabled != 0)
  1450. for(int i = 0; i < synth->buffersize; ++i) {
  1451. float punchamp = NoteGlobalPar.Punch.initialvalue
  1452. * NoteGlobalPar.Punch.t + 1.0f;
  1453. outl[i] *= punchamp;
  1454. outr[i] *= punchamp;
  1455. NoteGlobalPar.Punch.t -= NoteGlobalPar.Punch.dt;
  1456. if(NoteGlobalPar.Punch.t < 0.0f) {
  1457. NoteGlobalPar.Punch.Enabled = 0;
  1458. break;
  1459. }
  1460. }
  1461. // Apply legato-specific sound signal modifications
  1462. legato.apply(*this, outl, outr);
  1463. // Check if the global amplitude is finished.
  1464. // If it does, disable the note
  1465. if(NoteGlobalPar.AmpEnvelope->finished()) {
  1466. for(int i = 0; i < synth->buffersize; ++i) { //fade-out
  1467. float tmp = 1.0f - (float)i / synth->buffersize_f;
  1468. outl[i] *= tmp;
  1469. outr[i] *= tmp;
  1470. }
  1471. KillNote();
  1472. }
  1473. return 1;
  1474. }
  1475. /*
  1476. * Relase the key (NoteOff)
  1477. */
  1478. void ADnote::relasekey()
  1479. {
  1480. for(int nvoice = 0; nvoice < NUM_VOICES; ++nvoice)
  1481. NoteVoicePar[nvoice].releasekey();
  1482. NoteGlobalPar.FreqEnvelope->relasekey();
  1483. NoteGlobalPar.FilterEnvelope->relasekey();
  1484. NoteGlobalPar.AmpEnvelope->relasekey();
  1485. }
  1486. /*
  1487. * Check if the note is finished
  1488. */
  1489. int ADnote::finished() const
  1490. {
  1491. if(NoteEnabled == ON)
  1492. return 0;
  1493. else
  1494. return 1;
  1495. }
  1496. void ADnote::Voice::releasekey()
  1497. {
  1498. if(!Enabled)
  1499. return;
  1500. if(AmpEnvelope)
  1501. AmpEnvelope->relasekey();
  1502. if(FreqEnvelope)
  1503. FreqEnvelope->relasekey();
  1504. if(FilterEnvelope)
  1505. FilterEnvelope->relasekey();
  1506. if(FMFreqEnvelope)
  1507. FMFreqEnvelope->relasekey();
  1508. if(FMAmpEnvelope)
  1509. FMAmpEnvelope->relasekey();
  1510. }
  1511. template<class T>
  1512. static inline void nullify(T &t) {delete t; t = NULL; }
  1513. template<class T>
  1514. static inline void arrayNullify(T &t) {delete [] t; t = NULL; }
  1515. void ADnote::Voice::kill()
  1516. {
  1517. arrayNullify(OscilSmp);
  1518. nullify(FreqEnvelope);
  1519. nullify(FreqLfo);
  1520. nullify(AmpEnvelope);
  1521. nullify(AmpLfo);
  1522. nullify(VoiceFilterL);
  1523. nullify(VoiceFilterR);
  1524. nullify(FilterEnvelope);
  1525. nullify(FilterLfo);
  1526. nullify(FMFreqEnvelope);
  1527. nullify(FMAmpEnvelope);
  1528. if((FMEnabled != NONE) && (FMVoice < 0)) {
  1529. delete[] FMSmp;
  1530. FMSmp = NULL;
  1531. }
  1532. if(VoiceOut)
  1533. memset(VoiceOut, 0, synth->bufferbytes);
  1534. //do not delete, yet: perhaps is used by another voice
  1535. Enabled = OFF;
  1536. }
  1537. void ADnote::Global::kill()
  1538. {
  1539. nullify(FreqEnvelope);
  1540. nullify(FreqLfo);
  1541. nullify(AmpEnvelope);
  1542. nullify(AmpLfo);
  1543. nullify(GlobalFilterL);
  1544. nullify(GlobalFilterR);
  1545. nullify(FilterEnvelope);
  1546. nullify(FilterLfo);
  1547. }
  1548. void ADnote::Global::initparameters(const ADnoteGlobalParam &param,
  1549. float basefreq, float velocity,
  1550. bool stereo)
  1551. {
  1552. FreqEnvelope = new Envelope(param.FreqEnvelope, basefreq);
  1553. FreqLfo = new LFO(param.FreqLfo, basefreq);
  1554. AmpEnvelope = new Envelope(param.AmpEnvelope, basefreq);
  1555. AmpLfo = new LFO(param.AmpLfo, basefreq);
  1556. Volume = 4.0f * powf(0.1f, 3.0f * (1.0f - param.PVolume / 96.0f)) //-60 dB .. 0 dB
  1557. * VelF(velocity, param.PAmpVelocityScaleFunction); //sensing
  1558. GlobalFilterL = Filter::generate(param.GlobalFilter);
  1559. if(stereo)
  1560. GlobalFilterR = Filter::generate(param.GlobalFilter);
  1561. else
  1562. GlobalFilterR = NULL;
  1563. FilterEnvelope = new Envelope(param.FilterEnvelope, basefreq);
  1564. FilterLfo = new LFO(param.FilterLfo, basefreq);
  1565. FilterQ = param.GlobalFilter->getq();
  1566. FilterFreqTracking = param.GlobalFilter->getfreqtracking(basefreq);
  1567. }