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.

1803 lines
65KB

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