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.

1801 lines
67KB

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