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.

903 lines
29KB

  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 <math.h>
  18. #include "PADnoteParameters.h"
  19. #include "../Misc/WavFile.h"
  20. PADnoteParameters::PADnoteParameters(FFTwrapper *fft_,
  21. pthread_mutex_t *mutex_):Presets()
  22. {
  23. setpresettype("Ppadsynth");
  24. fft = fft_;
  25. mutex = mutex_;
  26. resonance = new Resonance();
  27. oscilgen = new OscilGen(fft_, resonance);
  28. oscilgen->ADvsPAD = true;
  29. FreqEnvelope = new EnvelopeParams(0, 0);
  30. FreqEnvelope->ASRinit(64, 50, 64, 60);
  31. FreqLfo = new LFOParams(70, 0, 64, 0, 0, 0, 0, 0);
  32. AmpEnvelope = new EnvelopeParams(64, 1);
  33. AmpEnvelope->ADSRinit_dB(0, 40, 127, 25);
  34. AmpLfo = new LFOParams(80, 0, 64, 0, 0, 0, 0, 1);
  35. GlobalFilter = new FilterParams(2, 94, 40);
  36. FilterEnvelope = new EnvelopeParams(0, 1);
  37. FilterEnvelope->ADSRinit_filter(64, 40, 64, 70, 60, 64);
  38. FilterLfo = new LFOParams(80, 0, 64, 0, 0, 0, 0, 2);
  39. for(int i = 0; i < PAD_MAX_SAMPLES; ++i)
  40. sample[i].smp = NULL;
  41. newsample.smp = NULL;
  42. defaults();
  43. }
  44. PADnoteParameters::~PADnoteParameters()
  45. {
  46. deletesamples();
  47. delete (oscilgen);
  48. delete (resonance);
  49. delete (FreqEnvelope);
  50. delete (FreqLfo);
  51. delete (AmpEnvelope);
  52. delete (AmpLfo);
  53. delete (GlobalFilter);
  54. delete (FilterEnvelope);
  55. delete (FilterLfo);
  56. }
  57. void PADnoteParameters::defaults()
  58. {
  59. Pmode = 0;
  60. Php.base.type = 0;
  61. Php.base.par1 = 80;
  62. Php.freqmult = 0;
  63. Php.modulator.par1 = 0;
  64. Php.modulator.freq = 30;
  65. Php.width = 127;
  66. Php.amp.type = 0;
  67. Php.amp.mode = 0;
  68. Php.amp.par1 = 80;
  69. Php.amp.par2 = 64;
  70. Php.autoscale = true;
  71. Php.onehalf = 0;
  72. setPbandwidth(500);
  73. Pbwscale = 0;
  74. resonance->defaults();
  75. oscilgen->defaults();
  76. Phrpos.type = 0;
  77. Phrpos.par1 = 64;
  78. Phrpos.par2 = 64;
  79. Phrpos.par3 = 0;
  80. Pquality.samplesize = 3;
  81. Pquality.basenote = 4;
  82. Pquality.oct = 3;
  83. Pquality.smpoct = 2;
  84. PStereo = 1; //stereo
  85. /* Frequency Global Parameters */
  86. Pfixedfreq = 0;
  87. PfixedfreqET = 0;
  88. PDetune = 8192; //zero
  89. PCoarseDetune = 0;
  90. PDetuneType = 1;
  91. FreqEnvelope->defaults();
  92. FreqLfo->defaults();
  93. /* Amplitude Global Parameters */
  94. PVolume = 90;
  95. PPanning = 64; //center
  96. PAmpVelocityScaleFunction = 64;
  97. AmpEnvelope->defaults();
  98. AmpLfo->defaults();
  99. PPunchStrength = 0;
  100. PPunchTime = 60;
  101. PPunchStretch = 64;
  102. PPunchVelocitySensing = 72;
  103. /* Filter Global Parameters*/
  104. PFilterVelocityScale = 64;
  105. PFilterVelocityScaleFunction = 64;
  106. GlobalFilter->defaults();
  107. FilterEnvelope->defaults();
  108. FilterLfo->defaults();
  109. deletesamples();
  110. }
  111. void PADnoteParameters::deletesample(int n)
  112. {
  113. if((n < 0) || (n >= PAD_MAX_SAMPLES))
  114. return;
  115. if(sample[n].smp != NULL) {
  116. delete[] sample[n].smp;
  117. sample[n].smp = NULL;
  118. }
  119. sample[n].size = 0;
  120. sample[n].basefreq = 440.0f;
  121. }
  122. void PADnoteParameters::deletesamples()
  123. {
  124. for(int i = 0; i < PAD_MAX_SAMPLES; ++i)
  125. deletesample(i);
  126. }
  127. /*
  128. * Get the harmonic profile (i.e. the frequency distributio of a single harmonic)
  129. */
  130. float PADnoteParameters::getprofile(float *smp, int size)
  131. {
  132. for(int i = 0; i < size; ++i)
  133. smp[i] = 0.0f;
  134. const int supersample = 16;
  135. float basepar = powf(2.0f, (1.0f - Php.base.par1 / 127.0f) * 12.0f);
  136. float freqmult = floor(powf(2.0f,
  137. Php.freqmult / 127.0f
  138. * 5.0f) + 0.000001f);
  139. float modfreq = floor(powf(2.0f,
  140. Php.modulator.freq / 127.0f
  141. * 5.0f) + 0.000001f);
  142. float modpar1 = powf(Php.modulator.par1 / 127.0f, 4.0f) * 5.0f / sqrt(
  143. modfreq);
  144. float amppar1 =
  145. powf(2.0f, powf(Php.amp.par1 / 127.0f, 2.0f) * 10.0f) - 0.999f;
  146. float amppar2 = (1.0f - Php.amp.par2 / 127.0f) * 0.998f + 0.001f;
  147. float width = powf(150.0f / (Php.width + 22.0f), 2.0f);
  148. for(int i = 0; i < size * supersample; ++i) {
  149. bool makezero = false;
  150. float x = i * 1.0f / (size * (float) supersample);
  151. float origx = x;
  152. //do the sizing (width)
  153. x = (x - 0.5f) * width + 0.5f;
  154. if(x < 0.0f) {
  155. x = 0.0f;
  156. makezero = true;
  157. }
  158. else
  159. if(x > 1.0f) {
  160. x = 1.0f;
  161. makezero = true;
  162. }
  163. //compute the full profile or one half
  164. switch(Php.onehalf) {
  165. case 1:
  166. x = x * 0.5f + 0.5f;
  167. break;
  168. case 2:
  169. x = x * 0.5f;
  170. break;
  171. }
  172. float x_before_freq_mult = x;
  173. //do the frequency multiplier
  174. x *= freqmult;
  175. //do the modulation of the profile
  176. x += sinf(x_before_freq_mult * 3.1415926f * modfreq) * modpar1;
  177. x = fmod(x + 1000.0f, 1.0f) * 2.0f - 1.0f;
  178. //this is the base function of the profile
  179. float f;
  180. switch(Php.base.type) {
  181. case 1:
  182. f = expf(-(x * x) * basepar);
  183. if(f < 0.4f)
  184. f = 0.0f;
  185. else
  186. f = 1.0f;
  187. break;
  188. case 2:
  189. f = expf(-(fabs(x)) * sqrt(basepar));
  190. break;
  191. default:
  192. f = expf(-(x * x) * basepar);
  193. break;
  194. }
  195. if(makezero)
  196. f = 0.0f;
  197. float amp = 1.0f;
  198. origx = origx * 2.0f - 1.0f;
  199. //compute the amplitude multiplier
  200. switch(Php.amp.type) {
  201. case 1:
  202. amp = expf(-(origx * origx) * 10.0f * amppar1);
  203. break;
  204. case 2:
  205. amp = 0.5f
  206. * (1.0f
  207. + cosf(3.1415926f * origx * sqrt(amppar1 * 4.0f + 1.0f)));
  208. break;
  209. case 3:
  210. amp = 1.0f
  211. / (powf(origx * (amppar1 * 2.0f + 0.8f), 14.0f) + 1.0f);
  212. break;
  213. }
  214. //apply the amplitude multiplier
  215. float finalsmp = f;
  216. if(Php.amp.type != 0)
  217. switch(Php.amp.mode) {
  218. case 0:
  219. finalsmp = amp * (1.0f - amppar2) + finalsmp * amppar2;
  220. break;
  221. case 1:
  222. finalsmp *= amp * (1.0f - amppar2) + amppar2;
  223. break;
  224. case 2:
  225. finalsmp = finalsmp
  226. / (amp + powf(amppar2, 4.0f) * 20.0f + 0.0001f);
  227. break;
  228. case 3:
  229. finalsmp = amp
  230. / (finalsmp
  231. + powf(amppar2, 4.0f) * 20.0f + 0.0001f);
  232. break;
  233. }
  234. ;
  235. smp[i / supersample] += finalsmp / supersample;
  236. }
  237. //normalize the profile (make the max. to be equal to 1.0f)
  238. float max = 0.0f;
  239. for(int i = 0; i < size; ++i) {
  240. if(smp[i] < 0.0f)
  241. smp[i] = 0.0f;
  242. if(smp[i] > max)
  243. max = smp[i];
  244. }
  245. if(max < 0.00001f)
  246. max = 1.0f;
  247. for(int i = 0; i < size; ++i)
  248. smp[i] /= max;
  249. if(!Php.autoscale)
  250. return 0.5f;
  251. //compute the estimated perceived bandwidth
  252. float sum = 0.0f;
  253. int i;
  254. for(i = 0; i < size / 2 - 2; ++i) {
  255. sum += smp[i] * smp[i] + smp[size - i - 1] * smp[size - i - 1];
  256. if(sum >= 4.0f)
  257. break;
  258. }
  259. float result = 1.0f - 2.0f * i / (float) size;
  260. return result;
  261. }
  262. /*
  263. * Compute the real bandwidth in cents and returns it
  264. * Also, sets the bandwidth parameter
  265. */
  266. float PADnoteParameters::setPbandwidth(int Pbandwidth)
  267. {
  268. this->Pbandwidth = Pbandwidth;
  269. float result = powf(Pbandwidth / 1000.0f, 1.1f);
  270. result = powf(10.0f, result * 4.0f) * 0.25f;
  271. return result;
  272. }
  273. /*
  274. * Get the harmonic(overtone) position
  275. */
  276. float PADnoteParameters::getNhr(int n)
  277. {
  278. float result = 1.0f;
  279. float par1 = powf(10.0f, -(1.0f - Phrpos.par1 / 255.0f) * 3.0f);
  280. float par2 = Phrpos.par2 / 255.0f;
  281. float n0 = n - 1.0f;
  282. float tmp = 0.0f;
  283. int thresh = 0;
  284. switch(Phrpos.type) {
  285. case 1:
  286. thresh = (int)(par2 * par2 * 100.0f) + 1;
  287. if(n < thresh)
  288. result = n;
  289. else
  290. result = 1.0f + n0 + (n0 - thresh + 1.0f) * par1 * 8.0f;
  291. break;
  292. case 2:
  293. thresh = (int)(par2 * par2 * 100.0f) + 1;
  294. if(n < thresh)
  295. result = n;
  296. else
  297. result = 1.0f + n0 - (n0 - thresh + 1.0f) * par1 * 0.90f;
  298. break;
  299. case 3:
  300. tmp = par1 * 100.0f + 1.0f;
  301. result = powf(n0 / tmp, 1.0f - par2 * 0.8f) * tmp + 1.0f;
  302. break;
  303. case 4:
  304. result = n0
  305. * (1.0f
  306. - par1)
  307. + powf(n0 * 0.1f, par2 * 3.0f
  308. + 1.0f) * par1 * 10.0f + 1.0f;
  309. break;
  310. case 5:
  311. result = n0
  312. + sinf(n0 * par2 * par2 * PI
  313. * 0.999f) * sqrt(par1) * 2.0f + 1.0f;
  314. break;
  315. case 6:
  316. tmp = powf(par2 * 2.0f, 2.0f) + 0.1f;
  317. result = n0 * powf(1.0f + par1 * powf(n0 * 0.8f, tmp), tmp) + 1.0f;
  318. break;
  319. default:
  320. result = n;
  321. break;
  322. }
  323. float par3 = Phrpos.par3 / 255.0f;
  324. float iresult = floor(result + 0.5f);
  325. float dresult = result - iresult;
  326. result = iresult + (1.0f - par3) * dresult;
  327. return result;
  328. }
  329. /*
  330. * Generates the long spectrum for Bandwidth mode (only amplitudes are generated; phases will be random)
  331. */
  332. void PADnoteParameters::generatespectrum_bandwidthMode(float *spectrum,
  333. int size,
  334. float basefreq,
  335. float *profile,
  336. int profilesize,
  337. float bwadjust)
  338. {
  339. for(int i = 0; i < size; ++i)
  340. spectrum[i] = 0.0f;
  341. float harmonics[synth->oscilsize / 2];
  342. for(int i = 0; i < synth->oscilsize / 2; ++i)
  343. harmonics[i] = 0.0f;
  344. //get the harmonic structure from the oscillator (I am using the frequency amplitudes, only)
  345. oscilgen->get(harmonics, basefreq, false);
  346. //normalize
  347. float max = 0.0f;
  348. for(int i = 0; i < synth->oscilsize / 2; ++i)
  349. if(harmonics[i] > max)
  350. max = harmonics[i];
  351. if(max < 0.000001f)
  352. max = 1;
  353. for(int i = 0; i < synth->oscilsize / 2; ++i)
  354. harmonics[i] /= max;
  355. for(int nh = 1; nh < synth->oscilsize / 2; ++nh) { //for each harmonic
  356. float realfreq = getNhr(nh) * basefreq;
  357. if(realfreq > synth->samplerate_f * 0.49999f)
  358. break;
  359. if(realfreq < 20.0f)
  360. break;
  361. if(harmonics[nh - 1] < 1e-4)
  362. continue;
  363. //compute the bandwidth of each harmonic
  364. float bandwidthcents = setPbandwidth(Pbandwidth);
  365. float bw =
  366. (powf(2.0f, bandwidthcents / 1200.0f) - 1.0f) * basefreq / bwadjust;
  367. float power = 1.0f;
  368. switch(Pbwscale) {
  369. case 0:
  370. power = 1.0f;
  371. break;
  372. case 1:
  373. power = 0.0f;
  374. break;
  375. case 2:
  376. power = 0.25f;
  377. break;
  378. case 3:
  379. power = 0.5f;
  380. break;
  381. case 4:
  382. power = 0.75f;
  383. break;
  384. case 5:
  385. power = 1.5f;
  386. break;
  387. case 6:
  388. power = 2.0f;
  389. break;
  390. case 7:
  391. power = -0.5f;
  392. break;
  393. }
  394. bw = bw * powf(realfreq / basefreq, power);
  395. int ibw = (int)((bw / (synth->samplerate_f * 0.5f) * size)) + 1;
  396. float amp = harmonics[nh - 1];
  397. if(resonance->Penabled)
  398. amp *= resonance->getfreqresponse(realfreq);
  399. if(ibw > profilesize) { //if the bandwidth is larger than the profilesize
  400. float rap = sqrt((float)profilesize / (float)ibw);
  401. int cfreq =
  402. (int) (realfreq
  403. / (synth->samplerate_f * 0.5f) * size) - ibw / 2;
  404. for(int i = 0; i < ibw; ++i) {
  405. int src = (int)(i * rap * rap);
  406. int spfreq = i + cfreq;
  407. if(spfreq < 0)
  408. continue;
  409. if(spfreq >= size)
  410. break;
  411. spectrum[spfreq] += amp * profile[src] * rap;
  412. }
  413. }
  414. else { //if the bandwidth is smaller than the profilesize
  415. float rap = sqrt((float)ibw / (float)profilesize);
  416. float ibasefreq = realfreq / (synth->samplerate_f * 0.5f) * size;
  417. for(int i = 0; i < profilesize; ++i) {
  418. float idfreq = i / (float)profilesize - 0.5f;
  419. idfreq *= ibw;
  420. int spfreq = (int) (idfreq + ibasefreq);
  421. float fspfreq = fmodf((float)idfreq + ibasefreq, 1.0f);
  422. if(spfreq <= 0)
  423. continue;
  424. if(spfreq >= size - 1)
  425. break;
  426. spectrum[spfreq] += amp * profile[i] * rap
  427. * (1.0f - fspfreq);
  428. spectrum[spfreq + 1] += amp * profile[i] * rap * fspfreq;
  429. }
  430. }
  431. }
  432. }
  433. /*
  434. * Generates the long spectrum for non-Bandwidth modes (only amplitudes are generated; phases will be random)
  435. */
  436. void PADnoteParameters::generatespectrum_otherModes(float *spectrum,
  437. int size,
  438. float basefreq)
  439. {
  440. for(int i = 0; i < size; ++i)
  441. spectrum[i] = 0.0f;
  442. float harmonics[synth->oscilsize / 2];
  443. for(int i = 0; i < synth->oscilsize / 2; ++i)
  444. harmonics[i] = 0.0f;
  445. //get the harmonic structure from the oscillator (I am using the frequency amplitudes, only)
  446. oscilgen->get(harmonics, basefreq, false);
  447. //normalize
  448. float max = 0.0f;
  449. for(int i = 0; i < synth->oscilsize / 2; ++i)
  450. if(harmonics[i] > max)
  451. max = harmonics[i];
  452. if(max < 0.000001f)
  453. max = 1;
  454. for(int i = 0; i < synth->oscilsize / 2; ++i)
  455. harmonics[i] /= max;
  456. for(int nh = 1; nh < synth->oscilsize / 2; ++nh) { //for each harmonic
  457. float realfreq = getNhr(nh) * basefreq;
  458. ///sa fac aici interpolarea si sa am grija daca frecv descresc
  459. if(realfreq > synth->samplerate_f * 0.49999f)
  460. break;
  461. if(realfreq < 20.0f)
  462. break;
  463. // if (harmonics[nh-1]<1e-4) continue;
  464. float amp = harmonics[nh - 1];
  465. if(resonance->Penabled)
  466. amp *= resonance->getfreqresponse(realfreq);
  467. int cfreq = (int) (realfreq / (synth->samplerate_f * 0.5f) * size);
  468. spectrum[cfreq] = amp + 1e-9;
  469. }
  470. if(Pmode != 1) {
  471. int old = 0;
  472. for(int k = 1; k < size; ++k)
  473. if((spectrum[k] > 1e-10) || (k == (size - 1))) {
  474. int delta = k - old;
  475. float val1 = spectrum[old];
  476. float val2 = spectrum[k];
  477. float idelta = 1.0f / delta;
  478. for(int i = 0; i < delta; ++i) {
  479. float x = idelta * i;
  480. spectrum[old + i] = val1 * (1.0f - x) + val2 * x;
  481. }
  482. old = k;
  483. }
  484. }
  485. }
  486. /*
  487. * Applies the parameters (i.e. computes all the samples, based on parameters);
  488. */
  489. void PADnoteParameters::applyparameters(bool lockmutex)
  490. {
  491. const int samplesize = (((int) 1) << (Pquality.samplesize + 14));
  492. int spectrumsize = samplesize / 2;
  493. float spectrum[spectrumsize];
  494. int profilesize = 512;
  495. float profile[profilesize];
  496. float bwadjust = getprofile(profile, profilesize);
  497. // for (int i=0;i<profilesize;i++) profile[i]*=profile[i];
  498. float basefreq = 65.406f * powf(2.0f, Pquality.basenote / 2);
  499. if(Pquality.basenote % 2 == 1)
  500. basefreq *= 1.5f;
  501. int samplemax = Pquality.oct + 1;
  502. int smpoct = Pquality.smpoct;
  503. if(Pquality.smpoct == 5)
  504. smpoct = 6;
  505. if(Pquality.smpoct == 6)
  506. smpoct = 12;
  507. if(smpoct != 0)
  508. samplemax *= smpoct;
  509. else
  510. samplemax = samplemax / 2 + 1;
  511. if(samplemax == 0)
  512. samplemax = 1;
  513. //prepare a BIG FFT stuff
  514. FFTwrapper *fft = new FFTwrapper(samplesize);
  515. fft_t *fftfreqs = new fft_t[samplesize / 2];
  516. float adj[samplemax]; //this is used to compute frequency relation to the base frequency
  517. for(int nsample = 0; nsample < samplemax; ++nsample)
  518. adj[nsample] = (Pquality.oct + 1.0f) * (float)nsample / samplemax;
  519. for(int nsample = 0; nsample < samplemax; ++nsample) {
  520. float tmp = adj[nsample] - adj[samplemax - 1] * 0.5f;
  521. float basefreqadjust = powf(2.0f, tmp);
  522. if(Pmode == 0)
  523. generatespectrum_bandwidthMode(spectrum,
  524. spectrumsize,
  525. basefreq * basefreqadjust,
  526. profile,
  527. profilesize,
  528. bwadjust);
  529. else
  530. generatespectrum_otherModes(spectrum, spectrumsize,
  531. basefreq * basefreqadjust);
  532. const int extra_samples = 5; //the last samples contains the first samples (used for linear/cubic interpolation)
  533. newsample.smp = new float[samplesize + extra_samples];
  534. newsample.smp[0] = 0.0f;
  535. for(int i = 1; i < spectrumsize; ++i) //randomize the phases
  536. fftfreqs[i] = std::polar(spectrum[i], (float)RND * 6.29f);
  537. fft->freqs2smps(fftfreqs, newsample.smp); //that's all; here is the only ifft for the whole sample; no windows are used ;-)
  538. //normalize(rms)
  539. float rms = 0.0f;
  540. for(int i = 0; i < samplesize; ++i)
  541. rms += newsample.smp[i] * newsample.smp[i];
  542. rms = sqrt(rms);
  543. if(rms < 0.000001f)
  544. rms = 1.0f;
  545. rms *= sqrt(262144.0f / samplesize);
  546. for(int i = 0; i < samplesize; ++i)
  547. newsample.smp[i] *= 1.0f / rms * 50.0f;
  548. //prepare extra samples used by the linear or cubic interpolation
  549. for(int i = 0; i < extra_samples; ++i)
  550. newsample.smp[i + samplesize] = newsample.smp[i];
  551. //replace the current sample with the new computed sample
  552. if(lockmutex) {
  553. pthread_mutex_lock(mutex);
  554. deletesample(nsample);
  555. sample[nsample].smp = newsample.smp;
  556. sample[nsample].size = samplesize;
  557. sample[nsample].basefreq = basefreq * basefreqadjust;
  558. pthread_mutex_unlock(mutex);
  559. }
  560. else {
  561. deletesample(nsample);
  562. sample[nsample].smp = newsample.smp;
  563. sample[nsample].size = samplesize;
  564. sample[nsample].basefreq = basefreq * basefreqadjust;
  565. }
  566. newsample.smp = NULL;
  567. }
  568. delete (fft);
  569. delete[] fftfreqs;
  570. //delete the additional samples that might exists and are not useful
  571. if(lockmutex) {
  572. pthread_mutex_lock(mutex);
  573. for(int i = samplemax; i < PAD_MAX_SAMPLES; ++i)
  574. deletesample(i);
  575. pthread_mutex_unlock(mutex);
  576. }
  577. else
  578. for(int i = samplemax; i < PAD_MAX_SAMPLES; ++i)
  579. deletesample(i);
  580. ;
  581. }
  582. void PADnoteParameters::export2wav(std::string basefilename)
  583. {
  584. applyparameters(true);
  585. basefilename += "_PADsynth_";
  586. for(int k = 0; k < PAD_MAX_SAMPLES; ++k) {
  587. if(sample[k].smp == NULL)
  588. continue;
  589. char tmpstr[20];
  590. snprintf(tmpstr, 20, "_%02d", k + 1);
  591. std::string filename = basefilename + std::string(tmpstr) + ".wav";
  592. WavFile wav(filename, synth->samplerate, 1);
  593. if(wav.good()) {
  594. int nsmps = sample[k].size;
  595. short int *smps = new short int[nsmps];
  596. for(int i = 0; i < nsmps; ++i)
  597. smps[i] = (short int)(sample[k].smp[i] * 32767.0f);
  598. wav.writeMonoSamples(nsmps, smps);
  599. }
  600. }
  601. }
  602. void PADnoteParameters::add2XML(XMLwrapper *xml)
  603. {
  604. xml->setPadSynth(true);
  605. xml->addparbool("stereo", PStereo);
  606. xml->addpar("mode", Pmode);
  607. xml->addpar("bandwidth", Pbandwidth);
  608. xml->addpar("bandwidth_scale", Pbwscale);
  609. xml->beginbranch("HARMONIC_PROFILE");
  610. xml->addpar("base_type", Php.base.type);
  611. xml->addpar("base_par1", Php.base.par1);
  612. xml->addpar("frequency_multiplier", Php.freqmult);
  613. xml->addpar("modulator_par1", Php.modulator.par1);
  614. xml->addpar("modulator_frequency", Php.modulator.freq);
  615. xml->addpar("width", Php.width);
  616. xml->addpar("amplitude_multiplier_type", Php.amp.type);
  617. xml->addpar("amplitude_multiplier_mode", Php.amp.mode);
  618. xml->addpar("amplitude_multiplier_par1", Php.amp.par1);
  619. xml->addpar("amplitude_multiplier_par2", Php.amp.par2);
  620. xml->addparbool("autoscale", Php.autoscale);
  621. xml->addpar("one_half", Php.onehalf);
  622. xml->endbranch();
  623. xml->beginbranch("OSCIL");
  624. oscilgen->add2XML(xml);
  625. xml->endbranch();
  626. xml->beginbranch("RESONANCE");
  627. resonance->add2XML(xml);
  628. xml->endbranch();
  629. xml->beginbranch("HARMONIC_POSITION");
  630. xml->addpar("type", Phrpos.type);
  631. xml->addpar("parameter1", Phrpos.par1);
  632. xml->addpar("parameter2", Phrpos.par2);
  633. xml->addpar("parameter3", Phrpos.par3);
  634. xml->endbranch();
  635. xml->beginbranch("SAMPLE_QUALITY");
  636. xml->addpar("samplesize", Pquality.samplesize);
  637. xml->addpar("basenote", Pquality.basenote);
  638. xml->addpar("octaves", Pquality.oct);
  639. xml->addpar("samples_per_octave", Pquality.smpoct);
  640. xml->endbranch();
  641. xml->beginbranch("AMPLITUDE_PARAMETERS");
  642. xml->addpar("volume", PVolume);
  643. xml->addpar("panning", PPanning);
  644. xml->addpar("velocity_sensing", PAmpVelocityScaleFunction);
  645. xml->addpar("punch_strength", PPunchStrength);
  646. xml->addpar("punch_time", PPunchTime);
  647. xml->addpar("punch_stretch", PPunchStretch);
  648. xml->addpar("punch_velocity_sensing", PPunchVelocitySensing);
  649. xml->beginbranch("AMPLITUDE_ENVELOPE");
  650. AmpEnvelope->add2XML(xml);
  651. xml->endbranch();
  652. xml->beginbranch("AMPLITUDE_LFO");
  653. AmpLfo->add2XML(xml);
  654. xml->endbranch();
  655. xml->endbranch();
  656. xml->beginbranch("FREQUENCY_PARAMETERS");
  657. xml->addpar("fixed_freq", Pfixedfreq);
  658. xml->addpar("fixed_freq_et", PfixedfreqET);
  659. xml->addpar("detune", PDetune);
  660. xml->addpar("coarse_detune", PCoarseDetune);
  661. xml->addpar("detune_type", PDetuneType);
  662. xml->beginbranch("FREQUENCY_ENVELOPE");
  663. FreqEnvelope->add2XML(xml);
  664. xml->endbranch();
  665. xml->beginbranch("FREQUENCY_LFO");
  666. FreqLfo->add2XML(xml);
  667. xml->endbranch();
  668. xml->endbranch();
  669. xml->beginbranch("FILTER_PARAMETERS");
  670. xml->addpar("velocity_sensing_amplitude", PFilterVelocityScale);
  671. xml->addpar("velocity_sensing", PFilterVelocityScaleFunction);
  672. xml->beginbranch("FILTER");
  673. GlobalFilter->add2XML(xml);
  674. xml->endbranch();
  675. xml->beginbranch("FILTER_ENVELOPE");
  676. FilterEnvelope->add2XML(xml);
  677. xml->endbranch();
  678. xml->beginbranch("FILTER_LFO");
  679. FilterLfo->add2XML(xml);
  680. xml->endbranch();
  681. xml->endbranch();
  682. }
  683. void PADnoteParameters::getfromXML(XMLwrapper *xml)
  684. {
  685. PStereo = xml->getparbool("stereo", PStereo);
  686. Pmode = xml->getpar127("mode", 0);
  687. Pbandwidth = xml->getpar("bandwidth", Pbandwidth, 0, 1000);
  688. Pbwscale = xml->getpar127("bandwidth_scale", Pbwscale);
  689. if(xml->enterbranch("HARMONIC_PROFILE")) {
  690. Php.base.type = xml->getpar127("base_type", Php.base.type);
  691. Php.base.par1 = xml->getpar127("base_par1", Php.base.par1);
  692. Php.freqmult = xml->getpar127("frequency_multiplier",
  693. Php.freqmult);
  694. Php.modulator.par1 = xml->getpar127("modulator_par1",
  695. Php.modulator.par1);
  696. Php.modulator.freq = xml->getpar127("modulator_frequency",
  697. Php.modulator.freq);
  698. Php.width = xml->getpar127("width", Php.width);
  699. Php.amp.type = xml->getpar127("amplitude_multiplier_type",
  700. Php.amp.type);
  701. Php.amp.mode = xml->getpar127("amplitude_multiplier_mode",
  702. Php.amp.mode);
  703. Php.amp.par1 = xml->getpar127("amplitude_multiplier_par1",
  704. Php.amp.par1);
  705. Php.amp.par2 = xml->getpar127("amplitude_multiplier_par2",
  706. Php.amp.par2);
  707. Php.autoscale = xml->getparbool("autoscale", Php.autoscale);
  708. Php.onehalf = xml->getpar127("one_half", Php.onehalf);
  709. xml->exitbranch();
  710. }
  711. if(xml->enterbranch("OSCIL")) {
  712. oscilgen->getfromXML(xml);
  713. xml->exitbranch();
  714. }
  715. if(xml->enterbranch("RESONANCE")) {
  716. resonance->getfromXML(xml);
  717. xml->exitbranch();
  718. }
  719. if(xml->enterbranch("HARMONIC_POSITION")) {
  720. Phrpos.type = xml->getpar127("type", Phrpos.type);
  721. Phrpos.par1 = xml->getpar("parameter1", Phrpos.par1, 0, 255);
  722. Phrpos.par2 = xml->getpar("parameter2", Phrpos.par2, 0, 255);
  723. Phrpos.par3 = xml->getpar("parameter3", Phrpos.par3, 0, 255);
  724. xml->exitbranch();
  725. }
  726. if(xml->enterbranch("SAMPLE_QUALITY")) {
  727. Pquality.samplesize = xml->getpar127("samplesize", Pquality.samplesize);
  728. Pquality.basenote = xml->getpar127("basenote", Pquality.basenote);
  729. Pquality.oct = xml->getpar127("octaves", Pquality.oct);
  730. Pquality.smpoct = xml->getpar127("samples_per_octave",
  731. Pquality.smpoct);
  732. xml->exitbranch();
  733. }
  734. if(xml->enterbranch("AMPLITUDE_PARAMETERS")) {
  735. PVolume = xml->getpar127("volume", PVolume);
  736. PPanning = xml->getpar127("panning", PPanning);
  737. PAmpVelocityScaleFunction = xml->getpar127("velocity_sensing",
  738. PAmpVelocityScaleFunction);
  739. PPunchStrength = xml->getpar127("punch_strength", PPunchStrength);
  740. PPunchTime = xml->getpar127("punch_time", PPunchTime);
  741. PPunchStretch = xml->getpar127("punch_stretch", PPunchStretch);
  742. PPunchVelocitySensing = xml->getpar127("punch_velocity_sensing",
  743. PPunchVelocitySensing);
  744. xml->enterbranch("AMPLITUDE_ENVELOPE");
  745. AmpEnvelope->getfromXML(xml);
  746. xml->exitbranch();
  747. xml->enterbranch("AMPLITUDE_LFO");
  748. AmpLfo->getfromXML(xml);
  749. xml->exitbranch();
  750. xml->exitbranch();
  751. }
  752. if(xml->enterbranch("FREQUENCY_PARAMETERS")) {
  753. Pfixedfreq = xml->getpar127("fixed_freq", Pfixedfreq);
  754. PfixedfreqET = xml->getpar127("fixed_freq_et", PfixedfreqET);
  755. PDetune = xml->getpar("detune", PDetune, 0, 16383);
  756. PCoarseDetune = xml->getpar("coarse_detune", PCoarseDetune, 0, 16383);
  757. PDetuneType = xml->getpar127("detune_type", PDetuneType);
  758. xml->enterbranch("FREQUENCY_ENVELOPE");
  759. FreqEnvelope->getfromXML(xml);
  760. xml->exitbranch();
  761. xml->enterbranch("FREQUENCY_LFO");
  762. FreqLfo->getfromXML(xml);
  763. xml->exitbranch();
  764. xml->exitbranch();
  765. }
  766. if(xml->enterbranch("FILTER_PARAMETERS")) {
  767. PFilterVelocityScale = xml->getpar127("velocity_sensing_amplitude",
  768. PFilterVelocityScale);
  769. PFilterVelocityScaleFunction = xml->getpar127(
  770. "velocity_sensing",
  771. PFilterVelocityScaleFunction);
  772. xml->enterbranch("FILTER");
  773. GlobalFilter->getfromXML(xml);
  774. xml->exitbranch();
  775. xml->enterbranch("FILTER_ENVELOPE");
  776. FilterEnvelope->getfromXML(xml);
  777. xml->exitbranch();
  778. xml->enterbranch("FILTER_LFO");
  779. FilterLfo->getfromXML(xml);
  780. xml->exitbranch();
  781. xml->exitbranch();
  782. }
  783. }