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.

1226 lines
38KB

  1. /*
  2. ZynAddSubFX - a software synthesizer
  3. ADnoteParameters.cpp - Parameters for ADnote (ADsynth)
  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 <stdlib.h>
  12. #include <stdio.h>
  13. #include <math.h>
  14. #include "ADnoteParameters.h"
  15. #include "EnvelopeParams.h"
  16. #include "LFOParams.h"
  17. #include "../Misc/XMLwrapper.h"
  18. #include "../DSP/FFTwrapper.h"
  19. #include "../Synth/OscilGen.h"
  20. #include "../Synth/Resonance.h"
  21. #include "FilterParams.h"
  22. #include <rtosc/ports.h>
  23. #include <rtosc/port-sugar.h>
  24. using rtosc::Ports;
  25. using rtosc::RtData;
  26. #define EXPAND(x) x
  27. #define rObject ADnoteVoiceParam
  28. #undef rChangeCb
  29. #define rChangeCb if (obj->time) { obj->last_update_timestamp = obj->time->time(); }
  30. static const Ports voicePorts = {
  31. //Send Messages To Oscillator Realtime Table
  32. {"OscilSmp/", rDoc("Primary Oscillator"),
  33. &OscilGen::ports,
  34. rBOIL_BEGIN
  35. if(obj->OscilSmp == NULL) return;
  36. data.obj = obj->OscilSmp;
  37. SNIP
  38. OscilGen::realtime_ports.dispatch(msg, data);
  39. if(data.matches == 0)
  40. data.forward();
  41. rBOIL_END},
  42. {"FMSmp/", rDoc("Modulating Oscillator"),
  43. &OscilGen::ports,
  44. rBOIL_BEGIN
  45. if(obj->FMSmp == NULL) return;
  46. data.obj = obj->FMSmp;
  47. SNIP
  48. OscilGen::realtime_ports.dispatch(msg, data);
  49. if(data.matches == 0)
  50. data.forward();
  51. rBOIL_END},
  52. rRecurp(FreqLfo, "Frequency LFO"),
  53. rRecurp(AmpLfo, "Amplitude LFO"),
  54. rRecurp(FilterLfo, "Filter LFO"),
  55. rRecurp(FreqEnvelope, "Frequency Envelope"),
  56. rRecurp(AmpEnvelope, "Amplitude Envelope"),
  57. rRecurp(FilterEnvelope, "Filter Envelope"),
  58. rRecurp(FMFreqEnvelope, "Modulator Frequency Envelope"),
  59. rRecurp(FMAmpEnvelope, "Modulator Amplitude Envelope"),
  60. rRecurp(VoiceFilter, "Optional Voice Filter"),
  61. rToggle(Enabled, "Voice Enable"),
  62. rParamZyn(Unison_size, "Number of subvoices"),
  63. rParamZyn(Unison_phase_randomness, "Phase Randomness"),
  64. rParamZyn(Unison_frequency_spread, "Subvoice detune"),
  65. rParamZyn(Unison_stereo_spread, "Subvoice L/R Separation"),
  66. rParamZyn(Unison_vibratto, "Subvoice vibratto"),
  67. rParamZyn(Unison_vibratto_speed, "Subvoice vibratto speed"),
  68. rOption(Unison_invert_phase, rOptions(none, random, 50%, 33%, 25%), "Subvoice Phases"),
  69. rOption(Type, rOptions(Sound,White,Pink), "Type of Sound"),
  70. rParamZyn(PDelay, "Voice Startup Delay"),
  71. rToggle(Presonance, "Resonance Enable"),
  72. rParamI(Pextoscil, rMap(min, -1), rMap(max, 16), "External Oscilator Selection"),
  73. rParamI(PextFMoscil, rMap(min, -1), rMap(max, 16), "External FM Oscilator Selection"),
  74. rParamZyn(Poscilphase, "Oscillator Phase"),
  75. rParamZyn(PFMoscilphase, "FM Oscillator Phase"),
  76. rToggle(Pfilterbypass, "Filter Bypass"),
  77. //Freq Stuff
  78. rToggle(Pfixedfreq, "If frequency is fixed"),
  79. rParamZyn(PfixedfreqET, "Equal Tempermant Parameter"),
  80. rParamZyn(PBendAdjust, "Pitch bend adjustment"),
  81. rParamZyn(POffsetHz, "Voice constant offset"),
  82. rParamI(PDetune, "Fine Detune"),
  83. rParamI(PCoarseDetune, "Coarse Detune"),
  84. rParamZyn(PDetuneType, "Magnitude of Detune"),
  85. rToggle(PFreqEnvelopeEnabled, "Frequency Envelope Enable"),
  86. rToggle(PFreqLfoEnabled, "Frequency LFO Enable"),
  87. //Amplitude Stuff
  88. rParamZyn(PPanning, "Panning"),
  89. rParamZyn(PVolume, "Volume"),
  90. rToggle(PVolumeminus, "Signal Inverter"), //do we really need this??
  91. rParamZyn(PAmpVelocityScaleFunction, "Velocity Sensing"),
  92. rToggle(PAmpEnvelopeEnabled, "Amplitude Envelope Enable"),
  93. rToggle(PAmpLfoEnabled, "Amplitude LFO Enable"),
  94. //Filter Stuff
  95. rToggle(PFilterEnabled, "Filter Enable"),
  96. rToggle(PFilterEnvelopeEnabled, "Filter Envelope Enable"),
  97. rToggle(PFilterLfoEnabled, "Filter LFO Enable"),
  98. rParamZyn(PFilterVelocityScale, "Filter Velocity Magnitude"),
  99. rParamZyn(PFilterVelocityScaleFunction, "Filter Velocity Function Shape"),
  100. //Modulator Stuff
  101. rOption(PFMEnabled, rOptions(none, morph, ring modulation, phase modulation,
  102. frequency modulation, pitch modulation), "Modulator mode"),
  103. rParamI(PFMVoice, "Modulator Oscillator Selection"),
  104. rParamZyn(PFMVolume, "Modulator Magnitude"),
  105. rParamZyn(PFMVolumeDamp, "Modulator HF dampening"),
  106. rParamZyn(PFMVelocityScaleFunction, "Modulator Velocity Function"),
  107. rParamI(PFMDetune, "Modulator Fine Detune"),
  108. rParamI(PFMCoarseDetune, "Modulator Coarse Detune"),
  109. rParamZyn(PFMDetuneType, "Modulator Detune Magnitude"),
  110. rToggle(PFMFixedFreq, "Modulator Frequency Fixed"),
  111. rToggle(PFMFreqEnvelopeEnabled, "Modulator Frequency Envelope"),
  112. rToggle(PFMAmpEnvelopeEnabled, "Modulator Amplitude Envelope"),
  113. //weird stuff for PCoarseDetune
  114. {"detunevalue:", rMap(unit,cents) rDoc("Get detune in cents"), NULL,
  115. [](const char *, RtData &d)
  116. {
  117. rObject *obj = (rObject *)d.obj;
  118. unsigned detuneType =
  119. obj->PDetuneType == 0 ? *(obj->GlobalPDetuneType)
  120. : obj->PDetuneType;
  121. //TODO check if this is accurate or if PCoarseDetune is utilized
  122. //TODO do the same for the other engines
  123. d.reply(d.loc, "f", getdetune(detuneType, 0, obj->PDetune));
  124. }},
  125. {"octave::c:i", rProp(parameter) rDoc("Octave note offset"), NULL,
  126. [](const char *msg, RtData &d)
  127. {
  128. rObject *obj = (rObject *)d.obj;
  129. if(!rtosc_narguments(msg)) {
  130. int k=obj->PCoarseDetune/1024;
  131. if (k>=8) k-=16;
  132. d.reply(d.loc, "i", k);
  133. } else {
  134. int k=(int) rtosc_argument(msg, 0).i;
  135. if (k<0) k+=16;
  136. obj->PCoarseDetune = k*1024 + obj->PCoarseDetune%1024;
  137. }
  138. }},
  139. {"coarsedetune::c:i", rProp(parameter) rDoc("Coarse note detune"), NULL,
  140. [](const char *msg, RtData &d)
  141. {
  142. rObject *obj = (rObject *)d.obj;
  143. if(!rtosc_narguments(msg)) {
  144. int k=obj->PCoarseDetune%1024;
  145. if (k>=512) k-=1024;
  146. d.reply(d.loc, "i", k);
  147. } else {
  148. int k=(int) rtosc_argument(msg, 0).i;
  149. if (k<0) k+=1024;
  150. obj->PCoarseDetune = k + (obj->PCoarseDetune/1024)*1024;
  151. }
  152. }},
  153. //weird stuff for PCoarseDetune
  154. {"FMdetunevalue:", rMap(unit,cents) rDoc("Get modulator detune"), NULL, [](const char *, RtData &d)
  155. {
  156. rObject *obj = (rObject *)d.obj;
  157. unsigned detuneType =
  158. obj->PFMDetuneType == 0 ? *(obj->GlobalPDetuneType)
  159. : obj->PFMDetuneType;
  160. //TODO check if this is accurate or if PCoarseDetune is utilized
  161. //TODO do the same for the other engines
  162. d.reply(d.loc, "f", getdetune(detuneType, 0, obj->PFMDetune));
  163. }},
  164. {"FMoctave::c:i", rProp(parameter) rDoc("Octave note offset for modulator"), NULL,
  165. [](const char *msg, RtData &d)
  166. {
  167. rObject *obj = (rObject *)d.obj;
  168. if(!rtosc_narguments(msg)) {
  169. int k=obj->PFMCoarseDetune/1024;
  170. if (k>=8) k-=16;
  171. d.reply(d.loc, "i", k);
  172. } else {
  173. int k=(int) rtosc_argument(msg, 0).i;
  174. if (k<0) k+=16;
  175. obj->PFMCoarseDetune = k*1024 + obj->PFMCoarseDetune%1024;
  176. }
  177. }},
  178. {"FMcoarsedetune::c:i", rProp(parameter) rDoc("Coarse note detune for modulator"),
  179. NULL, [](const char *msg, RtData &d)
  180. {
  181. rObject *obj = (rObject *)d.obj;
  182. if(!rtosc_narguments(msg)) {
  183. int k=obj->PFMCoarseDetune%1024;
  184. if (k>=512) k-=1024;
  185. d.reply(d.loc, "i", k);
  186. } else {
  187. int k=(int) rtosc_argument(msg, 0).i;
  188. if (k<0) k+=1024;
  189. obj->PFMCoarseDetune = k + (obj->PFMCoarseDetune/1024)*1024;
  190. }
  191. }},
  192. //Reader
  193. {"unisonFrequencySpreadCents:", rMap(unit,cents) rDoc("Unison Frequency Spread"),
  194. NULL, [](const char *, RtData &d)
  195. {
  196. rObject *obj = (rObject *)d.obj;
  197. d.reply(d.loc, "f", obj->getUnisonFrequencySpreadCents());
  198. }},
  199. };
  200. #undef rChangeCb
  201. #undef rObject
  202. #define rObject ADnoteGlobalParam
  203. #define rChangeCb if (obj->time) { obj->last_update_timestamp = obj->time->time(); }
  204. static const Ports globalPorts = {
  205. rRecurp(Reson, "Resonance"),
  206. rRecurp(FreqLfo, "Frequency LFO"),
  207. rRecurp(AmpLfo, "Amplitude LFO"),
  208. rRecurp(FilterLfo, "Filter LFO"),
  209. rRecurp(FreqEnvelope, "Frequency Envelope"),
  210. rRecurp(AmpEnvelope, "Frequency Envelope"),
  211. rRecurp(FilterEnvelope, "Frequency Envelope"),
  212. rRecurp(GlobalFilter, "Filter"),
  213. rToggle(PStereo, "Mono/Stereo Enable"),
  214. //Frequency
  215. rParamI(PDetune, "Fine Detune"),
  216. rParamI(PCoarseDetune, "Coarse Detune"),
  217. rParamZyn(PDetuneType, "Detune Scaling Type"),
  218. rParamZyn(PBandwidth, "Relative Fine Detune Gain"),
  219. //Amplitude
  220. rParamZyn(PPanning, "Panning of ADsynth (0 random, 1 left, 127 right)"),
  221. rParamZyn(PVolume, "volume control"),
  222. rParamZyn(PAmpVelocityScaleFunction, "Volume Velocity Control"),
  223. rParamZyn(Fadein_adjustment, "Adjustment for anti-pop strategy."),
  224. rParamZyn(PPunchStrength, "Punch Strength"),
  225. rParamZyn(PPunchTime, "UNKNOWN"),
  226. rParamZyn(PPunchStretch, "How Punch changes with note frequency"),
  227. rParamZyn(PPunchVelocitySensing, "Punch Velocity control"),
  228. //Filter
  229. rParamZyn(PFilterVelocityScale, "Filter Velocity Magnitude"),
  230. rParamZyn(PFilterVelocityScaleFunction, "Filter Velocity Function Shape"),
  231. //Resonance
  232. rToggle(Hrandgrouping, "How randomness is applied to multiple voices using the same oscil"),
  233. //weird stuff for PCoarseDetune
  234. {"detunevalue:", rMap(unit,cents) rDoc("Get detune in cents"), NULL,
  235. [](const char *, RtData &d)
  236. {
  237. rObject *obj = (rObject *)d.obj;
  238. d.reply(d.loc, "f", getdetune(obj->PDetuneType, 0, obj->PDetune));
  239. }},
  240. {"octave::c:i", rProp(parameter) rDoc("Octave note offset"), NULL,
  241. [](const char *msg, RtData &d)
  242. {
  243. rObject *obj = (rObject *)d.obj;
  244. if(!rtosc_narguments(msg)) {
  245. int k=obj->PCoarseDetune/1024;
  246. if (k>=8) k-=16;
  247. d.reply(d.loc, "i", k);
  248. } else {
  249. int k=(int) rtosc_argument(msg, 0).i;
  250. if (k<0) k+=16;
  251. obj->PCoarseDetune = k*1024 + obj->PCoarseDetune%1024;
  252. }
  253. }},
  254. {"coarsedetune::c:i", rProp(parameter) rDoc("Coarse note detune"), NULL,
  255. [](const char *msg, RtData &d)
  256. {
  257. rObject *obj = (rObject *)d.obj;
  258. if(!rtosc_narguments(msg)) {
  259. int k=obj->PCoarseDetune%1024;
  260. if (k>=512) k-=1024;
  261. d.reply(d.loc, "i", k);
  262. } else {
  263. int k=(int) rtosc_argument(msg, 0).i;
  264. if (k<0) k+=1024;
  265. obj->PCoarseDetune = k + (obj->PCoarseDetune/1024)*1024;
  266. }
  267. }},
  268. };
  269. #undef rChangeCb
  270. #undef rObject
  271. #define rObject ADnoteParameters
  272. #define rChangeCb obj->last_update_timestamp = obj->time.time();
  273. static const Ports adPorts = {//XXX 16 should not be hard coded
  274. rSelf(ADnoteParameters),
  275. rPaste,
  276. rArrayPaste,
  277. rRecurs(VoicePar, NUM_VOICES),
  278. rRecur(GlobalPar, "Adnote Parameters"),
  279. };
  280. #undef rChangeCb
  281. const Ports &ADnoteParameters::ports = adPorts;
  282. const Ports &ADnoteVoiceParam::ports = voicePorts;
  283. const Ports &ADnoteGlobalParam::ports = globalPorts;
  284. ADnoteParameters::ADnoteParameters(const SYNTH_T &synth, FFTwrapper *fft_,
  285. const AbsTime *time_)
  286. :PresetsArray(), GlobalPar(time_), time(time_), last_update_timestamp(0)
  287. {
  288. setpresettype("Padsynth");
  289. fft = fft_;
  290. for(int nvoice = 0; nvoice < NUM_VOICES; ++nvoice) {
  291. VoicePar[nvoice].GlobalPDetuneType = &GlobalPar.PDetuneType;
  292. VoicePar[nvoice].time = time_;
  293. EnableVoice(synth, nvoice, time_);
  294. }
  295. defaults();
  296. }
  297. ADnoteGlobalParam::ADnoteGlobalParam(const AbsTime *time_) :
  298. time(time_), last_update_timestamp(0)
  299. {
  300. FreqEnvelope = new EnvelopeParams(0, 0, time_);
  301. FreqEnvelope->ASRinit(64, 50, 64, 60);
  302. FreqLfo = new LFOParams(70, 0, 64, 0, 0, 0, 0, 0, time_);
  303. AmpEnvelope = new EnvelopeParams(64, 1, time_);
  304. AmpEnvelope->ADSRinit_dB(0, 40, 127, 25);
  305. AmpLfo = new LFOParams(80, 0, 64, 0, 0, 0, 0, 1, time_);
  306. GlobalFilter = new FilterParams(2, 94, 40, time_);
  307. FilterEnvelope = new EnvelopeParams(0, 1, time_);
  308. FilterEnvelope->ADSRinit_filter(64, 40, 64, 70, 60, 64);
  309. FilterLfo = new LFOParams(80, 0, 64, 0, 0, 0, 0, 2, time_);
  310. Reson = new Resonance();
  311. }
  312. void ADnoteParameters::defaults()
  313. {
  314. //Default Parameters
  315. GlobalPar.defaults();
  316. for(int nvoice = 0; nvoice < NUM_VOICES; ++nvoice)
  317. defaults(nvoice);
  318. VoicePar[0].Enabled = 1;
  319. }
  320. void ADnoteGlobalParam::defaults()
  321. {
  322. /* Frequency Global Parameters */
  323. PStereo = 1; //stereo
  324. PDetune = 8192; //zero
  325. PCoarseDetune = 0;
  326. PDetuneType = 1;
  327. FreqEnvelope->defaults();
  328. FreqLfo->defaults();
  329. PBandwidth = 64;
  330. /* Amplitude Global Parameters */
  331. PVolume = 90;
  332. PPanning = 64; //center
  333. PAmpVelocityScaleFunction = 64;
  334. AmpEnvelope->defaults();
  335. AmpLfo->defaults();
  336. Fadein_adjustment = FADEIN_ADJUSTMENT_SCALE;
  337. PPunchStrength = 0;
  338. PPunchTime = 60;
  339. PPunchStretch = 64;
  340. PPunchVelocitySensing = 72;
  341. Hrandgrouping = 0;
  342. /* Filter Global Parameters*/
  343. PFilterVelocityScale = 64;
  344. PFilterVelocityScaleFunction = 64;
  345. GlobalFilter->defaults();
  346. FilterEnvelope->defaults();
  347. FilterLfo->defaults();
  348. Reson->defaults();
  349. }
  350. /*
  351. * Defaults a voice
  352. */
  353. void ADnoteParameters::defaults(int n)
  354. {
  355. VoicePar[n].defaults();
  356. }
  357. void ADnoteVoiceParam::defaults()
  358. {
  359. Enabled = 0;
  360. Unison_size = 1;
  361. Unison_frequency_spread = 60;
  362. Unison_stereo_spread = 64;
  363. Unison_vibratto = 64;
  364. Unison_vibratto_speed = 64;
  365. Unison_invert_phase = 0;
  366. Unison_phase_randomness = 127;
  367. Type = 0;
  368. Pfixedfreq = 0;
  369. PfixedfreqET = 0;
  370. PBendAdjust = 88; // 64 + 24
  371. POffsetHz = 64;
  372. Presonance = 1;
  373. Pfilterbypass = 0;
  374. Pextoscil = -1;
  375. PextFMoscil = -1;
  376. Poscilphase = 64;
  377. PFMoscilphase = 64;
  378. PDelay = 0;
  379. PVolume = 100;
  380. PVolumeminus = 0;
  381. PPanning = 64; //center
  382. PDetune = 8192; //8192=0
  383. PCoarseDetune = 0;
  384. PDetuneType = 0;
  385. PFreqLfoEnabled = 0;
  386. PFreqEnvelopeEnabled = 0;
  387. PAmpEnvelopeEnabled = 0;
  388. PAmpLfoEnabled = 0;
  389. PAmpVelocityScaleFunction = 127;
  390. PFilterEnabled = 0;
  391. PFilterEnvelopeEnabled = 0;
  392. PFilterLfoEnabled = 0;
  393. PFilterVelocityScale = 0;
  394. PFilterVelocityScaleFunction = 64;
  395. PFMEnabled = 0;
  396. PFMFixedFreq = false;
  397. //I use the internal oscillator (-1)
  398. PFMVoice = -1;
  399. PFMVolume = 90;
  400. PFMVolumeDamp = 64;
  401. PFMDetune = 8192;
  402. PFMCoarseDetune = 0;
  403. PFMDetuneType = 0;
  404. PFMFreqEnvelopeEnabled = 0;
  405. PFMAmpEnvelopeEnabled = 0;
  406. PFMVelocityScaleFunction = 64;
  407. OscilSmp->defaults();
  408. FMSmp->defaults();
  409. AmpEnvelope->defaults();
  410. AmpLfo->defaults();
  411. FreqEnvelope->defaults();
  412. FreqLfo->defaults();
  413. VoiceFilter->defaults();
  414. FilterEnvelope->defaults();
  415. FilterLfo->defaults();
  416. FMFreqEnvelope->defaults();
  417. FMAmpEnvelope->defaults();
  418. }
  419. /*
  420. * Init the voice parameters
  421. */
  422. void ADnoteParameters::EnableVoice(const SYNTH_T &synth, int nvoice,
  423. const AbsTime *time)
  424. {
  425. VoicePar[nvoice].enable(synth, fft, GlobalPar.Reson, time);
  426. }
  427. void ADnoteVoiceParam::enable(const SYNTH_T &synth, FFTwrapper *fft,
  428. Resonance *Reson, const AbsTime *time)
  429. {
  430. OscilSmp = new OscilGen(synth, fft, Reson);
  431. FMSmp = new OscilGen(synth, fft, NULL);
  432. AmpEnvelope = new EnvelopeParams(64, 1, time);
  433. AmpEnvelope->ADSRinit_dB(0, 100, 127, 100);
  434. AmpLfo = new LFOParams(90, 32, 64, 0, 0, 30, 0, 1, time);
  435. FreqEnvelope = new EnvelopeParams(0, 0, time);
  436. FreqEnvelope->ASRinit(30, 40, 64, 60);
  437. FreqLfo = new LFOParams(50, 40, 0, 0, 0, 0, 0, 0, time);
  438. VoiceFilter = new FilterParams(2, 50, 60, time);
  439. FilterEnvelope = new EnvelopeParams(0, 0, time);
  440. FilterEnvelope->ADSRinit_filter(90, 70, 40, 70, 10, 40);
  441. FilterLfo = new LFOParams(50, 20, 64, 0, 0, 0, 0, 2, time);
  442. FMFreqEnvelope = new EnvelopeParams(0, 0, time);
  443. FMFreqEnvelope->ASRinit(20, 90, 40, 80);
  444. FMAmpEnvelope = new EnvelopeParams(64, 1, time);
  445. FMAmpEnvelope->ADSRinit(80, 90, 127, 100);
  446. }
  447. /*
  448. * Get the Multiplier of the fine detunes of the voices
  449. */
  450. float ADnoteParameters::getBandwidthDetuneMultiplier() const
  451. {
  452. float bw = (GlobalPar.PBandwidth - 64.0f) / 64.0f;
  453. bw = powf(2.0f, bw * powf(fabs(bw), 0.2f) * 5.0f);
  454. return bw;
  455. }
  456. /*
  457. * Get the unison spread in cents for a voice
  458. */
  459. float ADnoteParameters::getUnisonFrequencySpreadCents(int nvoice) const
  460. {
  461. return VoicePar[nvoice].getUnisonFrequencySpreadCents();
  462. }
  463. float ADnoteVoiceParam::getUnisonFrequencySpreadCents(void) const {
  464. return powf(Unison_frequency_spread / 127.0 * 2.0f, 2.0f) * 50.0f; //cents
  465. }
  466. /*
  467. * Kill the voice
  468. */
  469. void ADnoteParameters::KillVoice(int nvoice)
  470. {
  471. VoicePar[nvoice].kill();
  472. }
  473. void ADnoteVoiceParam::kill()
  474. {
  475. delete OscilSmp;
  476. delete FMSmp;
  477. delete AmpEnvelope;
  478. delete AmpLfo;
  479. delete FreqEnvelope;
  480. delete FreqLfo;
  481. delete VoiceFilter;
  482. delete FilterEnvelope;
  483. delete FilterLfo;
  484. delete FMFreqEnvelope;
  485. delete FMAmpEnvelope;
  486. }
  487. ADnoteGlobalParam::~ADnoteGlobalParam()
  488. {
  489. delete FreqEnvelope;
  490. delete FreqLfo;
  491. delete AmpEnvelope;
  492. delete AmpLfo;
  493. delete GlobalFilter;
  494. delete FilterEnvelope;
  495. delete FilterLfo;
  496. delete Reson;
  497. }
  498. ADnoteParameters::~ADnoteParameters()
  499. {
  500. for(int nvoice = 0; nvoice < NUM_VOICES; ++nvoice)
  501. KillVoice(nvoice);
  502. }
  503. void ADnoteParameters::add2XMLsection(XMLwrapper& xml, int n)
  504. {
  505. int nvoice = n;
  506. if(nvoice >= NUM_VOICES)
  507. return;
  508. int oscilused = 0, fmoscilused = 0; //if the oscil or fmoscil are used by another voice
  509. for(int i = 0; i < NUM_VOICES; ++i) {
  510. if(VoicePar[i].Pextoscil == nvoice)
  511. oscilused = 1;
  512. if(VoicePar[i].PextFMoscil == nvoice)
  513. fmoscilused = 1;
  514. }
  515. xml.addparbool("enabled", VoicePar[nvoice].Enabled);
  516. if(((VoicePar[nvoice].Enabled == 0) && (oscilused == 0)
  517. && (fmoscilused == 0)) && (xml.minimal))
  518. return;
  519. VoicePar[nvoice].add2XML(xml, fmoscilused);
  520. }
  521. void ADnoteVoiceParam::add2XML(XMLwrapper& xml, bool fmoscilused)
  522. {
  523. xml.addpar("type", Type);
  524. xml.addpar("unison_size", Unison_size);
  525. xml.addpar("unison_frequency_spread",
  526. Unison_frequency_spread);
  527. xml.addpar("unison_stereo_spread", Unison_stereo_spread);
  528. xml.addpar("unison_vibratto", Unison_vibratto);
  529. xml.addpar("unison_vibratto_speed", Unison_vibratto_speed);
  530. xml.addpar("unison_invert_phase", Unison_invert_phase);
  531. xml.addpar("unison_phase_randomness", Unison_phase_randomness);
  532. xml.addpar("delay", PDelay);
  533. xml.addparbool("resonance", Presonance);
  534. xml.addpar("ext_oscil", Pextoscil);
  535. xml.addpar("ext_fm_oscil", PextFMoscil);
  536. xml.addpar("oscil_phase", Poscilphase);
  537. xml.addpar("oscil_fm_phase", PFMoscilphase);
  538. xml.addparbool("filter_enabled", PFilterEnabled);
  539. xml.addparbool("filter_bypass", Pfilterbypass);
  540. xml.addpar("fm_enabled", PFMEnabled);
  541. xml.beginbranch("OSCIL");
  542. OscilSmp->add2XML(xml);
  543. xml.endbranch();
  544. xml.beginbranch("AMPLITUDE_PARAMETERS");
  545. xml.addpar("panning", PPanning);
  546. xml.addpar("volume", PVolume);
  547. xml.addparbool("volume_minus", PVolumeminus);
  548. xml.addpar("velocity_sensing", PAmpVelocityScaleFunction);
  549. xml.addparbool("amp_envelope_enabled",
  550. PAmpEnvelopeEnabled);
  551. if((PAmpEnvelopeEnabled != 0) || (!xml.minimal)) {
  552. xml.beginbranch("AMPLITUDE_ENVELOPE");
  553. AmpEnvelope->add2XML(xml);
  554. xml.endbranch();
  555. }
  556. xml.addparbool("amp_lfo_enabled", PAmpLfoEnabled);
  557. if((PAmpLfoEnabled != 0) || (!xml.minimal)) {
  558. xml.beginbranch("AMPLITUDE_LFO");
  559. AmpLfo->add2XML(xml);
  560. xml.endbranch();
  561. }
  562. xml.endbranch();
  563. xml.beginbranch("FREQUENCY_PARAMETERS");
  564. xml.addparbool("fixed_freq", Pfixedfreq);
  565. xml.addpar("fixed_freq_et", PfixedfreqET);
  566. xml.addpar("bend_adjust", PBendAdjust);
  567. xml.addpar("offset_hz", POffsetHz);
  568. xml.addpar("detune", PDetune);
  569. xml.addpar("coarse_detune", PCoarseDetune);
  570. xml.addpar("detune_type", PDetuneType);
  571. xml.addparbool("freq_envelope_enabled",
  572. PFreqEnvelopeEnabled);
  573. if((PFreqEnvelopeEnabled != 0) || (!xml.minimal)) {
  574. xml.beginbranch("FREQUENCY_ENVELOPE");
  575. FreqEnvelope->add2XML(xml);
  576. xml.endbranch();
  577. }
  578. xml.addparbool("freq_lfo_enabled", PFreqLfoEnabled);
  579. if((PFreqLfoEnabled != 0) || (!xml.minimal)) {
  580. xml.beginbranch("FREQUENCY_LFO");
  581. FreqLfo->add2XML(xml);
  582. xml.endbranch();
  583. }
  584. xml.endbranch();
  585. if((PFilterEnabled != 0) || (!xml.minimal)) {
  586. xml.beginbranch("FILTER_PARAMETERS");
  587. xml.addpar("velocity_sensing_amplitude", PFilterVelocityScale);
  588. xml.addpar("velocity_sensing", PFilterVelocityScaleFunction);
  589. xml.beginbranch("FILTER");
  590. VoiceFilter->add2XML(xml);
  591. xml.endbranch();
  592. xml.addparbool("filter_envelope_enabled",
  593. PFilterEnvelopeEnabled);
  594. if((PFilterEnvelopeEnabled != 0) || (!xml.minimal)) {
  595. xml.beginbranch("FILTER_ENVELOPE");
  596. FilterEnvelope->add2XML(xml);
  597. xml.endbranch();
  598. }
  599. xml.addparbool("filter_lfo_enabled",
  600. PFilterLfoEnabled);
  601. if((PFilterLfoEnabled != 0) || (!xml.minimal)) {
  602. xml.beginbranch("FILTER_LFO");
  603. FilterLfo->add2XML(xml);
  604. xml.endbranch();
  605. }
  606. xml.endbranch();
  607. }
  608. if((PFMEnabled != 0) || (fmoscilused != 0)
  609. || (!xml.minimal)) {
  610. xml.beginbranch("FM_PARAMETERS");
  611. xml.addpar("input_voice", PFMVoice);
  612. xml.addpar("volume", PFMVolume);
  613. xml.addpar("volume_damp", PFMVolumeDamp);
  614. xml.addpar("velocity_sensing",
  615. PFMVelocityScaleFunction);
  616. xml.addparbool("amp_envelope_enabled",
  617. PFMAmpEnvelopeEnabled);
  618. if((PFMAmpEnvelopeEnabled != 0) || (!xml.minimal)) {
  619. xml.beginbranch("AMPLITUDE_ENVELOPE");
  620. FMAmpEnvelope->add2XML(xml);
  621. xml.endbranch();
  622. }
  623. xml.beginbranch("MODULATOR");
  624. xml.addpar("detune", PFMDetune);
  625. xml.addpar("coarse_detune", PFMCoarseDetune);
  626. xml.addpar("detune_type", PFMDetuneType);
  627. xml.addparbool("freq_envelope_enabled",
  628. PFMFreqEnvelopeEnabled);
  629. xml.addparbool("fixed_freq", PFMFixedFreq);
  630. if((PFMFreqEnvelopeEnabled != 0) || (!xml.minimal)) {
  631. xml.beginbranch("FREQUENCY_ENVELOPE");
  632. FMFreqEnvelope->add2XML(xml);
  633. xml.endbranch();
  634. }
  635. xml.beginbranch("OSCIL");
  636. FMSmp->add2XML(xml);
  637. xml.endbranch();
  638. xml.endbranch();
  639. xml.endbranch();
  640. }
  641. }
  642. void ADnoteGlobalParam::add2XML(XMLwrapper& xml)
  643. {
  644. xml.addparbool("stereo", PStereo);
  645. xml.beginbranch("AMPLITUDE_PARAMETERS");
  646. xml.addpar("volume", PVolume);
  647. xml.addpar("panning", PPanning);
  648. xml.addpar("velocity_sensing", PAmpVelocityScaleFunction);
  649. xml.addpar("fadein_adjustment", Fadein_adjustment);
  650. xml.addpar("punch_strength", PPunchStrength);
  651. xml.addpar("punch_time", PPunchTime);
  652. xml.addpar("punch_stretch", PPunchStretch);
  653. xml.addpar("punch_velocity_sensing", PPunchVelocitySensing);
  654. xml.addpar("harmonic_randomness_grouping", Hrandgrouping);
  655. xml.beginbranch("AMPLITUDE_ENVELOPE");
  656. AmpEnvelope->add2XML(xml);
  657. xml.endbranch();
  658. xml.beginbranch("AMPLITUDE_LFO");
  659. AmpLfo->add2XML(xml);
  660. xml.endbranch();
  661. xml.endbranch();
  662. xml.beginbranch("FREQUENCY_PARAMETERS");
  663. xml.addpar("detune", PDetune);
  664. xml.addpar("coarse_detune", PCoarseDetune);
  665. xml.addpar("detune_type", PDetuneType);
  666. xml.addpar("bandwidth", PBandwidth);
  667. xml.beginbranch("FREQUENCY_ENVELOPE");
  668. FreqEnvelope->add2XML(xml);
  669. xml.endbranch();
  670. xml.beginbranch("FREQUENCY_LFO");
  671. FreqLfo->add2XML(xml);
  672. xml.endbranch();
  673. xml.endbranch();
  674. xml.beginbranch("FILTER_PARAMETERS");
  675. xml.addpar("velocity_sensing_amplitude", PFilterVelocityScale);
  676. xml.addpar("velocity_sensing", PFilterVelocityScaleFunction);
  677. xml.beginbranch("FILTER");
  678. GlobalFilter->add2XML(xml);
  679. xml.endbranch();
  680. xml.beginbranch("FILTER_ENVELOPE");
  681. FilterEnvelope->add2XML(xml);
  682. xml.endbranch();
  683. xml.beginbranch("FILTER_LFO");
  684. FilterLfo->add2XML(xml);
  685. xml.endbranch();
  686. xml.endbranch();
  687. xml.beginbranch("RESONANCE");
  688. Reson->add2XML(xml);
  689. xml.endbranch();
  690. }
  691. void ADnoteParameters::add2XML(XMLwrapper& xml)
  692. {
  693. GlobalPar.add2XML(xml);
  694. for(int nvoice = 0; nvoice < NUM_VOICES; ++nvoice) {
  695. xml.beginbranch("VOICE", nvoice);
  696. add2XMLsection(xml, nvoice);
  697. xml.endbranch();
  698. }
  699. }
  700. void ADnoteGlobalParam::getfromXML(XMLwrapper& xml)
  701. {
  702. PStereo = xml.getparbool("stereo", PStereo);
  703. if(xml.enterbranch("AMPLITUDE_PARAMETERS")) {
  704. PVolume = xml.getpar127("volume", PVolume);
  705. PPanning = xml.getpar127("panning", PPanning);
  706. PAmpVelocityScaleFunction = xml.getpar127("velocity_sensing",
  707. PAmpVelocityScaleFunction);
  708. Fadein_adjustment = xml.getpar127("fadein_adjustment", Fadein_adjustment);
  709. PPunchStrength = xml.getpar127("punch_strength", PPunchStrength);
  710. PPunchTime = xml.getpar127("punch_time", PPunchTime);
  711. PPunchStretch = xml.getpar127("punch_stretch", PPunchStretch);
  712. PPunchVelocitySensing = xml.getpar127("punch_velocity_sensing",
  713. PPunchVelocitySensing);
  714. Hrandgrouping = xml.getpar127("harmonic_randomness_grouping",
  715. Hrandgrouping);
  716. if(xml.enterbranch("AMPLITUDE_ENVELOPE")) {
  717. AmpEnvelope->getfromXML(xml);
  718. xml.exitbranch();
  719. }
  720. if(xml.enterbranch("AMPLITUDE_LFO")) {
  721. AmpLfo->getfromXML(xml);
  722. xml.exitbranch();
  723. }
  724. xml.exitbranch();
  725. }
  726. if(xml.enterbranch("FREQUENCY_PARAMETERS")) {
  727. PDetune = xml.getpar("detune", PDetune, 0, 16383);
  728. PCoarseDetune = xml.getpar("coarse_detune", PCoarseDetune, 0, 16383);
  729. PDetuneType = xml.getpar127("detune_type", PDetuneType);
  730. PBandwidth = xml.getpar127("bandwidth", PBandwidth);
  731. xml.enterbranch("FREQUENCY_ENVELOPE");
  732. FreqEnvelope->getfromXML(xml);
  733. xml.exitbranch();
  734. xml.enterbranch("FREQUENCY_LFO");
  735. FreqLfo->getfromXML(xml);
  736. xml.exitbranch();
  737. xml.exitbranch();
  738. }
  739. if(xml.enterbranch("FILTER_PARAMETERS")) {
  740. PFilterVelocityScale = xml.getpar127("velocity_sensing_amplitude",
  741. PFilterVelocityScale);
  742. PFilterVelocityScaleFunction = xml.getpar127(
  743. "velocity_sensing",
  744. PFilterVelocityScaleFunction);
  745. xml.enterbranch("FILTER");
  746. GlobalFilter->getfromXML(xml);
  747. xml.exitbranch();
  748. xml.enterbranch("FILTER_ENVELOPE");
  749. FilterEnvelope->getfromXML(xml);
  750. xml.exitbranch();
  751. xml.enterbranch("FILTER_LFO");
  752. FilterLfo->getfromXML(xml);
  753. xml.exitbranch();
  754. xml.exitbranch();
  755. }
  756. if(xml.enterbranch("RESONANCE")) {
  757. Reson->getfromXML(xml);
  758. xml.exitbranch();
  759. }
  760. }
  761. void ADnoteParameters::getfromXML(XMLwrapper& xml)
  762. {
  763. GlobalPar.getfromXML(xml);
  764. for(int nvoice = 0; nvoice < NUM_VOICES; ++nvoice) {
  765. VoicePar[nvoice].Enabled = 0;
  766. if(xml.enterbranch("VOICE", nvoice) == 0)
  767. continue;
  768. getfromXMLsection(xml, nvoice);
  769. xml.exitbranch();
  770. }
  771. }
  772. void ADnoteParameters::getfromXMLsection(XMLwrapper& xml, int n)
  773. {
  774. int nvoice = n;
  775. if(nvoice >= NUM_VOICES)
  776. return;
  777. VoicePar[nvoice].getfromXML(xml, nvoice);
  778. }
  779. void ADnoteParameters::paste(ADnoteParameters &a)
  780. {
  781. this->GlobalPar.paste(a.GlobalPar);
  782. for(int i=0; i<NUM_VOICES; ++i)
  783. this->VoicePar[i].paste(a.VoicePar[i]);
  784. if ( time ) {
  785. last_update_timestamp = time->time();
  786. }
  787. }
  788. void ADnoteParameters::pasteArray(ADnoteParameters &a, int nvoice)
  789. {
  790. if(nvoice >= NUM_VOICES)
  791. return;
  792. VoicePar[nvoice].paste(a.VoicePar[nvoice]);
  793. if ( time ) {
  794. last_update_timestamp = time->time();
  795. }
  796. }
  797. #define copy(x) this->x = a.x
  798. #define RCopy(x) this->x->paste(*a.x)
  799. void ADnoteVoiceParam::paste(ADnoteVoiceParam &a)
  800. {
  801. //Come on C++ get some darn reflection, this is horrible
  802. copy(Enabled);
  803. copy(Unison_size);
  804. copy(Unison_frequency_spread);
  805. copy(Unison_stereo_spread);
  806. copy(Unison_vibratto);
  807. copy(Unison_vibratto_speed);
  808. copy(Unison_invert_phase);
  809. copy(Unison_phase_randomness);
  810. copy(Type);
  811. copy(PDelay);
  812. copy(Presonance);
  813. copy(Pextoscil);
  814. copy(PextFMoscil);
  815. copy(Poscilphase);
  816. copy(PFMoscilphase);
  817. copy(PFilterEnabled);
  818. copy(Pfilterbypass);
  819. copy(PFMEnabled);
  820. copy(PFMFixedFreq);
  821. RCopy(OscilSmp);
  822. copy(PPanning);
  823. copy(PVolume);
  824. copy(PVolumeminus);
  825. copy(PAmpVelocityScaleFunction);
  826. copy(PAmpEnvelopeEnabled);
  827. RCopy(AmpEnvelope);
  828. copy(PAmpLfoEnabled);
  829. RCopy(AmpLfo);
  830. copy(Pfixedfreq);
  831. copy(PfixedfreqET);
  832. copy(PDetune);
  833. copy(PCoarseDetune);
  834. copy(PDetuneType);
  835. copy(PBendAdjust);
  836. copy(POffsetHz);
  837. copy(PFreqEnvelopeEnabled);
  838. RCopy(FreqEnvelope);
  839. copy(PFreqLfoEnabled);
  840. RCopy(FreqLfo);
  841. RCopy(VoiceFilter);
  842. copy(PFilterEnvelopeEnabled);
  843. RCopy(FilterEnvelope);
  844. copy(PFilterLfoEnabled);
  845. copy(PFilterVelocityScale);
  846. copy(PFilterVelocityScaleFunction);
  847. RCopy(FilterLfo);
  848. copy(PFMVoice);
  849. copy(PFMVolume);
  850. copy(PFMVolumeDamp);
  851. copy(PFMVelocityScaleFunction);
  852. copy(PFMAmpEnvelopeEnabled);
  853. RCopy(FMAmpEnvelope);
  854. copy(PFMDetune);
  855. copy(PFMCoarseDetune);
  856. copy(PFMDetuneType);
  857. copy(PFMFreqEnvelopeEnabled);
  858. RCopy(FMFreqEnvelope);
  859. RCopy(FMSmp);
  860. if ( time ) {
  861. last_update_timestamp = time->time();
  862. }
  863. }
  864. void ADnoteGlobalParam::paste(ADnoteGlobalParam &a)
  865. {
  866. copy(PStereo);
  867. copy(PVolume);
  868. copy(PPanning);
  869. copy(PAmpVelocityScaleFunction);
  870. copy(Fadein_adjustment);
  871. copy(PPunchStrength);
  872. copy(PPunchTime);
  873. copy(PPunchStretch);
  874. copy(PPunchVelocitySensing);
  875. copy(Hrandgrouping);
  876. RCopy(AmpEnvelope);
  877. RCopy(AmpLfo);
  878. copy(PDetune);
  879. copy(PCoarseDetune);
  880. copy(PDetuneType);
  881. copy(PBandwidth);
  882. RCopy(FreqEnvelope);
  883. RCopy(FreqLfo);
  884. copy(PFilterVelocityScale);
  885. copy(PFilterVelocityScaleFunction);
  886. RCopy(GlobalFilter);
  887. RCopy(FilterEnvelope);
  888. RCopy(FilterLfo);
  889. RCopy(Reson);
  890. if ( time ) {
  891. last_update_timestamp = time->time();
  892. }
  893. }
  894. #undef copy
  895. #undef RCopy
  896. void ADnoteVoiceParam::getfromXML(XMLwrapper& xml, unsigned nvoice)
  897. {
  898. Enabled = xml.getparbool("enabled", 0);
  899. Unison_size = xml.getpar127("unison_size", Unison_size);
  900. Unison_frequency_spread = xml.getpar127("unison_frequency_spread",
  901. Unison_frequency_spread);
  902. Unison_stereo_spread = xml.getpar127("unison_stereo_spread",
  903. Unison_stereo_spread);
  904. Unison_vibratto = xml.getpar127("unison_vibratto", Unison_vibratto);
  905. Unison_vibratto_speed = xml.getpar127("unison_vibratto_speed",
  906. Unison_vibratto_speed);
  907. Unison_invert_phase = xml.getpar127("unison_invert_phase",
  908. Unison_invert_phase);
  909. Unison_phase_randomness = xml.getpar127("unison_phase_randomness",
  910. Unison_phase_randomness);
  911. Type = xml.getpar127("type", Type);
  912. PDelay = xml.getpar127("delay", PDelay);
  913. Presonance = xml.getparbool("resonance", Presonance);
  914. Pextoscil = xml.getpar("ext_oscil", -1, -1, nvoice - 1);
  915. PextFMoscil = xml.getpar("ext_fm_oscil", -1, -1, nvoice - 1);
  916. Poscilphase = xml.getpar127("oscil_phase", Poscilphase);
  917. PFMoscilphase = xml.getpar127("oscil_fm_phase", PFMoscilphase);
  918. PFilterEnabled = xml.getparbool("filter_enabled", PFilterEnabled);
  919. Pfilterbypass = xml.getparbool("filter_bypass", Pfilterbypass);
  920. PFMEnabled = xml.getpar127("fm_enabled", PFMEnabled);
  921. if(xml.enterbranch("OSCIL")) {
  922. OscilSmp->getfromXML(xml);
  923. xml.exitbranch();
  924. }
  925. if(xml.enterbranch("AMPLITUDE_PARAMETERS")) {
  926. PPanning = xml.getpar127("panning", PPanning);
  927. PVolume = xml.getpar127("volume", PVolume);
  928. PVolumeminus = xml.getparbool("volume_minus", PVolumeminus);
  929. PAmpVelocityScaleFunction = xml.getpar127("velocity_sensing",
  930. PAmpVelocityScaleFunction);
  931. PAmpEnvelopeEnabled = xml.getparbool("amp_envelope_enabled",
  932. PAmpEnvelopeEnabled);
  933. if(xml.enterbranch("AMPLITUDE_ENVELOPE")) {
  934. AmpEnvelope->getfromXML(xml);
  935. xml.exitbranch();
  936. }
  937. PAmpLfoEnabled = xml.getparbool("amp_lfo_enabled", PAmpLfoEnabled);
  938. if(xml.enterbranch("AMPLITUDE_LFO")) {
  939. AmpLfo->getfromXML(xml);
  940. xml.exitbranch();
  941. }
  942. xml.exitbranch();
  943. }
  944. if(xml.enterbranch("FREQUENCY_PARAMETERS")) {
  945. Pfixedfreq = xml.getparbool("fixed_freq", Pfixedfreq);
  946. PfixedfreqET = xml.getpar127("fixed_freq_et", PfixedfreqET);
  947. PBendAdjust = xml.getpar127("bend_adjust", PBendAdjust);
  948. POffsetHz = xml.getpar127("offset_hz", POffsetHz);
  949. PDetune = xml.getpar("detune", PDetune, 0, 16383);
  950. PCoarseDetune = xml.getpar("coarse_detune", PCoarseDetune, 0, 16383);
  951. PDetuneType = xml.getpar127("detune_type", PDetuneType);
  952. PFreqEnvelopeEnabled = xml.getparbool("freq_envelope_enabled",
  953. PFreqEnvelopeEnabled);
  954. if(xml.enterbranch("FREQUENCY_ENVELOPE")) {
  955. FreqEnvelope->getfromXML(xml);
  956. xml.exitbranch();
  957. }
  958. PFreqLfoEnabled = xml.getparbool("freq_lfo_enabled", PFreqLfoEnabled);
  959. if(xml.enterbranch("FREQUENCY_LFO")) {
  960. FreqLfo->getfromXML(xml);
  961. xml.exitbranch();
  962. }
  963. xml.exitbranch();
  964. }
  965. if(xml.enterbranch("FILTER_PARAMETERS")) {
  966. PFilterVelocityScale = xml.getpar127("velocity_sensing_amplitude",
  967. PFilterVelocityScale);
  968. PFilterVelocityScaleFunction = xml.getpar127(
  969. "velocity_sensing",
  970. PFilterVelocityScaleFunction);
  971. if(xml.enterbranch("FILTER")) {
  972. VoiceFilter->getfromXML(xml);
  973. xml.exitbranch();
  974. }
  975. PFilterEnvelopeEnabled = xml.getparbool("filter_envelope_enabled",
  976. PFilterEnvelopeEnabled);
  977. if(xml.enterbranch("FILTER_ENVELOPE")) {
  978. FilterEnvelope->getfromXML(xml);
  979. xml.exitbranch();
  980. }
  981. PFilterLfoEnabled = xml.getparbool("filter_lfo_enabled",
  982. PFilterLfoEnabled);
  983. if(xml.enterbranch("FILTER_LFO")) {
  984. FilterLfo->getfromXML(xml);
  985. xml.exitbranch();
  986. }
  987. xml.exitbranch();
  988. }
  989. if(xml.enterbranch("FM_PARAMETERS")) {
  990. PFMVoice = xml.getpar("input_voice", PFMVoice, -1, nvoice - 1);
  991. PFMVolume = xml.getpar127("volume", PFMVolume);
  992. PFMVolumeDamp = xml.getpar127("volume_damp", PFMVolumeDamp);
  993. PFMVelocityScaleFunction = xml.getpar127("velocity_sensing",
  994. PFMVelocityScaleFunction);
  995. PFMAmpEnvelopeEnabled = xml.getparbool("amp_envelope_enabled",
  996. PFMAmpEnvelopeEnabled);
  997. if(xml.enterbranch("AMPLITUDE_ENVELOPE")) {
  998. FMAmpEnvelope->getfromXML(xml);
  999. xml.exitbranch();
  1000. }
  1001. if(xml.enterbranch("MODULATOR")) {
  1002. PFMDetune = xml.getpar("detune", PFMDetune, 0, 16383);
  1003. PFMCoarseDetune = xml.getpar("coarse_detune",
  1004. PFMCoarseDetune,
  1005. 0,
  1006. 16383);
  1007. PFMDetuneType = xml.getpar127("detune_type", PFMDetuneType);
  1008. PFMFreqEnvelopeEnabled = xml.getparbool("freq_envelope_enabled",
  1009. PFMFreqEnvelopeEnabled);
  1010. PFMFixedFreq = xml.getparbool("fixed_freq",
  1011. PFMFixedFreq);
  1012. if(xml.enterbranch("FREQUENCY_ENVELOPE")) {
  1013. FMFreqEnvelope->getfromXML(xml);
  1014. xml.exitbranch();
  1015. }
  1016. if(xml.enterbranch("OSCIL")) {
  1017. FMSmp->getfromXML(xml);
  1018. xml.exitbranch();
  1019. }
  1020. xml.exitbranch();
  1021. }
  1022. xml.exitbranch();
  1023. }
  1024. }