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.

Part.cpp 37KB

9 years ago
9 years ago
9 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236
  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
  7. modify it under the terms of the GNU General Public License
  8. as published by the Free Software Foundation; either version 2
  9. of the License, or (at your option) any later version.
  10. */
  11. #include "Part.h"
  12. #include "Microtonal.h"
  13. #include "Util.h"
  14. #include "XMLwrapper.h"
  15. #include "Allocator.h"
  16. #include "../Effects/EffectMgr.h"
  17. #include "../Params/ADnoteParameters.h"
  18. #include "../Params/SUBnoteParameters.h"
  19. #include "../Params/PADnoteParameters.h"
  20. #include "../Synth/Resonance.h"
  21. #include "../Synth/SynthNote.h"
  22. #include "../Synth/ADnote.h"
  23. #include "../Synth/SUBnote.h"
  24. #include "../Synth/PADnote.h"
  25. #include "../Containers/ScratchString.h"
  26. #include "../DSP/FFTwrapper.h"
  27. #include "../Misc/Util.h"
  28. #include <cstdlib>
  29. #include <cstdio>
  30. #include <cstring>
  31. #include <cassert>
  32. #include <rtosc/ports.h>
  33. #include <rtosc/port-sugar.h>
  34. #include <iostream>
  35. namespace zyncarla {
  36. using rtosc::Ports;
  37. using rtosc::RtData;
  38. #define rObject Part
  39. static const Ports partPorts = {
  40. rRecurs(kit, 16, "Kit"),//NUM_KIT_ITEMS
  41. rRecursp(partefx, 3, "Part Effect"),
  42. rRecur(ctl, "Controller"),
  43. rParamZyn(partno, rProp(internal),
  44. "How many parts are before this in the Master"),
  45. #undef rChangeCb
  46. #define rChangeCb if(obj->Penabled == false) obj->AllNotesOff();
  47. rToggle(Penabled, rShort("enable"), rDefaultDepends(partno),
  48. rPresets(true), rDefault(false), "Part enable"),
  49. #undef rChangeCb
  50. #define rChangeCb
  51. #undef rChangeCb
  52. #define rChangeCb obj->setPvolume(obj->Pvolume);
  53. rParamZyn(Pvolume, rShort("Vol"), rDefault(96),"Part Volume"),
  54. #undef rChangeCb
  55. #define rChangeCb obj->setPpanning(obj->Ppanning);
  56. rParamZyn(Ppanning, rShort("pan"), rDefault(64), "Set Panning"),
  57. #undef rChangeCb
  58. #define rChangeCb obj->setkeylimit(obj->Pkeylimit);
  59. rParamI(Pkeylimit, rShort("limit"), rProp(parameter),
  60. rMap(min,0), rMap(max, POLYPHONY), rDefault(15), "Key limit per part"),
  61. #undef rChangeCb
  62. #define rChangeCb
  63. rParamZyn(Pminkey, rShort("min"), rDefault(0), "Min Used Key"),
  64. rParamZyn(Pmaxkey, rShort("max"), rDefault(127), "Max Used Key"),
  65. rParamZyn(Pkeyshift, rShort("shift"), rDefault(64), "Part keyshift"),
  66. rParamZyn(Prcvchn, rOptions(ch1, ch2, ch3, ch4, ch5, ch6, ch7, ch8, ch9, ch10, ch11, ch12, ch13, ch14, ch15, ch16),
  67. rPresets(ch1, ch2, ch3, ch4, ch5, ch6, ch7, ch8, ch9, ch10, ch11, ch12, ch13, ch14, ch15, ch16),
  68. "Active MIDI channel"),
  69. rParamZyn(Pvelsns, rShort("sense"), rDefault(64), "Velocity sensing"),
  70. rParamZyn(Pveloffs, rShort("offset"), rDefault(64),"Velocity offset"),
  71. rToggle(Pnoteon, rDefault(true), "If the channel accepts note on events"),
  72. rOption(Pkitmode, rOptions(Off, Multi-Kit, Single-Kit), rDefault(Off),
  73. "Kit mode/enable\n"
  74. "Off - Only the first kit is ever utilized\n"
  75. "Multi-kit - Every applicable kit is run for a note\n"
  76. "Single-kit - The first applicable kit is run for a given note"),
  77. rToggle(Pdrummode, rDefault(false), "Drum mode enable\n"
  78. "When drum mode is enabled all keys are mapped to 12tET and legato is disabled"),
  79. rToggle(Ppolymode, rDefault(true), "Polyphony mode"),
  80. rToggle(Plegatomode, rDefault(false), "Legato mode"),
  81. rParamZyn(info.Ptype, rDefault(0), "Class of Instrument"),
  82. rString(info.Pauthor, MAX_INFO_TEXT_SIZE, rDefault(""),
  83. "Instrument author"),
  84. rString(info.Pcomments, MAX_INFO_TEXT_SIZE, rDefault(""),
  85. "Instrument comments"),
  86. rString(Pname, PART_MAX_NAME_LEN, rDefault(""), "User specified label"),
  87. rArrayI(Pefxroute, NUM_PART_EFX,
  88. rOptions(Next Effect,Part Out,Dry Out), rDefaultId(Next Effect),
  89. "Effect Routing"),
  90. rArrayT(Pefxbypass, NUM_PART_EFX, rDefault(false),
  91. "If an effect is bypassed"),
  92. {"captureMin:", rDoc("Capture minimum valid note"), NULL,
  93. [](const char *, RtData &r)
  94. {Part *p = (Part*)r.obj; p->Pminkey = p->lastnote;}},
  95. {"captureMax:", rDoc("Capture maximum valid note"), NULL,
  96. [](const char *, RtData &r)
  97. {Part *p = (Part*)r.obj; p->Pmaxkey = p->lastnote;}},
  98. {"polyType::c:i", rProp(parameter) rOptions(Polyphonic, Monophonic, Legato)
  99. rDoc("Synthesis polyphony type\n"
  100. "Polyphonic - Each note is played independently\n"
  101. "Monophonic - A single note is played at a time with"
  102. " envelopes resetting between notes\n"
  103. "Legato - A single note is played at a time without"
  104. " envelopes resetting between notes\n"
  105. ), NULL,
  106. [](const char *msg, RtData &d)
  107. {
  108. Part *p = (Part*)d.obj;
  109. if(!rtosc_narguments(msg)) {
  110. int res = 0;
  111. if(!p->Ppolymode)
  112. res = p->Plegatomode ? 2 : 1;
  113. d.reply(d.loc, "i", res);
  114. return;
  115. }
  116. int i = rtosc_argument(msg, 0).i;
  117. if(i == 0) {
  118. p->Ppolymode = 1;
  119. p->Plegatomode = 0;
  120. } else if(i==1) {
  121. p->Ppolymode = 0;
  122. p->Plegatomode = 0;
  123. } else {
  124. p->Ppolymode = 0;
  125. p->Plegatomode = 1;
  126. }}},
  127. {"clear:", rProp(internal) rDoc("Reset Part To Defaults"), 0,
  128. [](const char *, RtData &d)
  129. {
  130. //XXX todo forward this event for middleware to handle
  131. //Part *p = (Part*)d.obj;
  132. //p->defaults();
  133. //char part_loc[128];
  134. //strcpy(part_loc, d.loc);
  135. //char *end = strrchr(part_loc, '/');
  136. //if(end)
  137. // end[1] = 0;
  138. //d.broadcast("/damage", "s", part_loc);
  139. }},
  140. //{"kit#16::T:F", "::Enables or disables kit item", 0,
  141. // [](const char *m, RtData &d) {
  142. // auto loc = d.loc;
  143. // Part *p = (Part*)d.obj;
  144. // unsigned kitid = -1;
  145. // //Note that this event will be captured before transmitted, thus
  146. // //reply/broadcast don't matter
  147. // for(int i=0; i<NUM_KIT_ITEMS; ++i) {
  148. // d.reply("/middleware/oscil", "siisb", loc, kitid, i,
  149. // "oscil", sizeof(void*),
  150. // p->kit[kitid]->adpars->voice[i]->OscilSmp);
  151. // d.reply("/middleware/oscil", "siisb", loc, kitid, i, "oscil-mod"
  152. // sizeof(void*),
  153. // p->kit[kitid]->adpars->voice[i]->somethingelse);
  154. // }
  155. // d.reply("/middleware/pad", "sib", loc, kitid,
  156. // sizeof(PADnoteParameters*),
  157. // p->kit[kitid]->padpars)
  158. // }}
  159. };
  160. #undef rObject
  161. #define rObject Part::Kit
  162. static const Ports kitPorts = {
  163. rSelf(Part::Kit, rEnabledBy(Penabled)),
  164. rRecurp(padpars, "Padnote parameters"),
  165. rRecurp(adpars, "Adnote parameters"),
  166. rRecurp(subpars, "Adnote parameters"),
  167. rToggle(firstkit, rProp(internal), "If this is the part's first kit"),
  168. rToggle(Penabled, rDefaultDepends(firstkit),
  169. rPreset(true, true), rPreset(false, false),
  170. "Kit item enable"),
  171. rToggle(Pmuted, rDefault(false), "Kit item mute"),
  172. rParamZyn(Pminkey, rDefault(0), "Kit item min key"),
  173. rParamZyn(Pmaxkey, rDefault(127) "Kit item max key"),
  174. rToggle(Padenabled, rDefaultDepends(firstkit),
  175. rPreset(true, true), rPreset(false, false)
  176. "ADsynth enable"),
  177. rToggle(Psubenabled, rDefault(false), "SUBsynth enable"),
  178. rToggle(Ppadenabled, rDefault(false), "PADsynth enable"),
  179. rParamZyn(Psendtoparteffect,
  180. rOptions(FX1, FX2, FX3, Off), rDefault(FX1),
  181. "Effect Levels"),
  182. rString(Pname, PART_MAX_NAME_LEN, rDefault(""), "Kit User Specified Label"),
  183. {"captureMin:", rDoc("Capture minimum valid note"), NULL,
  184. [](const char *, RtData &r)
  185. {Part::Kit *p = (Part::Kit*)r.obj; p->Pminkey = p->parent->lastnote;}},
  186. {"captureMax:", rDoc("Capture maximum valid note"), NULL, [](const char *, RtData &r)
  187. {Part::Kit *p = (Part::Kit*)r.obj; p->Pmaxkey = p->parent->lastnote;}},
  188. {"padpars-data:b", rProp(internal) rDoc("Set PADsynth data pointer"), 0,
  189. [](const char *msg, RtData &d) {
  190. rObject &o = *(rObject*)d.obj;
  191. assert(o.padpars == NULL);
  192. o.padpars = *(decltype(o.padpars)*)rtosc_argument(msg, 0).b.data;
  193. }},
  194. {"adpars-data:b", rProp(internal) rDoc("Set ADsynth data pointer"), 0,
  195. [](const char *msg, RtData &d) {
  196. rObject &o = *(rObject*)d.obj;
  197. assert(o.adpars == NULL);
  198. o.adpars = *(decltype(o.adpars)*)rtosc_argument(msg, 0).b.data;
  199. }},
  200. {"subpars-data:b", rProp(internal) rDoc("Set SUBsynth data pointer"), 0,
  201. [](const char *msg, RtData &d) {
  202. rObject &o = *(rObject*)d.obj;
  203. assert(o.subpars == NULL);
  204. o.subpars = *(decltype(o.subpars)*)rtosc_argument(msg, 0).b.data;
  205. }},
  206. };
  207. const Ports &Part::Kit::ports = kitPorts;
  208. const Ports &Part::ports = partPorts;
  209. Part::Part(Allocator &alloc, const SYNTH_T &synth_, const AbsTime &time_,
  210. const int &gzip_compression, const int &interpolation,
  211. Microtonal *microtonal_, FFTwrapper *fft_, WatchManager *wm_, const char *prefix_)
  212. :Pdrummode(false),
  213. Ppolymode(true),
  214. Plegatomode(false),
  215. partoutl(new float[synth_.buffersize]),
  216. partoutr(new float[synth_.buffersize]),
  217. ctl(synth_, &time_),
  218. microtonal(microtonal_),
  219. fft(fft_),
  220. wm(wm_),
  221. memory(alloc),
  222. synth(synth_),
  223. time(time_),
  224. gzip_compression(gzip_compression),
  225. interpolation(interpolation)
  226. {
  227. if(prefix_)
  228. strncpy(prefix, prefix_, sizeof(prefix));
  229. else
  230. memset(prefix, 0, sizeof(prefix));
  231. monomemClear();
  232. for(int n = 0; n < NUM_KIT_ITEMS; ++n) {
  233. kit[n].parent = this;
  234. kit[n].Pname = new char [PART_MAX_NAME_LEN];
  235. kit[n].adpars = nullptr;
  236. kit[n].subpars = nullptr;
  237. kit[n].padpars = nullptr;
  238. }
  239. kit[0].adpars = new ADnoteParameters(synth, fft, &time);
  240. //Part's Insertion Effects init
  241. for(int nefx = 0; nefx < NUM_PART_EFX; ++nefx) {
  242. partefx[nefx] = new EffectMgr(memory, synth, 1, &time);
  243. Pefxbypass[nefx] = false;
  244. }
  245. assert(partefx[0]);
  246. for(int n = 0; n < NUM_PART_EFX + 1; ++n) {
  247. partfxinputl[n] = new float [synth.buffersize];
  248. partfxinputr[n] = new float [synth.buffersize];
  249. }
  250. killallnotes = false;
  251. oldfreq = -1.0f;
  252. cleanup();
  253. Pname = new char[PART_MAX_NAME_LEN];
  254. oldvolumel = oldvolumer = 0.5f;
  255. lastnote = -1;
  256. defaults();
  257. assert(partefx[0]);
  258. }
  259. Part::Kit::Kit(void)
  260. :parent(nullptr),
  261. Penabled(false), Pmuted(false),
  262. Pminkey(0), Pmaxkey(127),
  263. Pname(nullptr),
  264. Padenabled(false), Psubenabled(false),
  265. Ppadenabled(false), Psendtoparteffect(0),
  266. adpars(nullptr), subpars(nullptr), padpars(nullptr)
  267. {
  268. }
  269. void Part::cloneTraits(Part &p) const
  270. {
  271. #define CLONE(x) p.x = this->x
  272. CLONE(Penabled);
  273. p.setPvolume(this->Pvolume);
  274. p.setPpanning(this->Ppanning);
  275. CLONE(Pminkey);
  276. CLONE(Pmaxkey);
  277. CLONE(Pkeyshift);
  278. CLONE(Prcvchn);
  279. CLONE(Pvelsns);
  280. CLONE(Pveloffs);
  281. CLONE(Pnoteon);
  282. CLONE(Ppolymode);
  283. CLONE(Plegatomode);
  284. CLONE(Pkeylimit);
  285. CLONE(ctl);
  286. }
  287. void Part::defaults()
  288. {
  289. Penabled = 0;
  290. Pminkey = 0;
  291. Pmaxkey = 127;
  292. Pnoteon = 1;
  293. Ppolymode = 1;
  294. Plegatomode = 0;
  295. setPvolume(96);
  296. Pkeyshift = 64;
  297. Prcvchn = 0;
  298. setPpanning(64);
  299. Pvelsns = 64;
  300. Pveloffs = 64;
  301. Pkeylimit = 15;
  302. defaultsinstrument();
  303. ctl.defaults();
  304. }
  305. void Part::defaultsinstrument()
  306. {
  307. ZERO(Pname, PART_MAX_NAME_LEN);
  308. info.Ptype = 0;
  309. ZERO(info.Pauthor, MAX_INFO_TEXT_SIZE + 1);
  310. ZERO(info.Pcomments, MAX_INFO_TEXT_SIZE + 1);
  311. Pkitmode = 0;
  312. Pdrummode = 0;
  313. for(int n = 0; n < NUM_KIT_ITEMS; ++n) {
  314. //kit[n].Penabled = false;
  315. kit[n].firstkit = false;
  316. kit[n].Pmuted = false;
  317. kit[n].Pminkey = 0;
  318. kit[n].Pmaxkey = 127;
  319. kit[n].Padenabled = false;
  320. kit[n].Psubenabled = false;
  321. kit[n].Ppadenabled = false;
  322. ZERO(kit[n].Pname, PART_MAX_NAME_LEN);
  323. kit[n].Psendtoparteffect = 0;
  324. if(n != 0)
  325. setkititemstatus(n, 0);
  326. }
  327. kit[0].firstkit = true;
  328. kit[0].Penabled = 1;
  329. kit[0].Padenabled = 1;
  330. kit[0].adpars->defaults();
  331. for(int nefx = 0; nefx < NUM_PART_EFX; ++nefx) {
  332. partefx[nefx]->defaults();
  333. Pefxroute[nefx] = 0; //route to next effect
  334. }
  335. }
  336. /*
  337. * Cleanup the part
  338. */
  339. void Part::cleanup(bool final_)
  340. {
  341. notePool.killAllNotes();
  342. for(int i = 0; i < synth.buffersize; ++i) {
  343. partoutl[i] = final_ ? 0.0f : synth.denormalkillbuf[i];
  344. partoutr[i] = final_ ? 0.0f : synth.denormalkillbuf[i];
  345. }
  346. ctl.resetall();
  347. for(int nefx = 0; nefx < NUM_PART_EFX; ++nefx)
  348. partefx[nefx]->cleanup();
  349. for(int n = 0; n < NUM_PART_EFX + 1; ++n)
  350. for(int i = 0; i < synth.buffersize; ++i) {
  351. partfxinputl[n][i] = final_ ? 0.0f : synth.denormalkillbuf[i];
  352. partfxinputr[n][i] = final_ ? 0.0f : synth.denormalkillbuf[i];
  353. }
  354. }
  355. Part::~Part()
  356. {
  357. cleanup(true);
  358. for(int n = 0; n < NUM_KIT_ITEMS; ++n) {
  359. delete kit[n].adpars;
  360. delete kit[n].subpars;
  361. delete kit[n].padpars;
  362. delete [] kit[n].Pname;
  363. }
  364. delete [] Pname;
  365. delete [] partoutl;
  366. delete [] partoutr;
  367. for(int nefx = 0; nefx < NUM_PART_EFX; ++nefx)
  368. delete partefx[nefx];
  369. for(int n = 0; n < NUM_PART_EFX + 1; ++n) {
  370. delete [] partfxinputl[n];
  371. delete [] partfxinputr[n];
  372. }
  373. }
  374. static void assert_kit_sanity(const Part::Kit *kits)
  375. {
  376. for(int i=0; i<NUM_KIT_ITEMS; ++i) {
  377. //an enabled kit must have a corresponding parameter object
  378. assert(!kits[i].Padenabled || kits[i].adpars);
  379. assert(!kits[i].Ppadenabled || kits[i].padpars);
  380. assert(!kits[i].Psubenabled || kits[i].subpars);
  381. }
  382. }
  383. static int kit_usage(const Part::Kit *kits, int note, int mode)
  384. {
  385. const bool non_kit = mode == 0;
  386. const bool singl_kit = mode == 2;
  387. int synth_usage = 0;
  388. for(uint8_t i = 0; i < NUM_KIT_ITEMS; ++i) {
  389. const auto &item = kits[i];
  390. if(!non_kit && !item.validNote(note))
  391. continue;
  392. synth_usage += item.Padenabled;
  393. synth_usage += item.Psubenabled;
  394. synth_usage += item.Ppadenabled;
  395. //Partial Kit Use
  396. if(non_kit || (singl_kit && item.active()))
  397. break;
  398. }
  399. return synth_usage;
  400. }
  401. /*
  402. * Note On Messages
  403. */
  404. bool Part::NoteOn(unsigned char note,
  405. unsigned char velocity,
  406. int masterkeyshift)
  407. {
  408. //Verify Basic Mode and sanity
  409. const bool isRunningNote = notePool.existsRunningNote();
  410. const bool doingLegato = isRunningNote && isLegatoMode() &&
  411. lastlegatomodevalid;
  412. if(!Pnoteon || !inRange(note, Pminkey, Pmaxkey) || notePool.full() ||
  413. notePool.synthFull(kit_usage(kit, note, Pkitmode)))
  414. return false;
  415. verifyKeyMode();
  416. assert_kit_sanity(kit);
  417. //Preserve Note Stack
  418. if(isMonoMode() || isLegatoMode()) {
  419. monomemPush(note);
  420. monomem[note].velocity = velocity;
  421. monomem[note].mkeyshift = masterkeyshift;
  422. } else if(!monomemEmpty())
  423. monomemClear();
  424. //Mono/Legato Release old notes
  425. if(isMonoMode() || (isLegatoMode() && !doingLegato))
  426. notePool.releasePlayingNotes();
  427. lastlegatomodevalid = isLegatoMode();
  428. //Compute Note Parameters
  429. const float vel = getVelocity(velocity, Pvelsns, Pveloffs);
  430. const int partkeyshift = (int)Pkeyshift - 64;
  431. const int keyshift = masterkeyshift + partkeyshift;
  432. const float notebasefreq = getBaseFreq(note, keyshift);
  433. if(notebasefreq < 0)
  434. return false;
  435. //Portamento
  436. lastnote = note;
  437. if(oldfreq < 1.0f)
  438. oldfreq = notebasefreq;//this is only the first note is played
  439. // For Mono/Legato: Force Portamento Off on first
  440. // notes. That means it is required that the previous note is
  441. // still held down or sustained for the Portamento to activate
  442. // (that's like Legato).
  443. bool portamento = false;
  444. if(Ppolymode || isRunningNote)
  445. portamento = ctl.initportamento(oldfreq, notebasefreq, doingLegato);
  446. oldfreq = notebasefreq;
  447. //Adjust Existing Notes
  448. if(doingLegato) {
  449. LegatoParams pars = {notebasefreq, vel, portamento, note, true};
  450. notePool.applyLegato(pars);
  451. return true;
  452. }
  453. if(Ppolymode)
  454. notePool.makeUnsustainable(note);
  455. //Create New Notes
  456. for(uint8_t i = 0; i < NUM_KIT_ITEMS; ++i) {
  457. ScratchString pre = prefix;
  458. auto &item = kit[i];
  459. if(Pkitmode != 0 && !item.validNote(note))
  460. continue;
  461. SynthParams pars{memory, ctl, synth, time, notebasefreq, vel,
  462. portamento, note, false};
  463. const int sendto = Pkitmode ? item.sendto() : 0;
  464. try {
  465. if(item.Padenabled)
  466. notePool.insertNote(note, sendto,
  467. {memory.alloc<ADnote>(kit[i].adpars, pars,
  468. wm, (pre+"kit"+i+"/adpars/").c_str), 0, i});
  469. if(item.Psubenabled)
  470. notePool.insertNote(note, sendto,
  471. {memory.alloc<SUBnote>(kit[i].subpars, pars), 1, i});
  472. if(item.Ppadenabled)
  473. notePool.insertNote(note, sendto,
  474. {memory.alloc<PADnote>(kit[i].padpars, pars, interpolation, wm,
  475. (pre+"kit"+i+"/padpars/").c_str), 2, i});
  476. } catch (std::bad_alloc & ba) {
  477. std::cerr << "dropped new note: " << ba.what() << std::endl;
  478. }
  479. //Partial Kit Use
  480. if(isNonKit() || (isSingleKit() && item.active()))
  481. break;
  482. }
  483. if(isLegatoMode())
  484. notePool.upgradeToLegato();
  485. //Enforce the key limit
  486. setkeylimit(Pkeylimit);
  487. return true;
  488. }
  489. /*
  490. * Note Off Messages
  491. */
  492. void Part::NoteOff(unsigned char note) //release the key
  493. {
  494. // This note is released, so we remove it from the list.
  495. if(!monomemEmpty())
  496. monomemPop(note);
  497. for(auto &desc:notePool.activeDesc()) {
  498. if(desc.note != note || !desc.playing())
  499. continue;
  500. if(!ctl.sustain.sustain) { //the sustain pedal is not pushed
  501. if((isMonoMode() || isLegatoMode()) && !monomemEmpty())
  502. MonoMemRenote();//Play most recent still active note
  503. else
  504. notePool.release(desc);
  505. }
  506. else { //the sustain pedal is pushed
  507. if(desc.canSustain())
  508. desc.doSustain();
  509. else
  510. notePool.release(desc);
  511. }
  512. }
  513. }
  514. void Part::PolyphonicAftertouch(unsigned char note,
  515. unsigned char velocity,
  516. int masterkeyshift)
  517. {
  518. (void) masterkeyshift;
  519. if(!Pnoteon || !inRange(note, Pminkey, Pmaxkey) || Pdrummode)
  520. return;
  521. // MonoMem stuff:
  522. if(!Ppolymode) // if Poly is off
  523. monomem[note].velocity = velocity; // Store this note's velocity.
  524. const float vel = getVelocity(velocity, Pvelsns, Pveloffs);
  525. for(auto &d:notePool.activeDesc()) {
  526. if(d.note == note && d.playing())
  527. for(auto &s:notePool.activeNotes(d))
  528. s.note->setVelocity(vel);
  529. }
  530. }
  531. /*
  532. * Controllers
  533. */
  534. void Part::SetController(unsigned int type, int par)
  535. {
  536. switch(type) {
  537. case C_pitchwheel:
  538. ctl.setpitchwheel(par);
  539. break;
  540. case C_expression:
  541. ctl.setexpression(par);
  542. setPvolume(Pvolume); //update the volume
  543. break;
  544. case C_portamento:
  545. ctl.setportamento(par);
  546. break;
  547. case C_panning:
  548. ctl.setpanning(par);
  549. setPpanning(Ppanning); //update the panning
  550. break;
  551. case C_filtercutoff:
  552. ctl.setfiltercutoff(par);
  553. break;
  554. case C_filterq:
  555. ctl.setfilterq(par);
  556. break;
  557. case C_bandwidth:
  558. ctl.setbandwidth(par);
  559. break;
  560. case C_modwheel:
  561. ctl.setmodwheel(par);
  562. break;
  563. case C_fmamp:
  564. ctl.setfmamp(par);
  565. break;
  566. case C_volume:
  567. ctl.setvolume(par);
  568. if(ctl.volume.receive != 0)
  569. volume = ctl.volume.volume;
  570. else
  571. setPvolume(Pvolume);
  572. break;
  573. case C_sustain:
  574. ctl.setsustain(par);
  575. if(ctl.sustain.sustain == 0)
  576. ReleaseSustainedKeys();
  577. break;
  578. case C_allsoundsoff:
  579. AllNotesOff(); //Panic
  580. break;
  581. case C_resetallcontrollers:
  582. ctl.resetall();
  583. ReleaseSustainedKeys();
  584. if(ctl.volume.receive != 0)
  585. volume = ctl.volume.volume;
  586. else
  587. setPvolume(Pvolume);
  588. setPvolume(Pvolume); //update the volume
  589. setPpanning(Ppanning); //update the panning
  590. for(int item = 0; item < NUM_KIT_ITEMS; ++item) {
  591. if(kit[item].adpars == NULL)
  592. continue;
  593. kit[item].adpars->GlobalPar.Reson->
  594. sendcontroller(C_resonance_center, 1.0f);
  595. kit[item].adpars->GlobalPar.Reson->
  596. sendcontroller(C_resonance_bandwidth, 1.0f);
  597. }
  598. //more update to add here if I add controllers
  599. break;
  600. case C_allnotesoff:
  601. ReleaseAllKeys();
  602. break;
  603. case C_resonance_center:
  604. ctl.setresonancecenter(par);
  605. for(int item = 0; item < NUM_KIT_ITEMS; ++item) {
  606. if(kit[item].adpars == NULL)
  607. continue;
  608. kit[item].adpars->GlobalPar.Reson->
  609. sendcontroller(C_resonance_center,
  610. ctl.resonancecenter.relcenter);
  611. }
  612. break;
  613. case C_resonance_bandwidth:
  614. ctl.setresonancebw(par);
  615. kit[0].adpars->GlobalPar.Reson->
  616. sendcontroller(C_resonance_bandwidth, ctl.resonancebandwidth.relbw);
  617. break;
  618. }
  619. }
  620. /*
  621. * Release the sustained keys
  622. */
  623. void Part::ReleaseSustainedKeys()
  624. {
  625. // Let's call MonoMemRenote() on some conditions:
  626. if((isMonoMode() || isLegatoMode()) && !monomemEmpty())
  627. if(monomemBack() != lastnote) // Sustain controller manipulation would cause repeated same note respawn without this check.
  628. MonoMemRenote(); // To play most recent still held note.
  629. for(auto &d:notePool.activeDesc())
  630. if(d.sustained())
  631. for(auto &s:notePool.activeNotes(d))
  632. s.note->releasekey();
  633. }
  634. /*
  635. * Release all keys
  636. */
  637. void Part::ReleaseAllKeys()
  638. {
  639. for(auto &d:notePool.activeDesc())
  640. if(!d.released())
  641. for(auto &s:notePool.activeNotes(d))
  642. s.note->releasekey();
  643. }
  644. // Call NoteOn(...) with the most recent still held key as new note
  645. // (Made for Mono/Legato).
  646. void Part::MonoMemRenote()
  647. {
  648. unsigned char mmrtempnote = monomemBack(); // Last list element.
  649. monomemPop(mmrtempnote); // We remove it, will be added again in NoteOn(...).
  650. NoteOn(mmrtempnote, monomem[mmrtempnote].velocity,
  651. monomem[mmrtempnote].mkeyshift);
  652. }
  653. float Part::getBaseFreq(int note, int keyshift) const
  654. {
  655. if(Pdrummode)
  656. return 440.0f * powf(2.0f, (note - 69.0f) / 12.0f);
  657. else
  658. return microtonal->getnotefreq(note, keyshift);
  659. }
  660. float Part::getVelocity(uint8_t velocity, uint8_t velocity_sense,
  661. uint8_t velocity_offset) const
  662. {
  663. //compute sense function
  664. const float vel = VelF(velocity / 127.0f, velocity_sense);
  665. //compute the velocity offset
  666. return limit(vel + (velocity_offset - 64.0f) / 64.0f, 0.0f, 1.0f);
  667. }
  668. void Part::verifyKeyMode(void)
  669. {
  670. if(Plegatomode && !Pdrummode && Ppolymode) {
  671. fprintf(stderr,
  672. "WARNING: Poly & Legato modes are On, that shouldn't happen\n"
  673. "Disabling Legato mode...\n"
  674. "(Part.cpp::NoteOn(..))\n");
  675. Plegatomode = 0;
  676. }
  677. }
  678. /*
  679. * Set Part's key limit
  680. */
  681. void Part::setkeylimit(unsigned char Pkeylimit_)
  682. {
  683. Pkeylimit = Pkeylimit_;
  684. int keylimit = Pkeylimit;
  685. if(keylimit == 0)
  686. keylimit = POLYPHONY - 5;
  687. if(notePool.getRunningNotes() >= keylimit)
  688. notePool.enforceKeyLimit(keylimit);
  689. }
  690. /*
  691. * Prepare all notes to be turned off
  692. */
  693. void Part::AllNotesOff()
  694. {
  695. killallnotes = true;
  696. }
  697. /*
  698. * Compute Part samples and store them in the partoutl[] and partoutr[]
  699. */
  700. void Part::ComputePartSmps()
  701. {
  702. assert(partefx[0]);
  703. for(unsigned nefx = 0; nefx < NUM_PART_EFX + 1; ++nefx) {
  704. memset(partfxinputl[nefx], 0, synth.bufferbytes);
  705. memset(partfxinputr[nefx], 0, synth.bufferbytes);
  706. }
  707. for(auto &d:notePool.activeDesc()) {
  708. d.age++;
  709. for(auto &s:notePool.activeNotes(d)) {
  710. float tmpoutr[synth.buffersize];
  711. float tmpoutl[synth.buffersize];
  712. auto &note = *s.note;
  713. note.noteout(&tmpoutl[0], &tmpoutr[0]);
  714. for(int i = 0; i < synth.buffersize; ++i) { //add the note to part(mix)
  715. partfxinputl[d.sendto][i] += tmpoutl[i];
  716. partfxinputr[d.sendto][i] += tmpoutr[i];
  717. }
  718. if(note.finished())
  719. notePool.kill(s);
  720. }
  721. }
  722. //Apply part's effects and mix them
  723. for(int nefx = 0; nefx < NUM_PART_EFX; ++nefx) {
  724. if(!Pefxbypass[nefx]) {
  725. partefx[nefx]->out(partfxinputl[nefx], partfxinputr[nefx]);
  726. if(Pefxroute[nefx] == 2)
  727. for(int i = 0; i < synth.buffersize; ++i) {
  728. partfxinputl[nefx + 1][i] += partefx[nefx]->efxoutl[i];
  729. partfxinputr[nefx + 1][i] += partefx[nefx]->efxoutr[i];
  730. }
  731. }
  732. int routeto = ((Pefxroute[nefx] == 0) ? nefx + 1 : NUM_PART_EFX);
  733. for(int i = 0; i < synth.buffersize; ++i) {
  734. partfxinputl[routeto][i] += partfxinputl[nefx][i];
  735. partfxinputr[routeto][i] += partfxinputr[nefx][i];
  736. }
  737. }
  738. for(int i = 0; i < synth.buffersize; ++i) {
  739. partoutl[i] = partfxinputl[NUM_PART_EFX][i];
  740. partoutr[i] = partfxinputr[NUM_PART_EFX][i];
  741. }
  742. if(killallnotes) {
  743. for(int i = 0; i < synth.buffersize; ++i) {
  744. float tmp = (synth.buffersize_f - i) / synth.buffersize_f;
  745. partoutl[i] *= tmp;
  746. partoutr[i] *= tmp;
  747. }
  748. notePool.killAllNotes();
  749. monomemClear();
  750. killallnotes = false;
  751. for(int nefx = 0; nefx < NUM_PART_EFX; ++nefx)
  752. partefx[nefx]->cleanup();
  753. }
  754. ctl.updateportamento();
  755. }
  756. /*
  757. * Parameter control
  758. */
  759. void Part::setPvolume(char Pvolume_)
  760. {
  761. Pvolume = Pvolume_;
  762. volume =
  763. dB2rap((Pvolume - 96.0f) / 96.0f * 40.0f) * ctl.expression.relvolume;
  764. }
  765. void Part::setPpanning(char Ppanning_)
  766. {
  767. Ppanning = Ppanning_;
  768. panning = limit(Ppanning / 127.0f + ctl.panning.pan, 0.0f, 1.0f);
  769. }
  770. /*
  771. * Enable or disable a kit item
  772. */
  773. void Part::setkititemstatus(unsigned kititem, bool Penabled_)
  774. {
  775. //nonexistent kit item and the first kit item is always enabled
  776. if((kititem == 0) || (kititem >= NUM_KIT_ITEMS))
  777. return;
  778. Kit &kkit = kit[kititem];
  779. //no need to update if
  780. if(kkit.Penabled == Penabled_)
  781. return;
  782. kkit.Penabled = Penabled_;
  783. if(!Penabled_) {
  784. delete kkit.adpars;
  785. delete kkit.subpars;
  786. delete kkit.padpars;
  787. kkit.adpars = nullptr;
  788. kkit.subpars = nullptr;
  789. kkit.padpars = nullptr;
  790. kkit.Pname[0] = '\0';
  791. notePool.killAllNotes();
  792. }
  793. else {
  794. //All parameters must be NULL in this case
  795. assert(!(kkit.adpars || kkit.subpars || kkit.padpars));
  796. kkit.adpars = new ADnoteParameters(synth, fft, &time);
  797. kkit.subpars = new SUBnoteParameters(&time);
  798. kkit.padpars = new PADnoteParameters(synth, fft, &time);
  799. }
  800. }
  801. void Part::add2XMLinstrument(XMLwrapper& xml)
  802. {
  803. xml.beginbranch("INFO");
  804. xml.addparstr("name", (char *)Pname);
  805. xml.addparstr("author", (char *)info.Pauthor);
  806. xml.addparstr("comments", (char *)info.Pcomments);
  807. xml.addpar("type", info.Ptype);
  808. xml.endbranch();
  809. xml.beginbranch("INSTRUMENT_KIT");
  810. xml.addpar("kit_mode", Pkitmode);
  811. xml.addparbool("drum_mode", Pdrummode);
  812. for(int i = 0; i < NUM_KIT_ITEMS; ++i) {
  813. xml.beginbranch("INSTRUMENT_KIT_ITEM", i);
  814. xml.addparbool("enabled", kit[i].Penabled);
  815. if(kit[i].Penabled != 0) {
  816. xml.addparstr("name", (char *)kit[i].Pname);
  817. xml.addparbool("muted", kit[i].Pmuted);
  818. xml.addpar("min_key", kit[i].Pminkey);
  819. xml.addpar("max_key", kit[i].Pmaxkey);
  820. xml.addpar("send_to_instrument_effect", kit[i].Psendtoparteffect);
  821. xml.addparbool("add_enabled", kit[i].Padenabled);
  822. if(kit[i].Padenabled && kit[i].adpars) {
  823. xml.beginbranch("ADD_SYNTH_PARAMETERS");
  824. kit[i].adpars->add2XML(xml);
  825. xml.endbranch();
  826. }
  827. xml.addparbool("sub_enabled", kit[i].Psubenabled);
  828. if(kit[i].Psubenabled && kit[i].subpars) {
  829. xml.beginbranch("SUB_SYNTH_PARAMETERS");
  830. kit[i].subpars->add2XML(xml);
  831. xml.endbranch();
  832. }
  833. xml.addparbool("pad_enabled", kit[i].Ppadenabled);
  834. if(kit[i].Ppadenabled && kit[i].padpars) {
  835. xml.beginbranch("PAD_SYNTH_PARAMETERS");
  836. kit[i].padpars->add2XML(xml);
  837. xml.endbranch();
  838. }
  839. }
  840. xml.endbranch();
  841. }
  842. xml.endbranch();
  843. xml.beginbranch("INSTRUMENT_EFFECTS");
  844. for(int nefx = 0; nefx < NUM_PART_EFX; ++nefx) {
  845. xml.beginbranch("INSTRUMENT_EFFECT", nefx);
  846. xml.beginbranch("EFFECT");
  847. partefx[nefx]->add2XML(xml);
  848. xml.endbranch();
  849. xml.addpar("route", Pefxroute[nefx]);
  850. partefx[nefx]->setdryonly(Pefxroute[nefx] == 2);
  851. xml.addparbool("bypass", Pefxbypass[nefx]);
  852. xml.endbranch();
  853. }
  854. xml.endbranch();
  855. }
  856. void Part::add2XML(XMLwrapper& xml)
  857. {
  858. //parameters
  859. xml.addparbool("enabled", Penabled);
  860. if((Penabled == 0) && (xml.minimal))
  861. return;
  862. xml.addpar("volume", Pvolume);
  863. xml.addpar("panning", Ppanning);
  864. xml.addpar("min_key", Pminkey);
  865. xml.addpar("max_key", Pmaxkey);
  866. xml.addpar("key_shift", Pkeyshift);
  867. xml.addpar("rcv_chn", Prcvchn);
  868. xml.addpar("velocity_sensing", Pvelsns);
  869. xml.addpar("velocity_offset", Pveloffs);
  870. xml.addparbool("note_on", Pnoteon);
  871. xml.addparbool("poly_mode", Ppolymode);
  872. xml.addpar("legato_mode", Plegatomode);
  873. xml.addpar("key_limit", Pkeylimit);
  874. xml.beginbranch("INSTRUMENT");
  875. add2XMLinstrument(xml);
  876. xml.endbranch();
  877. xml.beginbranch("CONTROLLER");
  878. ctl.add2XML(xml);
  879. xml.endbranch();
  880. }
  881. int Part::saveXML(const char *filename)
  882. {
  883. XMLwrapper xml;
  884. xml.beginbranch("INSTRUMENT");
  885. add2XMLinstrument(xml);
  886. xml.endbranch();
  887. int result = xml.saveXMLfile(filename, gzip_compression);
  888. return result;
  889. }
  890. int Part::loadXMLinstrument(const char *filename)
  891. {
  892. XMLwrapper xml;
  893. if(xml.loadXMLfile(filename) < 0) {
  894. return -1;
  895. }
  896. if(xml.enterbranch("INSTRUMENT") == 0)
  897. return -10;
  898. getfromXMLinstrument(xml);
  899. xml.exitbranch();
  900. return 0;
  901. }
  902. void Part::applyparameters(void)
  903. {
  904. applyparameters([]{return false;});
  905. }
  906. void Part::applyparameters(std::function<bool()> do_abort)
  907. {
  908. for(int n = 0; n < NUM_KIT_ITEMS; ++n)
  909. if(kit[n].Ppadenabled && kit[n].padpars)
  910. kit[n].padpars->applyparameters(do_abort);
  911. }
  912. void Part::initialize_rt(void)
  913. {
  914. for(int i=0; i<NUM_PART_EFX; ++i)
  915. partefx[i]->init();
  916. }
  917. void Part::kill_rt(void)
  918. {
  919. for(int i=0; i<NUM_PART_EFX; ++i)
  920. partefx[i]->kill();
  921. notePool.killAllNotes();
  922. }
  923. void Part::monomemPush(char note)
  924. {
  925. for(int i=0; i<256; ++i)
  926. if(monomemnotes[i]==note)
  927. return;
  928. for(int i=254;i>=0; --i)
  929. monomemnotes[i+1] = monomemnotes[i];
  930. monomemnotes[0] = note;
  931. }
  932. void Part::monomemPop(char note)
  933. {
  934. int note_pos=-1;
  935. for(int i=0; i<256; ++i)
  936. if(monomemnotes[i]==note)
  937. note_pos = i;
  938. if(note_pos != -1) {
  939. for(int i=note_pos; i<256; ++i)
  940. monomemnotes[i] = monomemnotes[i+1];
  941. monomemnotes[255] = -1;
  942. }
  943. }
  944. char Part::monomemBack(void) const
  945. {
  946. return monomemnotes[0];
  947. }
  948. bool Part::monomemEmpty(void) const
  949. {
  950. return monomemnotes[0] == -1;
  951. }
  952. void Part::monomemClear(void)
  953. {
  954. for(int i=0; i<256; ++i)
  955. monomemnotes[i] = -1;
  956. }
  957. void Part::getfromXMLinstrument(XMLwrapper& xml)
  958. {
  959. if(xml.enterbranch("INFO")) {
  960. xml.getparstr("name", (char *)Pname, PART_MAX_NAME_LEN);
  961. xml.getparstr("author", (char *)info.Pauthor, MAX_INFO_TEXT_SIZE);
  962. xml.getparstr("comments", (char *)info.Pcomments, MAX_INFO_TEXT_SIZE);
  963. info.Ptype = xml.getpar("type", info.Ptype, 0, 16);
  964. xml.exitbranch();
  965. }
  966. if(xml.enterbranch("INSTRUMENT_KIT")) {
  967. Pkitmode = xml.getpar127("kit_mode", Pkitmode);
  968. Pdrummode = xml.getparbool("drum_mode", Pdrummode);
  969. setkititemstatus(0, 0);
  970. for(int i = 0; i < NUM_KIT_ITEMS; ++i) {
  971. if(xml.enterbranch("INSTRUMENT_KIT_ITEM", i) == 0)
  972. continue;
  973. setkititemstatus(i, xml.getparbool("enabled", kit[i].Penabled));
  974. if(kit[i].Penabled == 0) {
  975. xml.exitbranch();
  976. continue;
  977. }
  978. xml.getparstr("name", (char *)kit[i].Pname, PART_MAX_NAME_LEN);
  979. kit[i].Pmuted = xml.getparbool("muted", kit[i].Pmuted);
  980. kit[i].Pminkey = xml.getpar127("min_key", kit[i].Pminkey);
  981. kit[i].Pmaxkey = xml.getpar127("max_key", kit[i].Pmaxkey);
  982. kit[i].Psendtoparteffect = xml.getpar127(
  983. "send_to_instrument_effect",
  984. kit[i].Psendtoparteffect);
  985. kit[i].Padenabled = xml.getparbool("add_enabled",
  986. kit[i].Padenabled);
  987. if(xml.enterbranch("ADD_SYNTH_PARAMETERS")) {
  988. if(!kit[i].adpars)
  989. kit[i].adpars = new ADnoteParameters(synth, fft, &time);
  990. kit[i].adpars->getfromXML(xml);
  991. xml.exitbranch();
  992. }
  993. kit[i].Psubenabled = xml.getparbool("sub_enabled",
  994. kit[i].Psubenabled);
  995. if(xml.enterbranch("SUB_SYNTH_PARAMETERS")) {
  996. if(!kit[i].subpars)
  997. kit[i].subpars = new SUBnoteParameters(&time);
  998. kit[i].subpars->getfromXML(xml);
  999. xml.exitbranch();
  1000. }
  1001. kit[i].Ppadenabled = xml.getparbool("pad_enabled",
  1002. kit[i].Ppadenabled);
  1003. if(xml.enterbranch("PAD_SYNTH_PARAMETERS")) {
  1004. if(!kit[i].padpars)
  1005. kit[i].padpars = new PADnoteParameters(synth, fft, &time);
  1006. kit[i].padpars->getfromXML(xml);
  1007. xml.exitbranch();
  1008. }
  1009. xml.exitbranch();
  1010. }
  1011. xml.exitbranch();
  1012. }
  1013. if(xml.enterbranch("INSTRUMENT_EFFECTS")) {
  1014. for(int nefx = 0; nefx < NUM_PART_EFX; ++nefx) {
  1015. if(xml.enterbranch("INSTRUMENT_EFFECT", nefx) == 0)
  1016. continue;
  1017. if(xml.enterbranch("EFFECT")) {
  1018. partefx[nefx]->getfromXML(xml);
  1019. xml.exitbranch();
  1020. }
  1021. Pefxroute[nefx] = xml.getpar("route",
  1022. Pefxroute[nefx],
  1023. 0,
  1024. NUM_PART_EFX);
  1025. partefx[nefx]->setdryonly(Pefxroute[nefx] == 2);
  1026. Pefxbypass[nefx] = xml.getparbool("bypass", Pefxbypass[nefx]);
  1027. xml.exitbranch();
  1028. }
  1029. xml.exitbranch();
  1030. }
  1031. }
  1032. void Part::getfromXML(XMLwrapper& xml)
  1033. {
  1034. Penabled = xml.getparbool("enabled", Penabled);
  1035. setPvolume(xml.getpar127("volume", Pvolume));
  1036. setPpanning(xml.getpar127("panning", Ppanning));
  1037. Pminkey = xml.getpar127("min_key", Pminkey);
  1038. Pmaxkey = xml.getpar127("max_key", Pmaxkey);
  1039. Pkeyshift = xml.getpar127("key_shift", Pkeyshift);
  1040. Prcvchn = xml.getpar127("rcv_chn", Prcvchn);
  1041. Pvelsns = xml.getpar127("velocity_sensing", Pvelsns);
  1042. Pveloffs = xml.getpar127("velocity_offset", Pveloffs);
  1043. Pnoteon = xml.getparbool("note_on", Pnoteon);
  1044. Ppolymode = xml.getparbool("poly_mode", Ppolymode);
  1045. Plegatomode = xml.getparbool("legato_mode", Plegatomode); //older versions
  1046. if(!Plegatomode)
  1047. Plegatomode = xml.getpar127("legato_mode", Plegatomode);
  1048. Pkeylimit = xml.getpar127("key_limit", Pkeylimit);
  1049. if(xml.enterbranch("INSTRUMENT")) {
  1050. getfromXMLinstrument(xml);
  1051. xml.exitbranch();
  1052. }
  1053. if(xml.enterbranch("CONTROLLER")) {
  1054. ctl.getfromXML(xml);
  1055. xml.exitbranch();
  1056. }
  1057. }
  1058. bool Part::Kit::active(void) const
  1059. {
  1060. return Padenabled || Psubenabled || Ppadenabled;
  1061. }
  1062. uint8_t Part::Kit::sendto(void) const
  1063. {
  1064. return limit((int)Psendtoparteffect, 0, NUM_PART_EFX);
  1065. }
  1066. bool Part::Kit::validNote(char note) const
  1067. {
  1068. return !Pmuted && inRange((uint8_t)note, Pminkey, Pmaxkey);
  1069. }
  1070. }