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.

1417 lines
47KB

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