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.

1404 lines
46KB

  1. /*
  2. ZynAddSubFX - a software synthesizer
  3. Part.cpp - Part implementation
  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 "Part.h"
  18. #include "Microtonal.h"
  19. #include "Util.h"
  20. #include "XMLwrapper.h"
  21. #include "Allocator.h"
  22. #include "../Effects/EffectMgr.h"
  23. #include "../Params/ADnoteParameters.h"
  24. #include "../Params/SUBnoteParameters.h"
  25. #include "../Params/PADnoteParameters.h"
  26. #include "../Synth/Resonance.h"
  27. #include "../Synth/SynthNote.h"
  28. #include "../Synth/ADnote.h"
  29. #include "../Synth/SUBnote.h"
  30. #include "../Synth/PADnote.h"
  31. #include "../DSP/FFTwrapper.h"
  32. #include "../Misc/Util.h"
  33. #include <cstdlib>
  34. #include <cstdio>
  35. #include <cstring>
  36. #include <cassert>
  37. #include <rtosc/ports.h>
  38. #include <rtosc/port-sugar.h>
  39. using rtosc::Ports;
  40. using rtosc::RtData;
  41. #define rObject Part
  42. static const Ports partPorts = {
  43. rRecurs(kit, 16, "Kit"),//NUM_KIT_ITEMS
  44. rRecursp(partefx, 3, "Part Effect"),
  45. rRecur(ctl, "Controller"),
  46. rToggle(Penabled, "Part enable"),
  47. #undef rChangeCb
  48. #define rChangeCb obj->setPvolume(obj->Pvolume);
  49. rParamZyn(Pvolume, "Part Volume"),
  50. #undef rChangeCb
  51. #define rChangeCb obj->setPpanning(obj->Ppanning);
  52. rParamZyn(Ppanning, "Set Panning"),
  53. #undef rChangeCb
  54. #define rChangeCb obj->setkeylimit(obj->Pkeylimit);
  55. rParamI(Pkeylimit, rProp(parameter), rMap(min,0), rMap(max, POLYPHONY), "Key limit per part"),
  56. #undef rChangeCb
  57. #define rChangeCb
  58. rParamZyn(Pminkey, "Min Used Key"),
  59. rParamZyn(Pmaxkey, "Max Used Key"),
  60. rParamZyn(Pkeyshift, "Part keyshift"),
  61. rParamZyn(Prcvchn, "Active MIDI channel"),
  62. rParamZyn(Pvelsns, "Velocity sensing"),
  63. rParamZyn(Pveloffs, "Velocity offset"),
  64. rToggle(Pnoteon, "If the channel accepts note on events"),
  65. //TODO FIXME Change to 0=OFF 1=MULTI 2=SINGLE
  66. rParamI(Pkitmode, "Kit mode enable"),
  67. rToggle(Pdrummode, "Drum mode enable"),
  68. rToggle(Ppolymode, "Polyphoney mode"),
  69. rToggle(Plegatomode, "Legato enable"),
  70. rParamZyn(info.Ptype, "Class of Instrument"),
  71. rString(info.Pauthor, MAX_INFO_TEXT_SIZE, "Instrument Author"),
  72. rString(info.Pcomments, MAX_INFO_TEXT_SIZE, "Instrument Comments"),
  73. rString(Pname, PART_MAX_NAME_LEN, "Kit User Specified Label"),
  74. rArray(Pefxroute, NUM_PART_EFX, "Effect Routing"),
  75. rArrayT(Pefxbypass, NUM_PART_EFX, "If an effect is bypassed"),
  76. {"captureMin:", NULL, NULL, [](const char *, RtData &r)
  77. {Part *p = (Part*)r.obj; p->Pminkey = p->lastnote;}},
  78. {"captureMax:", NULL, NULL, [](const char *, RtData &r)
  79. {Part *p = (Part*)r.obj; p->Pmaxkey = p->lastnote;}},
  80. {"polyType::c:i", NULL, NULL, [](const char *msg, RtData &d)
  81. {
  82. Part *p = (Part*)d.obj;
  83. if(!rtosc_narguments(msg)) {
  84. int res = 0;
  85. if(!p->Ppolymode)
  86. res = p->Plegatomode ? 2 : 1;
  87. d.reply(d.loc, "c", res);
  88. return;
  89. }
  90. int i = rtosc_argument(msg, 0).i;
  91. if(i == 0) {
  92. p->Ppolymode = 1;
  93. p->Plegatomode = 0;
  94. } else if(i==1) {
  95. p->Ppolymode = 0;
  96. p->Plegatomode = 0;
  97. } else {
  98. p->Ppolymode = 0;
  99. p->Plegatomode = 1;
  100. }}},
  101. {"clear:", rProp(internal) rDoc("Reset Part To Defaults"), 0, [](const char *, RtData &d)
  102. {
  103. //XXX todo forward this event for middleware to handle
  104. //Part *p = (Part*)d.obj;
  105. //p->defaults();
  106. //char part_loc[128];
  107. //strcpy(part_loc, d.loc);
  108. //char *end = strrchr(part_loc, '/');
  109. //if(end)
  110. // end[1] = 0;
  111. //d.broadcast("/damage", "s", part_loc);
  112. }},
  113. //{"kit#16::T:F", "::Enables or disables kit item", 0,
  114. // [](const char *m, RtData &d) {
  115. // auto loc = d.loc;
  116. // Part *p = (Part*)d.obj;
  117. // unsigned kitid = -1;
  118. // //Note that this event will be captured before transmitted, thus
  119. // //reply/broadcast don't matter
  120. // for(int i=0; i<NUM_KIT_ITEMS; ++i) {
  121. // d.reply("/middleware/oscil", "siisb", loc, kitid, i,
  122. // "oscil", sizeof(void*),
  123. // p->kit[kitid]->adpars->voice[i]->OscilSmp);
  124. // d.reply("/middleware/oscil", "siisb", loc, kitid, i, "oscil-mod"
  125. // sizeof(void*),
  126. // p->kit[kitid]->adpars->voice[i]->somethingelse);
  127. // }
  128. // d.reply("/middleware/pad", "sib", loc, kitid,
  129. // sizeof(PADnoteParameters*),
  130. // p->kit[kitid]->padpars)
  131. // }}
  132. };
  133. #undef rObject
  134. #define rObject Part::Kit
  135. static const Ports kitPorts = {
  136. rRecurp(padpars, "Padnote parameters"),
  137. rRecurp(adpars, "Adnote parameters"),
  138. rRecurp(subpars, "Adnote parameters"),
  139. rToggle(Penabled, "Kit item enable"),
  140. rToggle(Pmuted, "Kit item mute"),
  141. rParamZyn(Pminkey, "Kit item min key"),
  142. rParamZyn(Pmaxkey, "Kit item max key"),
  143. rToggle(Padenabled, "ADsynth enable"),
  144. rToggle(Psubenabled, "SUBsynth enable"),
  145. rToggle(Ppadenabled, "PADsynth enable"),
  146. rParamZyn(Psendtoparteffect, "Effect Levels"),
  147. rString(Pname, PART_MAX_NAME_LEN, "Kit User Specified Label"),
  148. {"padpars-data:b", rProp(internal), 0,
  149. [](const char *msg, RtData &d) {
  150. rObject &o = *(rObject*)d.obj;
  151. assert(o.padpars == NULL);
  152. o.padpars = *(decltype(o.padpars)*)rtosc_argument(msg, 0).b.data;
  153. }},
  154. {"adpars-data:b", rProp(internal), 0,
  155. [](const char *msg, RtData &d) {
  156. rObject &o = *(rObject*)d.obj;
  157. assert(o.adpars == NULL);
  158. o.adpars = *(decltype(o.adpars)*)rtosc_argument(msg, 0).b.data;
  159. }},
  160. {"subpars-data:b", rProp(internal), 0,
  161. [](const char *msg, RtData &d) {
  162. rObject &o = *(rObject*)d.obj;
  163. assert(o.subpars == NULL);
  164. o.subpars = *(decltype(o.subpars)*)rtosc_argument(msg, 0).b.data;
  165. }},
  166. // [](
  167. };
  168. const Ports &Part::Kit::ports = kitPorts;
  169. const Ports &Part::ports = partPorts;
  170. Part::Part(Allocator &alloc, const SYNTH_T &synth_, Microtonal *microtonal_, FFTwrapper *fft_)
  171. :ctl(synth_), memory(alloc), synth(synth_)
  172. {
  173. microtonal = microtonal_;
  174. fft = fft_;
  175. partoutl = new float [synth.buffersize];
  176. partoutr = new float [synth.buffersize];
  177. monomemClear();
  178. for(int n = 0; n < NUM_KIT_ITEMS; ++n) {
  179. kit[n].Pname = new char [PART_MAX_NAME_LEN];
  180. kit[n].adpars = nullptr;
  181. kit[n].subpars = nullptr;
  182. kit[n].padpars = nullptr;
  183. }
  184. kit[0].adpars = new ADnoteParameters(synth, fft);
  185. //Part's Insertion Effects init
  186. for(int nefx = 0; nefx < NUM_PART_EFX; ++nefx) {
  187. partefx[nefx] = new EffectMgr(memory, synth, 1);
  188. Pefxbypass[nefx] = false;
  189. }
  190. for(int n = 0; n < NUM_PART_EFX + 1; ++n) {
  191. partfxinputl[n] = new float [synth.buffersize];
  192. partfxinputr[n] = new float [synth.buffersize];
  193. }
  194. killallnotes = false;
  195. oldfreq = -1.0f;
  196. for(int i = 0; i < POLYPHONY; ++i) {
  197. partnote[i].status = KEY_OFF;
  198. partnote[i].note = -1;
  199. partnote[i].itemsplaying = 0;
  200. for(int j = 0; j < NUM_KIT_ITEMS; ++j) {
  201. partnote[i].kititem[j].adnote = NULL;
  202. partnote[i].kititem[j].subnote = NULL;
  203. partnote[i].kititem[j].padnote = NULL;
  204. }
  205. partnote[i].time = 0;
  206. }
  207. cleanup();
  208. Pname = new char[PART_MAX_NAME_LEN];
  209. oldvolumel = oldvolumer = 0.5f;
  210. lastnote = -1;
  211. lastpos = 0; // lastpos will store previously used NoteOn(...)'s pos.
  212. lastlegatomodevalid = false; // To store previous legatomodevalid value.
  213. defaults();
  214. }
  215. void Part::cloneTraits(Part &p) const
  216. {
  217. #define CLONE(x) p.x = this->x
  218. CLONE(Penabled);
  219. p.setPvolume(this->Pvolume);
  220. p.setPpanning(this->Ppanning);
  221. CLONE(Pminkey);
  222. CLONE(Pmaxkey);
  223. CLONE(Pkeyshift);
  224. CLONE(Prcvchn);
  225. CLONE(Pvelsns);
  226. CLONE(Pveloffs);
  227. CLONE(Pnoteon);
  228. CLONE(Ppolymode);
  229. CLONE(Plegatomode);
  230. CLONE(Pkeylimit);
  231. CLONE(ctl);
  232. }
  233. void Part::defaults()
  234. {
  235. Penabled = 0;
  236. Pminkey = 0;
  237. Pmaxkey = 127;
  238. Pnoteon = 1;
  239. Ppolymode = 1;
  240. Plegatomode = 0;
  241. setPvolume(96);
  242. Pkeyshift = 64;
  243. Prcvchn = 0;
  244. setPpanning(64);
  245. Pvelsns = 64;
  246. Pveloffs = 64;
  247. Pkeylimit = 15;
  248. defaultsinstrument();
  249. ctl.defaults();
  250. }
  251. void Part::defaultsinstrument()
  252. {
  253. ZERO(Pname, PART_MAX_NAME_LEN);
  254. info.Ptype = 0;
  255. ZERO(info.Pauthor, MAX_INFO_TEXT_SIZE + 1);
  256. ZERO(info.Pcomments, MAX_INFO_TEXT_SIZE + 1);
  257. Pkitmode = 0;
  258. Pdrummode = 0;
  259. for(int n = 0; n < NUM_KIT_ITEMS; ++n) {
  260. kit[n].Penabled = false;
  261. kit[n].Pmuted = false;
  262. kit[n].Pminkey = 0;
  263. kit[n].Pmaxkey = 127;
  264. kit[n].Padenabled = false;
  265. kit[n].Psubenabled = false;
  266. kit[n].Ppadenabled = false;
  267. ZERO(kit[n].Pname, PART_MAX_NAME_LEN);
  268. kit[n].Psendtoparteffect = 0;
  269. if(n != 0)
  270. setkititemstatus(n, 0);
  271. }
  272. kit[0].Penabled = 1;
  273. kit[0].Padenabled = 1;
  274. kit[0].adpars->defaults();
  275. for(int nefx = 0; nefx < NUM_PART_EFX; ++nefx) {
  276. partefx[nefx]->defaults();
  277. Pefxroute[nefx] = 0; //route to next effect
  278. }
  279. }
  280. /*
  281. * Cleanup the part
  282. */
  283. void Part::cleanup(bool final_)
  284. {
  285. for(int k = 0; k < POLYPHONY; ++k)
  286. KillNotePos(k);
  287. for(int i = 0; i < synth.buffersize; ++i) {
  288. partoutl[i] = final_ ? 0.0f : denormalkillbuf[i];
  289. partoutr[i] = final_ ? 0.0f : denormalkillbuf[i];
  290. }
  291. ctl.resetall();
  292. for(int nefx = 0; nefx < NUM_PART_EFX; ++nefx)
  293. partefx[nefx]->cleanup();
  294. for(int n = 0; n < NUM_PART_EFX + 1; ++n)
  295. for(int i = 0; i < synth.buffersize; ++i) {
  296. partfxinputl[n][i] = final_ ? 0.0f : denormalkillbuf[i];
  297. partfxinputr[n][i] = final_ ? 0.0f : denormalkillbuf[i];
  298. }
  299. }
  300. Part::~Part()
  301. {
  302. cleanup(true);
  303. for(int n = 0; n < NUM_KIT_ITEMS; ++n) {
  304. delete kit[n].adpars;
  305. delete kit[n].subpars;
  306. delete kit[n].padpars;
  307. delete [] kit[n].Pname;
  308. }
  309. delete [] Pname;
  310. delete [] partoutl;
  311. delete [] partoutr;
  312. for(int nefx = 0; nefx < NUM_PART_EFX; ++nefx)
  313. delete partefx[nefx];
  314. for(int n = 0; n < NUM_PART_EFX + 1; ++n) {
  315. delete [] partfxinputl[n];
  316. delete [] partfxinputr[n];
  317. }
  318. }
  319. /*
  320. * Note On Messages
  321. */
  322. void Part::NoteOn(unsigned char note,
  323. unsigned char velocity,
  324. int masterkeyshift)
  325. {
  326. // Legato and MonoMem used vars:
  327. int posb = POLYPHONY - 1; // Just a dummy initial value.
  328. bool legatomodevalid = false; //true when legato mode is determined applicable.
  329. bool doinglegato = false; // true when we determined we do a legato note.
  330. bool ismonofirstnote = false; /*(In Mono/Legato) true when we determined
  331. no other notes are held down or sustained.*/
  332. int lastnotecopy = lastnote; //Useful after lastnote has been changed.
  333. if(!Pnoteon || !inRange(note, Pminkey, Pmaxkey))
  334. return;
  335. // MonoMem stuff:
  336. if(!Ppolymode) { // If Poly is off
  337. monomemPush(note); // Add note to the list.
  338. monomem[note].velocity = velocity; // Store this note's velocity.
  339. monomem[note].mkeyshift = masterkeyshift; /* Store masterkeyshift too*/
  340. if((partnote[lastpos].status != KEY_PLAYING)
  341. && (partnote[lastpos].status != KEY_RELEASED_AND_SUSTAINED))
  342. ismonofirstnote = true; // No other keys are held or sustained.
  343. } else if(!monomemEmpty())
  344. monomemClear();
  345. lastnote = note;
  346. int pos = -1;
  347. for(int i = 0; i < POLYPHONY; ++i)
  348. if(partnote[i].status == KEY_OFF) {
  349. pos = i;
  350. break;
  351. }
  352. if(Plegatomode && !Pdrummode) {
  353. if(Ppolymode != 0) {
  354. fprintf(
  355. stderr,
  356. "ZynAddSubFX WARNING: Poly and Legato modes are both On, that should not happen ! ... Disabling Legato mode ! - (Part.cpp::NoteOn(..))\n");
  357. Plegatomode = 0;
  358. }
  359. else {
  360. // Legato mode is on and applicable.
  361. legatomodevalid = true;
  362. if((not ismonofirstnote) && (lastlegatomodevalid)) {
  363. // At least one other key is held or sustained, and the
  364. // previous note was played while in valid legato mode.
  365. doinglegato = true; // So we'll do a legato note.
  366. pos = lastpos; // A legato note uses same pos as previous..
  367. posb = lastposb; // .. same goes for posb.
  368. }
  369. else {
  370. // Legato mode is valid, but this is only a first note.
  371. for(int i = 0; i < POLYPHONY; ++i)
  372. if((partnote[i].status == KEY_PLAYING)
  373. || (partnote[i].status == KEY_RELEASED_AND_SUSTAINED))
  374. ReleaseNotePos(i);
  375. // Set posb
  376. posb = (pos + 1) % POLYPHONY; //We really want it (if the following fails)
  377. for(int i = 0; i < POLYPHONY; ++i)
  378. if((partnote[i].status == KEY_OFF) && (pos != i)) {
  379. posb = i;
  380. break;
  381. }
  382. }
  383. lastposb = posb; // Keep a trace of used posb
  384. }
  385. }
  386. else // Legato mode is either off or non-applicable.
  387. if(!Ppolymode) { //if the mode is 'mono' turn off all other notes
  388. for(int i = 0; i < POLYPHONY; ++i)
  389. if(partnote[i].status == KEY_PLAYING)
  390. ReleaseNotePos(i);
  391. ReleaseSustainedKeys();
  392. }
  393. lastlegatomodevalid = legatomodevalid;
  394. if(pos == -1)
  395. fprintf(stderr,
  396. "%s",
  397. "NOTES TOO MANY (> POLYPHONY) - (Part.cpp::NoteOn(..))\n");
  398. else {
  399. //start the note
  400. partnote[pos].status = KEY_PLAYING;
  401. partnote[pos].note = note;
  402. if(legatomodevalid) {
  403. partnote[posb].status = KEY_PLAYING;
  404. partnote[posb].note = note;
  405. }
  406. //this computes the velocity sensing of the part
  407. float vel = VelF(velocity / 127.0f, Pvelsns);
  408. //compute the velocity offset
  409. vel = limit(vel + (Pveloffs - 64.0f) / 64.0f, 0.0f, 1.0f);
  410. //compute the keyshift
  411. int partkeyshift = (int)Pkeyshift - 64;
  412. int keyshift = masterkeyshift + partkeyshift;
  413. //initialise note frequency
  414. float notebasefreq;
  415. if(Pdrummode == 0) {
  416. notebasefreq = microtonal->getnotefreq(note, keyshift);
  417. if(notebasefreq < 0.0f)
  418. return;//the key is no mapped
  419. }
  420. else
  421. notebasefreq = 440.0f * powf(2.0f, (note - 69.0f) / 12.0f);
  422. //Portamento
  423. if(oldfreq < 1.0f)
  424. oldfreq = notebasefreq;//this is only the first note is played
  425. // For Mono/Legato: Force Portamento Off on first
  426. // notes. That means it is required that the previous note is
  427. // still held down or sustained for the Portamento to activate
  428. // (that's like Legato).
  429. bool portamento = false;
  430. if(Ppolymode || !ismonofirstnote)
  431. // I added a third argument to the
  432. // ctl.initportamento(...) function to be able
  433. // to tell it if we're doing a legato note.
  434. portamento = ctl.initportamento(oldfreq, notebasefreq, doinglegato);
  435. if(portamento)
  436. ctl.portamento.noteusing = pos;
  437. oldfreq = notebasefreq;
  438. lastpos = pos; // Keep a trace of used pos.
  439. if(doinglegato) {
  440. // Do Legato note
  441. if(Pkitmode == 0) { // "normal mode" legato note
  442. auto note1 = partnote[pos].kititem[0];
  443. auto note2 = partnote[posb].kititem[0];
  444. LegatoParams pars = {notebasefreq, vel, portamento, note, true};
  445. if(kit[0].Padenabled && note1.adnote && note2.adnote) {
  446. note1.adnote->legatonote(pars);
  447. note2.adnote->legatonote(pars);
  448. }
  449. if(kit[0].Psubenabled && note1.subnote && note2.subnote) {
  450. note1.subnote->legatonote(pars);
  451. note2.subnote->legatonote(pars);
  452. }
  453. if(kit[0].Ppadenabled && note1.padnote && note2.padnote) {
  454. note1.padnote->legatonote(pars);
  455. note2.padnote->legatonote(pars);
  456. }
  457. }
  458. else { // "kit mode" legato note
  459. int ci = 0;
  460. for(int item = 0; item < NUM_KIT_ITEMS; ++item) {
  461. //Make sure the key is valid and not across multiple ranges
  462. if(kit[item].Pmuted || !inRange(note, kit[item].Pminkey, kit[item].Pmaxkey)
  463. || !inRange((unsigned char)lastnotecopy, kit[item].Pminkey, kit[item].Pmaxkey))
  464. continue;
  465. auto note1 = partnote[pos].kititem[ci];
  466. auto note2 = partnote[posb].kititem[ci];
  467. LegatoParams pars = {notebasefreq, vel, portamento, note, true};
  468. note1.sendtoparteffect = limit((int)kit[item].Psendtoparteffect, 0, NUM_PART_EFX);
  469. note2.sendtoparteffect = limit((int)kit[item].Psendtoparteffect, 0, NUM_PART_EFX);
  470. if(kit[item].Padenabled && kit[item].adpars && note1.adnote && note2.adnote) {
  471. note1.adnote->legatonote(pars);
  472. note2.adnote->legatonote(pars);
  473. }
  474. if(kit[item].Psubenabled && kit[item].subpars && note1.subnote && note2.subnote) {
  475. note1.subnote->legatonote(pars);
  476. note2.subnote->legatonote(pars);
  477. }
  478. if(kit[item].Ppadenabled && kit[item].padpars && note1.padnote && note2.padnote) {
  479. note1.padnote->legatonote(pars);
  480. note2.padnote->legatonote(pars);
  481. }
  482. if(kit[item].adpars || kit[item].subpars || kit[item].padpars) {
  483. ci++;
  484. if((kit[item].Padenabled || kit[item].Psubenabled || kit[item].Ppadenabled) && (Pkitmode == 2))
  485. break;
  486. }
  487. }
  488. if(ci == 0) {
  489. // No legato were performed at all, so pretend nothing happened:
  490. monomemPop(monomemBack()); // Remove last note from the list.
  491. lastnote = lastnotecopy; // Set lastnote back to previous value.
  492. }
  493. }
  494. return; // Ok, Legato note done, return.
  495. }
  496. partnote[pos].itemsplaying = 0;
  497. if(legatomodevalid)
  498. partnote[posb].itemsplaying = 0;
  499. if(Pkitmode == 0) { //init the notes for the "normal mode"
  500. partnote[pos].kititem[0].sendtoparteffect = 0;
  501. SynthParams pars{memory, ctl, synth, notebasefreq, vel, (bool) portamento, note, false};
  502. if(kit[0].Padenabled)
  503. partnote[pos].kititem[0].adnote =
  504. memory.alloc<ADnote>(kit[0].adpars, pars);
  505. if(kit[0].Psubenabled)
  506. partnote[pos].kititem[0].subnote =
  507. memory.alloc<SUBnote>(kit[0].subpars, pars);
  508. if(kit[0].Ppadenabled)
  509. partnote[pos].kititem[0].padnote =
  510. memory.alloc<PADnote>(kit[0].padpars, pars);
  511. if(kit[0].Padenabled || kit[0].Psubenabled || kit[0].Ppadenabled)
  512. partnote[pos].itemsplaying++;
  513. // Spawn another note (but silent) if legatomodevalid==true
  514. if(legatomodevalid) {
  515. partnote[posb].kititem[0].sendtoparteffect = 0;
  516. pars.quiet = true;
  517. if(kit[0].Padenabled)
  518. partnote[posb].kititem[0].adnote =
  519. memory.alloc<ADnote>(kit[0].adpars, pars);
  520. if(kit[0].Psubenabled)
  521. partnote[posb].kititem[0].subnote =
  522. memory.alloc<SUBnote>(kit[0].subpars, pars);
  523. if(kit[0].Ppadenabled)
  524. partnote[posb].kititem[0].padnote =
  525. memory.alloc<PADnote>(kit[0].padpars, pars);
  526. if(kit[0].Padenabled || kit[0].Psubenabled || kit[0].Ppadenabled)
  527. partnote[posb].itemsplaying++;
  528. }
  529. }
  530. else //init the notes for the "kit mode"
  531. for(int item = 0; item < NUM_KIT_ITEMS; ++item) {
  532. if(kit[item].Pmuted || !inRange(note, kit[item].Pminkey, kit[item].Pmaxkey))
  533. continue;
  534. int ci = partnote[pos].itemsplaying; //ci=current item
  535. auto &note1 = partnote[pos].kititem[ci];
  536. //if this parameter is 127 for "unprocessed"
  537. note1.sendtoparteffect = limit((int)kit[item].Psendtoparteffect, 0, NUM_PART_EFX);
  538. SynthParams pars{memory, ctl, synth, notebasefreq, vel, (bool) portamento, note, false};
  539. if(kit[item].adpars && kit[item].Padenabled)
  540. note1.adnote =
  541. memory.alloc<ADnote>(kit[item].adpars, pars);
  542. if(kit[item].subpars && kit[item].Psubenabled)
  543. note1.subnote =
  544. memory.alloc<SUBnote>(kit[item].subpars, pars);
  545. if(kit[item].padpars && kit[item].Ppadenabled)
  546. note1.padnote =
  547. memory.alloc<PADnote>(kit[item].padpars, pars);
  548. // Spawn another note (but silent) if legatomodevalid==true
  549. if(legatomodevalid) {
  550. auto &note2 = partnote[posb].kititem[ci];
  551. note2.sendtoparteffect = limit((int)kit[item].Psendtoparteffect, 0, NUM_PART_EFX);
  552. pars.quiet = true;
  553. if(kit[item].adpars && kit[item].Padenabled)
  554. note2.adnote =
  555. memory.alloc<ADnote>(kit[item].adpars, pars);
  556. if(kit[item].subpars && kit[item].Psubenabled)
  557. note2.subnote =
  558. memory.alloc<SUBnote>(kit[item].subpars, pars);
  559. if(kit[item].padpars && kit[item].Ppadenabled)
  560. note2.padnote =
  561. memory.alloc<PADnote>(kit[item].padpars, pars);
  562. if(kit[item].adpars || kit[item].subpars || kit[item].padpars)
  563. partnote[posb].itemsplaying++;
  564. }
  565. if(kit[item].adpars || kit[item].subpars) {
  566. partnote[pos].itemsplaying++;
  567. if((kit[item].Padenabled || kit[item].Psubenabled || kit[item].Ppadenabled) && (Pkitmode == 2))
  568. break;
  569. }
  570. }
  571. }
  572. //this only release the keys if there is maximum number of keys allowed
  573. setkeylimit(Pkeylimit);
  574. }
  575. /*
  576. * Note Off Messages
  577. */
  578. void Part::NoteOff(unsigned char note) //release the key
  579. {
  580. // This note is released, so we remove it from the list.
  581. if(!monomemEmpty())
  582. monomemPop(note);
  583. for(int i = POLYPHONY - 1; i >= 0; i--) //first note in, is first out if there are same note multiple times
  584. if((partnote[i].status == KEY_PLAYING) && (partnote[i].note == note)) {
  585. if(!ctl.sustain.sustain) { //the sustain pedal is not pushed
  586. if(!Ppolymode && !monomemEmpty())
  587. MonoMemRenote();//Play most recent still active note
  588. else
  589. ReleaseNotePos(i);
  590. }
  591. else //the sustain pedal is pushed
  592. partnote[i].status = KEY_RELEASED_AND_SUSTAINED;
  593. }
  594. }
  595. void Part::PolyphonicAftertouch(unsigned char note,
  596. unsigned char velocity,
  597. int masterkeyshift)
  598. {
  599. (void) masterkeyshift;
  600. if(!Pnoteon || !inRange(note, Pminkey, Pmaxkey) || Pdrummode)
  601. return;
  602. // MonoMem stuff:
  603. if(!Ppolymode) // if Poly is off
  604. monomem[note].velocity = velocity; // Store this note's velocity.
  605. for(int i = 0; i < POLYPHONY; ++i)
  606. if((partnote[i].note == note) && (partnote[i].status == KEY_PLAYING)) {
  607. /* update velocity */
  608. // compute the velocity offset
  609. float vel = VelF(velocity / 127.0f, Pvelsns) + (Pveloffs - 64.0f) / 64.0f;
  610. vel = limit(vel, 0.0f, 1.0f);
  611. if(!Pkitmode) { // "normal mode"
  612. if(kit[0].Padenabled && partnote[i].kititem[0].adnote)
  613. partnote[i].kititem[0].adnote->setVelocity(vel);
  614. if(kit[0].Psubenabled && partnote[i].kititem[0].subnote)
  615. partnote[i].kititem[0].subnote->setVelocity(vel);
  616. if(kit[0].Ppadenabled && partnote[i].kititem[0].padnote)
  617. partnote[i].kititem[0].padnote->setVelocity(vel);
  618. }
  619. else // "kit mode"
  620. for(int item = 0; item < NUM_KIT_ITEMS; ++item) {
  621. if(kit[item].Pmuted || !inRange(note, kit[item].Pminkey, kit[item].Pmaxkey))
  622. continue;
  623. if(kit[item].Padenabled && partnote[i].kititem[item].adnote)
  624. partnote[i].kititem[item].adnote->setVelocity(vel);
  625. if(kit[item].Psubenabled && partnote[i].kititem[item].subnote)
  626. partnote[i].kititem[item].subnote->setVelocity(vel);
  627. if(kit[item].Ppadenabled && partnote[i].kititem[item].padnote)
  628. partnote[i].kititem[item].padnote->setVelocity(vel);
  629. }
  630. }
  631. }
  632. /*
  633. * Controllers
  634. */
  635. void Part::SetController(unsigned int type, int par)
  636. {
  637. switch(type) {
  638. case C_pitchwheel:
  639. ctl.setpitchwheel(par);
  640. break;
  641. case C_expression:
  642. ctl.setexpression(par);
  643. setPvolume(Pvolume); //update the volume
  644. break;
  645. case C_portamento:
  646. ctl.setportamento(par);
  647. break;
  648. case C_panning:
  649. ctl.setpanning(par);
  650. setPpanning(Ppanning); //update the panning
  651. break;
  652. case C_filtercutoff:
  653. ctl.setfiltercutoff(par);
  654. break;
  655. case C_filterq:
  656. ctl.setfilterq(par);
  657. break;
  658. case C_bandwidth:
  659. ctl.setbandwidth(par);
  660. break;
  661. case C_modwheel:
  662. ctl.setmodwheel(par);
  663. break;
  664. case C_fmamp:
  665. ctl.setfmamp(par);
  666. break;
  667. case C_volume:
  668. ctl.setvolume(par);
  669. if(ctl.volume.receive != 0)
  670. volume = ctl.volume.volume;
  671. else
  672. setPvolume(Pvolume);
  673. break;
  674. case C_sustain:
  675. ctl.setsustain(par);
  676. if(ctl.sustain.sustain == 0)
  677. ReleaseSustainedKeys();
  678. break;
  679. case C_allsoundsoff:
  680. AllNotesOff(); //Panic
  681. break;
  682. case C_resetallcontrollers:
  683. ctl.resetall();
  684. ReleaseSustainedKeys();
  685. if(ctl.volume.receive != 0)
  686. volume = ctl.volume.volume;
  687. else
  688. setPvolume(Pvolume);
  689. setPvolume(Pvolume); //update the volume
  690. setPpanning(Ppanning); //update the panning
  691. for(int item = 0; item < NUM_KIT_ITEMS; ++item) {
  692. if(kit[item].adpars == NULL)
  693. continue;
  694. kit[item].adpars->GlobalPar.Reson->
  695. sendcontroller(C_resonance_center, 1.0f);
  696. kit[item].adpars->GlobalPar.Reson->
  697. sendcontroller(C_resonance_bandwidth, 1.0f);
  698. }
  699. //more update to add here if I add controllers
  700. break;
  701. case C_allnotesoff:
  702. ReleaseAllKeys();
  703. break;
  704. case C_resonance_center:
  705. ctl.setresonancecenter(par);
  706. for(int item = 0; item < NUM_KIT_ITEMS; ++item) {
  707. if(kit[item].adpars == NULL)
  708. continue;
  709. kit[item].adpars->GlobalPar.Reson->
  710. sendcontroller(C_resonance_center,
  711. ctl.resonancecenter.relcenter);
  712. }
  713. break;
  714. case C_resonance_bandwidth:
  715. ctl.setresonancebw(par);
  716. kit[0].adpars->GlobalPar.Reson->
  717. sendcontroller(C_resonance_bandwidth, ctl.resonancebandwidth.relbw);
  718. break;
  719. }
  720. }
  721. /*
  722. * Release the sustained keys
  723. */
  724. void Part::ReleaseSustainedKeys()
  725. {
  726. // Let's call MonoMemRenote() on some conditions:
  727. if(Ppolymode == 0 && !monomemEmpty())
  728. if(monomemBack() != lastnote) // Sustain controller manipulation would cause repeated same note respawn without this check.
  729. MonoMemRenote(); // To play most recent still held note.
  730. for(int i = 0; i < POLYPHONY; ++i)
  731. if(partnote[i].status == KEY_RELEASED_AND_SUSTAINED)
  732. ReleaseNotePos(i);
  733. }
  734. /*
  735. * Release all keys
  736. */
  737. void Part::ReleaseAllKeys()
  738. {
  739. for(int i = 0; i < POLYPHONY; ++i)
  740. if((partnote[i].status != KEY_RELEASED)
  741. && (partnote[i].status != KEY_OFF)) //thanks to Frank Neumann
  742. ReleaseNotePos(i);
  743. }
  744. // Call NoteOn(...) with the most recent still held key as new note
  745. // (Made for Mono/Legato).
  746. void Part::MonoMemRenote()
  747. {
  748. unsigned char mmrtempnote = monomemBack(); // Last list element.
  749. monomemPop(mmrtempnote); // We remove it, will be added again in NoteOn(...).
  750. if(Pnoteon == 0)
  751. ReleaseNotePos(lastpos);
  752. else
  753. NoteOn(mmrtempnote, monomem[mmrtempnote].velocity,
  754. monomem[mmrtempnote].mkeyshift);
  755. }
  756. /*
  757. * Release note at position
  758. */
  759. void Part::ReleaseNotePos(int pos)
  760. {
  761. for(int j = 0; j < NUM_KIT_ITEMS; ++j) {
  762. if(partnote[pos].kititem[j].adnote)
  763. partnote[pos].kititem[j].adnote->releasekey();
  764. if(partnote[pos].kititem[j].subnote)
  765. partnote[pos].kititem[j].subnote->releasekey();
  766. if(partnote[pos].kititem[j].padnote)
  767. partnote[pos].kititem[j].padnote->releasekey();
  768. }
  769. partnote[pos].status = KEY_RELEASED;
  770. }
  771. /*
  772. * Kill note at position
  773. */
  774. void Part::KillNotePos(int pos)
  775. {
  776. partnote[pos].status = KEY_OFF;
  777. partnote[pos].note = -1;
  778. partnote[pos].time = 0;
  779. partnote[pos].itemsplaying = 0;
  780. for(int j = 0; j < NUM_KIT_ITEMS; ++j) {
  781. memory.dealloc(partnote[pos].kititem[j].adnote);
  782. memory.dealloc(partnote[pos].kititem[j].subnote);
  783. memory.dealloc(partnote[pos].kititem[j].padnote);
  784. }
  785. if(pos == ctl.portamento.noteusing) {
  786. ctl.portamento.noteusing = -1;
  787. ctl.portamento.used = 0;
  788. }
  789. }
  790. /*
  791. * Set Part's key limit
  792. */
  793. void Part::setkeylimit(unsigned char Pkeylimit)
  794. {
  795. this->Pkeylimit = Pkeylimit;
  796. int keylimit = Pkeylimit;
  797. if(keylimit == 0)
  798. keylimit = POLYPHONY - 5;
  799. //release old keys if the number of notes>keylimit
  800. if(Ppolymode != 0) {
  801. int notecount = 0;
  802. for(int i = 0; i < POLYPHONY; ++i)
  803. if((partnote[i].status == KEY_PLAYING) || (partnote[i].status == KEY_RELEASED_AND_SUSTAINED))
  804. notecount++;
  805. int oldestnotepos = -1;
  806. if(notecount > keylimit) //find out the oldest note
  807. for(int i = 0; i < POLYPHONY; ++i) {
  808. int maxtime = 0;
  809. if(((partnote[i].status == KEY_PLAYING) || (partnote[i].status == KEY_RELEASED_AND_SUSTAINED)) && (partnote[i].time > maxtime)) {
  810. maxtime = partnote[i].time;
  811. oldestnotepos = i;
  812. }
  813. }
  814. if(oldestnotepos != -1)
  815. ReleaseNotePos(oldestnotepos);
  816. }
  817. }
  818. /*
  819. * Prepare all notes to be turned off
  820. */
  821. void Part::AllNotesOff()
  822. {
  823. killallnotes = true;
  824. }
  825. void Part::RunNote(unsigned int k)
  826. {
  827. unsigned noteplay = 0;
  828. for(int item = 0; item < partnote[k].itemsplaying; ++item) {
  829. int sendcurrenttofx = partnote[k].kititem[item].sendtoparteffect;
  830. for(unsigned type = 0; type < 3; ++type) {
  831. //Select a note
  832. SynthNote **note = NULL;
  833. if(type == 0)
  834. note = &partnote[k].kititem[item].adnote;
  835. else if(type == 1)
  836. note = &partnote[k].kititem[item].subnote;
  837. else if(type == 2)
  838. note = &partnote[k].kititem[item].padnote;
  839. //Process if it exists
  840. if(!(*note))
  841. continue;
  842. noteplay++;
  843. float tmpoutr[synth.buffersize];
  844. float tmpoutl[synth.buffersize];
  845. (*note)->noteout(&tmpoutl[0], &tmpoutr[0]);
  846. if((*note)->finished())
  847. memory.dealloc(*note);
  848. for(int i = 0; i < synth.buffersize; ++i) { //add the note to part(mix)
  849. partfxinputl[sendcurrenttofx][i] += tmpoutl[i];
  850. partfxinputr[sendcurrenttofx][i] += tmpoutr[i];
  851. }
  852. }
  853. }
  854. //Kill note if there is no synth on that note
  855. if(!noteplay)
  856. KillNotePos(k);
  857. }
  858. /*
  859. * Compute Part samples and store them in the partoutl[] and partoutr[]
  860. */
  861. void Part::ComputePartSmps()
  862. {
  863. for(unsigned nefx = 0; nefx < NUM_PART_EFX + 1; ++nefx)
  864. for(int i = 0; i < synth.buffersize; ++i) {
  865. partfxinputl[nefx][i] = 0.0f;
  866. partfxinputr[nefx][i] = 0.0f;
  867. }
  868. for(unsigned k = 0; k < POLYPHONY; ++k) {
  869. if(partnote[k].status == KEY_OFF)
  870. continue;
  871. partnote[k].time++;
  872. //get the sampledata of the note and kill it if it's finished
  873. RunNote(k);
  874. }
  875. //Apply part's effects and mix them
  876. for(int nefx = 0; nefx < NUM_PART_EFX; ++nefx) {
  877. if(!Pefxbypass[nefx]) {
  878. partefx[nefx]->out(partfxinputl[nefx], partfxinputr[nefx]);
  879. if(Pefxroute[nefx] == 2)
  880. for(int i = 0; i < synth.buffersize; ++i) {
  881. partfxinputl[nefx + 1][i] += partefx[nefx]->efxoutl[i];
  882. partfxinputr[nefx + 1][i] += partefx[nefx]->efxoutr[i];
  883. }
  884. }
  885. int routeto = ((Pefxroute[nefx] == 0) ? nefx + 1 : NUM_PART_EFX);
  886. for(int i = 0; i < synth.buffersize; ++i) {
  887. partfxinputl[routeto][i] += partfxinputl[nefx][i];
  888. partfxinputr[routeto][i] += partfxinputr[nefx][i];
  889. }
  890. }
  891. for(int i = 0; i < synth.buffersize; ++i) {
  892. partoutl[i] = partfxinputl[NUM_PART_EFX][i];
  893. partoutr[i] = partfxinputr[NUM_PART_EFX][i];
  894. }
  895. if(killallnotes) {
  896. for(int i = 0; i < synth.buffersize; ++i) {
  897. float tmp = (synth.buffersize_f - i) / synth.buffersize_f;
  898. partoutl[i] *= tmp;
  899. partoutr[i] *= tmp;
  900. }
  901. for(int k = 0; k < POLYPHONY; ++k)
  902. KillNotePos(k);
  903. killallnotes = false;
  904. for(int nefx = 0; nefx < NUM_PART_EFX; ++nefx)
  905. partefx[nefx]->cleanup();
  906. }
  907. ctl.updateportamento();
  908. }
  909. /*
  910. * Parameter control
  911. */
  912. void Part::setPvolume(char Pvolume_)
  913. {
  914. Pvolume = Pvolume_;
  915. volume =
  916. dB2rap((Pvolume - 96.0f) / 96.0f * 40.0f) * ctl.expression.relvolume;
  917. }
  918. void Part::setPpanning(char Ppanning_)
  919. {
  920. Ppanning = Ppanning_;
  921. panning = limit(Ppanning / 127.0f + ctl.panning.pan, 0.0f, 1.0f);
  922. }
  923. /*
  924. * Enable or disable a kit item
  925. */
  926. void Part::setkititemstatus(unsigned kititem, bool Penabled_)
  927. {
  928. //nonexistent kit item and the first kit item is always enabled
  929. if((kititem == 0) || (kititem >= NUM_KIT_ITEMS))
  930. return;
  931. Kit &kkit = kit[kititem];
  932. //no need to update if
  933. if(kkit.Penabled == Penabled_)
  934. return;
  935. kkit.Penabled = Penabled_;
  936. if(!Penabled_) {
  937. delete kkit.adpars;
  938. delete kkit.subpars;
  939. delete kkit.padpars;
  940. kkit.Pname[0] = '\0';
  941. //Reset notes s.t. stale buffers will not get read
  942. for(int k = 0; k < POLYPHONY; ++k)
  943. KillNotePos(k);
  944. }
  945. else {
  946. //All parameters must be NULL in this case
  947. assert(!(kkit.adpars || kkit.subpars || kkit.padpars));
  948. kkit.adpars = new ADnoteParameters(synth, fft);
  949. kkit.subpars = new SUBnoteParameters();
  950. kkit.padpars = new PADnoteParameters(synth, fft);
  951. }
  952. }
  953. void Part::add2XMLinstrument(XMLwrapper *xml)
  954. {
  955. xml->beginbranch("INFO");
  956. xml->addparstr("name", (char *)Pname);
  957. xml->addparstr("author", (char *)info.Pauthor);
  958. xml->addparstr("comments", (char *)info.Pcomments);
  959. xml->addpar("type", info.Ptype);
  960. xml->endbranch();
  961. xml->beginbranch("INSTRUMENT_KIT");
  962. xml->addpar("kit_mode", Pkitmode);
  963. xml->addparbool("drum_mode", Pdrummode);
  964. for(int i = 0; i < NUM_KIT_ITEMS; ++i) {
  965. xml->beginbranch("INSTRUMENT_KIT_ITEM", i);
  966. xml->addparbool("enabled", kit[i].Penabled);
  967. if(kit[i].Penabled != 0) {
  968. xml->addparstr("name", (char *)kit[i].Pname);
  969. xml->addparbool("muted", kit[i].Pmuted);
  970. xml->addpar("min_key", kit[i].Pminkey);
  971. xml->addpar("max_key", kit[i].Pmaxkey);
  972. xml->addpar("send_to_instrument_effect", kit[i].Psendtoparteffect);
  973. xml->addparbool("add_enabled", kit[i].Padenabled);
  974. if(kit[i].Padenabled && kit[i].adpars) {
  975. xml->beginbranch("ADD_SYNTH_PARAMETERS");
  976. kit[i].adpars->add2XML(xml);
  977. xml->endbranch();
  978. }
  979. xml->addparbool("sub_enabled", kit[i].Psubenabled);
  980. if(kit[i].Psubenabled && kit[i].subpars) {
  981. xml->beginbranch("SUB_SYNTH_PARAMETERS");
  982. kit[i].subpars->add2XML(xml);
  983. xml->endbranch();
  984. }
  985. xml->addparbool("pad_enabled", kit[i].Ppadenabled);
  986. if(kit[i].Ppadenabled && kit[i].padpars) {
  987. xml->beginbranch("PAD_SYNTH_PARAMETERS");
  988. kit[i].padpars->add2XML(xml);
  989. xml->endbranch();
  990. }
  991. }
  992. xml->endbranch();
  993. }
  994. xml->endbranch();
  995. xml->beginbranch("INSTRUMENT_EFFECTS");
  996. for(int nefx = 0; nefx < NUM_PART_EFX; ++nefx) {
  997. xml->beginbranch("INSTRUMENT_EFFECT", nefx);
  998. xml->beginbranch("EFFECT");
  999. partefx[nefx]->add2XML(xml);
  1000. xml->endbranch();
  1001. xml->addpar("route", Pefxroute[nefx]);
  1002. partefx[nefx]->setdryonly(Pefxroute[nefx] == 2);
  1003. xml->addparbool("bypass", Pefxbypass[nefx]);
  1004. xml->endbranch();
  1005. }
  1006. xml->endbranch();
  1007. }
  1008. void Part::add2XML(XMLwrapper *xml)
  1009. {
  1010. //parameters
  1011. xml->addparbool("enabled", Penabled);
  1012. if((Penabled == 0) && (xml->minimal))
  1013. return;
  1014. xml->addpar("volume", Pvolume);
  1015. xml->addpar("panning", Ppanning);
  1016. xml->addpar("min_key", Pminkey);
  1017. xml->addpar("max_key", Pmaxkey);
  1018. xml->addpar("key_shift", Pkeyshift);
  1019. xml->addpar("rcv_chn", Prcvchn);
  1020. xml->addpar("velocity_sensing", Pvelsns);
  1021. xml->addpar("velocity_offset", Pveloffs);
  1022. xml->addparbool("note_on", Pnoteon);
  1023. xml->addparbool("poly_mode", Ppolymode);
  1024. xml->addpar("legato_mode", Plegatomode);
  1025. xml->addpar("key_limit", Pkeylimit);
  1026. xml->beginbranch("INSTRUMENT");
  1027. add2XMLinstrument(xml);
  1028. xml->endbranch();
  1029. xml->beginbranch("CONTROLLER");
  1030. ctl.add2XML(xml);
  1031. xml->endbranch();
  1032. }
  1033. int Part::saveXML(const char *filename)
  1034. {
  1035. XMLwrapper xml;
  1036. xml.beginbranch("INSTRUMENT");
  1037. add2XMLinstrument(&xml);
  1038. xml.endbranch();
  1039. int result = xml.saveXMLfile(filename);
  1040. return result;
  1041. }
  1042. int Part::loadXMLinstrument(const char *filename)
  1043. {
  1044. XMLwrapper xml;
  1045. if(xml.loadXMLfile(filename) < 0) {
  1046. return -1;
  1047. }
  1048. if(xml.enterbranch("INSTRUMENT") == 0)
  1049. return -10;
  1050. getfromXMLinstrument(&xml);
  1051. xml.exitbranch();
  1052. return 0;
  1053. }
  1054. void Part::applyparameters(void)
  1055. {
  1056. applyparameters([]{return false;});
  1057. }
  1058. void Part::applyparameters(std::function<bool()> do_abort)
  1059. {
  1060. for(int n = 0; n < NUM_KIT_ITEMS; ++n)
  1061. if(kit[n].Ppadenabled && kit[n].padpars)
  1062. kit[n].padpars->applyparameters(do_abort);
  1063. }
  1064. void Part::initialize_rt(void)
  1065. {
  1066. for(int i=0; i<NUM_PART_EFX; ++i)
  1067. partefx[i]->init();
  1068. }
  1069. void Part::kill_rt(void)
  1070. {
  1071. for(int i=0; i<NUM_PART_EFX; ++i)
  1072. partefx[i]->kill();
  1073. for(int k = 0; k < POLYPHONY; ++k)
  1074. KillNotePos(k);
  1075. }
  1076. void Part::monomemPush(char note)
  1077. {
  1078. for(int i=0; i<256; ++i)
  1079. if(monomemnotes[i]==note)
  1080. return;
  1081. for(int i=254;i>=0; --i)
  1082. monomemnotes[i+1] = monomemnotes[i];
  1083. monomemnotes[0] = note;
  1084. }
  1085. void Part::monomemPop(char note)
  1086. {
  1087. int note_pos=-1;
  1088. for(int i=0; i<256; ++i)
  1089. if(monomemnotes[i]==note)
  1090. note_pos = i;
  1091. if(note_pos != -1) {
  1092. for(int i=note_pos; i<256; ++i)
  1093. monomemnotes[i] = monomemnotes[i+1];
  1094. monomemnotes[255] = -1;
  1095. }
  1096. }
  1097. char Part::monomemBack(void) const
  1098. {
  1099. return monomemnotes[0];
  1100. }
  1101. bool Part::monomemEmpty(void) const
  1102. {
  1103. return monomemnotes[0] == -1;
  1104. }
  1105. void Part::monomemClear(void)
  1106. {
  1107. for(int i=0; i<256; ++i)
  1108. monomemnotes[i] = -1;
  1109. }
  1110. void Part::getfromXMLinstrument(XMLwrapper *xml)
  1111. {
  1112. if(xml->enterbranch("INFO")) {
  1113. xml->getparstr("name", (char *)Pname, PART_MAX_NAME_LEN);
  1114. xml->getparstr("author", (char *)info.Pauthor, MAX_INFO_TEXT_SIZE);
  1115. xml->getparstr("comments", (char *)info.Pcomments, MAX_INFO_TEXT_SIZE);
  1116. info.Ptype = xml->getpar("type", info.Ptype, 0, 16);
  1117. xml->exitbranch();
  1118. }
  1119. if(xml->enterbranch("INSTRUMENT_KIT")) {
  1120. Pkitmode = xml->getpar127("kit_mode", Pkitmode);
  1121. Pdrummode = xml->getparbool("drum_mode", Pdrummode);
  1122. setkititemstatus(0, 0);
  1123. for(int i = 0; i < NUM_KIT_ITEMS; ++i) {
  1124. if(xml->enterbranch("INSTRUMENT_KIT_ITEM", i) == 0)
  1125. continue;
  1126. setkititemstatus(i, xml->getparbool("enabled", kit[i].Penabled));
  1127. if(kit[i].Penabled == 0) {
  1128. xml->exitbranch();
  1129. continue;
  1130. }
  1131. xml->getparstr("name", (char *)kit[i].Pname, PART_MAX_NAME_LEN);
  1132. kit[i].Pmuted = xml->getparbool("muted", kit[i].Pmuted);
  1133. kit[i].Pminkey = xml->getpar127("min_key", kit[i].Pminkey);
  1134. kit[i].Pmaxkey = xml->getpar127("max_key", kit[i].Pmaxkey);
  1135. kit[i].Psendtoparteffect = xml->getpar127(
  1136. "send_to_instrument_effect",
  1137. kit[i].Psendtoparteffect);
  1138. kit[i].Padenabled = xml->getparbool("add_enabled",
  1139. kit[i].Padenabled);
  1140. if(xml->enterbranch("ADD_SYNTH_PARAMETERS")) {
  1141. if(!kit[i].adpars)
  1142. kit[i].adpars = new ADnoteParameters(synth, fft);
  1143. kit[i].adpars->getfromXML(xml);
  1144. xml->exitbranch();
  1145. }
  1146. kit[i].Psubenabled = xml->getparbool("sub_enabled",
  1147. kit[i].Psubenabled);
  1148. if(xml->enterbranch("SUB_SYNTH_PARAMETERS")) {
  1149. if(!kit[i].subpars)
  1150. kit[i].subpars = new SUBnoteParameters();
  1151. kit[i].subpars->getfromXML(xml);
  1152. xml->exitbranch();
  1153. }
  1154. kit[i].Ppadenabled = xml->getparbool("pad_enabled",
  1155. kit[i].Ppadenabled);
  1156. if(xml->enterbranch("PAD_SYNTH_PARAMETERS")) {
  1157. if(!kit[i].padpars)
  1158. kit[i].padpars = new PADnoteParameters(synth, fft);
  1159. kit[i].padpars->getfromXML(xml);
  1160. xml->exitbranch();
  1161. }
  1162. xml->exitbranch();
  1163. }
  1164. xml->exitbranch();
  1165. }
  1166. if(xml->enterbranch("INSTRUMENT_EFFECTS")) {
  1167. for(int nefx = 0; nefx < NUM_PART_EFX; ++nefx) {
  1168. if(xml->enterbranch("INSTRUMENT_EFFECT", nefx) == 0)
  1169. continue;
  1170. if(xml->enterbranch("EFFECT")) {
  1171. partefx[nefx]->getfromXML(xml);
  1172. xml->exitbranch();
  1173. }
  1174. Pefxroute[nefx] = xml->getpar("route",
  1175. Pefxroute[nefx],
  1176. 0,
  1177. NUM_PART_EFX);
  1178. partefx[nefx]->setdryonly(Pefxroute[nefx] == 2);
  1179. Pefxbypass[nefx] = xml->getparbool("bypass", Pefxbypass[nefx]);
  1180. xml->exitbranch();
  1181. }
  1182. xml->exitbranch();
  1183. }
  1184. }
  1185. void Part::getfromXML(XMLwrapper *xml)
  1186. {
  1187. Penabled = xml->getparbool("enabled", Penabled);
  1188. setPvolume(xml->getpar127("volume", Pvolume));
  1189. setPpanning(xml->getpar127("panning", Ppanning));
  1190. Pminkey = xml->getpar127("min_key", Pminkey);
  1191. Pmaxkey = xml->getpar127("max_key", Pmaxkey);
  1192. Pkeyshift = xml->getpar127("key_shift", Pkeyshift);
  1193. Prcvchn = xml->getpar127("rcv_chn", Prcvchn);
  1194. Pvelsns = xml->getpar127("velocity_sensing", Pvelsns);
  1195. Pveloffs = xml->getpar127("velocity_offset", Pveloffs);
  1196. Pnoteon = xml->getparbool("note_on", Pnoteon);
  1197. Ppolymode = xml->getparbool("poly_mode", Ppolymode);
  1198. Plegatomode = xml->getparbool("legato_mode", Plegatomode); //older versions
  1199. if(!Plegatomode)
  1200. Plegatomode = xml->getpar127("legato_mode", Plegatomode);
  1201. Pkeylimit = xml->getpar127("key_limit", Pkeylimit);
  1202. if(xml->enterbranch("INSTRUMENT")) {
  1203. getfromXMLinstrument(xml);
  1204. xml->exitbranch();
  1205. }
  1206. if(xml->enterbranch("CONTROLLER")) {
  1207. ctl.getfromXML(xml);
  1208. xml->exitbranch();
  1209. }
  1210. }