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.

1244 lines
41KB

  1. /*
  2. ZynAddSubFX - a software synthesizer
  3. PADnoteParameters.cpp - Parameters for PADnote (PADsynth)
  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 "PADnoteParameters.h"
  13. #include "FilterParams.h"
  14. #include "EnvelopeParams.h"
  15. #include "LFOParams.h"
  16. #include "../Synth/Resonance.h"
  17. #include "../Synth/OscilGen.h"
  18. #include "../Misc/WavFile.h"
  19. #include "../Misc/Time.h"
  20. #include <cstdio>
  21. #include <rtosc/ports.h>
  22. #include <rtosc/port-sugar.h>
  23. using namespace rtosc;
  24. #define rObject PADnoteParameters
  25. #undef rChangeCb
  26. #define rChangeCb if (obj->time) { obj->last_update_timestamp = obj->time->time(); }
  27. static const rtosc::Ports realtime_ports =
  28. {
  29. rRecurp(FreqLfo, "Frequency LFO"),
  30. rRecurp(AmpLfo, "Amplitude LFO"),
  31. rRecurp(FilterLfo, "Filter LFO"),
  32. rRecurp(FreqEnvelope, "Frequency Envelope"),
  33. rRecurp(AmpEnvelope, "Amplitude Envelope"),
  34. rRecurp(FilterEnvelope, "Filter Envelope"),
  35. rRecurp(GlobalFilter, "Post Filter"),
  36. //Volume
  37. rToggle(PStereo, rShort("stereo"), "Stereo/Mono Mode"),
  38. rParamZyn(PPanning, rShort("panning"), "Left Right Panning"),
  39. rParamZyn(PVolume, rShort("vol"), "Synth Volume"),
  40. rParamZyn(PAmpVelocityScaleFunction, rShort("sense"), "Amplitude Velocity Sensing function"),
  41. rParamZyn(Fadein_adjustment, rShort("a.pop."), "Adjustment for anti-pop strategy."),
  42. //Punch
  43. rParamZyn(PPunchStrength, rShort("strength"), "Punch Strength"),
  44. rParamZyn(PPunchTime, rShort("time"), "Length of punch"),
  45. rParamZyn(PPunchStretch, rShort("stretch"), "How Punch changes with note frequency"),
  46. rParamZyn(PPunchVelocitySensing, rShort("sense"), "Punch Velocity control"),
  47. //Filter
  48. rParamZyn(PFilterVelocityScale, rShort("scale"), "Filter Velocity Magnitude"),
  49. rParamZyn(PFilterVelocityScaleFunction, rShort("sense"), "Filter Velocity Function Shape"),
  50. //Freq
  51. rToggle(Pfixedfreq, rShort("fixed"), "Base frequency fixed frequency enable"),
  52. rParamZyn(PfixedfreqET, rShort("f.ET"), "Equal temeperate control for fixed frequency operation"),
  53. rParamZyn(PBendAdjust, "Pitch bend adjustment"),
  54. rParamZyn(POffsetHz, rShort("offset"), "Voice constant offset"),
  55. rParamI(PDetune, rShort("fine"), rLinear(0, 16383), "Fine Detune"),
  56. rParamI(PCoarseDetune, rShort("coarse"), "Coarse Detune"),
  57. rParamZyn(PDetuneType, rShort("type"),
  58. rOptions(L35cents, L10cents, E100cents, E1200cents),
  59. "Magnitude of Detune"),
  60. {"sample#64:ifb", rProp(internal) rDoc("Nothing to see here"), 0,
  61. [](const char *m, rtosc::RtData &d)
  62. {
  63. PADnoteParameters *p = (PADnoteParameters*)d.obj;
  64. const char *mm = m;
  65. while(!isdigit(*mm))++mm;
  66. unsigned n = atoi(mm);
  67. p->sample[n].size = rtosc_argument(m,0).i;
  68. p->sample[n].basefreq = rtosc_argument(m,1).f;
  69. p->sample[n].smp = *(float**)rtosc_argument(m,2).b.data;
  70. //XXX TODO memory managment (deallocation of smp buffer)
  71. }},
  72. //weird stuff for PCoarseDetune
  73. {"detunevalue:", rMap(unit,cents) rDoc("Get detune value"), NULL,
  74. [](const char *, RtData &d)
  75. {
  76. PADnoteParameters *obj = (PADnoteParameters *)d.obj;
  77. d.reply(d.loc, "f", getdetune(obj->PDetuneType, 0, obj->PDetune));
  78. }},
  79. {"octave::c:i", rProp(parameter) rShort("octave") rLinear(-8,7)
  80. rDoc("Octave note offset"), NULL,
  81. [](const char *msg, RtData &d)
  82. {
  83. PADnoteParameters *obj = (PADnoteParameters *)d.obj;
  84. if(!rtosc_narguments(msg)) {
  85. int k=obj->PCoarseDetune/1024;
  86. if (k>=8) k-=16;
  87. d.reply(d.loc, "i", k);
  88. } else {
  89. int k=(int) rtosc_argument(msg, 0).i;
  90. if (k<0) k+=16;
  91. obj->PCoarseDetune = k*1024 + obj->PCoarseDetune%1024;
  92. }
  93. }},
  94. {"coarsedetune::c:i", rProp(parameter) rShort("coarse") rLinear(-64, 63)
  95. rDoc("Coarse note detune"), NULL,
  96. [](const char *msg, RtData &d)
  97. {
  98. PADnoteParameters *obj = (PADnoteParameters *)d.obj;
  99. if(!rtosc_narguments(msg)) {
  100. int k=obj->PCoarseDetune%1024;
  101. if (k>=512) k-=1024;
  102. d.reply(d.loc, "i", k);
  103. } else {
  104. int k=(int) rtosc_argument(msg, 0).i;
  105. if (k<0) k+=1024;
  106. obj->PCoarseDetune = k + (obj->PCoarseDetune/1024)*1024;
  107. }
  108. }},
  109. {"paste:b", rProp(internal) rDoc("paste port"), 0,
  110. [](const char *m, rtosc::RtData &d){
  111. rObject &paste = **(rObject **)rtosc_argument(m,0).b.data;
  112. rObject &o = *(rObject*)d.obj;
  113. o.pasteRT(paste);}}
  114. };
  115. static const rtosc::Ports non_realtime_ports =
  116. {
  117. rSelf(PADnoteParameters),
  118. rPresetType,
  119. {"paste:b", rProp(internal) rDoc("paste port"), 0,
  120. [](const char *m, rtosc::RtData &d){
  121. rObject &paste = **(rObject **)rtosc_argument(m,0).b.data;
  122. rObject &o = *(rObject*)d.obj;
  123. o.paste(paste);
  124. //avoid the match to forward the request along
  125. d.matches--;}},
  126. //Harmonic Source Distribution
  127. rRecurp(oscilgen, "Oscillator"),
  128. rRecurp(resonance, "Resonance"),
  129. //Harmonic Shape
  130. rOption(Pmode, rMap(min, 0), rMap(max, 2), rShort("distribution"), rOptions(bandwidth,discrete,continious),
  131. "Harmonic Distribution Model"),
  132. rOption(Php.base.type, rOptions(Gaussian, Rectanglar, Double Exponential), rShort("shape"),
  133. "Harmonic profile shape"),
  134. rParamZyn(Php.base.par1, rShort("warp"), "Harmonic shape distribution parameter"),
  135. rParamZyn(Php.freqmult, rShort("clone"), "Frequency multiplier on distribution"),
  136. rParamZyn(Php.modulator.par1, rShort("p1"), "Distribution modulator parameter"),
  137. rParamZyn(Php.modulator.freq, rShort("freq"), "Frequency of modulator parameter"),
  138. rParamZyn(Php.width, rShort("bandwidth"), "Width of base harmonic"),
  139. rOption(Php.amp.mode, rShort("mode"), rOptions(Sum, Mult, Div1, Div2),
  140. "Amplitude harmonic multiplier type"),
  141. //Harmonic Modulation
  142. rOption(Php.amp.type, rShort("mult"), rOptions(Off, Gauss, Sine, Flat),
  143. "Type of amplitude multipler"),
  144. rParamZyn(Php.amp.par1, rShort("p1"), "Amplitude multiplier parameter"),
  145. rParamZyn(Php.amp.par2, rShort("p2"), "Amplitude multiplier parameter"),
  146. rToggle(Php.autoscale, rShort("auto"), "Autoscaling Harmonics"),
  147. rOption(Php.onehalf, rShort("side"),
  148. rOptions(Full, Upper Half, Lower Half),
  149. "Harmonic cutoff model"),
  150. //Harmonic Bandwidth
  151. rOption(Pbwscale, rShort("bw scale"),
  152. rOptions(Normal,
  153. EqualHz, Quater,
  154. Half, 75%, 150%,
  155. Double, Inv. Half),
  156. "Bandwidth scaling"),
  157. //Harmonic Position Modulation
  158. rOption(Phrpos.type,
  159. rOptions(Harmonic, ShiftU, ShiftL, PowerU, PowerL, Sine,
  160. Power, Shift),
  161. "Harmonic Overtone shifting mode"),
  162. rParamI(Phrpos.par1, rShort("p1"), rLinear(0,255), "Harmonic position parameter"),
  163. rParamI(Phrpos.par2, rShort("p2"), rLinear(0,255), "Harmonic position parameter"),
  164. rParamI(Phrpos.par3, rShort("force h."), rLinear(0,255), "Harmonic position parameter"),
  165. //Quality
  166. rOption(Pquality.samplesize, rShort("quality"),
  167. rOptions(16k (Tiny), 32k, 64k (Small), 128k,
  168. 256k (Normal), 512k, 1M (Big)),
  169. "Size of each wavetable element"),
  170. rOption(Pquality.basenote, rShort("basenote"),
  171. rOptions(C-2, G-2, C-3, G-3, C-4,
  172. G-4, C-5, G-5, G-6,),
  173. "Base note for wavetable"),
  174. rOption(Pquality.smpoct, rShort("smp/oct"),
  175. rOptions(0.5, 1, 2, 3, 4, 6, 12),
  176. "Samples per octave"),
  177. rParamI(Pquality.oct, rShort("octaves"), rLinear(0,7),
  178. "Number of octaves to sample (above the first sample"),
  179. {"Pbandwidth::i", rShort("bandwidth") rProp(parameter) rLinear(0,1000) rDoc("Bandwith Of Harmonics"), NULL,
  180. [](const char *msg, rtosc::RtData &d) {
  181. PADnoteParameters *p = ((PADnoteParameters*)d.obj);
  182. if(rtosc_narguments(msg)) {
  183. p->setPbandwidth(rtosc_argument(msg, 0).i);
  184. } else {
  185. d.reply(d.loc, "i", p->Pbandwidth);
  186. }}},
  187. {"bandwidthvalue:", rMap(unit, cents) rDoc("Get Bandwidth"), NULL,
  188. [](const char *, rtosc::RtData &d) {
  189. PADnoteParameters *p = ((PADnoteParameters*)d.obj);
  190. d.reply(d.loc, "f", p->setPbandwidth(p->Pbandwidth));
  191. }},
  192. {"nhr:", rProp(non-realtime) rDoc("Returns the harmonic shifts"),
  193. NULL, [](const char *, rtosc::RtData &d) {
  194. PADnoteParameters *p = ((PADnoteParameters*)d.obj);
  195. const unsigned n = p->synth.oscilsize / 2;
  196. float *tmp = new float[n];
  197. *tmp = 0;
  198. for(unsigned i=1; i<n; ++i)
  199. tmp[i] = p->getNhr(i);
  200. d.reply(d.loc, "b", n*sizeof(float), tmp);
  201. delete[] tmp;}},
  202. {"profile:i", rProp(non-realtime) rDoc("UI display of the harmonic profile"),
  203. NULL, [](const char *m, rtosc::RtData &d) {
  204. PADnoteParameters *p = ((PADnoteParameters*)d.obj);
  205. const int n = rtosc_argument(m, 0).i;
  206. if(n<=0)
  207. return;
  208. float *tmp = new float[n];
  209. float realbw = p->getprofile(tmp, n);
  210. d.reply(d.loc, "b", n*sizeof(float), tmp);
  211. d.reply(d.loc, "i", (int)realbw);
  212. delete[] tmp;}},
  213. {"harmonic_profile:", rProp(non-realtime) rDoc("UI display of the harmonic profile"),
  214. NULL, [](const char *m, rtosc::RtData &d) {
  215. PADnoteParameters *p = ((PADnoteParameters*)d.obj);
  216. #define RES 512
  217. char types[RES+2] = {0};
  218. rtosc_arg_t args[RES+1];
  219. float tmp[RES];
  220. types[0] = 'f';
  221. args[0].f = p->getprofile(tmp, RES);
  222. for(int i=0; i<RES; ++i) {
  223. types[i+1] = 'f';
  224. args[i+1].f = tmp[i];
  225. }
  226. d.replyArray(d.loc, types, args);
  227. #undef RES
  228. }},
  229. {"needPrepare:", rDoc("Unimplemented Stub"),
  230. NULL, [](const char *, rtosc::RtData&) {}},
  231. };
  232. #undef rChangeCb
  233. const rtosc::Ports &PADnoteParameters::non_realtime_ports = ::non_realtime_ports;
  234. const rtosc::Ports &PADnoteParameters::realtime_ports = ::realtime_ports;
  235. const rtosc::MergePorts PADnoteParameters::ports =
  236. {
  237. &realtime_ports,
  238. &non_realtime_ports
  239. };
  240. PADnoteParameters::PADnoteParameters(const SYNTH_T &synth_, FFTwrapper *fft_,
  241. const AbsTime *time_)
  242. : Presets(), time(time_), last_update_timestamp(0), synth(synth_)
  243. {
  244. setpresettype("Ppadsynth");
  245. fft = fft_;
  246. resonance = new Resonance();
  247. oscilgen = new OscilGen(synth, fft_, resonance);
  248. oscilgen->ADvsPAD = true;
  249. FreqEnvelope = new EnvelopeParams(0, 0, time_);
  250. FreqEnvelope->ASRinit(64, 50, 64, 60);
  251. FreqLfo = new LFOParams(70, 0, 64, 0, 0, 0, 0, 0, time_);
  252. AmpEnvelope = new EnvelopeParams(64, 1, time_);
  253. AmpEnvelope->ADSRinit_dB(0, 40, 127, 25);
  254. AmpLfo = new LFOParams(80, 0, 64, 0, 0, 0, 0, 1, time_);
  255. GlobalFilter = new FilterParams(2, 94, 40, time_);
  256. FilterEnvelope = new EnvelopeParams(0, 1, time_);
  257. FilterEnvelope->ADSRinit_filter(64, 40, 64, 70, 60, 64);
  258. FilterLfo = new LFOParams(80, 0, 64, 0, 0, 0, 0, 2, time_);
  259. for(int i = 0; i < PAD_MAX_SAMPLES; ++i)
  260. sample[i].smp = NULL;
  261. defaults();
  262. }
  263. PADnoteParameters::~PADnoteParameters()
  264. {
  265. deletesamples();
  266. delete (oscilgen);
  267. delete (resonance);
  268. delete (FreqEnvelope);
  269. delete (FreqLfo);
  270. delete (AmpEnvelope);
  271. delete (AmpLfo);
  272. delete (GlobalFilter);
  273. delete (FilterEnvelope);
  274. delete (FilterLfo);
  275. }
  276. void PADnoteParameters::defaults()
  277. {
  278. Pmode = 0;
  279. Php.base.type = 0;
  280. Php.base.par1 = 80;
  281. Php.freqmult = 0;
  282. Php.modulator.par1 = 0;
  283. Php.modulator.freq = 30;
  284. Php.width = 127;
  285. Php.amp.type = 0;
  286. Php.amp.mode = 0;
  287. Php.amp.par1 = 80;
  288. Php.amp.par2 = 64;
  289. Php.autoscale = true;
  290. Php.onehalf = 0;
  291. setPbandwidth(500);
  292. Pbwscale = 0;
  293. resonance->defaults();
  294. oscilgen->defaults();
  295. Phrpos.type = 0;
  296. Phrpos.par1 = 0;
  297. Phrpos.par2 = 0;
  298. Phrpos.par3 = 0;
  299. Pquality.samplesize = 3;
  300. Pquality.basenote = 4;
  301. Pquality.oct = 3;
  302. Pquality.smpoct = 2;
  303. PStereo = 1; //stereo
  304. /* Frequency Global Parameters */
  305. Pfixedfreq = 0;
  306. PfixedfreqET = 0;
  307. PBendAdjust = 88; // 64 + 24
  308. POffsetHz = 64;
  309. PDetune = 8192; //zero
  310. PCoarseDetune = 0;
  311. PDetuneType = 1;
  312. FreqEnvelope->defaults();
  313. FreqLfo->defaults();
  314. /* Amplitude Global Parameters */
  315. PVolume = 90;
  316. PPanning = 64; //center
  317. PAmpVelocityScaleFunction = 64;
  318. AmpEnvelope->defaults();
  319. AmpLfo->defaults();
  320. Fadein_adjustment = FADEIN_ADJUSTMENT_SCALE;
  321. PPunchStrength = 0;
  322. PPunchTime = 60;
  323. PPunchStretch = 64;
  324. PPunchVelocitySensing = 72;
  325. /* Filter Global Parameters*/
  326. PFilterVelocityScale = 64;
  327. PFilterVelocityScaleFunction = 64;
  328. GlobalFilter->defaults();
  329. FilterEnvelope->defaults();
  330. FilterLfo->defaults();
  331. deletesamples();
  332. }
  333. void PADnoteParameters::deletesample(int n)
  334. {
  335. if((n < 0) || (n >= PAD_MAX_SAMPLES))
  336. return;
  337. delete[] sample[n].smp;
  338. sample[n].smp = NULL;
  339. sample[n].size = 0;
  340. sample[n].basefreq = 440.0f;
  341. }
  342. void PADnoteParameters::deletesamples()
  343. {
  344. for(int i = 0; i < PAD_MAX_SAMPLES; ++i)
  345. deletesample(i);
  346. }
  347. /*
  348. * Get the harmonic profile (i.e. the frequency distributio of a single harmonic)
  349. */
  350. float PADnoteParameters::getprofile(float *smp, int size)
  351. {
  352. for(int i = 0; i < size; ++i)
  353. smp[i] = 0.0f;
  354. const int supersample = 16;
  355. float basepar = powf(2.0f, (1.0f - Php.base.par1 / 127.0f) * 12.0f);
  356. float freqmult = floor(powf(2.0f,
  357. Php.freqmult / 127.0f
  358. * 5.0f) + 0.000001f);
  359. float modfreq = floor(powf(2.0f,
  360. Php.modulator.freq / 127.0f
  361. * 5.0f) + 0.000001f);
  362. float modpar1 = powf(Php.modulator.par1 / 127.0f, 4.0f) * 5.0f / sqrt(
  363. modfreq);
  364. float amppar1 =
  365. powf(2.0f, powf(Php.amp.par1 / 127.0f, 2.0f) * 10.0f) - 0.999f;
  366. float amppar2 = (1.0f - Php.amp.par2 / 127.0f) * 0.998f + 0.001f;
  367. float width = powf(150.0f / (Php.width + 22.0f), 2.0f);
  368. for(int i = 0; i < size * supersample; ++i) {
  369. bool makezero = false;
  370. float x = i * 1.0f / (size * (float) supersample);
  371. float origx = x;
  372. //do the sizing (width)
  373. x = (x - 0.5f) * width + 0.5f;
  374. if(x < 0.0f) {
  375. x = 0.0f;
  376. makezero = true;
  377. }
  378. else
  379. if(x > 1.0f) {
  380. x = 1.0f;
  381. makezero = true;
  382. }
  383. //compute the full profile or one half
  384. switch(Php.onehalf) {
  385. case 1:
  386. x = x * 0.5f + 0.5f;
  387. break;
  388. case 2:
  389. x = x * 0.5f;
  390. break;
  391. }
  392. float x_before_freq_mult = x;
  393. //do the frequency multiplier
  394. x *= freqmult;
  395. //do the modulation of the profile
  396. x += sinf(x_before_freq_mult * 3.1415926f * modfreq) * modpar1;
  397. x = fmod(x + 1000.0f, 1.0f) * 2.0f - 1.0f;
  398. //this is the base function of the profile
  399. float f;
  400. switch(Php.base.type) {
  401. case 1:
  402. f = expf(-(x * x) * basepar);
  403. if(f < 0.4f)
  404. f = 0.0f;
  405. else
  406. f = 1.0f;
  407. break;
  408. case 2:
  409. f = expf(-(fabs(x)) * sqrt(basepar));
  410. break;
  411. default:
  412. f = expf(-(x * x) * basepar);
  413. break;
  414. }
  415. if(makezero)
  416. f = 0.0f;
  417. float amp = 1.0f;
  418. origx = origx * 2.0f - 1.0f;
  419. //compute the amplitude multiplier
  420. switch(Php.amp.type) {
  421. case 1:
  422. amp = expf(-(origx * origx) * 10.0f * amppar1);
  423. break;
  424. case 2:
  425. amp = 0.5f
  426. * (1.0f
  427. + cosf(3.1415926f * origx * sqrt(amppar1 * 4.0f + 1.0f)));
  428. break;
  429. case 3:
  430. amp = 1.0f
  431. / (powf(origx * (amppar1 * 2.0f + 0.8f), 14.0f) + 1.0f);
  432. break;
  433. }
  434. //apply the amplitude multiplier
  435. float finalsmp = f;
  436. if(Php.amp.type != 0)
  437. switch(Php.amp.mode) {
  438. case 0:
  439. finalsmp = amp * (1.0f - amppar2) + finalsmp * amppar2;
  440. break;
  441. case 1:
  442. finalsmp *= amp * (1.0f - amppar2) + amppar2;
  443. break;
  444. case 2:
  445. finalsmp = finalsmp
  446. / (amp + powf(amppar2, 4.0f) * 20.0f + 0.0001f);
  447. break;
  448. case 3:
  449. finalsmp = amp
  450. / (finalsmp
  451. + powf(amppar2, 4.0f) * 20.0f + 0.0001f);
  452. break;
  453. }
  454. ;
  455. smp[i / supersample] += finalsmp / supersample;
  456. }
  457. //normalize the profile (make the max. to be equal to 1.0f)
  458. float max = 0.0f;
  459. for(int i = 0; i < size; ++i) {
  460. if(smp[i] < 0.0f)
  461. smp[i] = 0.0f;
  462. if(smp[i] > max)
  463. max = smp[i];
  464. }
  465. if(max < 0.00001f)
  466. max = 1.0f;
  467. for(int i = 0; i < size; ++i)
  468. smp[i] /= max;
  469. if(!Php.autoscale)
  470. return 0.5f;
  471. //compute the estimated perceived bandwidth
  472. float sum = 0.0f;
  473. int i;
  474. for(i = 0; i < size / 2 - 2; ++i) {
  475. sum += smp[i] * smp[i] + smp[size - i - 1] * smp[size - i - 1];
  476. if(sum >= 4.0f)
  477. break;
  478. }
  479. float result = 1.0f - 2.0f * i / (float) size;
  480. return result;
  481. }
  482. /*
  483. * Compute the real bandwidth in cents and returns it
  484. * Also, sets the bandwidth parameter
  485. */
  486. float PADnoteParameters::setPbandwidth(int Pbandwidth)
  487. {
  488. this->Pbandwidth = Pbandwidth;
  489. float result = powf(Pbandwidth / 1000.0f, 1.1f);
  490. result = powf(10.0f, result * 4.0f) * 0.25f;
  491. return result;
  492. }
  493. /*
  494. * Get the harmonic(overtone) position
  495. */
  496. float PADnoteParameters::getNhr(int n)
  497. {
  498. float result = 1.0f;
  499. const float par1 = powf(10.0f, -(1.0f - Phrpos.par1 / 255.0f) * 3.0f);
  500. const float par2 = Phrpos.par2 / 255.0f;
  501. const float n0 = n - 1.0f;
  502. float tmp = 0.0f;
  503. int thresh = 0;
  504. switch(Phrpos.type) {
  505. case 1:
  506. thresh = (int)(par2 * par2 * 100.0f) + 1;
  507. if(n < thresh)
  508. result = n;
  509. else
  510. result = 1.0f + n0 + (n0 - thresh + 1.0f) * par1 * 8.0f;
  511. break;
  512. case 2:
  513. thresh = (int)(par2 * par2 * 100.0f) + 1;
  514. if(n < thresh)
  515. result = n;
  516. else
  517. result = 1.0f + n0 - (n0 - thresh + 1.0f) * par1 * 0.90f;
  518. break;
  519. case 3:
  520. tmp = par1 * 100.0f + 1.0f;
  521. result = powf(n0 / tmp, 1.0f - par2 * 0.8f) * tmp + 1.0f;
  522. break;
  523. case 4:
  524. result = n0
  525. * (1.0f
  526. - par1)
  527. + powf(n0 * 0.1f, par2 * 3.0f
  528. + 1.0f) * par1 * 10.0f + 1.0f;
  529. break;
  530. case 5:
  531. result = n0
  532. + sinf(n0 * par2 * par2 * PI
  533. * 0.999f) * sqrt(par1) * 2.0f + 1.0f;
  534. break;
  535. case 6:
  536. tmp = powf(par2 * 2.0f, 2.0f) + 0.1f;
  537. result = n0 * powf(1.0f + par1 * powf(n0 * 0.8f, tmp), tmp) + 1.0f;
  538. break;
  539. case 7:
  540. result = (n + Phrpos.par1 / 255.0f) / (Phrpos.par1 / 255.0f + 1);
  541. break;
  542. default:
  543. result = n;
  544. break;
  545. }
  546. const float par3 = Phrpos.par3 / 255.0f;
  547. const float iresult = floor(result + 0.5f);
  548. const float dresult = result - iresult;
  549. return iresult + (1.0f - par3) * dresult;
  550. }
  551. //Transform non zero positive signals into ones with a max of one
  552. static void normalize_max(float *f, size_t len)
  553. {
  554. float max = 0.0f;
  555. for(unsigned i = 0; i < len; ++i)
  556. if(f[i] > i)
  557. max = f[i];
  558. if(max > 0.000001f)
  559. for(unsigned i = 0; i < len; ++i)
  560. f[i] /= max;
  561. }
  562. //Translate Bandwidth scale integer into floating point value
  563. static float Pbwscale_translate(char Pbwscale)
  564. {
  565. switch(Pbwscale) {
  566. case 0: return 1.0f;
  567. case 1: return 0.0f;
  568. case 2: return 0.25f;
  569. case 3: return 0.5f;
  570. case 4: return 0.75f;
  571. case 5: return 1.5f;
  572. case 6: return 2.0f;
  573. case 7: return -0.5f;
  574. default: return 1.0;
  575. }
  576. }
  577. /*
  578. * Generates the long spectrum for Bandwidth mode (only amplitudes are generated; phases will be random)
  579. */
  580. //Requires
  581. // - bandwidth scaling power
  582. // - bandwidth
  583. // - oscilator harmonics at various frequences (oodles of data)
  584. // - sampled resonance
  585. void PADnoteParameters::generatespectrum_bandwidthMode(float *spectrum,
  586. int size,
  587. float basefreq,
  588. float *profile,
  589. int profilesize,
  590. float bwadjust)
  591. {
  592. float harmonics[synth.oscilsize];
  593. memset(spectrum, 0, sizeof(float) * size);
  594. memset(harmonics, 0, sizeof(float) * synth.oscilsize);
  595. //get the harmonic structure from the oscillator (I am using the frequency amplitudes, only)
  596. oscilgen->get(harmonics, basefreq, false);
  597. //normalize
  598. normalize_max(harmonics, synth.oscilsize / 2);
  599. //Constants across harmonics
  600. const float power = Pbwscale_translate(Pbwscale);
  601. const float bandwidthcents = setPbandwidth(Pbandwidth);
  602. for(int nh = 1; nh < synth.oscilsize / 2; ++nh) { //for each harmonic
  603. const float realfreq = getNhr(nh) * basefreq;
  604. if(realfreq > synth.samplerate_f * 0.49999f)
  605. break;
  606. if(realfreq < 20.0f)
  607. break;
  608. if(harmonics[nh - 1] < 1e-4)
  609. continue;
  610. //compute the bandwidth of each harmonic
  611. const float bw =
  612. ((powf(2.0f, bandwidthcents / 1200.0f) - 1.0f) * basefreq / bwadjust)
  613. * powf(realfreq / basefreq, power);
  614. const int ibw = (int)((bw / (synth.samplerate_f * 0.5f) * size)) + 1;
  615. float amp = harmonics[nh - 1];
  616. if(resonance->Penabled)
  617. amp *= resonance->getfreqresponse(realfreq);
  618. if(ibw > profilesize) { //if the bandwidth is larger than the profilesize
  619. const float rap = sqrt((float)profilesize / (float)ibw);
  620. const int cfreq =
  621. (int) (realfreq
  622. / (synth.samplerate_f * 0.5f) * size) - ibw / 2;
  623. for(int i = 0; i < ibw; ++i) {
  624. const int src = i * rap * rap;
  625. const int spfreq = i + cfreq;
  626. if(spfreq < 0)
  627. continue;
  628. if(spfreq >= size)
  629. break;
  630. spectrum[spfreq] += amp * profile[src] * rap;
  631. }
  632. }
  633. else { //if the bandwidth is smaller than the profilesize
  634. const float rap = sqrt((float)ibw / (float)profilesize);
  635. const float ibasefreq = realfreq / (synth.samplerate_f * 0.5f) * size;
  636. for(int i = 0; i < profilesize; ++i) {
  637. const float idfreq = (i / (float)profilesize - 0.5f) * ibw;
  638. const float freqsum = idfreq + ibasefreq;
  639. const int spfreq = (int)freqsum;
  640. const float fspfreq = freqsum - spfreq;
  641. if(spfreq <= 0)
  642. continue;
  643. if(spfreq >= size - 1)
  644. break;
  645. spectrum[spfreq] += amp * profile[i] * rap
  646. * (1.0f - fspfreq);
  647. spectrum[spfreq + 1] += amp * profile[i] * rap * fspfreq;
  648. }
  649. }
  650. }
  651. }
  652. /*
  653. * Generates the long spectrum for non-Bandwidth modes (only amplitudes are generated; phases will be random)
  654. */
  655. void PADnoteParameters::generatespectrum_otherModes(float *spectrum,
  656. int size,
  657. float basefreq)
  658. {
  659. float harmonics[synth.oscilsize];
  660. memset(spectrum, 0, sizeof(float) * size);
  661. memset(harmonics, 0, sizeof(float) * synth.oscilsize);
  662. //get the harmonic structure from the oscillator (I am using the frequency amplitudes, only)
  663. oscilgen->get(harmonics, basefreq, false);
  664. //normalize
  665. normalize_max(harmonics, synth.oscilsize / 2);
  666. for(int nh = 1; nh < synth.oscilsize / 2; ++nh) { //for each harmonic
  667. const float realfreq = getNhr(nh) * basefreq;
  668. //take care of interpolation if frequency decreases
  669. if(realfreq > synth.samplerate_f * 0.49999f)
  670. break;
  671. if(realfreq < 20.0f)
  672. break;
  673. float amp = harmonics[nh - 1];
  674. if(resonance->Penabled)
  675. amp *= resonance->getfreqresponse(realfreq);
  676. const int cfreq = realfreq / (synth.samplerate_f * 0.5f) * size;
  677. spectrum[cfreq] = amp + 1e-9;
  678. }
  679. //In continous mode the spectrum gets additional interpolation between the
  680. //spectral peaks
  681. if(Pmode != 1) { //continous mode
  682. int old = 0;
  683. for(int k = 1; k < size; ++k)
  684. if((spectrum[k] > 1e-10) || (k == (size - 1))) {
  685. const int delta = k - old;
  686. const float val1 = spectrum[old];
  687. const float val2 = spectrum[k];
  688. const float idelta = 1.0f / delta;
  689. for(int i = 0; i < delta; ++i) {
  690. const float x = idelta * i;
  691. spectrum[old + i] = val1 * (1.0f - x) + val2 * x;
  692. }
  693. old = k;
  694. }
  695. }
  696. }
  697. /*
  698. * Applies the parameters (i.e. computes all the samples, based on parameters);
  699. */
  700. void PADnoteParameters::applyparameters()
  701. {
  702. applyparameters([]{return false;});
  703. }
  704. void PADnoteParameters::applyparameters(std::function<bool()> do_abort)
  705. {
  706. if(do_abort())
  707. return;
  708. unsigned max = 0;
  709. sampleGenerator([&max,this]
  710. (unsigned N, PADnoteParameters::Sample &smp) {
  711. delete[] sample[N].smp;
  712. sample[N] = smp;
  713. max = max < N ? N : max;
  714. },
  715. do_abort);
  716. //Delete remaining unused samples
  717. for(unsigned i = max; i < PAD_MAX_SAMPLES; ++i)
  718. deletesample(i);
  719. }
  720. //Requires
  721. // - Pquality.samplesize
  722. // - Pquality.basenote
  723. // - Pquality.oct
  724. // - Pquality.smpoct
  725. // - spectrum at various frequencies (oodles of data)
  726. void PADnoteParameters::sampleGenerator(PADnoteParameters::callback cb,
  727. std::function<bool()> do_abort)
  728. {
  729. const int samplesize = (((int) 1) << (Pquality.samplesize + 14));
  730. const int spectrumsize = samplesize / 2;
  731. float *spectrum = new float[spectrumsize];
  732. const int profilesize = 512;
  733. float profile[profilesize];
  734. const float bwadjust = getprofile(profile, profilesize);
  735. float basefreq = 65.406f * powf(2.0f, Pquality.basenote / 2);
  736. if(Pquality.basenote % 2 == 1)
  737. basefreq *= 1.5f;
  738. int samplemax = Pquality.oct + 1;
  739. int smpoct = Pquality.smpoct;
  740. if(Pquality.smpoct == 5)
  741. smpoct = 6;
  742. if(Pquality.smpoct == 6)
  743. smpoct = 12;
  744. if(smpoct != 0)
  745. samplemax *= smpoct;
  746. else
  747. samplemax = samplemax / 2 + 1;
  748. if(samplemax == 0)
  749. samplemax = 1;
  750. //prepare a BIG FFT
  751. FFTwrapper *fft = new FFTwrapper(samplesize);
  752. fft_t *fftfreqs = new fft_t[samplesize / 2];
  753. //this is used to compute frequency relation to the base frequency
  754. float adj[samplemax];
  755. for(int nsample = 0; nsample < samplemax; ++nsample)
  756. adj[nsample] = (Pquality.oct + 1.0f) * (float)nsample / samplemax;
  757. for(int nsample = 0; nsample < samplemax; ++nsample) {
  758. if(do_abort())
  759. goto exit;
  760. const float basefreqadjust =
  761. powf(2.0f, adj[nsample] - adj[samplemax - 1] * 0.5f);
  762. if(Pmode == 0)
  763. generatespectrum_bandwidthMode(spectrum,
  764. spectrumsize,
  765. basefreq * basefreqadjust,
  766. profile,
  767. profilesize,
  768. bwadjust);
  769. else
  770. generatespectrum_otherModes(spectrum, spectrumsize,
  771. basefreq * basefreqadjust);
  772. //the last samples contains the first samples
  773. //(used for linear/cubic interpolation)
  774. const int extra_samples = 5;
  775. PADnoteParameters::Sample newsample;
  776. newsample.smp = new float[samplesize + extra_samples];
  777. newsample.smp[0] = 0.0f;
  778. for(int i = 1; i < spectrumsize; ++i) //randomize the phases
  779. fftfreqs[i] = FFTpolar(spectrum[i], (float)RND * 2 * PI);
  780. //that's all; here is the only ifft for the whole sample;
  781. //no windows are used ;-)
  782. fft->freqs2smps(fftfreqs, newsample.smp);
  783. //normalize(rms)
  784. float rms = 0.0f;
  785. for(int i = 0; i < samplesize; ++i)
  786. rms += newsample.smp[i] * newsample.smp[i];
  787. rms = sqrt(rms);
  788. if(rms < 0.000001f)
  789. rms = 1.0f;
  790. rms *= sqrt(262144.0f / samplesize);//262144=2^18
  791. for(int i = 0; i < samplesize; ++i)
  792. newsample.smp[i] *= 1.0f / rms * 50.0f;
  793. //prepare extra samples used by the linear or cubic interpolation
  794. for(int i = 0; i < extra_samples; ++i)
  795. newsample.smp[i + samplesize] = newsample.smp[i];
  796. //yield new sample
  797. newsample.size = samplesize;
  798. newsample.basefreq = basefreq * basefreqadjust;
  799. cb(nsample, newsample);
  800. }
  801. exit:
  802. //Cleanup
  803. delete (fft);
  804. delete[] fftfreqs;
  805. delete[] spectrum;
  806. }
  807. void PADnoteParameters::export2wav(std::string basefilename)
  808. {
  809. applyparameters();
  810. basefilename += "_PADsynth_";
  811. for(int k = 0; k < PAD_MAX_SAMPLES; ++k) {
  812. if(sample[k].smp == NULL)
  813. continue;
  814. char tmpstr[20];
  815. snprintf(tmpstr, 20, "_%02d", k + 1);
  816. std::string filename = basefilename + std::string(tmpstr) + ".wav";
  817. WavFile wav(filename, synth.samplerate, 1);
  818. if(wav.good()) {
  819. int nsmps = sample[k].size;
  820. short int *smps = new short int[nsmps];
  821. for(int i = 0; i < nsmps; ++i)
  822. smps[i] = (short int)(sample[k].smp[i] * 32767.0f);
  823. wav.writeMonoSamples(nsmps, smps);
  824. }
  825. }
  826. }
  827. void PADnoteParameters::add2XML(XMLwrapper& xml)
  828. {
  829. xml.setPadSynth(true);
  830. xml.addparbool("stereo", PStereo);
  831. xml.addpar("mode", Pmode);
  832. xml.addpar("bandwidth", Pbandwidth);
  833. xml.addpar("bandwidth_scale", Pbwscale);
  834. xml.beginbranch("HARMONIC_PROFILE");
  835. xml.addpar("base_type", Php.base.type);
  836. xml.addpar("base_par1", Php.base.par1);
  837. xml.addpar("frequency_multiplier", Php.freqmult);
  838. xml.addpar("modulator_par1", Php.modulator.par1);
  839. xml.addpar("modulator_frequency", Php.modulator.freq);
  840. xml.addpar("width", Php.width);
  841. xml.addpar("amplitude_multiplier_type", Php.amp.type);
  842. xml.addpar("amplitude_multiplier_mode", Php.amp.mode);
  843. xml.addpar("amplitude_multiplier_par1", Php.amp.par1);
  844. xml.addpar("amplitude_multiplier_par2", Php.amp.par2);
  845. xml.addparbool("autoscale", Php.autoscale);
  846. xml.addpar("one_half", Php.onehalf);
  847. xml.endbranch();
  848. xml.beginbranch("OSCIL");
  849. oscilgen->add2XML(xml);
  850. xml.endbranch();
  851. xml.beginbranch("RESONANCE");
  852. resonance->add2XML(xml);
  853. xml.endbranch();
  854. xml.beginbranch("HARMONIC_POSITION");
  855. xml.addpar("type", Phrpos.type);
  856. xml.addpar("parameter1", Phrpos.par1);
  857. xml.addpar("parameter2", Phrpos.par2);
  858. xml.addpar("parameter3", Phrpos.par3);
  859. xml.endbranch();
  860. xml.beginbranch("SAMPLE_QUALITY");
  861. xml.addpar("samplesize", Pquality.samplesize);
  862. xml.addpar("basenote", Pquality.basenote);
  863. xml.addpar("octaves", Pquality.oct);
  864. xml.addpar("samples_per_octave", Pquality.smpoct);
  865. xml.endbranch();
  866. xml.beginbranch("AMPLITUDE_PARAMETERS");
  867. xml.addpar("volume", PVolume);
  868. xml.addpar("panning", PPanning);
  869. xml.addpar("velocity_sensing", PAmpVelocityScaleFunction);
  870. xml.addpar("fadein_adjustment", Fadein_adjustment);
  871. xml.addpar("punch_strength", PPunchStrength);
  872. xml.addpar("punch_time", PPunchTime);
  873. xml.addpar("punch_stretch", PPunchStretch);
  874. xml.addpar("punch_velocity_sensing", PPunchVelocitySensing);
  875. xml.beginbranch("AMPLITUDE_ENVELOPE");
  876. AmpEnvelope->add2XML(xml);
  877. xml.endbranch();
  878. xml.beginbranch("AMPLITUDE_LFO");
  879. AmpLfo->add2XML(xml);
  880. xml.endbranch();
  881. xml.endbranch();
  882. xml.beginbranch("FREQUENCY_PARAMETERS");
  883. xml.addpar("fixed_freq", Pfixedfreq);
  884. xml.addpar("fixed_freq_et", PfixedfreqET);
  885. xml.addpar("bend_adjust", PBendAdjust);
  886. xml.addpar("offset_hz", POffsetHz);
  887. xml.addpar("detune", PDetune);
  888. xml.addpar("coarse_detune", PCoarseDetune);
  889. xml.addpar("detune_type", PDetuneType);
  890. xml.beginbranch("FREQUENCY_ENVELOPE");
  891. FreqEnvelope->add2XML(xml);
  892. xml.endbranch();
  893. xml.beginbranch("FREQUENCY_LFO");
  894. FreqLfo->add2XML(xml);
  895. xml.endbranch();
  896. xml.endbranch();
  897. xml.beginbranch("FILTER_PARAMETERS");
  898. xml.addpar("velocity_sensing_amplitude", PFilterVelocityScale);
  899. xml.addpar("velocity_sensing", PFilterVelocityScaleFunction);
  900. xml.beginbranch("FILTER");
  901. GlobalFilter->add2XML(xml);
  902. xml.endbranch();
  903. xml.beginbranch("FILTER_ENVELOPE");
  904. FilterEnvelope->add2XML(xml);
  905. xml.endbranch();
  906. xml.beginbranch("FILTER_LFO");
  907. FilterLfo->add2XML(xml);
  908. xml.endbranch();
  909. xml.endbranch();
  910. }
  911. void PADnoteParameters::getfromXML(XMLwrapper& xml)
  912. {
  913. PStereo = xml.getparbool("stereo", PStereo);
  914. Pmode = xml.getpar127("mode", 0);
  915. Pbandwidth = xml.getpar("bandwidth", Pbandwidth, 0, 1000);
  916. Pbwscale = xml.getpar127("bandwidth_scale", Pbwscale);
  917. if(xml.enterbranch("HARMONIC_PROFILE")) {
  918. Php.base.type = xml.getpar127("base_type", Php.base.type);
  919. Php.base.par1 = xml.getpar127("base_par1", Php.base.par1);
  920. Php.freqmult = xml.getpar127("frequency_multiplier",
  921. Php.freqmult);
  922. Php.modulator.par1 = xml.getpar127("modulator_par1",
  923. Php.modulator.par1);
  924. Php.modulator.freq = xml.getpar127("modulator_frequency",
  925. Php.modulator.freq);
  926. Php.width = xml.getpar127("width", Php.width);
  927. Php.amp.type = xml.getpar127("amplitude_multiplier_type",
  928. Php.amp.type);
  929. Php.amp.mode = xml.getpar127("amplitude_multiplier_mode",
  930. Php.amp.mode);
  931. Php.amp.par1 = xml.getpar127("amplitude_multiplier_par1",
  932. Php.amp.par1);
  933. Php.amp.par2 = xml.getpar127("amplitude_multiplier_par2",
  934. Php.amp.par2);
  935. Php.autoscale = xml.getparbool("autoscale", Php.autoscale);
  936. Php.onehalf = xml.getpar127("one_half", Php.onehalf);
  937. xml.exitbranch();
  938. }
  939. if(xml.enterbranch("OSCIL")) {
  940. oscilgen->getfromXML(xml);
  941. xml.exitbranch();
  942. }
  943. if(xml.enterbranch("RESONANCE")) {
  944. resonance->getfromXML(xml);
  945. xml.exitbranch();
  946. }
  947. if(xml.enterbranch("HARMONIC_POSITION")) {
  948. Phrpos.type = xml.getpar127("type", Phrpos.type);
  949. Phrpos.par1 = xml.getpar("parameter1", Phrpos.par1, 0, 255);
  950. Phrpos.par2 = xml.getpar("parameter2", Phrpos.par2, 0, 255);
  951. Phrpos.par3 = xml.getpar("parameter3", Phrpos.par3, 0, 255);
  952. xml.exitbranch();
  953. }
  954. if(xml.enterbranch("SAMPLE_QUALITY")) {
  955. Pquality.samplesize = xml.getpar127("samplesize", Pquality.samplesize);
  956. Pquality.basenote = xml.getpar127("basenote", Pquality.basenote);
  957. Pquality.oct = xml.getpar127("octaves", Pquality.oct);
  958. Pquality.smpoct = xml.getpar127("samples_per_octave",
  959. Pquality.smpoct);
  960. xml.exitbranch();
  961. }
  962. if(xml.enterbranch("AMPLITUDE_PARAMETERS")) {
  963. PVolume = xml.getpar127("volume", PVolume);
  964. PPanning = xml.getpar127("panning", PPanning);
  965. PAmpVelocityScaleFunction = xml.getpar127("velocity_sensing",
  966. PAmpVelocityScaleFunction);
  967. Fadein_adjustment = xml.getpar127("fadein_adjustment", Fadein_adjustment);
  968. PPunchStrength = xml.getpar127("punch_strength", PPunchStrength);
  969. PPunchTime = xml.getpar127("punch_time", PPunchTime);
  970. PPunchStretch = xml.getpar127("punch_stretch", PPunchStretch);
  971. PPunchVelocitySensing = xml.getpar127("punch_velocity_sensing",
  972. PPunchVelocitySensing);
  973. xml.enterbranch("AMPLITUDE_ENVELOPE");
  974. AmpEnvelope->getfromXML(xml);
  975. xml.exitbranch();
  976. xml.enterbranch("AMPLITUDE_LFO");
  977. AmpLfo->getfromXML(xml);
  978. xml.exitbranch();
  979. xml.exitbranch();
  980. }
  981. if(xml.enterbranch("FREQUENCY_PARAMETERS")) {
  982. Pfixedfreq = xml.getpar127("fixed_freq", Pfixedfreq);
  983. PfixedfreqET = xml.getpar127("fixed_freq_et", PfixedfreqET);
  984. PBendAdjust = xml.getpar127("bend_adjust", PBendAdjust);
  985. POffsetHz = xml.getpar127("offset_hz", POffsetHz);
  986. PDetune = xml.getpar("detune", PDetune, 0, 16383);
  987. PCoarseDetune = xml.getpar("coarse_detune", PCoarseDetune, 0, 16383);
  988. PDetuneType = xml.getpar127("detune_type", PDetuneType);
  989. xml.enterbranch("FREQUENCY_ENVELOPE");
  990. FreqEnvelope->getfromXML(xml);
  991. xml.exitbranch();
  992. xml.enterbranch("FREQUENCY_LFO");
  993. FreqLfo->getfromXML(xml);
  994. xml.exitbranch();
  995. xml.exitbranch();
  996. }
  997. if(xml.enterbranch("FILTER_PARAMETERS")) {
  998. PFilterVelocityScale = xml.getpar127("velocity_sensing_amplitude",
  999. PFilterVelocityScale);
  1000. PFilterVelocityScaleFunction = xml.getpar127(
  1001. "velocity_sensing",
  1002. PFilterVelocityScaleFunction);
  1003. xml.enterbranch("FILTER");
  1004. GlobalFilter->getfromXML(xml);
  1005. xml.exitbranch();
  1006. xml.enterbranch("FILTER_ENVELOPE");
  1007. FilterEnvelope->getfromXML(xml);
  1008. xml.exitbranch();
  1009. xml.enterbranch("FILTER_LFO");
  1010. FilterLfo->getfromXML(xml);
  1011. xml.exitbranch();
  1012. xml.exitbranch();
  1013. }
  1014. }
  1015. #define COPY(y) this->y = x.y
  1016. void PADnoteParameters::paste(PADnoteParameters &x)
  1017. {
  1018. COPY(Pmode);
  1019. COPY(Php.base.type);
  1020. COPY(Php.base.par1);
  1021. COPY(Php.freqmult);
  1022. COPY(Php.modulator.par1);
  1023. COPY(Php.modulator.freq);
  1024. COPY(Php.width);
  1025. COPY(Php.amp.mode);
  1026. COPY(Php.amp.type);
  1027. COPY(Php.amp.par1);
  1028. COPY(Php.amp.par2);
  1029. COPY(Php.autoscale);
  1030. COPY(Php.onehalf);
  1031. COPY(Pbandwidth);
  1032. COPY(Pbwscale);
  1033. COPY(Phrpos.type);
  1034. COPY(Phrpos.par1);
  1035. COPY(Phrpos.par2);
  1036. COPY(Phrpos.par3);
  1037. COPY(Pquality.samplesize);
  1038. COPY(Pquality.basenote);
  1039. COPY(Pquality.oct);
  1040. COPY(Pquality.smpoct);
  1041. oscilgen->paste(*x.oscilgen);
  1042. resonance->paste(*x.resonance);
  1043. if ( time ) {
  1044. last_update_timestamp = time->time();
  1045. }
  1046. }
  1047. void PADnoteParameters::pasteRT(PADnoteParameters &x)
  1048. {
  1049. //Realtime stuff
  1050. COPY(Pfixedfreq);
  1051. COPY(PfixedfreqET);
  1052. COPY(PBendAdjust);
  1053. COPY(POffsetHz);
  1054. COPY(PDetune);
  1055. COPY(PCoarseDetune);
  1056. COPY(PDetuneType);
  1057. FreqEnvelope->paste(*x.FreqEnvelope);
  1058. FreqLfo->paste(*x.FreqLfo);
  1059. COPY(PStereo);
  1060. COPY(PPanning);
  1061. COPY(PVolume);
  1062. COPY(PAmpVelocityScaleFunction);
  1063. AmpEnvelope->paste(*x.AmpEnvelope);
  1064. AmpLfo->paste(*x.AmpLfo);
  1065. COPY(Fadein_adjustment);
  1066. COPY(PPunchStrength);
  1067. COPY(PPunchTime);
  1068. COPY(PPunchStretch);
  1069. COPY(PPunchVelocitySensing);
  1070. GlobalFilter->paste(*x.GlobalFilter);
  1071. COPY(PFilterVelocityScale);
  1072. COPY(PFilterVelocityScaleFunction);
  1073. FilterEnvelope->paste(*x.FilterEnvelope);
  1074. FilterLfo->paste(*x.FilterLfo);
  1075. if ( time ) {
  1076. last_update_timestamp = time->time();
  1077. }
  1078. }
  1079. #undef COPY