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.

1078 lines
34KB

  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 modify
  7. it under the terms of version 2 of the GNU General Public License
  8. as published by the Free Software Foundation.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License (version 2 or later) for more details.
  13. You should have received a copy of the GNU General Public License (version 2)
  14. along with this program; if not, write to the Free Software Foundation,
  15. Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  16. */
  17. #include <cmath>
  18. #include "PADnoteParameters.h"
  19. #include "FilterParams.h"
  20. #include "EnvelopeParams.h"
  21. #include "LFOParams.h"
  22. #include "../Synth/Resonance.h"
  23. #include "../Synth/OscilGen.h"
  24. #include "../Misc/WavFile.h"
  25. #include <cstdio>
  26. #include <rtosc/ports.h>
  27. #include <rtosc/port-sugar.h>
  28. using namespace rtosc;
  29. #define PC(x) rParamZyn(P##x, "undocumented padnote parameter")
  30. template<int i>
  31. void simpleset(const char *m, rtosc::RtData &d)
  32. {
  33. unsigned char *addr = ((unsigned char*) d.obj)+i;
  34. if(!rtosc_narguments(m))
  35. d.reply(d.loc, "c", *addr);
  36. else
  37. *addr = rtosc_argument(m, 0).i;
  38. }
  39. #define rObject PADnoteParameters
  40. #define P_C(x) rtosc::Port{#x "::c", "::", NULL, \
  41. simpleset<__builtin_offsetof(class PADnoteParameters, P##x)>}
  42. static const rtosc::Ports PADnotePorts =
  43. {
  44. rRecurp(oscilgen, "Oscillator"),
  45. rRecurp(FreqLfo, "Frequency LFO"),
  46. rRecurp(AmpLfo, "Amplitude LFO"),
  47. rRecurp(FilterLfo, "Filter LFO"),
  48. rRecurp(resonance, "Resonance"),
  49. rRecurp(FreqEnvelope, "Frequency Envelope"),
  50. rRecurp(AmpEnvelope, "Amplitude Envelope"),
  51. rRecurp(FilterEnvelope, "Filter Envelope"),
  52. rRecurp(GlobalFilter, "Post Filter"),
  53. rParamI(Pmode, rMap(min, 0), rMap(max, 2), "0 - bandwidth, 1 - discrete 2 - continious"),
  54. PC(Volume),
  55. PC(hp.base.type),
  56. PC(hp.base.par1),
  57. PC(hp.freqmult),
  58. PC(hp.modulator.par1),
  59. PC(hp.modulator.freq),
  60. PC(hp.width),
  61. PC(hp.amp.mode),
  62. PC(hp.amp.type),
  63. PC(hp.amp.par1),
  64. PC(hp.amp.par2),
  65. rToggle(Php.autoscale, "Autoscaling Harmonics"),
  66. PC(hp.onehalf),
  67. PC(bwscale),
  68. PC(hrpos.type),
  69. PC(hrpos.par1),
  70. PC(hrpos.par2),
  71. PC(hrpos.par3),
  72. PC(quality.samplesize),
  73. PC(quality.basenote),
  74. PC(quality.oct),
  75. PC(quality.smpoct),
  76. PC(fixedfreq),
  77. PC(fixedfreqET),
  78. //TODO detune, coarse detune
  79. PC(DetuneType),
  80. PC(Stereo),
  81. PC(Panning),
  82. PC(AmpVelocityScaleFunction),
  83. PC(PunchStrength),
  84. PC(PunchTime),
  85. PC(PunchStretch),
  86. PC(PunchVelocitySensing),
  87. PC(FilterVelocityScale),
  88. PC(FilterVelocityScaleFunction),
  89. rParamI(PDetune, "Fine Detune"),
  90. rParamI(PCoarseDetune, "Coarse Detune"),
  91. rParamZyn(PDetuneType, "Magnitude of Detune"),
  92. {"Pbandwidth::i", rProp(parameter) rDoc("Bandwith Of Harmonics"), NULL,
  93. [](const char *msg, rtosc::RtData &d) {
  94. PADnoteParameters *p = ((PADnoteParameters*)d.obj);
  95. if(rtosc_narguments(msg)) {
  96. p->setPbandwidth(rtosc_argument(msg, 0).i);
  97. } else {
  98. d.reply(d.loc, "i", p->Pbandwidth);
  99. }}},
  100. {"bandwidthvalue:", NULL, NULL,
  101. [](const char *, rtosc::RtData &d) {
  102. PADnoteParameters *p = ((PADnoteParameters*)d.obj);
  103. d.reply(d.loc, "f", p->setPbandwidth(p->Pbandwidth));
  104. }},
  105. {"nhr:", rProp(non-realtime) rDoc("Returns the harmonic shifts"),
  106. NULL, [](const char *, rtosc::RtData &d) {
  107. PADnoteParameters *p = ((PADnoteParameters*)d.obj);
  108. const unsigned n = p->synth.oscilsize / 2;
  109. float *tmp = new float[n];
  110. *tmp = 0;
  111. for(unsigned i=1; i<n; ++i)
  112. tmp[i] = p->getNhr(i);
  113. d.reply(d.loc, "b", n*sizeof(float), tmp);
  114. delete[] tmp;}},
  115. {"profile:i", rProp(non-realtime) rDoc("UI display of the harmonic profile"),
  116. NULL, [](const char *m, rtosc::RtData &d) {
  117. PADnoteParameters *p = ((PADnoteParameters*)d.obj);
  118. const int n = rtosc_argument(m, 0).i;
  119. if(n<=0)
  120. return;
  121. float *tmp = new float[n];
  122. float realbw = p->getprofile(tmp, n);
  123. d.reply(d.loc, "b", n*sizeof(float), tmp);
  124. d.reply(d.loc, "i", realbw);
  125. delete[] tmp;}},
  126. {"sample#64:ifb", rDoc("Nothing to see here"), 0,
  127. [](const char *m, rtosc::RtData &d)
  128. {
  129. PADnoteParameters *p = (PADnoteParameters*)d.obj;
  130. const char *mm = m;
  131. while(!isdigit(*mm))++mm;
  132. unsigned n = atoi(mm);
  133. p->sample[n].size = rtosc_argument(m,0).i;
  134. p->sample[n].basefreq = rtosc_argument(m,1).f;
  135. p->sample[n].smp = *(float**)rtosc_argument(m,2).b.data;
  136. //XXX TODO memory managment (deallocation of smp buffer)
  137. }},
  138. //weird stuff for PCoarseDetune
  139. {"detunevalue:", NULL, NULL, [](const char *, RtData &d)
  140. {
  141. PADnoteParameters *obj = (PADnoteParameters *)d.obj;
  142. d.reply(d.loc, "f", getdetune(obj->PDetuneType, 0, obj->PDetune));
  143. }},
  144. {"octave::c:i", NULL, NULL, [](const char *msg, RtData &d)
  145. {
  146. PADnoteParameters *obj = (PADnoteParameters *)d.obj;
  147. if(!rtosc_narguments(msg)) {
  148. int k=obj->PCoarseDetune/1024;
  149. if (k>=8) k-=16;
  150. d.reply(d.loc, "i", k);
  151. } else {
  152. int k=(int) rtosc_argument(msg, 0).i;
  153. if (k<0) k+=16;
  154. obj->PCoarseDetune = k*1024 + obj->PCoarseDetune%1024;
  155. }
  156. }},
  157. {"coarsedetune::c:i", NULL, NULL, [](const char *msg, RtData &d)
  158. {
  159. PADnoteParameters *obj = (PADnoteParameters *)d.obj;
  160. if(!rtosc_narguments(msg)) {
  161. int k=obj->PCoarseDetune%1024;
  162. if (k>=512) k-=1024;
  163. d.reply(d.loc, "i", k);
  164. } else {
  165. int k=(int) rtosc_argument(msg, 0).i;
  166. if (k<0) k+=1024;
  167. obj->PCoarseDetune = k + (obj->PCoarseDetune/1024)*1024;
  168. }
  169. }},
  170. };
  171. const rtosc::Ports &PADnoteParameters::ports = PADnotePorts;
  172. PADnoteParameters::PADnoteParameters(const SYNTH_T &synth_, FFTwrapper *fft_)
  173. :Presets(), synth(synth_)
  174. {
  175. setpresettype("Ppadsynth");
  176. fft = fft_;
  177. resonance = new Resonance();
  178. oscilgen = new OscilGen(synth, fft_, resonance);
  179. oscilgen->ADvsPAD = true;
  180. FreqEnvelope = new EnvelopeParams(0, 0);
  181. FreqEnvelope->ASRinit(64, 50, 64, 60);
  182. FreqLfo = new LFOParams(70, 0, 64, 0, 0, 0, 0, 0);
  183. AmpEnvelope = new EnvelopeParams(64, 1);
  184. AmpEnvelope->ADSRinit_dB(0, 40, 127, 25);
  185. AmpLfo = new LFOParams(80, 0, 64, 0, 0, 0, 0, 1);
  186. GlobalFilter = new FilterParams(2, 94, 40);
  187. FilterEnvelope = new EnvelopeParams(0, 1);
  188. FilterEnvelope->ADSRinit_filter(64, 40, 64, 70, 60, 64);
  189. FilterLfo = new LFOParams(80, 0, 64, 0, 0, 0, 0, 2);
  190. for(int i = 0; i < PAD_MAX_SAMPLES; ++i)
  191. sample[i].smp = NULL;
  192. defaults();
  193. }
  194. PADnoteParameters::~PADnoteParameters()
  195. {
  196. deletesamples();
  197. delete (oscilgen);
  198. delete (resonance);
  199. delete (FreqEnvelope);
  200. delete (FreqLfo);
  201. delete (AmpEnvelope);
  202. delete (AmpLfo);
  203. delete (GlobalFilter);
  204. delete (FilterEnvelope);
  205. delete (FilterLfo);
  206. }
  207. void PADnoteParameters::defaults()
  208. {
  209. Pmode = 0;
  210. Php.base.type = 0;
  211. Php.base.par1 = 80;
  212. Php.freqmult = 0;
  213. Php.modulator.par1 = 0;
  214. Php.modulator.freq = 30;
  215. Php.width = 127;
  216. Php.amp.type = 0;
  217. Php.amp.mode = 0;
  218. Php.amp.par1 = 80;
  219. Php.amp.par2 = 64;
  220. Php.autoscale = true;
  221. Php.onehalf = 0;
  222. setPbandwidth(500);
  223. Pbwscale = 0;
  224. resonance->defaults();
  225. oscilgen->defaults();
  226. Phrpos.type = 0;
  227. Phrpos.par1 = 64;
  228. Phrpos.par2 = 64;
  229. Phrpos.par3 = 0;
  230. Pquality.samplesize = 3;
  231. Pquality.basenote = 4;
  232. Pquality.oct = 3;
  233. Pquality.smpoct = 2;
  234. PStereo = 1; //stereo
  235. /* Frequency Global Parameters */
  236. Pfixedfreq = 0;
  237. PfixedfreqET = 0;
  238. PDetune = 8192; //zero
  239. PCoarseDetune = 0;
  240. PDetuneType = 1;
  241. FreqEnvelope->defaults();
  242. FreqLfo->defaults();
  243. /* Amplitude Global Parameters */
  244. PVolume = 90;
  245. PPanning = 64; //center
  246. PAmpVelocityScaleFunction = 64;
  247. AmpEnvelope->defaults();
  248. AmpLfo->defaults();
  249. PPunchStrength = 0;
  250. PPunchTime = 60;
  251. PPunchStretch = 64;
  252. PPunchVelocitySensing = 72;
  253. /* Filter Global Parameters*/
  254. PFilterVelocityScale = 64;
  255. PFilterVelocityScaleFunction = 64;
  256. GlobalFilter->defaults();
  257. FilterEnvelope->defaults();
  258. FilterLfo->defaults();
  259. deletesamples();
  260. }
  261. void PADnoteParameters::deletesample(int n)
  262. {
  263. if((n < 0) || (n >= PAD_MAX_SAMPLES))
  264. return;
  265. delete[] sample[n].smp;
  266. sample[n].smp = NULL;
  267. sample[n].size = 0;
  268. sample[n].basefreq = 440.0f;
  269. }
  270. void PADnoteParameters::deletesamples()
  271. {
  272. for(int i = 0; i < PAD_MAX_SAMPLES; ++i)
  273. deletesample(i);
  274. }
  275. /*
  276. * Get the harmonic profile (i.e. the frequency distributio of a single harmonic)
  277. */
  278. float PADnoteParameters::getprofile(float *smp, int size)
  279. {
  280. for(int i = 0; i < size; ++i)
  281. smp[i] = 0.0f;
  282. const int supersample = 16;
  283. float basepar = powf(2.0f, (1.0f - Php.base.par1 / 127.0f) * 12.0f);
  284. float freqmult = floor(powf(2.0f,
  285. Php.freqmult / 127.0f
  286. * 5.0f) + 0.000001f);
  287. float modfreq = floor(powf(2.0f,
  288. Php.modulator.freq / 127.0f
  289. * 5.0f) + 0.000001f);
  290. float modpar1 = powf(Php.modulator.par1 / 127.0f, 4.0f) * 5.0f / sqrt(
  291. modfreq);
  292. float amppar1 =
  293. powf(2.0f, powf(Php.amp.par1 / 127.0f, 2.0f) * 10.0f) - 0.999f;
  294. float amppar2 = (1.0f - Php.amp.par2 / 127.0f) * 0.998f + 0.001f;
  295. float width = powf(150.0f / (Php.width + 22.0f), 2.0f);
  296. for(int i = 0; i < size * supersample; ++i) {
  297. bool makezero = false;
  298. float x = i * 1.0f / (size * (float) supersample);
  299. float origx = x;
  300. //do the sizing (width)
  301. x = (x - 0.5f) * width + 0.5f;
  302. if(x < 0.0f) {
  303. x = 0.0f;
  304. makezero = true;
  305. }
  306. else
  307. if(x > 1.0f) {
  308. x = 1.0f;
  309. makezero = true;
  310. }
  311. //compute the full profile or one half
  312. switch(Php.onehalf) {
  313. case 1:
  314. x = x * 0.5f + 0.5f;
  315. break;
  316. case 2:
  317. x = x * 0.5f;
  318. break;
  319. }
  320. float x_before_freq_mult = x;
  321. //do the frequency multiplier
  322. x *= freqmult;
  323. //do the modulation of the profile
  324. x += sinf(x_before_freq_mult * 3.1415926f * modfreq) * modpar1;
  325. x = fmod(x + 1000.0f, 1.0f) * 2.0f - 1.0f;
  326. //this is the base function of the profile
  327. float f;
  328. switch(Php.base.type) {
  329. case 1:
  330. f = expf(-(x * x) * basepar);
  331. if(f < 0.4f)
  332. f = 0.0f;
  333. else
  334. f = 1.0f;
  335. break;
  336. case 2:
  337. f = expf(-(fabs(x)) * sqrt(basepar));
  338. break;
  339. default:
  340. f = expf(-(x * x) * basepar);
  341. break;
  342. }
  343. if(makezero)
  344. f = 0.0f;
  345. float amp = 1.0f;
  346. origx = origx * 2.0f - 1.0f;
  347. //compute the amplitude multiplier
  348. switch(Php.amp.type) {
  349. case 1:
  350. amp = expf(-(origx * origx) * 10.0f * amppar1);
  351. break;
  352. case 2:
  353. amp = 0.5f
  354. * (1.0f
  355. + cosf(3.1415926f * origx * sqrt(amppar1 * 4.0f + 1.0f)));
  356. break;
  357. case 3:
  358. amp = 1.0f
  359. / (powf(origx * (amppar1 * 2.0f + 0.8f), 14.0f) + 1.0f);
  360. break;
  361. }
  362. //apply the amplitude multiplier
  363. float finalsmp = f;
  364. if(Php.amp.type != 0)
  365. switch(Php.amp.mode) {
  366. case 0:
  367. finalsmp = amp * (1.0f - amppar2) + finalsmp * amppar2;
  368. break;
  369. case 1:
  370. finalsmp *= amp * (1.0f - amppar2) + amppar2;
  371. break;
  372. case 2:
  373. finalsmp = finalsmp
  374. / (amp + powf(amppar2, 4.0f) * 20.0f + 0.0001f);
  375. break;
  376. case 3:
  377. finalsmp = amp
  378. / (finalsmp
  379. + powf(amppar2, 4.0f) * 20.0f + 0.0001f);
  380. break;
  381. }
  382. ;
  383. smp[i / supersample] += finalsmp / supersample;
  384. }
  385. //normalize the profile (make the max. to be equal to 1.0f)
  386. float max = 0.0f;
  387. for(int i = 0; i < size; ++i) {
  388. if(smp[i] < 0.0f)
  389. smp[i] = 0.0f;
  390. if(smp[i] > max)
  391. max = smp[i];
  392. }
  393. if(max < 0.00001f)
  394. max = 1.0f;
  395. for(int i = 0; i < size; ++i)
  396. smp[i] /= max;
  397. if(!Php.autoscale)
  398. return 0.5f;
  399. //compute the estimated perceived bandwidth
  400. float sum = 0.0f;
  401. int i;
  402. for(i = 0; i < size / 2 - 2; ++i) {
  403. sum += smp[i] * smp[i] + smp[size - i - 1] * smp[size - i - 1];
  404. if(sum >= 4.0f)
  405. break;
  406. }
  407. float result = 1.0f - 2.0f * i / (float) size;
  408. return result;
  409. }
  410. /*
  411. * Compute the real bandwidth in cents and returns it
  412. * Also, sets the bandwidth parameter
  413. */
  414. float PADnoteParameters::setPbandwidth(int Pbandwidth)
  415. {
  416. this->Pbandwidth = Pbandwidth;
  417. float result = powf(Pbandwidth / 1000.0f, 1.1f);
  418. result = powf(10.0f, result * 4.0f) * 0.25f;
  419. return result;
  420. }
  421. /*
  422. * Get the harmonic(overtone) position
  423. */
  424. float PADnoteParameters::getNhr(int n)
  425. {
  426. float result = 1.0f;
  427. const float par1 = powf(10.0f, -(1.0f - Phrpos.par1 / 255.0f) * 3.0f);
  428. const float par2 = Phrpos.par2 / 255.0f;
  429. const float n0 = n - 1.0f;
  430. float tmp = 0.0f;
  431. int thresh = 0;
  432. switch(Phrpos.type) {
  433. case 1:
  434. thresh = (int)(par2 * par2 * 100.0f) + 1;
  435. if(n < thresh)
  436. result = n;
  437. else
  438. result = 1.0f + n0 + (n0 - thresh + 1.0f) * par1 * 8.0f;
  439. break;
  440. case 2:
  441. thresh = (int)(par2 * par2 * 100.0f) + 1;
  442. if(n < thresh)
  443. result = n;
  444. else
  445. result = 1.0f + n0 - (n0 - thresh + 1.0f) * par1 * 0.90f;
  446. break;
  447. case 3:
  448. tmp = par1 * 100.0f + 1.0f;
  449. result = powf(n0 / tmp, 1.0f - par2 * 0.8f) * tmp + 1.0f;
  450. break;
  451. case 4:
  452. result = n0
  453. * (1.0f
  454. - par1)
  455. + powf(n0 * 0.1f, par2 * 3.0f
  456. + 1.0f) * par1 * 10.0f + 1.0f;
  457. break;
  458. case 5:
  459. result = n0
  460. + sinf(n0 * par2 * par2 * PI
  461. * 0.999f) * sqrt(par1) * 2.0f + 1.0f;
  462. break;
  463. case 6:
  464. tmp = powf(par2 * 2.0f, 2.0f) + 0.1f;
  465. result = n0 * powf(1.0f + par1 * powf(n0 * 0.8f, tmp), tmp) + 1.0f;
  466. break;
  467. case 7:
  468. result = (n + Phrpos.par1 / 255.0f) / (Phrpos.par1 / 255.0f + 1);
  469. break;
  470. default:
  471. result = n;
  472. break;
  473. }
  474. const float par3 = Phrpos.par3 / 255.0f;
  475. const float iresult = floor(result + 0.5f);
  476. const float dresult = result - iresult;
  477. return iresult + (1.0f - par3) * dresult;
  478. }
  479. //Transform non zero positive signals into ones with a max of one
  480. static void normalize_max(float *f, size_t len)
  481. {
  482. float max = 0.0f;
  483. for(unsigned i = 0; i < len; ++i)
  484. if(f[i] > i)
  485. max = f[i];
  486. if(max > 0.000001f)
  487. for(unsigned i = 0; i < len; ++i)
  488. f[i] /= max;
  489. }
  490. //Translate Bandwidth scale integer into floating point value
  491. static float Pbwscale_translate(char Pbwscale)
  492. {
  493. switch(Pbwscale) {
  494. case 0: return 1.0f;
  495. case 1: return 0.0f;
  496. case 2: return 0.25f;
  497. case 3: return 0.5f;
  498. case 4: return 0.75f;
  499. case 5: return 1.5f;
  500. case 6: return 2.0f;
  501. case 7: return -0.5f;
  502. default: return 1.0;
  503. }
  504. }
  505. /*
  506. * Generates the long spectrum for Bandwidth mode (only amplitudes are generated; phases will be random)
  507. */
  508. //Requires
  509. // - bandwidth scaling power
  510. // - bandwidth
  511. // - oscilator harmonics at various frequences (oodles of data)
  512. // - sampled resonance
  513. void PADnoteParameters::generatespectrum_bandwidthMode(float *spectrum,
  514. int size,
  515. float basefreq,
  516. float *profile,
  517. int profilesize,
  518. float bwadjust)
  519. {
  520. float harmonics[synth.oscilsize];
  521. memset(spectrum, 0, sizeof(float) * size);
  522. memset(harmonics, 0, sizeof(float) * synth.oscilsize);
  523. //get the harmonic structure from the oscillator (I am using the frequency amplitudes, only)
  524. oscilgen->get(harmonics, basefreq, false);
  525. //normalize
  526. normalize_max(harmonics, synth.oscilsize / 2);
  527. //Constants across harmonics
  528. const float power = Pbwscale_translate(Pbwscale);
  529. const float bandwidthcents = setPbandwidth(Pbandwidth);
  530. for(int nh = 1; nh < synth.oscilsize / 2; ++nh) { //for each harmonic
  531. const float realfreq = getNhr(nh) * basefreq;
  532. if(realfreq > synth.samplerate_f * 0.49999f)
  533. break;
  534. if(realfreq < 20.0f)
  535. break;
  536. if(harmonics[nh - 1] < 1e-4)
  537. continue;
  538. //compute the bandwidth of each harmonic
  539. const float bw =
  540. ((powf(2.0f, bandwidthcents / 1200.0f) - 1.0f) * basefreq / bwadjust)
  541. * powf(realfreq / basefreq, power);
  542. const int ibw = (int)((bw / (synth.samplerate_f * 0.5f) * size)) + 1;
  543. float amp = harmonics[nh - 1];
  544. if(resonance->Penabled)
  545. amp *= resonance->getfreqresponse(realfreq);
  546. if(ibw > profilesize) { //if the bandwidth is larger than the profilesize
  547. const float rap = sqrt((float)profilesize / (float)ibw);
  548. const int cfreq =
  549. (int) (realfreq
  550. / (synth.samplerate_f * 0.5f) * size) - ibw / 2;
  551. for(int i = 0; i < ibw; ++i) {
  552. const int src = i * rap * rap;
  553. const int spfreq = i + cfreq;
  554. if(spfreq < 0)
  555. continue;
  556. if(spfreq >= size)
  557. break;
  558. spectrum[spfreq] += amp * profile[src] * rap;
  559. }
  560. }
  561. else { //if the bandwidth is smaller than the profilesize
  562. const float rap = sqrt((float)ibw / (float)profilesize);
  563. const float ibasefreq = realfreq / (synth.samplerate_f * 0.5f) * size;
  564. for(int i = 0; i < profilesize; ++i) {
  565. const float idfreq = (i / (float)profilesize - 0.5f) * ibw;
  566. const int spfreq = (int) (idfreq + ibasefreq);
  567. const float fspfreq = fmodf((float)idfreq + ibasefreq, 1.0f);
  568. if(spfreq <= 0)
  569. continue;
  570. if(spfreq >= size - 1)
  571. break;
  572. spectrum[spfreq] += amp * profile[i] * rap
  573. * (1.0f - fspfreq);
  574. spectrum[spfreq + 1] += amp * profile[i] * rap * fspfreq;
  575. }
  576. }
  577. }
  578. }
  579. /*
  580. * Generates the long spectrum for non-Bandwidth modes (only amplitudes are generated; phases will be random)
  581. */
  582. void PADnoteParameters::generatespectrum_otherModes(float *spectrum,
  583. int size,
  584. float basefreq)
  585. {
  586. float harmonics[synth.oscilsize];
  587. memset(spectrum, 0, sizeof(float) * size);
  588. memset(harmonics, 0, sizeof(float) * synth.oscilsize);
  589. //get the harmonic structure from the oscillator (I am using the frequency amplitudes, only)
  590. oscilgen->get(harmonics, basefreq, false);
  591. //normalize
  592. normalize_max(harmonics, synth.oscilsize / 2);
  593. for(int nh = 1; nh < synth.oscilsize / 2; ++nh) { //for each harmonic
  594. const float realfreq = getNhr(nh) * basefreq;
  595. //take care of interpolation if frequency decreases
  596. if(realfreq > synth.samplerate_f * 0.49999f)
  597. break;
  598. if(realfreq < 20.0f)
  599. break;
  600. float amp = harmonics[nh - 1];
  601. if(resonance->Penabled)
  602. amp *= resonance->getfreqresponse(realfreq);
  603. const int cfreq = realfreq / (synth.samplerate_f * 0.5f) * size;
  604. spectrum[cfreq] = amp + 1e-9;
  605. }
  606. //In continous mode the spectrum gets additional interpolation between the
  607. //spectral peaks
  608. if(Pmode != 1) { //continous mode
  609. int old = 0;
  610. for(int k = 1; k < size; ++k)
  611. if((spectrum[k] > 1e-10) || (k == (size - 1))) {
  612. const int delta = k - old;
  613. const float val1 = spectrum[old];
  614. const float val2 = spectrum[k];
  615. const float idelta = 1.0f / delta;
  616. for(int i = 0; i < delta; ++i) {
  617. const float x = idelta * i;
  618. spectrum[old + i] = val1 * (1.0f - x) + val2 * x;
  619. }
  620. old = k;
  621. }
  622. }
  623. }
  624. /*
  625. * Applies the parameters (i.e. computes all the samples, based on parameters);
  626. */
  627. void PADnoteParameters::applyparameters()
  628. {
  629. applyparameters([]{return false;});
  630. }
  631. void PADnoteParameters::applyparameters(std::function<bool()> do_abort)
  632. {
  633. if(do_abort())
  634. return;
  635. unsigned max = 0;
  636. sampleGenerator([&max,this]
  637. (unsigned N, PADnoteParameters::Sample &smp) {
  638. delete[] sample[N].smp;
  639. sample[N] = smp;
  640. max = max < N ? N : max;
  641. },
  642. do_abort);
  643. //Delete remaining unused samples
  644. for(unsigned i = max; i < PAD_MAX_SAMPLES; ++i)
  645. deletesample(i);
  646. }
  647. //Requires
  648. // - Pquality.samplesize
  649. // - Pquality.basenote
  650. // - Pquality.oct
  651. // - Pquality.smpoct
  652. // - spectrum at various frequencies (oodles of data)
  653. void PADnoteParameters::sampleGenerator(PADnoteParameters::callback cb,
  654. std::function<bool()> do_abort)
  655. {
  656. const int samplesize = (((int) 1) << (Pquality.samplesize + 14));
  657. const int spectrumsize = samplesize / 2;
  658. float *spectrum = new float[spectrumsize];
  659. const int profilesize = 512;
  660. float profile[profilesize];
  661. const float bwadjust = getprofile(profile, profilesize);
  662. float basefreq = 65.406f * powf(2.0f, Pquality.basenote / 2);
  663. if(Pquality.basenote % 2 == 1)
  664. basefreq *= 1.5f;
  665. int samplemax = Pquality.oct + 1;
  666. int smpoct = Pquality.smpoct;
  667. if(Pquality.smpoct == 5)
  668. smpoct = 6;
  669. if(Pquality.smpoct == 6)
  670. smpoct = 12;
  671. if(smpoct != 0)
  672. samplemax *= smpoct;
  673. else
  674. samplemax = samplemax / 2 + 1;
  675. if(samplemax == 0)
  676. samplemax = 1;
  677. //prepare a BIG FFT
  678. FFTwrapper *fft = new FFTwrapper(samplesize);
  679. fft_t *fftfreqs = new fft_t[samplesize / 2];
  680. //this is used to compute frequency relation to the base frequency
  681. float adj[samplemax];
  682. for(int nsample = 0; nsample < samplemax; ++nsample)
  683. adj[nsample] = (Pquality.oct + 1.0f) * (float)nsample / samplemax;
  684. for(int nsample = 0; nsample < samplemax; ++nsample) {
  685. if(do_abort())
  686. goto exit;
  687. const float basefreqadjust =
  688. powf(2.0f, adj[nsample] - adj[samplemax - 1] * 0.5f);
  689. if(Pmode == 0)
  690. generatespectrum_bandwidthMode(spectrum,
  691. spectrumsize,
  692. basefreq * basefreqadjust,
  693. profile,
  694. profilesize,
  695. bwadjust);
  696. else
  697. generatespectrum_otherModes(spectrum, spectrumsize,
  698. basefreq * basefreqadjust);
  699. //the last samples contains the first samples
  700. //(used for linear/cubic interpolation)
  701. const int extra_samples = 5;
  702. PADnoteParameters::Sample newsample;
  703. newsample.smp = new float[samplesize + extra_samples];
  704. newsample.smp[0] = 0.0f;
  705. for(int i = 1; i < spectrumsize; ++i) //randomize the phases
  706. fftfreqs[i] = FFTpolar(spectrum[i], (float)RND * 2 * PI);
  707. //that's all; here is the only ifft for the whole sample;
  708. //no windows are used ;-)
  709. fft->freqs2smps(fftfreqs, newsample.smp);
  710. //normalize(rms)
  711. float rms = 0.0f;
  712. for(int i = 0; i < samplesize; ++i)
  713. rms += newsample.smp[i] * newsample.smp[i];
  714. rms = sqrt(rms);
  715. if(rms < 0.000001f)
  716. rms = 1.0f;
  717. rms *= sqrt(262144.0f / samplesize);//262144=2^18
  718. for(int i = 0; i < samplesize; ++i)
  719. newsample.smp[i] *= 1.0f / rms * 50.0f;
  720. //prepare extra samples used by the linear or cubic interpolation
  721. for(int i = 0; i < extra_samples; ++i)
  722. newsample.smp[i + samplesize] = newsample.smp[i];
  723. //yield new sample
  724. newsample.size = samplesize;
  725. newsample.basefreq = basefreq * basefreqadjust;
  726. cb(nsample, newsample);
  727. }
  728. exit:
  729. //Cleanup
  730. delete (fft);
  731. delete[] fftfreqs;
  732. delete[] spectrum;
  733. }
  734. void PADnoteParameters::export2wav(std::string basefilename)
  735. {
  736. applyparameters();
  737. basefilename += "_PADsynth_";
  738. for(int k = 0; k < PAD_MAX_SAMPLES; ++k) {
  739. if(sample[k].smp == NULL)
  740. continue;
  741. char tmpstr[20];
  742. snprintf(tmpstr, 20, "_%02d", k + 1);
  743. std::string filename = basefilename + std::string(tmpstr) + ".wav";
  744. WavFile wav(filename, synth.samplerate, 1);
  745. if(wav.good()) {
  746. int nsmps = sample[k].size;
  747. short int *smps = new short int[nsmps];
  748. for(int i = 0; i < nsmps; ++i)
  749. smps[i] = (short int)(sample[k].smp[i] * 32767.0f);
  750. wav.writeMonoSamples(nsmps, smps);
  751. }
  752. }
  753. }
  754. void PADnoteParameters::add2XML(XMLwrapper *xml)
  755. {
  756. xml->setPadSynth(true);
  757. xml->addparbool("stereo", PStereo);
  758. xml->addpar("mode", Pmode);
  759. xml->addpar("bandwidth", Pbandwidth);
  760. xml->addpar("bandwidth_scale", Pbwscale);
  761. xml->beginbranch("HARMONIC_PROFILE");
  762. xml->addpar("base_type", Php.base.type);
  763. xml->addpar("base_par1", Php.base.par1);
  764. xml->addpar("frequency_multiplier", Php.freqmult);
  765. xml->addpar("modulator_par1", Php.modulator.par1);
  766. xml->addpar("modulator_frequency", Php.modulator.freq);
  767. xml->addpar("width", Php.width);
  768. xml->addpar("amplitude_multiplier_type", Php.amp.type);
  769. xml->addpar("amplitude_multiplier_mode", Php.amp.mode);
  770. xml->addpar("amplitude_multiplier_par1", Php.amp.par1);
  771. xml->addpar("amplitude_multiplier_par2", Php.amp.par2);
  772. xml->addparbool("autoscale", Php.autoscale);
  773. xml->addpar("one_half", Php.onehalf);
  774. xml->endbranch();
  775. xml->beginbranch("OSCIL");
  776. oscilgen->add2XML(xml);
  777. xml->endbranch();
  778. xml->beginbranch("RESONANCE");
  779. resonance->add2XML(xml);
  780. xml->endbranch();
  781. xml->beginbranch("HARMONIC_POSITION");
  782. xml->addpar("type", Phrpos.type);
  783. xml->addpar("parameter1", Phrpos.par1);
  784. xml->addpar("parameter2", Phrpos.par2);
  785. xml->addpar("parameter3", Phrpos.par3);
  786. xml->endbranch();
  787. xml->beginbranch("SAMPLE_QUALITY");
  788. xml->addpar("samplesize", Pquality.samplesize);
  789. xml->addpar("basenote", Pquality.basenote);
  790. xml->addpar("octaves", Pquality.oct);
  791. xml->addpar("samples_per_octave", Pquality.smpoct);
  792. xml->endbranch();
  793. xml->beginbranch("AMPLITUDE_PARAMETERS");
  794. xml->addpar("volume", PVolume);
  795. xml->addpar("panning", PPanning);
  796. xml->addpar("velocity_sensing", PAmpVelocityScaleFunction);
  797. xml->addpar("punch_strength", PPunchStrength);
  798. xml->addpar("punch_time", PPunchTime);
  799. xml->addpar("punch_stretch", PPunchStretch);
  800. xml->addpar("punch_velocity_sensing", PPunchVelocitySensing);
  801. xml->beginbranch("AMPLITUDE_ENVELOPE");
  802. AmpEnvelope->add2XML(xml);
  803. xml->endbranch();
  804. xml->beginbranch("AMPLITUDE_LFO");
  805. AmpLfo->add2XML(xml);
  806. xml->endbranch();
  807. xml->endbranch();
  808. xml->beginbranch("FREQUENCY_PARAMETERS");
  809. xml->addpar("fixed_freq", Pfixedfreq);
  810. xml->addpar("fixed_freq_et", PfixedfreqET);
  811. xml->addpar("detune", PDetune);
  812. xml->addpar("coarse_detune", PCoarseDetune);
  813. xml->addpar("detune_type", PDetuneType);
  814. xml->beginbranch("FREQUENCY_ENVELOPE");
  815. FreqEnvelope->add2XML(xml);
  816. xml->endbranch();
  817. xml->beginbranch("FREQUENCY_LFO");
  818. FreqLfo->add2XML(xml);
  819. xml->endbranch();
  820. xml->endbranch();
  821. xml->beginbranch("FILTER_PARAMETERS");
  822. xml->addpar("velocity_sensing_amplitude", PFilterVelocityScale);
  823. xml->addpar("velocity_sensing", PFilterVelocityScaleFunction);
  824. xml->beginbranch("FILTER");
  825. GlobalFilter->add2XML(xml);
  826. xml->endbranch();
  827. xml->beginbranch("FILTER_ENVELOPE");
  828. FilterEnvelope->add2XML(xml);
  829. xml->endbranch();
  830. xml->beginbranch("FILTER_LFO");
  831. FilterLfo->add2XML(xml);
  832. xml->endbranch();
  833. xml->endbranch();
  834. }
  835. void PADnoteParameters::getfromXML(XMLwrapper *xml)
  836. {
  837. PStereo = xml->getparbool("stereo", PStereo);
  838. Pmode = xml->getpar127("mode", 0);
  839. Pbandwidth = xml->getpar("bandwidth", Pbandwidth, 0, 1000);
  840. Pbwscale = xml->getpar127("bandwidth_scale", Pbwscale);
  841. if(xml->enterbranch("HARMONIC_PROFILE")) {
  842. Php.base.type = xml->getpar127("base_type", Php.base.type);
  843. Php.base.par1 = xml->getpar127("base_par1", Php.base.par1);
  844. Php.freqmult = xml->getpar127("frequency_multiplier",
  845. Php.freqmult);
  846. Php.modulator.par1 = xml->getpar127("modulator_par1",
  847. Php.modulator.par1);
  848. Php.modulator.freq = xml->getpar127("modulator_frequency",
  849. Php.modulator.freq);
  850. Php.width = xml->getpar127("width", Php.width);
  851. Php.amp.type = xml->getpar127("amplitude_multiplier_type",
  852. Php.amp.type);
  853. Php.amp.mode = xml->getpar127("amplitude_multiplier_mode",
  854. Php.amp.mode);
  855. Php.amp.par1 = xml->getpar127("amplitude_multiplier_par1",
  856. Php.amp.par1);
  857. Php.amp.par2 = xml->getpar127("amplitude_multiplier_par2",
  858. Php.amp.par2);
  859. Php.autoscale = xml->getparbool("autoscale", Php.autoscale);
  860. Php.onehalf = xml->getpar127("one_half", Php.onehalf);
  861. xml->exitbranch();
  862. }
  863. if(xml->enterbranch("OSCIL")) {
  864. oscilgen->getfromXML(xml);
  865. xml->exitbranch();
  866. }
  867. if(xml->enterbranch("RESONANCE")) {
  868. resonance->getfromXML(xml);
  869. xml->exitbranch();
  870. }
  871. if(xml->enterbranch("HARMONIC_POSITION")) {
  872. Phrpos.type = xml->getpar127("type", Phrpos.type);
  873. Phrpos.par1 = xml->getpar("parameter1", Phrpos.par1, 0, 255);
  874. Phrpos.par2 = xml->getpar("parameter2", Phrpos.par2, 0, 255);
  875. Phrpos.par3 = xml->getpar("parameter3", Phrpos.par3, 0, 255);
  876. xml->exitbranch();
  877. }
  878. if(xml->enterbranch("SAMPLE_QUALITY")) {
  879. Pquality.samplesize = xml->getpar127("samplesize", Pquality.samplesize);
  880. Pquality.basenote = xml->getpar127("basenote", Pquality.basenote);
  881. Pquality.oct = xml->getpar127("octaves", Pquality.oct);
  882. Pquality.smpoct = xml->getpar127("samples_per_octave",
  883. Pquality.smpoct);
  884. xml->exitbranch();
  885. }
  886. if(xml->enterbranch("AMPLITUDE_PARAMETERS")) {
  887. PVolume = xml->getpar127("volume", PVolume);
  888. PPanning = xml->getpar127("panning", PPanning);
  889. PAmpVelocityScaleFunction = xml->getpar127("velocity_sensing",
  890. PAmpVelocityScaleFunction);
  891. PPunchStrength = xml->getpar127("punch_strength", PPunchStrength);
  892. PPunchTime = xml->getpar127("punch_time", PPunchTime);
  893. PPunchStretch = xml->getpar127("punch_stretch", PPunchStretch);
  894. PPunchVelocitySensing = xml->getpar127("punch_velocity_sensing",
  895. PPunchVelocitySensing);
  896. xml->enterbranch("AMPLITUDE_ENVELOPE");
  897. AmpEnvelope->getfromXML(xml);
  898. xml->exitbranch();
  899. xml->enterbranch("AMPLITUDE_LFO");
  900. AmpLfo->getfromXML(xml);
  901. xml->exitbranch();
  902. xml->exitbranch();
  903. }
  904. if(xml->enterbranch("FREQUENCY_PARAMETERS")) {
  905. Pfixedfreq = xml->getpar127("fixed_freq", Pfixedfreq);
  906. PfixedfreqET = xml->getpar127("fixed_freq_et", PfixedfreqET);
  907. PDetune = xml->getpar("detune", PDetune, 0, 16383);
  908. PCoarseDetune = xml->getpar("coarse_detune", PCoarseDetune, 0, 16383);
  909. PDetuneType = xml->getpar127("detune_type", PDetuneType);
  910. xml->enterbranch("FREQUENCY_ENVELOPE");
  911. FreqEnvelope->getfromXML(xml);
  912. xml->exitbranch();
  913. xml->enterbranch("FREQUENCY_LFO");
  914. FreqLfo->getfromXML(xml);
  915. xml->exitbranch();
  916. xml->exitbranch();
  917. }
  918. if(xml->enterbranch("FILTER_PARAMETERS")) {
  919. PFilterVelocityScale = xml->getpar127("velocity_sensing_amplitude",
  920. PFilterVelocityScale);
  921. PFilterVelocityScaleFunction = xml->getpar127(
  922. "velocity_sensing",
  923. PFilterVelocityScaleFunction);
  924. xml->enterbranch("FILTER");
  925. GlobalFilter->getfromXML(xml);
  926. xml->exitbranch();
  927. xml->enterbranch("FILTER_ENVELOPE");
  928. FilterEnvelope->getfromXML(xml);
  929. xml->exitbranch();
  930. xml->enterbranch("FILTER_LFO");
  931. FilterLfo->getfromXML(xml);
  932. xml->exitbranch();
  933. xml->exitbranch();
  934. }
  935. }