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.

1854 lines
69KB

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