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.

Master.cpp 23KB

11 years ago
11 years ago
11 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808
  1. /*
  2. ZynAddSubFX - a software synthesizer
  3. Master.cpp - It sends Midi Messages to Parts, receives samples from parts,
  4. process them with system/insertion effects and mix them
  5. Copyright (C) 2002-2005 Nasca Octavian Paul
  6. Author: Nasca Octavian Paul
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of version 2 of the GNU General Public License
  9. as published by the Free Software Foundation.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License (version 2 or later) for more details.
  14. You should have received a copy of the GNU General Public License (version 2)
  15. along with this program; if not, write to the Free Software Foundation,
  16. Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  17. */
  18. #include "Master.h"
  19. #include "Part.h"
  20. #include "../Params/LFOParams.h"
  21. #include "../Effects/EffectMgr.h"
  22. #include "../DSP/FFTwrapper.h"
  23. #include <stdio.h>
  24. #include <sys/stat.h>
  25. #include <sys/types.h>
  26. #include <iostream>
  27. #include <algorithm>
  28. #include <cmath>
  29. #include <unistd.h>
  30. using namespace std;
  31. vuData::vuData(void)
  32. :outpeakl(0.0f), outpeakr(0.0f), maxoutpeakl(0.0f), maxoutpeakr(0.0f),
  33. rmspeakl(0.0f), rmspeakr(0.0f), clipped(0)
  34. {}
  35. static Master* masterInstance = NULL;
  36. Master::Master()
  37. {
  38. swaplr = 0;
  39. off = 0;
  40. smps = 0;
  41. bufl = new float[synth->buffersize];
  42. bufr = new float[synth->buffersize];
  43. pthread_mutex_init(&mutex, NULL);
  44. pthread_mutex_init(&vumutex, NULL);
  45. fft = new FFTwrapper(synth->oscilsize);
  46. shutup = 0;
  47. for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart) {
  48. vuoutpeakpart[npart] = 1e-9;
  49. fakepeakpart[npart] = 0;
  50. }
  51. for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart)
  52. part[npart] = new Part(&microtonal, fft, &mutex);
  53. //Insertion Effects init
  54. for(int nefx = 0; nefx < NUM_INS_EFX; ++nefx)
  55. insefx[nefx] = new EffectMgr(1, &mutex);
  56. //System Effects init
  57. for(int nefx = 0; nefx < NUM_SYS_EFX; ++nefx)
  58. sysefx[nefx] = new EffectMgr(0, &mutex);
  59. defaults();
  60. }
  61. void Master::defaults()
  62. {
  63. volume = 1.0f;
  64. setPvolume(80);
  65. setPkeyshift(64);
  66. for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart) {
  67. part[npart]->defaults();
  68. part[npart]->Prcvchn = npart % NUM_MIDI_CHANNELS;
  69. }
  70. partonoff(0, 1); //enable the first part
  71. for(int nefx = 0; nefx < NUM_INS_EFX; ++nefx) {
  72. insefx[nefx]->defaults();
  73. Pinsparts[nefx] = -1;
  74. }
  75. //System Effects init
  76. for(int nefx = 0; nefx < NUM_SYS_EFX; ++nefx) {
  77. sysefx[nefx]->defaults();
  78. for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart)
  79. setPsysefxvol(npart, nefx, 0);
  80. for(int nefxto = 0; nefxto < NUM_SYS_EFX; ++nefxto)
  81. setPsysefxsend(nefx, nefxto, 0);
  82. }
  83. microtonal.defaults();
  84. ShutUp();
  85. }
  86. bool Master::mutexLock(lockset request)
  87. {
  88. switch(request) {
  89. case MUTEX_TRYLOCK:
  90. return !pthread_mutex_trylock(&mutex);
  91. case MUTEX_LOCK:
  92. return !pthread_mutex_lock(&mutex);
  93. case MUTEX_UNLOCK:
  94. return !pthread_mutex_unlock(&mutex);
  95. }
  96. return false;
  97. }
  98. Master &Master::getInstance()
  99. {
  100. if (!masterInstance)
  101. masterInstance = new Master;
  102. return *masterInstance;
  103. }
  104. void Master::deleteInstance()
  105. {
  106. if (masterInstance)
  107. {
  108. delete masterInstance;
  109. masterInstance = NULL;
  110. }
  111. }
  112. /*
  113. * Note On Messages (velocity=0 for NoteOff)
  114. */
  115. void Master::noteOn(char chan, char note, char velocity)
  116. {
  117. if(velocity) {
  118. for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart)
  119. if(chan == part[npart]->Prcvchn) {
  120. fakepeakpart[npart] = velocity * 2;
  121. if(part[npart]->Penabled)
  122. part[npart]->NoteOn(note, velocity, keyshift);
  123. }
  124. }
  125. else
  126. this->noteOff(chan, note);
  127. HDDRecorder.triggernow();
  128. }
  129. /*
  130. * Note Off Messages
  131. */
  132. void Master::noteOff(char chan, char note)
  133. {
  134. for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart)
  135. if((chan == part[npart]->Prcvchn) && part[npart]->Penabled)
  136. part[npart]->NoteOff(note);
  137. }
  138. /*
  139. * Pressure Messages (velocity=0 for NoteOff)
  140. */
  141. void Master::polyphonicAftertouch(char chan, char note, char velocity)
  142. {
  143. if(velocity) {
  144. for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart)
  145. if(chan == part[npart]->Prcvchn)
  146. if(part[npart]->Penabled)
  147. part[npart]->PolyphonicAftertouch(note, velocity, keyshift);
  148. }
  149. else
  150. this->noteOff(chan, note);
  151. }
  152. /*
  153. * Controllers
  154. */
  155. void Master::setController(char chan, int type, int par)
  156. {
  157. if((type == C_dataentryhi) || (type == C_dataentrylo)
  158. || (type == C_nrpnhi) || (type == C_nrpnlo)) { //Process RPN and NRPN by the Master (ignore the chan)
  159. ctl.setparameternumber(type, par);
  160. int parhi = -1, parlo = -1, valhi = -1, vallo = -1;
  161. if(ctl.getnrpn(&parhi, &parlo, &valhi, &vallo) == 0) //this is NRPN
  162. //fprintf(stderr,"rcv. NRPN: %d %d %d %d\n",parhi,parlo,valhi,vallo);
  163. switch(parhi) {
  164. case 0x04: //System Effects
  165. if(parlo < NUM_SYS_EFX)
  166. sysefx[parlo]->seteffectpar_nolock(valhi, vallo);
  167. ;
  168. break;
  169. case 0x08: //Insertion Effects
  170. if(parlo < NUM_INS_EFX)
  171. insefx[parlo]->seteffectpar_nolock(valhi, vallo);
  172. ;
  173. break;
  174. }
  175. ;
  176. }
  177. else
  178. if(type == C_bankselectmsb) { // Change current bank
  179. if(((unsigned int)par < bank.banks.size())
  180. && (bank.banks[par].dir != bank.bankfiletitle))
  181. bank.loadbank(bank.banks[par].dir);
  182. }
  183. else { //other controllers
  184. for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart) //Send the controller to all part assigned to the channel
  185. if((chan == part[npart]->Prcvchn) && (part[npart]->Penabled != 0))
  186. part[npart]->SetController(type, par);
  187. ;
  188. if(type == C_allsoundsoff) { //cleanup insertion/system FX
  189. for(int nefx = 0; nefx < NUM_SYS_EFX; ++nefx)
  190. sysefx[nefx]->cleanup();
  191. for(int nefx = 0; nefx < NUM_INS_EFX; ++nefx)
  192. insefx[nefx]->cleanup();
  193. }
  194. }
  195. }
  196. void Master::setProgram(char chan, unsigned int pgm)
  197. {
  198. if(config.cfg.IgnoreProgramChange)
  199. return;
  200. for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart)
  201. if(chan == part[npart]->Prcvchn) {
  202. bank.loadfromslot(pgm, part[npart]);
  203. //Hack to get pad note parameters to update
  204. //this is not real time safe and makes assumptions about the calling
  205. //convention of this function...
  206. pthread_mutex_unlock(&mutex);
  207. part[npart]->applyparameters();
  208. pthread_mutex_lock(&mutex);
  209. }
  210. }
  211. void Master::vuUpdate(const float *outl, const float *outr)
  212. {
  213. //Peak computation (for vumeters)
  214. vu.outpeakl = 1e-12;
  215. vu.outpeakr = 1e-12;
  216. for(int i = 0; i < synth->buffersize; ++i) {
  217. if(fabs(outl[i]) > vu.outpeakl)
  218. vu.outpeakl = fabs(outl[i]);
  219. if(fabs(outr[i]) > vu.outpeakr)
  220. vu.outpeakr = fabs(outr[i]);
  221. }
  222. if((vu.outpeakl > 1.0f) || (vu.outpeakr > 1.0f))
  223. vu.clipped = 1;
  224. if(vu.maxoutpeakl < vu.outpeakl)
  225. vu.maxoutpeakl = vu.outpeakl;
  226. if(vu.maxoutpeakr < vu.outpeakr)
  227. vu.maxoutpeakr = vu.outpeakr;
  228. //RMS Peak computation (for vumeters)
  229. vu.rmspeakl = 1e-12;
  230. vu.rmspeakr = 1e-12;
  231. for(int i = 0; i < synth->buffersize; ++i) {
  232. vu.rmspeakl += outl[i] * outl[i];
  233. vu.rmspeakr += outr[i] * outr[i];
  234. }
  235. vu.rmspeakl = sqrt(vu.rmspeakl / synth->buffersize_f);
  236. vu.rmspeakr = sqrt(vu.rmspeakr / synth->buffersize_f);
  237. //Part Peak computation (for Part vumeters or fake part vumeters)
  238. for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart) {
  239. vuoutpeakpart[npart] = 1.0e-12f;
  240. if(part[npart]->Penabled != 0) {
  241. float *outl = part[npart]->partoutl,
  242. *outr = part[npart]->partoutr;
  243. for(int i = 0; i < synth->buffersize; ++i) {
  244. float tmp = fabs(outl[i] + outr[i]);
  245. if(tmp > vuoutpeakpart[npart])
  246. vuoutpeakpart[npart] = tmp;
  247. }
  248. vuoutpeakpart[npart] *= volume;
  249. }
  250. else
  251. if(fakepeakpart[npart] > 1)
  252. fakepeakpart[npart]--;
  253. }
  254. }
  255. /*
  256. * Enable/Disable a part
  257. */
  258. void Master::partonoff(int npart, int what)
  259. {
  260. if(npart >= NUM_MIDI_PARTS)
  261. return;
  262. if(what == 0) { //disable part
  263. fakepeakpart[npart] = 0;
  264. part[npart]->Penabled = 0;
  265. part[npart]->cleanup();
  266. for(int nefx = 0; nefx < NUM_INS_EFX; ++nefx) {
  267. if(Pinsparts[nefx] == npart)
  268. insefx[nefx]->cleanup();
  269. ;
  270. }
  271. }
  272. else { //enabled
  273. part[npart]->Penabled = 1;
  274. fakepeakpart[npart] = 0;
  275. }
  276. }
  277. /*
  278. * Master audio out (the final sound)
  279. */
  280. void Master::AudioOut(float *outl, float *outr)
  281. {
  282. //Swaps the Left channel with Right Channel
  283. if(swaplr)
  284. swap(outl, outr);
  285. //clean up the output samples (should not be needed?)
  286. memset(outl, 0, synth->bufferbytes);
  287. memset(outr, 0, synth->bufferbytes);
  288. //Compute part samples and store them part[npart]->partoutl,partoutr
  289. for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart) {
  290. if(part[npart]->Penabled != 0 && !pthread_mutex_trylock(&part[npart]->load_mutex)) {
  291. part[npart]->ComputePartSmps();
  292. pthread_mutex_unlock(&part[npart]->load_mutex);
  293. }
  294. }
  295. //Insertion effects
  296. for(int nefx = 0; nefx < NUM_INS_EFX; ++nefx)
  297. if(Pinsparts[nefx] >= 0) {
  298. int efxpart = Pinsparts[nefx];
  299. if(part[efxpart]->Penabled)
  300. insefx[nefx]->out(part[efxpart]->partoutl,
  301. part[efxpart]->partoutr);
  302. }
  303. //Apply the part volumes and pannings (after insertion effects)
  304. for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart) {
  305. if(part[npart]->Penabled == 0)
  306. continue;
  307. Stereo<float> newvol(part[npart]->volume),
  308. oldvol(part[npart]->oldvolumel,
  309. part[npart]->oldvolumer);
  310. float pan = part[npart]->panning;
  311. if(pan < 0.5f)
  312. newvol.l *= pan * 2.0f;
  313. else
  314. newvol.r *= (1.0f - pan) * 2.0f;
  315. //the volume or the panning has changed and needs interpolation
  316. if(ABOVE_AMPLITUDE_THRESHOLD(oldvol.l, newvol.l)
  317. || ABOVE_AMPLITUDE_THRESHOLD(oldvol.r, newvol.r)) {
  318. for(int i = 0; i < synth->buffersize; ++i) {
  319. Stereo<float> vol(INTERPOLATE_AMPLITUDE(oldvol.l, newvol.l,
  320. i, synth->buffersize),
  321. INTERPOLATE_AMPLITUDE(oldvol.r, newvol.r,
  322. i, synth->buffersize));
  323. part[npart]->partoutl[i] *= vol.l;
  324. part[npart]->partoutr[i] *= vol.r;
  325. }
  326. part[npart]->oldvolumel = newvol.l;
  327. part[npart]->oldvolumer = newvol.r;
  328. }
  329. else
  330. for(int i = 0; i < synth->buffersize; ++i) { //the volume did not changed
  331. part[npart]->partoutl[i] *= newvol.l;
  332. part[npart]->partoutr[i] *= newvol.r;
  333. }
  334. }
  335. //System effects
  336. for(int nefx = 0; nefx < NUM_SYS_EFX; ++nefx) {
  337. if(sysefx[nefx]->geteffect() == 0)
  338. continue; //the effect is disabled
  339. float tmpmixl[synth->buffersize];
  340. float tmpmixr[synth->buffersize];
  341. //Clean up the samples used by the system effects
  342. memset(tmpmixl, 0, synth->bufferbytes);
  343. memset(tmpmixr, 0, synth->bufferbytes);
  344. //Mix the channels according to the part settings about System Effect
  345. for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart) {
  346. //skip if the part has no output to effect
  347. if(Psysefxvol[nefx][npart] == 0)
  348. continue;
  349. //skip if the part is disabled
  350. if(part[npart]->Penabled == 0)
  351. continue;
  352. //the output volume of each part to system effect
  353. const float vol = sysefxvol[nefx][npart];
  354. for(int i = 0; i < synth->buffersize; ++i) {
  355. tmpmixl[i] += part[npart]->partoutl[i] * vol;
  356. tmpmixr[i] += part[npart]->partoutr[i] * vol;
  357. }
  358. }
  359. // system effect send to next ones
  360. for(int nefxfrom = 0; nefxfrom < nefx; ++nefxfrom)
  361. if(Psysefxsend[nefxfrom][nefx] != 0) {
  362. const float vol = sysefxsend[nefxfrom][nefx];
  363. for(int i = 0; i < synth->buffersize; ++i) {
  364. tmpmixl[i] += sysefx[nefxfrom]->efxoutl[i] * vol;
  365. tmpmixr[i] += sysefx[nefxfrom]->efxoutr[i] * vol;
  366. }
  367. }
  368. sysefx[nefx]->out(tmpmixl, tmpmixr);
  369. //Add the System Effect to sound output
  370. const float outvol = sysefx[nefx]->sysefxgetvolume();
  371. for(int i = 0; i < synth->buffersize; ++i) {
  372. outl[i] += tmpmixl[i] * outvol;
  373. outr[i] += tmpmixr[i] * outvol;
  374. }
  375. }
  376. //Mix all parts
  377. for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart)
  378. if(part[npart]->Penabled) //only mix active parts
  379. for(int i = 0; i < synth->buffersize; ++i) { //the volume did not changed
  380. outl[i] += part[npart]->partoutl[i];
  381. outr[i] += part[npart]->partoutr[i];
  382. }
  383. //Insertion effects for Master Out
  384. for(int nefx = 0; nefx < NUM_INS_EFX; ++nefx)
  385. if(Pinsparts[nefx] == -2)
  386. insefx[nefx]->out(outl, outr);
  387. //Master Volume
  388. for(int i = 0; i < synth->buffersize; ++i) {
  389. outl[i] *= volume;
  390. outr[i] *= volume;
  391. }
  392. if(!pthread_mutex_trylock(&vumutex)) {
  393. vuUpdate(outl, outr);
  394. pthread_mutex_unlock(&vumutex);
  395. }
  396. //Shutup if it is asked (with fade-out)
  397. if(shutup) {
  398. for(int i = 0; i < synth->buffersize; ++i) {
  399. float tmp = (synth->buffersize_f - i) / synth->buffersize_f;
  400. outl[i] *= tmp;
  401. outr[i] *= tmp;
  402. }
  403. ShutUp();
  404. }
  405. //update the LFO's time
  406. LFOParams::time++;
  407. dump.inctick();
  408. }
  409. //TODO review the respective code from yoshimi for this
  410. //If memory serves correctly, libsamplerate was used
  411. void Master::GetAudioOutSamples(size_t nsamples,
  412. unsigned samplerate,
  413. float *outl,
  414. float *outr)
  415. {
  416. off_t out_off = 0;
  417. //Fail when resampling rather than doing a poor job
  418. if(synth->samplerate != samplerate) {
  419. printf("darn it: %d vs %d\n", synth->samplerate, samplerate);
  420. return;
  421. }
  422. while(nsamples) {
  423. //use all available samples
  424. if(nsamples >= smps) {
  425. memcpy(outl + out_off, bufl + off, sizeof(float) * smps);
  426. memcpy(outr + out_off, bufr + off, sizeof(float) * smps);
  427. nsamples -= smps;
  428. //generate samples
  429. AudioOut(bufl, bufr);
  430. off = 0;
  431. out_off += smps;
  432. smps = synth->buffersize;
  433. }
  434. else { //use some samples
  435. memcpy(outl + out_off, bufl + off, sizeof(float) * nsamples);
  436. memcpy(outr + out_off, bufr + off, sizeof(float) * nsamples);
  437. smps -= nsamples;
  438. off += nsamples;
  439. nsamples = 0;
  440. }
  441. }
  442. }
  443. Master::~Master()
  444. {
  445. delete []bufl;
  446. delete []bufr;
  447. for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart)
  448. delete part[npart];
  449. for(int nefx = 0; nefx < NUM_INS_EFX; ++nefx)
  450. delete insefx[nefx];
  451. for(int nefx = 0; nefx < NUM_SYS_EFX; ++nefx)
  452. delete sysefx[nefx];
  453. delete fft;
  454. pthread_mutex_destroy(&mutex);
  455. pthread_mutex_destroy(&vumutex);
  456. }
  457. /*
  458. * Parameter control
  459. */
  460. void Master::setPvolume(char Pvolume_)
  461. {
  462. Pvolume = Pvolume_;
  463. volume = dB2rap((Pvolume - 96.0f) / 96.0f * 40.0f);
  464. }
  465. void Master::setPkeyshift(char Pkeyshift_)
  466. {
  467. Pkeyshift = Pkeyshift_;
  468. keyshift = (int)Pkeyshift - 64;
  469. }
  470. void Master::setPsysefxvol(int Ppart, int Pefx, char Pvol)
  471. {
  472. Psysefxvol[Pefx][Ppart] = Pvol;
  473. sysefxvol[Pefx][Ppart] = powf(0.1f, (1.0f - Pvol / 96.0f) * 2.0f);
  474. }
  475. void Master::setPsysefxsend(int Pefxfrom, int Pefxto, char Pvol)
  476. {
  477. Psysefxsend[Pefxfrom][Pefxto] = Pvol;
  478. sysefxsend[Pefxfrom][Pefxto] = powf(0.1f, (1.0f - Pvol / 96.0f) * 2.0f);
  479. }
  480. /*
  481. * Panic! (Clean up all parts and effects)
  482. */
  483. void Master::ShutUp()
  484. {
  485. for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart) {
  486. part[npart]->cleanup();
  487. fakepeakpart[npart] = 0;
  488. }
  489. for(int nefx = 0; nefx < NUM_INS_EFX; ++nefx)
  490. insefx[nefx]->cleanup();
  491. for(int nefx = 0; nefx < NUM_SYS_EFX; ++nefx)
  492. sysefx[nefx]->cleanup();
  493. vuresetpeaks();
  494. shutup = 0;
  495. }
  496. /*
  497. * Reset peaks and clear the "cliped" flag (for VU-meter)
  498. */
  499. void Master::vuresetpeaks()
  500. {
  501. pthread_mutex_lock(&vumutex);
  502. vu.outpeakl = 1e-9;
  503. vu.outpeakr = 1e-9;
  504. vu.maxoutpeakl = 1e-9;
  505. vu.maxoutpeakr = 1e-9;
  506. vu.clipped = 0;
  507. pthread_mutex_unlock(&vumutex);
  508. }
  509. vuData Master::getVuData()
  510. {
  511. vuData tmp;
  512. pthread_mutex_lock(&vumutex);
  513. tmp = vu;
  514. pthread_mutex_unlock(&vumutex);
  515. return tmp;
  516. }
  517. void Master::applyparameters(bool lockmutex)
  518. {
  519. for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart)
  520. part[npart]->applyparameters(lockmutex);
  521. }
  522. void Master::add2XML(XMLwrapper *xml)
  523. {
  524. xml->addpar("volume", Pvolume);
  525. xml->addpar("key_shift", Pkeyshift);
  526. xml->addparbool("nrpn_receive", ctl.NRPN.receive);
  527. xml->beginbranch("MICROTONAL");
  528. microtonal.add2XML(xml);
  529. xml->endbranch();
  530. for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart) {
  531. xml->beginbranch("PART", npart);
  532. part[npart]->add2XML(xml);
  533. xml->endbranch();
  534. }
  535. xml->beginbranch("SYSTEM_EFFECTS");
  536. for(int nefx = 0; nefx < NUM_SYS_EFX; ++nefx) {
  537. xml->beginbranch("SYSTEM_EFFECT", nefx);
  538. xml->beginbranch("EFFECT");
  539. sysefx[nefx]->add2XML(xml);
  540. xml->endbranch();
  541. for(int pefx = 0; pefx < NUM_MIDI_PARTS; ++pefx) {
  542. xml->beginbranch("VOLUME", pefx);
  543. xml->addpar("vol", Psysefxvol[nefx][pefx]);
  544. xml->endbranch();
  545. }
  546. for(int tonefx = nefx + 1; tonefx < NUM_SYS_EFX; ++tonefx) {
  547. xml->beginbranch("SENDTO", tonefx);
  548. xml->addpar("send_vol", Psysefxsend[nefx][tonefx]);
  549. xml->endbranch();
  550. }
  551. xml->endbranch();
  552. }
  553. xml->endbranch();
  554. xml->beginbranch("INSERTION_EFFECTS");
  555. for(int nefx = 0; nefx < NUM_INS_EFX; ++nefx) {
  556. xml->beginbranch("INSERTION_EFFECT", nefx);
  557. xml->addpar("part", Pinsparts[nefx]);
  558. xml->beginbranch("EFFECT");
  559. insefx[nefx]->add2XML(xml);
  560. xml->endbranch();
  561. xml->endbranch();
  562. }
  563. xml->endbranch();
  564. }
  565. int Master::getalldata(char **data)
  566. {
  567. XMLwrapper *xml = new XMLwrapper();
  568. xml->beginbranch("MASTER");
  569. pthread_mutex_lock(&mutex);
  570. add2XML(xml);
  571. pthread_mutex_unlock(&mutex);
  572. xml->endbranch();
  573. *data = xml->getXMLdata();
  574. delete (xml);
  575. return strlen(*data) + 1;
  576. }
  577. void Master::putalldata(char *data, int /*size*/)
  578. {
  579. XMLwrapper *xml = new XMLwrapper();
  580. if(!xml->putXMLdata(data)) {
  581. delete (xml);
  582. return;
  583. }
  584. if(xml->enterbranch("MASTER") == 0)
  585. return;
  586. pthread_mutex_lock(&mutex);
  587. getfromXML(xml);
  588. pthread_mutex_unlock(&mutex);
  589. xml->exitbranch();
  590. delete (xml);
  591. }
  592. int Master::saveXML(const char *filename)
  593. {
  594. XMLwrapper *xml = new XMLwrapper();
  595. xml->beginbranch("MASTER");
  596. add2XML(xml);
  597. xml->endbranch();
  598. int result = xml->saveXMLfile(filename);
  599. delete (xml);
  600. return result;
  601. }
  602. int Master::loadXML(const char *filename)
  603. {
  604. XMLwrapper *xml = new XMLwrapper();
  605. if(xml->loadXMLfile(filename) < 0) {
  606. delete (xml);
  607. return -1;
  608. }
  609. if(xml->enterbranch("MASTER") == 0)
  610. return -10;
  611. getfromXML(xml);
  612. xml->exitbranch();
  613. delete (xml);
  614. return 0;
  615. }
  616. void Master::getfromXML(XMLwrapper *xml)
  617. {
  618. setPvolume(xml->getpar127("volume", Pvolume));
  619. setPkeyshift(xml->getpar127("key_shift", Pkeyshift));
  620. ctl.NRPN.receive = xml->getparbool("nrpn_receive", ctl.NRPN.receive);
  621. part[0]->Penabled = 0;
  622. for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart) {
  623. if(xml->enterbranch("PART", npart) == 0)
  624. continue;
  625. part[npart]->getfromXML(xml);
  626. xml->exitbranch();
  627. }
  628. if(xml->enterbranch("MICROTONAL")) {
  629. microtonal.getfromXML(xml);
  630. xml->exitbranch();
  631. }
  632. sysefx[0]->changeeffect(0);
  633. if(xml->enterbranch("SYSTEM_EFFECTS")) {
  634. for(int nefx = 0; nefx < NUM_SYS_EFX; ++nefx) {
  635. if(xml->enterbranch("SYSTEM_EFFECT", nefx) == 0)
  636. continue;
  637. if(xml->enterbranch("EFFECT")) {
  638. sysefx[nefx]->getfromXML(xml);
  639. xml->exitbranch();
  640. }
  641. for(int partefx = 0; partefx < NUM_MIDI_PARTS; ++partefx) {
  642. if(xml->enterbranch("VOLUME", partefx) == 0)
  643. continue;
  644. setPsysefxvol(partefx, nefx,
  645. xml->getpar127("vol", Psysefxvol[partefx][nefx]));
  646. xml->exitbranch();
  647. }
  648. for(int tonefx = nefx + 1; tonefx < NUM_SYS_EFX; ++tonefx) {
  649. if(xml->enterbranch("SENDTO", tonefx) == 0)
  650. continue;
  651. setPsysefxsend(nefx, tonefx,
  652. xml->getpar127("send_vol",
  653. Psysefxsend[nefx][tonefx]));
  654. xml->exitbranch();
  655. }
  656. xml->exitbranch();
  657. }
  658. xml->exitbranch();
  659. }
  660. if(xml->enterbranch("INSERTION_EFFECTS")) {
  661. for(int nefx = 0; nefx < NUM_INS_EFX; ++nefx) {
  662. if(xml->enterbranch("INSERTION_EFFECT", nefx) == 0)
  663. continue;
  664. Pinsparts[nefx] = xml->getpar("part",
  665. Pinsparts[nefx],
  666. -2,
  667. NUM_MIDI_PARTS);
  668. if(xml->enterbranch("EFFECT")) {
  669. insefx[nefx]->getfromXML(xml);
  670. xml->exitbranch();
  671. }
  672. xml->exitbranch();
  673. }
  674. xml->exitbranch();
  675. }
  676. }