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.

1901 lines
70KB

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