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.

1942 lines
72KB

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