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.

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