1 /*
2     Part.cpp - Part implementation
3 
4     Original ZynAddSubFX author Nasca Octavian Paul
5     Copyright (C) 2002-2005 Nasca Octavian Paul
6     Copyright 2009, James Morris
7     Copyright 2009-2011, Alan Calvert
8     Copyright 2014-2019, Will Godfrey
9     Copyright 2021 Kristian Amlie & others
10 
11     This file is part of yoshimi, which is free software: you can redistribute
12     it and/or modify it under the terms of the GNU Library General Public
13     License as published by the Free Software Foundation; either version 2 of
14     the License, or (at your option) any later version.
15 
16     yoshimi is distributed in the hope that it will be useful, but WITHOUT ANY
17     WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18     FOR A PARTICULAR PURPOSE.   See the GNU General Public License (version 2 or
19     later) for more details.
20 
21     You should have received a copy of the GNU General Public License along with
22     yoshimi; if not, write to the Free Software Foundation, Inc., 51 Franklin
23     Street, Fifth Floor, Boston, MA  02110-1301, USA.
24 
25     This file is derivative of ZynAddSubFX original code.
26 
27 */
28 
29 #include "Params/ADnoteParameters.h"
30 #include "Params/SUBnoteParameters.h"
31 #include "Params/PADnoteParameters.h"
32 #include "Synth/ADnote.h"
33 #include "Synth/SUBnote.h"
34 #include "Synth/PADnote.h"
35 #include "Params/Controller.h"
36 #include "Effects/EffectMgr.h"
37 #include "DSP/FFTwrapper.h"
38 #include "Misc/Microtonal.h"
39 #include "Misc/XMLwrapper.h"
40 #include "Misc/SynthEngine.h"
41 #include "Misc/SynthHelper.h"
42 #include "Misc/FileMgrFuncs.h"
43 #include "Misc/NumericFuncs.h"
44 #include "Misc/FormatFuncs.h"
45 #include "Interface/TextLists.h"
46 #include "Synth/Resonance.h"
47 #include "Misc/Part.h"
48 
49 using synth::velF;
50 using file::isRegularFile;
51 using file::setExtension;
52 using file::findLeafName;
53 using func::findSplitPoint;
54 using func::setAllPan;
55 using func::decibel;
56 
Part(Microtonal * microtonal_,FFTwrapper * fft_,SynthEngine * _synth)57 Part::Part(Microtonal *microtonal_, FFTwrapper *fft_, SynthEngine *_synth) :
58     microtonal(microtonal_),
59     fft(fft_),
60     killallnotes(false),
61     synth(_synth)
62 {
63     ctl = new Controller(synth);
64     partoutl = (float*)fftwf_malloc(synth->bufferbytes);
65     memset(partoutl, 0, synth->bufferbytes);
66     partoutr = (float*)fftwf_malloc(synth->bufferbytes);
67     memset(partoutr, 0, synth->bufferbytes);
68 
69     for (int n = 0; n < NUM_KIT_ITEMS; ++n)
70     {
71         kit[n].Pname.clear();
72         kit[n].adpars = NULL;
73         kit[n].subpars = NULL;
74         kit[n].padpars = NULL;
75     }
76 
77     kit[0].adpars = new ADnoteParameters(fft, synth);
78     kit[0].subpars = new SUBnoteParameters(synth);
79     kit[0].padpars = new PADnoteParameters(fft, synth);
80 
81     // Part's Insertion Effects init
82     for (int nefx = 0; nefx < NUM_PART_EFX; ++nefx)
83         partefx[nefx] = new EffectMgr(1, synth);
84 
85     for (int n = 0; n < NUM_PART_EFX + 1; ++n)
86     {
87         partfxinputl[n] = (float*)fftwf_malloc(synth->bufferbytes);
88         memset(partfxinputl[n], 0, synth->bufferbytes);
89         partfxinputr[n] = (float*)fftwf_malloc(synth->bufferbytes);
90         memset(partfxinputr[n], 0, synth->bufferbytes);
91         Pefxbypass[n] = false;
92     }
93 
94     oldfreq = -1.0f;
95 
96     int i, j;
97     for (i = 0; i < POLIPHONY; ++i)
98     {
99         partnote[i].status = KEY_OFF;
100         partnote[i].note = -1;
101         partnote[i].itemsplaying = 0;
102         for (j = 0; j < NUM_KIT_ITEMS; ++j)
103         {
104             partnote[i].kititem[j].adnote = NULL;
105             partnote[i].kititem[j].subnote = NULL;
106             partnote[i].kititem[j].padnote = NULL;
107         }
108         partnote[i].time = 0;
109     }
110     cleanup();
111     Pname.clear();
112 
113     lastnote = -1;
114     lastpos = 0; // lastpos will store previously used NoteOn(...)'s pos.
115     lastlegatomodevalid = false; // To store previous legatomodevalid value.
116     defaults();
117 }
118 
119 
defaults(void)120 void Part::defaults(void)
121 {
122     Penabled = 0;
123     Pminkey = 0;
124     Pmaxkey = 127;
125     Pkeymode = PART_NORMAL;
126     PchannelATchoice = 0;
127     PkeyATchoice = 0;
128     setVolume(96);
129     TransVolume = 128; // ensure it always gets set
130     Pkeyshift = 64;
131     PmapOffset = 0;
132     Prcvchn = 0;
133     oldFilterState = -1;
134     oldBendState = -1;
135     oldVolumeState = -1;
136     oldVolumeAdjust = 0;
137     oldModulationState = -1;
138     setPan(Ppanning = 64);
139     TransPanning = 128; // ensure it always gets set
140     Pvelsns = 64;
141     Pveloffs = 64;
142     Pkeylimit = PART_DEFAULT_LIMIT;
143     Pfrand = 0;
144     Pvelrand = 0;
145     PbreathControl = 2;
146     Peffnum = 0;
147     setDestination(1);
148     busy = false;
149     defaultsinstrument();
150     ctl->resetall();
151     setNoteMap(0);
152 }
153 
setNoteMap(int keyshift)154 void Part::setNoteMap(int keyshift)
155 {
156     for (int i = 0; i < 128; ++i)
157         if (Pdrummode)
158             PnoteMap[128 - PmapOffset + i] = microtonal->getFixedNoteFreq(i);
159         else
160             PnoteMap[128 - PmapOffset + i] = microtonal->getNoteFreq(i, keyshift + synth->Pkeyshift - 64);
161 }
162 
163 
defaultsinstrument(void)164 void Part::defaultsinstrument(void)
165 {
166     Pname = DEFAULT_NAME;
167     Poriginal = "";
168     PyoshiType = 0;
169     info.Ptype = 0;
170     info.Pauthor.clear();
171     info.Pcomments.clear();
172 
173     Pkitmode = 0;
174     Pkitfade = false;
175     Pdrummode = 0;
176     Pfrand = 0;
177     Pvelrand = 0;
178 
179     for (int n = 0; n < NUM_KIT_ITEMS; ++n)
180     {
181         kit[n].Penabled = 0;
182         kit[n].Pmuted = 0;
183         kit[n].Pminkey = 0;
184         kit[n].Pmaxkey = 127;
185         kit[n].Padenabled = 0;
186         kit[n].Psubenabled = 0;
187         kit[n].Ppadenabled = 0;
188         kit[n].Pname.clear();
189         kit[n].Psendtoparteffect = 0;
190         if (n != 0)
191             setkititemstatus(n, 0);
192     }
193     kit[0].Penabled = 1;
194     kit[0].Padenabled = 1;
195     kit[0].adpars->defaults();
196     kit[0].subpars->defaults();
197     kit[0].padpars->defaults();
198 
199     for (int nefx = 0; nefx < NUM_PART_EFX; ++nefx)
200     {
201         partefx[nefx]->defaults();
202         Pefxroute[nefx] = 0; // route to next effect
203     }
204     Peffnum = 0;
205 }
206 
207 
208 // Cleanup the part
cleanup(void)209 void Part::cleanup(void)
210 {
211     int enablepart = Penabled;
212     Penabled = 0;
213     for (int k = 0; k < POLIPHONY; ++k)
214         KillNotePos(k);
215     memset(partoutl, 0, synth->bufferbytes);
216     memset(partoutr, 0, synth->bufferbytes);
217 
218     for (int nefx = 0; nefx < NUM_PART_EFX; ++nefx)
219         partefx[nefx]->cleanup();
220     for (int n = 0; n < NUM_PART_EFX + 1; ++n)
221     {
222         memset(partfxinputl[n], 0, synth->bufferbytes);
223         memset(partfxinputr[n], 0, synth->bufferbytes);
224 
225     }
226     Penabled = enablepart;
227 }
228 
229 
~Part()230 Part::~Part()
231 {
232     cleanup();
233     for (int n = 0; n < NUM_KIT_ITEMS; ++n)
234     {
235         if (kit[n].adpars)
236             delete kit[n].adpars;
237         if (kit[n].subpars)
238             delete kit[n].subpars;
239         if (kit[n].padpars)
240             delete kit[n].padpars;
241     }
242     fftwf_free(partoutl);
243     fftwf_free(partoutr);
244     for (int nefx = 0; nefx < NUM_PART_EFX; ++nefx)
245     {
246         if (partefx[nefx])
247             delete partefx[nefx];
248     }
249     for (int n = 0; n < NUM_PART_EFX + 1; ++n)
250     {
251         if (partfxinputl[n])
252             fftwf_free(partfxinputl[n]);
253         if (partfxinputr[n])
254             fftwf_free(partfxinputr[n]);
255     }
256     if (ctl)
257         delete ctl;
258 }
259 
260 
setChannelAT(int type,int value)261 void Part::setChannelAT(int type, int value)
262 {
263     if (type & PART::aftertouchType::filterCutoff)
264     {
265         if (value > 0)
266         {
267             if (oldFilterState == -1)
268                 oldFilterState = ctl->filtercutoff.data;
269             float adjust = oldFilterState / 127.0f;
270             if (type & PART::aftertouchType::filterCutoffDown)
271                 ctl->setfiltercutoff(oldFilterState - (value * adjust));
272             else
273                 ctl->setfiltercutoff(oldFilterState + (value * adjust));
274         }
275         else
276         {
277             ctl->setfiltercutoff(oldFilterState);
278             oldFilterState = -1;
279         }
280     }
281 
282     if (type & PART::aftertouchType::filterQ)
283     {
284         if (value > 0)
285         {
286             if (oldFilterQstate == -1)
287                 oldFilterQstate = ctl->filtercutoff.data;
288             float adjust = oldFilterQstate / 127.0f;
289             if (type & PART::aftertouchType::filterQdown)
290                 ctl->setfilterq(oldFilterQstate - (value * adjust));
291             else
292                 ctl->setfilterq(oldFilterQstate + (value * adjust));
293         }
294         else
295         {
296             ctl->setfilterq(oldFilterQstate);
297             oldFilterQstate = -1;
298         }
299     }
300 
301     if (type & PART::aftertouchType::pitchBend)
302     {
303         if (value > 0)
304         {
305             if (oldBendState == -1)
306                 oldBendState = ctl->pitchwheel.data;
307             value *= 64.0f;
308             if (type & PART::aftertouchType::pitchBendDown)
309                 ctl->setpitchwheel(-value);
310             else
311                 ctl->setpitchwheel(value);
312         }
313         else
314         {
315             ctl->setpitchwheel(oldBendState);
316             oldBendState = -1;
317         }
318     }
319 
320     if (type & PART::aftertouchType::volume)
321     {
322         if (value > 0)
323         {
324             //float adjust = 0;
325             if (oldVolumeState == -1)
326             {
327                 oldVolumeState = Pvolume;
328                 oldVolumeAdjust = 127 - oldVolumeState;
329             }
330             //adjust = 127 - oldVolumeState;
331             setVolume(oldVolumeState + (value / 127.0f * oldVolumeAdjust));
332         }
333         else
334         {
335             setVolume(oldVolumeState);
336             oldVolumeState = -1;
337         }
338     }
339 
340     if (type & PART::aftertouchType::modulation)
341     {
342         if (value > 1) // 1 seems to foldback :(
343         {
344             if (oldModulationState == -1)
345                 oldModulationState = ctl->modwheel.data;
346             ctl->setmodwheel(value);
347         }
348         else
349         {
350             ctl->setmodwheel(oldModulationState);
351             oldModulationState = -1;
352         }
353     }
354 }
355 
356 
setKeyAT(int note,int type,int value)357 void Part::setKeyAT(int note, int type, int value)
358 {
359     if (note < Pminkey || note > Pmaxkey)
360         return;
361     for (int i = 0; i < POLIPHONY; ++i)
362     {
363         if (partnote[i].status != KEY_OFF && partnote[i].note == note)
364         {
365             partnote[i].keyATtype = type;
366             partnote[i].keyATvalue = value;
367         }
368     }
369 }
370 
371 
372 // Note On Messages
NoteOn(int note,int velocity,bool renote)373 void Part::NoteOn(int note, int velocity, bool renote)
374 {
375     if (note < Pminkey || note > Pmaxkey)
376         return;
377 
378     // Legato and MonoMem used vars:
379     int posb = POLIPHONY - 1;     // Just a dummy initial value.
380     bool legatomodevalid = false; // true when legato mode is determined applicable.
381     bool doinglegato = false;     // true when we determined we do a legato note.
382     bool ismonofirstnote = false; // (In Mono/Legato) true when we determined
383                                   // no other notes are held down or sustained.*/
384     int lastnotecopy = lastnote;  // Useful after lastnote has been changed.
385 
386     // MonoMem stuff:
387     if (Pkeymode > PART_NORMAL) // if Poly is off
388     {
389         if (!renote)
390             monomemnotes.push_back(note);        // Add note to the list.
391         monomem[note].velocity = velocity;       // Store this note's velocity.
392         if (partnote[lastpos].status != KEY_PLAYING
393             && partnote[lastpos].status != KEY_RELEASED_AND_SUSTAINED)
394         {
395             ismonofirstnote = true; // No other keys are held or sustained.
396         }
397     }
398     else // Poly mode is On, so just make sure the list is empty.
399     {
400         monomemnotes.clear();
401     }
402     lastnote = note;
403     int pos = -1;
404     for (int i = 0; i < POLIPHONY; ++i)
405     {
406         if (partnote[i].status == KEY_OFF)
407         {
408             pos = i;
409             break;
410         }
411     }
412     if (Pkeymode > PART_MONO && !Pdrummode)
413     {
414         // Legato mode is on and applicable.
415         legatomodevalid = true;
416         if (!ismonofirstnote && lastlegatomodevalid)
417         {
418             // At least one other key is held or sustained, and the
419             // previous note was played while in valid legato mode.
420             doinglegato = true; // So we'll do a legato note.
421             pos = lastpos;      // A legato note uses same pos as previous..
422             posb = lastposb;    // .. same goes for posb.
423         }
424         else
425         {
426             // Legato mode is valid, but this is only a first note.
427             for (int i = 0; i < POLIPHONY; ++i)
428                 if (partnote[i].status == KEY_PLAYING
429                     || partnote[i].status == KEY_RELEASED_AND_SUSTAINED)
430                     ReleaseNotePos(i);
431 
432             // Set posb
433             posb = (pos + 1) % POLIPHONY; // We really want it (if the following fails)
434             for (int i = 0; i < POLIPHONY; ++i)
435             {
436                 if (partnote[i].status == KEY_OFF && pos != i)
437                 {
438                     posb = i;
439                     break;
440                 }
441             }
442         }
443         lastposb = posb;// Keep a trace of used posb
444     }
445     else
446     {
447         // Legato mode is either off or non-applicable.
448         if ((Pkeymode & MIDI_NOT_LEGATO) == PART_MONO)
449         {   // if the mode is 'mono' turn off all other notes
450             for (int i = 0; i < POLIPHONY; ++i)
451             {
452                 if (partnote[i].status == KEY_PLAYING)
453                     ReleaseNotePos(i);
454             }
455             ReleaseSustainedKeys();
456         }
457     }
458     lastlegatomodevalid = legatomodevalid;
459 
460     if (pos == -1)
461     {
462         // test
463         synth->getRuntime().Log("Too many notes - notes > poliphony");
464     }
465     else
466     {
467         // start the note
468         partnote[pos].status = KEY_PLAYING;
469         partnote[pos].note = note;
470         partnote[pos].keyATtype = PART::aftertouchType::off;
471         partnote[pos].keyATvalue = 0;
472         if (legatomodevalid)
473         {
474             partnote[posb].status = KEY_PLAYING;
475             partnote[posb].note = note;
476             partnote[posb].keyATtype = PART::aftertouchType::off;
477             partnote[posb].keyATvalue = 0;
478         }
479 
480         // compute the velocity offset
481         float newVel = velocity;
482         if (Pvelrand >= 1)
483         {
484             newVel *= (1 - (synth->numRandom() * Pvelrand * 0.0104f));
485             //std::cout << "Vel rand " << Pvelrand << "  result " << newVel << std::endl;
486         }
487 
488 
489         float vel = velF(newVel / 127.0f, Pvelsns) + (Pveloffs - 64.0f) / 64.0f;
490         vel = (vel < 0.0f) ? 0.0f : vel;
491         vel = (vel > 1.0f) ? 1.0f : vel;
492 
493         // initialise note frequency
494         float notebasefreq;
495         if ((notebasefreq = PnoteMap[PmapOffset + note]) < 0.0f)
496             return; // the key is not mapped
497 
498         // Humanise
499         // cout << "\n" << notebasefreq << endl;
500         if (!Pdrummode && Pfrand >= 1) // otherwise 'off'
501             // this is an approximation to keep the math simple and is
502             // about 1 cent out at 50 cents
503             notebasefreq *= (1.0f + ((synth->numRandom() - 0.5f) * Pfrand * 0.00115f));
504         // cout << notebasefreq << endl;
505 
506         // Portamento
507         if (oldfreq < 1.0f)
508             oldfreq = notebasefreq; // this is only the first note is played
509 
510         // For Mono/Legato: Force Portamento Off on first
511         // notes. That means it is required that the previous note is
512         // still held down or sustained for the Portamento to activate
513         // (that's like Legato).
514         int portamento = 0;
515         if (Pkeymode == PART_NORMAL || !ismonofirstnote)
516         {
517             // I added a third argument to the
518             // ctl->initportamento(...) function to be able
519             // to tell it if we're doing a legato note.
520             portamento = ctl->initportamento(oldfreq, notebasefreq, doinglegato);
521         }
522 
523         if (portamento)
524             ctl->portamento.noteusing = pos;
525         oldfreq = notebasefreq;
526         lastpos = pos; // Keep a trace of used pos.
527         if (doinglegato)
528         {
529             // Do Legato note
530             if (!Pkitmode)
531             {   // "normal mode" legato note
532                 if ((kit[0].Padenabled)
533                     && (partnote[pos].kititem[0].adnote)
534                     && (partnote[posb].kititem[0].adnote))
535                 {
536                     // Set posb to clone state from pos and fade out...
537                     if (!portamento) // ...but only if portamento isn't in effect
538                         partnote[posb].kititem[0].adnote->
539                             legatoFadeOut(*partnote[pos].kititem[0].adnote);
540                     // Then set pos to the new note and fade in.
541                     // This function skips the fade if portamento is active.
542                     partnote[pos].kititem[0].adnote->
543                         legatoFadeIn(notebasefreq, vel, portamento, note);
544                 }
545 
546                 if ((kit[0].Psubenabled)
547                     && (partnote[pos].kititem[0].subnote)
548                     && (partnote[posb].kititem[0].subnote))
549                 {
550                     if (!portamento)
551                         partnote[posb].kititem[0].subnote->
552                             legatoFadeOut(*partnote[pos].kititem[0].subnote);
553                     partnote[pos].kititem[0].subnote->
554                         legatoFadeIn(notebasefreq, vel, portamento, note);
555                 }
556 
557                 if ((kit[0].Ppadenabled)
558                     && (partnote[pos].kititem[0].padnote)
559                     && (partnote[posb].kititem[0].padnote))
560                 {
561                     if (!portamento)
562                         partnote[posb].kititem[0].padnote->
563                             legatoFadeOut(*partnote[pos].kititem[0].padnote);
564                     partnote[pos].kititem[0].padnote->
565                         legatoFadeIn(notebasefreq, vel, portamento, note);
566                 }
567 
568             }
569             else
570             {   // "kit mode" legato note
571                 int ci = 0;
572                 for (int item = 0; item < NUM_KIT_ITEMS; ++item)
573                 {
574                     if (kit[item].Pmuted)
575                         continue;
576                     if ((note < kit[item].Pminkey) || (note > kit[item].Pmaxkey))
577                         continue;
578 
579                     if ((lastnotecopy < kit[item].Pminkey)
580                         || (lastnotecopy > kit[item].Pmaxkey))
581                         continue; // We will not perform legato across 2 key regions.
582 
583                     partnote[pos].kititem[ci].sendtoparteffect =
584                         (kit[item].Psendtoparteffect < NUM_PART_EFX)
585                             ? kit[item].Psendtoparteffect
586                             : NUM_PART_EFX; // if this parameter is 127 for "unprocessed"
587                     partnote[posb].kititem[ci].sendtoparteffect =
588                         (kit[item].Psendtoparteffect < NUM_PART_EFX)
589                             ? kit[item].Psendtoparteffect
590                             : NUM_PART_EFX;
591 
592                     if ((kit[item].Padenabled)
593                         && (kit[item].adpars)
594                         && (partnote[pos].kititem[ci].adnote)
595                         && (partnote[posb].kititem[ci].adnote))
596                     {
597                         // Set posb to clone state from pos and fade out...
598                         if (!portamento) // ...but only if portamento isn't in effect
599                             partnote[posb].kititem[ci].adnote->
600                                 legatoFadeOut(*partnote[pos].kititem[ci].adnote);
601                         // Then set pos to the new note and fade in.
602                         // This function skips the fade if portamento is active.
603                         partnote[pos].kititem[ci].adnote->
604                             legatoFadeIn(notebasefreq, vel, portamento, note);
605                     }
606                     if ((kit[item].Psubenabled)
607                         && (kit[item].subpars)
608                         && (partnote[pos].kititem[ci].subnote)
609                         && (partnote[posb].kititem[ci].subnote))
610                     {
611                         if (!portamento)
612                             partnote[posb].kititem[ci].subnote->
613                                 legatoFadeOut(*partnote[pos].kititem[ci].subnote);
614                         partnote[pos].kititem[ci].subnote->
615                             legatoFadeIn(notebasefreq, vel, portamento, note);
616                     }
617                     if ((kit[item].Ppadenabled)
618                         && (kit[item].padpars)
619                         && (partnote[pos].kititem[ci].padnote)
620                         && (partnote[posb].kititem[ci].padnote))
621                     {
622                         if (!portamento)
623                             partnote[posb].kititem[ci].padnote->
624                                 legatoFadeOut(*partnote[pos].kititem[ci].padnote);
625                         partnote[pos].kititem[ci].padnote->
626                             legatoFadeIn(notebasefreq, vel, portamento, note);
627                     }
628 
629                     if ((kit[item].adpars)
630                         || (kit[item].subpars)
631                         || (kit[item].padpars))
632                     {
633                         ci++;
634                         if (Pkitmode == 2
635                             && (kit[item].Padenabled
636                                 || kit[item].Psubenabled
637                                 || kit[item].Ppadenabled))
638                         break;
639                     }
640                 }
641                 if (ci == 0)
642                 {
643                     // No legato were performed at all, so pretend nothing happened:
644                     monomemnotes.pop_back(); // Remove last note from the list.
645                     lastnote = lastnotecopy; // Set lastnote back to previous value.
646                 }
647             }
648             return; // Ok, Legato note done, return.
649         }
650 
651         partnote[pos].itemsplaying = 0;
652         if (legatomodevalid)
653             partnote[posb].itemsplaying = 0;
654 
655         if (!Pkitmode)
656         {   // init the notes for the "normal mode"
657             partnote[pos].kititem[0].sendtoparteffect = 0;
658             if (kit[0].Padenabled)
659                 partnote[pos].kititem[0].adnote =
660                     new ADnote(kit[0].adpars, ctl, notebasefreq, vel,
661                                 portamento, note, synth);
662             if (kit[0].Psubenabled)
663                 partnote[pos].kititem[0].subnote =
664                     new SUBnote(kit[0].subpars, ctl, notebasefreq, vel,
665                                 portamento, note, synth);
666             if (kit[0].Ppadenabled)
667                 partnote[pos].kititem[0].padnote =
668                     new PADnote(kit[0].padpars, ctl, notebasefreq, vel,
669                                 portamento, note, synth);
670             if (kit[0].Padenabled || kit[0].Psubenabled || kit[0].Ppadenabled)
671                 partnote[pos].itemsplaying++;
672 
673             // Spawn another note (but silent) if legatomodevalid==true
674             if (legatomodevalid)
675             {
676                 partnote[posb].kititem[0].sendtoparteffect = 0;
677                 if (kit[0].Padenabled)
678                     partnote[posb].kititem[0].adnote =
679                         new ADnote(*partnote[pos].kititem[0].adnote);
680                 if (kit[0].Psubenabled)
681                     partnote[posb].kititem[0].subnote =
682                         new SUBnote(*partnote[pos].kititem[0].subnote);
683                 if (kit[0].Ppadenabled)
684                     partnote[posb].kititem[0].padnote =
685                         new PADnote(*partnote[pos].kititem[0].padnote);
686                 if (kit[0].Padenabled || kit[0].Psubenabled || kit[0].Ppadenabled)
687                     partnote[posb].itemsplaying++;
688             }
689         }
690         else
691         { // init the notes for the "kit mode"
692             float truevel = vel; // we need this as cross fade modifies the value
693             for (int item = 0; item < NUM_KIT_ITEMS; ++item)
694             {
695                 if (kit[item].Pmuted)
696                     continue;
697                 if (note < kit[item].Pminkey || note>kit[item].Pmaxkey)
698                     continue;
699 
700 
701                 // cross fade on multi
702                 if (Pkitfade)
703                 {
704                     vel = truevel; // always start with correct value
705                     int range = 0;
706                     int position;
707                     if ((item & 1) == 0 && kit[item + 1].Penabled) // crossfade lower item of pair
708                     {
709                         if (kit[item].Pmaxkey > kit[item + 1].Pminkey && kit[item].Pmaxkey < kit[item + 1].Pmaxkey)
710                         {
711                             if (note >= kit[item + 1].Pminkey)
712                             {
713                                 range = kit[item].Pmaxkey - kit[item + 1].Pminkey;
714                                 position = kit[item].Pmaxkey - note;
715                             }
716                         }
717                         else if (kit[item + 1].Pmaxkey > kit[item].Pminkey && kit[item + 1].Pmaxkey < kit[item].Pmaxkey ) // eliminate equal state
718                         {
719                             if (note <= kit[item + 1].Pmaxkey)
720                             {
721                                 range = kit[item + 1].Pmaxkey - kit[item].Pminkey;
722                                 position = (note - kit[item].Pminkey);
723                             }
724                         }
725                     }
726                     else if ((item & 1) == 1 && kit[item - 1].Penabled) // crossfade upper item of pair
727                     {
728 
729                         if (kit[item - 1].Pmaxkey > kit[item ].Pminkey && kit[item - 1].Pmaxkey < kit[item ].Pmaxkey)
730                         {
731                             if (note <= kit[item - 1].Pmaxkey)
732                             {
733                                 range = kit[item - 1].Pmaxkey - kit[item].Pminkey;
734                                 position = (note - kit[item].Pminkey);
735                             }
736                         }
737                         else if (kit[item].Pmaxkey > kit[item - 1].Pminkey && kit[item].Pmaxkey < kit[item - 1].Pmaxkey) // eliminate equal state
738                         {
739                             if (note >= kit[item - 1].Pminkey)
740                             {
741                                 range = kit[item].Pmaxkey - kit[item - 1].Pminkey;
742                                 position = kit[item].Pmaxkey - note;
743                             }
744                         }
745                     }
746                     if (range)
747                     {
748                         vel = truevel * (float(position) / float(range));
749                         //cout << item << "  " << vel << endl;
750                     }
751                 }
752                 // end of cross fade
753 
754 
755                 int ci = partnote[pos].itemsplaying; // ci=current item
756 
757                 partnote[pos].kititem[ci].sendtoparteffect =
758                     (kit[item].Psendtoparteffect < NUM_PART_EFX)
759                         ? kit[item].Psendtoparteffect
760                         : NUM_PART_EFX; // if this parameter is 127 for "unprocessed"
761 
762                 if (kit[item].adpars && kit[item].Padenabled)
763                 {
764                     partnote[pos].kititem[ci].adnote =
765                         new ADnote(kit[item].adpars, ctl, notebasefreq, vel,
766                                     portamento, note, synth);
767                 }
768                 if (kit[item].subpars && kit[item].Psubenabled)
769                     partnote[pos].kititem[ci].subnote =
770                         new SUBnote(kit[item].subpars, ctl, notebasefreq, vel,
771                                     portamento, note, synth);
772 
773                 if (kit[item].padpars && kit[item].Ppadenabled)
774                     partnote[pos].kititem[ci].padnote =
775                         new PADnote(kit[item].padpars, ctl, notebasefreq, vel,
776                                     portamento, note, synth);
777 
778                 // Spawn another note (but silent) if legatomodevalid==true
779                 if (legatomodevalid)
780                 {
781                     partnote[posb].kititem[ci].sendtoparteffect =
782                         (kit[item].Psendtoparteffect < NUM_PART_EFX)
783                             ? kit[item].Psendtoparteffect
784                             : NUM_PART_EFX; // if this parameter is 127 for "unprocessed"
785 
786                     if (kit[item].adpars && kit[item].Padenabled)
787                     {
788                         partnote[posb].kititem[ci].adnote =
789                             new ADnote(*partnote[pos].kititem[ci].adnote);
790                     }
791                     if (kit[item].subpars && kit[item].Psubenabled)
792                         partnote[posb].kititem[ci].subnote =
793                             new SUBnote(*partnote[pos].kititem[ci].subnote);
794                     if (kit[item].padpars && kit[item].Ppadenabled)
795                         partnote[posb].kititem[ci].padnote =
796                             new PADnote(*partnote[pos].kititem[ci].padnote);
797 
798                     if (kit[item].adpars || kit[item].subpars)
799                         partnote[posb].itemsplaying++;
800                 }
801 
802                 if (kit[item].adpars || kit[item].subpars)
803                 {
804                     partnote[pos].itemsplaying++;
805                     if (Pkitmode == 2 && (kit[item].Padenabled
806                                           || kit[item].Psubenabled
807                                           || kit[item].Ppadenabled))
808                         break;
809                 }
810             }
811         }
812     }
813 
814     // this only release the keys if there is maximum number of keys allowed
815     //setkeylimit(Pkeylimit);
816     if (Pkeymode == PART_NORMAL)
817         enforcekeylimit();
818 }
819 
820 
821 // Note Off Messages
NoteOff(int note)822 void Part::NoteOff(int note) //release the key
823 {
824     // This note is released, so we remove it from the list.
825     monomemnotes.remove(note);
826 
827     bool keep = Pkeymode > PART_NORMAL  && !Pdrummode && !monomemnotes.empty();
828     for (int i = 0; i < POLIPHONY; ++i)
829     {   //first note in, is first out if there are same note multiple times
830         if (partnote[i].status == KEY_PLAYING && partnote[i].note == note)
831         {
832             if (ctl->sustain.sustain)
833                 partnote[i].status = KEY_RELEASED_AND_SUSTAINED;
834             else
835             {   //the sustain pedal is not pushed
836                 if (keep)
837                     MonoMemRenote(); // To play most recent still held note.
838                 else
839                 {
840                     ReleaseNotePos(i);
841                     break; // only release one note.
842                 }
843             }
844         }
845     }
846 }
847 
848 
849 // Controllers
SetController(unsigned int type,int par)850 void Part::SetController(unsigned int type, int par)
851 {
852     switch (type)
853     {
854         case MIDI::CC::pitchWheel:
855             ctl->setpitchwheel(par);
856             break;
857 
858         case MIDI::CC::expression:
859             ctl->setexpression(par);
860             setVolume(Pvolume);
861             break;
862 
863         case MIDI::CC::portamento:
864             ctl->setportamento(par);
865             break;
866 
867         case MIDI::CC::panning:
868             par = 64 + (par - 64) * (ctl->panning.depth / 64.0); // force float during calculation
869             setPan(par);
870             break;
871 
872         case MIDI::CC::filterCutoff:
873             ctl->setfiltercutoff(par);
874             break;
875 
876         case MIDI::CC::filterQ:
877             ctl->setfilterq(par);
878             break;
879 
880         case MIDI::CC::bandwidth:
881             ctl->setbandwidth(par);
882             break;
883 
884         case MIDI::CC::modulation:
885             ctl->setmodwheel(par);
886             break;
887 
888         case MIDI::CC::fmamp:
889             ctl->setfmamp(par);
890             break;
891 
892         case MIDI::CC::volume:
893             if (ctl->volume.receive)
894                 setVolume(par * ctl->volume.volume);
895             break;
896 
897         case MIDI::CC::sustain:
898             ctl->setsustain(par);
899             if (!ctl->sustain.sustain)
900                 ReleaseSustainedKeys();
901             break;
902 
903         case MIDI::CC::allSoundOff:
904             AllNotesOff(); // Panic
905             break;
906 
907         case MIDI::CC::resetAllControllers:
908             ctl->resetall();
909             ReleaseSustainedKeys();
910             setVolume(Pvolume);
911             setPan(Ppanning);
912             Pkeymode &= MIDI_NOT_LEGATO; // clear temporary legato mode
913 
914             for (int item = 0; item < NUM_KIT_ITEMS; ++item)
915             {
916                 if (!kit[item].adpars)
917                     continue;
918                 kit[item].adpars->GlobalPar.Reson->sendcontroller(MIDI::CC::resonanceCenter, 1.0);
919                 kit[item].adpars->GlobalPar.Reson->sendcontroller(MIDI::CC::resonanceBandwidth, 1.0);
920             }
921             // more update to add here if I add controllers
922             break;
923 
924         case MIDI::CC::allNotesOff:
925             ReleaseAllKeys();
926             break;
927 
928         case MIDI::CC::resonanceCenter:
929             ctl->setresonancecenter(par);
930             for (int item = 0; item < NUM_KIT_ITEMS; ++item)
931             {
932                 if (!kit[item].adpars)
933                     continue;
934                 kit[item].adpars->GlobalPar.Reson->sendcontroller(MIDI::CC::resonanceCenter, ctl->resonancecenter.relcenter);
935             }
936             break;
937 
938         case MIDI::CC::resonanceBandwidth:
939             ctl->setresonancebw(par);
940             kit[0].adpars->GlobalPar.Reson->sendcontroller(MIDI::CC::resonanceBandwidth, ctl->resonancebandwidth.relbw);
941             break;
942 
943         case MIDI::CC::channelPressure:
944             setChannelAT(PchannelATchoice, par);
945             break;
946 
947         case MIDI::CC::keyPressure:
948         {
949             int note = par & 0xff;
950             int value = (par >> 8) & 0xff;
951             int type = PkeyATchoice;
952             if (value == 0)
953                 type = 0;
954             setKeyAT(note, type, value);
955             break;
956         }
957     }
958 }
959 
960 
961 // Release the sustained keys
ReleaseSustainedKeys(void)962 void Part::ReleaseSustainedKeys(void)
963 {
964     // Let's call MonoMemRenote() on some conditions:
965     if ((Pkeymode < PART_MONO || Pkeymode > PART_LEGATO) && (!monomemnotes.empty()))
966         if (monomemnotes.back() != lastnote)
967             // Sustain controller manipulation would cause repeated same note
968             // respawn without this check.
969             MonoMemRenote(); // To play most recent still held note.
970 
971     for (int i = 0; i < POLIPHONY; ++i)
972         if (partnote[i].status == KEY_RELEASED_AND_SUSTAINED)
973             ReleaseNotePos(i);
974 }
975 
976 
977 // Release all keys
ReleaseAllKeys(void)978 void Part::ReleaseAllKeys(void)
979 {
980     for (int i = 0; i < POLIPHONY; ++i)
981     {
982         if (partnote[i].status != KEY_RELEASED
983             && partnote[i].status != KEY_OFF) //thanks to Frank Neumann
984             ReleaseNotePos(i);
985     }
986     // Clear legato notes, if any.
987     monomemnotes.clear();
988 }
989 
990 
991 // Call NoteOn(...) with the most recent still held key as new note
992 // (Made for Mono/Legato).
MonoMemRenote(void)993 void Part::MonoMemRenote(void)
994 {
995     unsigned char mmrtempnote = monomemnotes.back(); // Last list element.
996     NoteOn(mmrtempnote, monomem[mmrtempnote].velocity, true);
997 }
998 
999 
1000 // Release note at position
ReleaseNotePos(int pos)1001 void Part::ReleaseNotePos(int pos)
1002 {
1003 
1004     for (int j = 0; j < NUM_KIT_ITEMS; ++j)
1005     {
1006         if (partnote[pos].kititem[j].adnote)
1007             if (partnote[pos].kititem[j].adnote)
1008                 partnote[pos].kititem[j].adnote->releasekey();
1009 
1010         if (partnote[pos].kititem[j].subnote)
1011             if (partnote[pos].kititem[j].subnote)
1012                 partnote[pos].kititem[j].subnote->releasekey();
1013 
1014         if (partnote[pos].kititem[j].padnote)
1015             if (partnote[pos].kititem[j].padnote)
1016                 partnote[pos].kititem[j].padnote->releasekey();
1017     }
1018     partnote[pos].status = KEY_RELEASED;
1019 }
1020 
1021 
1022 // Kill note at position
KillNotePos(int pos)1023 void Part::KillNotePos(int pos)
1024 {
1025     partnote[pos].status = KEY_OFF;
1026     partnote[pos].note = -1;
1027     partnote[pos].time = 0;
1028     partnote[pos].itemsplaying = 0;
1029 
1030     for (int j = 0; j < NUM_KIT_ITEMS; ++j)
1031     {
1032         if (partnote[pos].kititem[j].adnote)
1033         {
1034             delete partnote[pos].kititem[j].adnote;
1035             partnote[pos].kititem[j].adnote = NULL;
1036         }
1037         if (partnote[pos].kititem[j].subnote)
1038         {
1039             delete partnote[pos].kititem[j].subnote;
1040             partnote[pos].kititem[j].subnote = NULL;
1041         }
1042         if (partnote[pos].kititem[j].padnote)
1043         {
1044             delete partnote[pos].kititem[j].padnote;
1045             partnote[pos].kititem[j].padnote = NULL;
1046         }
1047     }
1048     if (pos == ctl->portamento.noteusing)
1049     {
1050         ctl->portamento.noteusing = -1;
1051         ctl->portamento.used = 0;
1052     }
1053 }
1054 
1055 
enforcekeylimit()1056 void Part::enforcekeylimit()
1057 {
1058     // release old keys if the number of notes>keylimit
1059     int notecount = 0;
1060     for (int i = 0; i < POLIPHONY; ++i)
1061     {
1062         if (partnote[i].status == KEY_PLAYING
1063             || partnote[i].status == KEY_RELEASED_AND_SUSTAINED)
1064             notecount++;
1065     }
1066     while (notecount > Pkeylimit)
1067     {   // find out the oldest note
1068         int oldestnotepos = 0;
1069         int maxtime = 0;
1070 
1071         for (int i = 0; i < POLIPHONY; ++i)
1072         {
1073             if ((partnote[i].status == KEY_PLAYING
1074                 || partnote[i].status == KEY_RELEASED_AND_SUSTAINED)
1075                 && partnote[i].time > maxtime)
1076             {
1077                 maxtime = partnote[i].time;
1078                 oldestnotepos = i;
1079             }
1080         }
1081         ReleaseNotePos(oldestnotepos);
1082         --notecount;
1083     }
1084 }
1085 
1086 
1087 // Compute Part samples and store them in the partoutl[] and partoutr[]
ComputePartSmps(void)1088 void Part::ComputePartSmps(void)
1089 {
1090     tmpoutl = synth->getRuntime().genMixl;
1091     tmpoutr = synth->getRuntime().genMixr;
1092     for (int nefx = 0; nefx < NUM_PART_EFX + 1; ++nefx)
1093     {
1094         memset(partfxinputl[nefx], 0, synth->sent_bufferbytes);
1095         memset(partfxinputr[nefx], 0, synth->sent_bufferbytes);
1096     }
1097 
1098     for (int k = 0; k < POLIPHONY; ++k)
1099     {
1100         int oldFilterState;
1101         int oldBendState;
1102         int oldModulationState;
1103         if (partnote[k].status == KEY_OFF)
1104             continue;
1105         int noteplay = 0; // 0 if there is nothing activated
1106         partnote[k].time++;
1107         int keyATtype = partnote[k].keyATtype;
1108         int keyATvalue = partnote[k].keyATvalue;
1109         if (keyATtype & PART::aftertouchType::filterCutoff)
1110         {
1111             oldFilterState = ctl->filtercutoff.data;
1112             float adjust = oldFilterState / 127.0f;
1113             if (keyATtype & PART::aftertouchType::filterCutoffDown)
1114                 ctl->setfiltercutoff(oldFilterState - (keyATvalue * adjust));
1115             else
1116                 ctl->setfiltercutoff(oldFilterState + (keyATvalue * adjust));
1117         }
1118         if (keyATtype & PART::aftertouchType::filterQ)
1119         {
1120             oldFilterQstate = ctl->filterq.data;
1121             float adjust = oldFilterQstate / 127.0f;
1122             if (keyATtype & PART::aftertouchType::filterQdown)
1123                 ctl->setfilterq(oldFilterQstate - (keyATvalue * adjust));
1124             else
1125                 ctl->setfilterq(oldFilterQstate + (keyATvalue * adjust));
1126         }
1127         if (keyATtype & PART::aftertouchType::pitchBend)
1128         {
1129             keyATvalue *= 64.0f;
1130             oldBendState = ctl->pitchwheel.data;
1131             if (keyATtype & PART::aftertouchType::pitchBendDown)
1132                 ctl->setpitchwheel(-keyATvalue);
1133             else
1134                 ctl->setpitchwheel(keyATvalue);
1135         }
1136         if (keyATtype & PART::aftertouchType::modulation)
1137         {
1138             oldModulationState = ctl->modwheel.data;
1139             ctl->setmodwheel(keyATvalue);
1140         }
1141 
1142         // get the sampledata of the note and kill it if it's finished
1143         for (int item = 0; item < partnote[k].itemsplaying; ++item)
1144         {
1145             int sendcurrenttofx = partnote[k].kititem[item].sendtoparteffect;
1146             ADnote *adnote = partnote[k].kititem[item].adnote;
1147             SUBnote *subnote = partnote[k].kititem[item].subnote;
1148             PADnote *padnote = partnote[k].kititem[item].padnote;
1149             // get from the ADnote
1150             if (adnote)
1151             {
1152                 noteplay++;
1153                 if (adnote->ready())
1154                 {
1155                     adnote->noteout(tmpoutl, tmpoutr);
1156                     for (int i = 0; i < synth->sent_buffersize; ++i)
1157                     {   // add the ADnote to part(mix)
1158                         partfxinputl[sendcurrenttofx][i] += tmpoutl[i];
1159                         partfxinputr[sendcurrenttofx][i] += tmpoutr[i];
1160                     }
1161                 }
1162                 if (adnote->finished())
1163                 {
1164                     delete partnote[k].kititem[item].adnote;
1165                     partnote[k].kititem[item].adnote = NULL;
1166                 }
1167             }
1168             // get from the SUBnote
1169             if (subnote)
1170             {
1171                 noteplay++;
1172                 if (subnote->ready())
1173                 {
1174                     subnote->noteout(tmpoutl, tmpoutr);
1175                     for (int i = 0; i < synth->sent_buffersize; ++i)
1176                     {   // add the SUBnote to part(mix)
1177                         partfxinputl[sendcurrenttofx][i] += tmpoutl[i];
1178                         partfxinputr[sendcurrenttofx][i] += tmpoutr[i];
1179                     }
1180                 }
1181                 if (subnote->finished())
1182                 {
1183                     delete partnote[k].kititem[item].subnote;
1184                     partnote[k].kititem[item].subnote = NULL;
1185                 }
1186             }
1187             // get from the PADnote
1188             if (padnote)
1189             {
1190                 noteplay++;
1191                 if (padnote->ready())
1192                 {
1193                     padnote->noteout(tmpoutl, tmpoutr);
1194                     for (int i = 0 ; i < synth->sent_buffersize; ++i)
1195                     {   // add the PADnote to part(mix)
1196                         partfxinputl[sendcurrenttofx][i] += tmpoutl[i];
1197                         partfxinputr[sendcurrenttofx][i] += tmpoutr[i];
1198                     }
1199                 }
1200                 if (padnote->finished())
1201                 {
1202                     delete partnote[k].kititem[item].padnote;
1203                     partnote[k].kititem[item].padnote = NULL;
1204                 }
1205             }
1206         }
1207         // Kill note if there is no synth on that note
1208         if (noteplay == 0)
1209             KillNotePos(k);
1210 
1211         if (keyATtype & PART::aftertouchType::filterCutoff)
1212             ctl->setfiltercutoff(oldFilterState);
1213         if (keyATtype & PART::aftertouchType::filterQ)
1214             ctl->setfilterq(oldFilterQstate);
1215         if (keyATtype & PART::aftertouchType::pitchBend)
1216             ctl->setpitchwheel(oldBendState);
1217         if (keyATtype & PART::aftertouchType::modulation)
1218             ctl->setmodwheel(oldModulationState);
1219     }
1220 
1221     // Apply part's effects and mix them
1222     for (int nefx = 0; nefx < NUM_PART_EFX; ++nefx)
1223     {
1224         if (!Pefxbypass[nefx])
1225         {
1226             partefx[nefx]->out(partfxinputl[nefx], partfxinputr[nefx]);
1227             if (Pefxroute[nefx] == 2)
1228             {
1229                 for (int i = 0; i < synth->sent_buffersize; ++i)
1230                 {
1231                     partfxinputl[nefx + 1][i] += partefx[nefx]->efxoutl[i];
1232                     partfxinputr[nefx + 1][i] += partefx[nefx]->efxoutr[i];
1233                 }
1234             }
1235         }
1236         int routeto = (Pefxroute[nefx] == 0) ? nefx + 1 : NUM_PART_EFX;
1237         for (int i = 0; i < synth->sent_buffersize; ++i)
1238         {
1239             partfxinputl[routeto][i] += partfxinputl[nefx][i];
1240             partfxinputr[routeto][i] += partfxinputr[nefx][i];
1241         }
1242     }
1243     memcpy(partoutl, partfxinputl[NUM_PART_EFX], synth->sent_bufferbytes);
1244     memcpy(partoutr, partfxinputr[NUM_PART_EFX], synth->sent_bufferbytes);
1245 
1246     // Kill All Notes if killallnotes true
1247     if (killallnotes)
1248     {
1249         for (int i = 0; i < synth->sent_buffersize; ++i)
1250         {
1251             float tmp = (synth->sent_buffersize - i) / synth->sent_buffersize_f;
1252             partoutl[i] *= tmp;
1253             partoutr[i] *= tmp;
1254         }
1255         for (int k = 0; k < POLIPHONY; ++k)
1256             KillNotePos(k);
1257         killallnotes = 0;
1258         for (int nefx = 0; nefx < NUM_PART_EFX; ++nefx)
1259             partefx[nefx]->cleanup();
1260     }
1261     ctl->updateportamento();
1262 }
1263 
1264 
1265 // Parameter control
setVolume(float value)1266 void Part::setVolume(float value)
1267 {
1268     Pvolume = value;
1269 }
1270 
1271 
checkVolume(float step)1272 void Part::checkVolume(float step)
1273 {
1274     TransVolume += step;
1275     volume = decibel<-40>(1.0f - TransVolume/96.0f);
1276     if (volume < 0.01015f) // done to get a smooth cutoff at what was - 40dB
1277         volume = 0.0f;
1278 }
1279 
1280 
setDestination(int value)1281 void Part::setDestination(int value)
1282 {
1283     Paudiodest = value;
1284 }
1285 
1286 
setPan(float value)1287 void Part::setPan(float value)
1288 {
1289     Ppanning = value;
1290 }
1291 
1292 
checkPanning(float step,unsigned char panLaw)1293 void Part::checkPanning(float step, unsigned char panLaw)
1294 {
1295     //float t;
1296     TransPanning += step;
1297     float actualPan = ((TransPanning + 1.0f) * (126.0f / 127.0f));
1298      // resolves min value full Left
1299     setAllPan(actualPan, pangainL,pangainR, panLaw);
1300 }
1301 
1302 
1303 // Enable or disable a kit item
setkititemstatus(int kititem,int Penabled_)1304 void Part::setkititemstatus(int kititem, int Penabled_)
1305 {
1306     if (kititem == 0 || kititem >= NUM_KIT_ITEMS)
1307         return; // nonexistent kit item and the first kit item is always enabled
1308     kit[kititem].Penabled = Penabled_;
1309 
1310     bool resetallnotes = false;
1311     if (!Penabled_)
1312     {
1313         kit[kititem].Pmuted = 0;
1314         kit[kititem].Padenabled = 0;
1315         kit[kititem].Psubenabled = 0;
1316         kit[kititem].Ppadenabled = 0;
1317         kit[kititem].Pname.clear();
1318         kit[kititem].Psendtoparteffect = 0;
1319         if (kit[kititem].adpars)
1320         {
1321             delete kit[kititem].adpars;
1322             kit[kititem].adpars = NULL;
1323         }
1324         if (kit[kititem].subpars)
1325         {
1326             delete kit[kititem].subpars;
1327             kit[kititem].subpars = NULL;
1328         }
1329         if (kit[kititem].padpars)
1330         {
1331             delete kit[kititem].padpars;
1332             kit[kititem].padpars = NULL;
1333             resetallnotes = true;
1334         }
1335     }
1336     else
1337     {
1338         if (!kit[kititem].adpars)
1339             kit[kititem].adpars = new ADnoteParameters(fft, synth);
1340         if (!kit[kititem].subpars)
1341             kit[kititem].subpars = new SUBnoteParameters(synth);
1342         if (!kit[kititem].padpars)
1343             kit[kititem].padpars = new PADnoteParameters(fft, synth);
1344     }
1345 
1346     if (resetallnotes)
1347         for (int k = 0; k < POLIPHONY; ++k)
1348             KillNotePos(k);
1349 }
1350 
1351 
add2XMLinstrument(XMLwrapper * xml)1352 void Part::add2XMLinstrument(XMLwrapper *xml)
1353 {
1354     xml->beginbranch("INFO");
1355     xml->addparstr("name", Poriginal);
1356     xml->addparstr("author", info.Pauthor);
1357     xml->addparstr("comments", info.Pcomments);
1358     xml->addpar("type", type_offset[info.Ptype]);
1359     xml->addparstr("file", Pname);
1360     xml->endbranch();
1361     if (Pname == DEFAULT_NAME)
1362         return;
1363 
1364     xml->beginbranch("INSTRUMENT_KIT");
1365     xml->addpar("kit_mode", Pkitmode);
1366     xml->addparbool("kit_crossfade", Pkitfade);
1367     xml->addparbool("drum_mode", Pdrummode);
1368 
1369     for (int i = 0; i < NUM_KIT_ITEMS; ++i)
1370     {
1371         xml->beginbranch("INSTRUMENT_KIT_ITEM",i);
1372         xml->addparbool("enabled", kit[i].Penabled);
1373         if (kit[i].Penabled)
1374         {
1375             xml->addparstr("name", kit[i].Pname.c_str());
1376 
1377             xml->addparbool("muted", kit[i].Pmuted);
1378             xml->addpar("min_key", kit[i].Pminkey);
1379             xml->addpar("max_key", kit[i].Pmaxkey);
1380 
1381             xml->addpar("send_to_instrument_effect", kit[i].Psendtoparteffect);
1382 
1383             xml->addparbool("add_enabled", kit[i].Padenabled);
1384             if (kit[i].Padenabled && kit[i].adpars)
1385             {
1386                 xml->beginbranch("ADD_SYNTH_PARAMETERS");
1387                 kit[i].adpars->add2XML(xml);
1388                 xml->endbranch();
1389             }
1390 
1391             xml->addparbool("sub_enabled", kit[i].Psubenabled);
1392             if (kit[i].Psubenabled && kit[i].subpars)
1393             {
1394                 xml->beginbranch("SUB_SYNTH_PARAMETERS");
1395                 kit[i].subpars->add2XML(xml);
1396                 xml->endbranch();
1397             }
1398 
1399             xml->addparbool("pad_enabled", kit[i].Ppadenabled);
1400             if (kit[i].Ppadenabled && kit[i].padpars)
1401             {
1402                 xml->beginbranch("PAD_SYNTH_PARAMETERS");
1403                 kit[i].padpars->add2XML(xml);
1404                 xml->endbranch();
1405             }
1406         }
1407         xml->endbranch();
1408     }
1409     xml->endbranch();
1410 
1411     xml->beginbranch("INSTRUMENT_EFFECTS");
1412     for (int nefx = 0; nefx < NUM_PART_EFX; ++nefx)
1413     {
1414         xml->beginbranch("INSTRUMENT_EFFECT",nefx);
1415         xml->beginbranch("EFFECT");
1416         partefx[nefx]->add2XML(xml);
1417         xml->endbranch();
1418 
1419         xml->addpar("route", Pefxroute[nefx]);
1420         partefx[nefx]->setdryonly(Pefxroute[nefx] == 2);
1421         xml->addparbool("bypass",Pefxbypass[nefx]);
1422         xml->endbranch();
1423     }
1424     xml->endbranch();
1425 }
1426 
1427 
add2XML(XMLwrapper * xml,bool subset)1428 void Part::add2XML(XMLwrapper *xml, bool subset)
1429 {
1430     // parameters
1431     if (!subset)
1432     {
1433         xml->addparbool("enabled", (Penabled == 1));
1434 
1435         xml->addpar("volume", Pvolume);
1436         xml->addpar("panning", Ppanning);
1437 
1438         xml->addpar("min_key", Pminkey);
1439         xml->addpar("max_key", Pmaxkey);
1440         xml->addpar("key_shift", Pkeyshift);
1441         xml->addpar("rcv_chn", Prcvchn);
1442 
1443         xml->addpar("velocity_sensing", Pvelsns);
1444         xml->addpar("velocity_offset", Pveloffs);
1445     // the following two lines maintain backward compatibility
1446         xml->addparbool("poly_mode", (Pkeymode & MIDI_NOT_LEGATO) == PART_NORMAL);
1447         xml->addpar("legato_mode", (Pkeymode & MIDI_NOT_LEGATO) == PART_LEGATO);
1448         xml->addpar("channel_aftertouch", PchannelATchoice);
1449         xml->addpar("key_aftertouch", PkeyATchoice);
1450         xml->addpar("key_limit", Pkeylimit);
1451         xml->addpar("random_detune", Pfrand);
1452         xml->addpar("random_velocity", Pvelrand);
1453         xml->addpar("destination", Paudiodest);
1454     }
1455     xml->beginbranch("INSTRUMENT");
1456     add2XMLinstrument(xml);
1457     if (subset)
1458     {
1459         xml->addpar("key_mode", Pkeymode & MIDI_NOT_LEGATO);
1460         xml->addpar("channel_aftertouch", PchannelATchoice);
1461         xml->addpar("key_aftertouch", PkeyATchoice);
1462         xml->addpar("random_detune", Pfrand);
1463         xml->addpar("random_velocity", Pvelrand);
1464         xml->addparbool("breath_disable", PbreathControl != 2);
1465     }
1466     xml->endbranch();
1467 
1468     xml->beginbranch("CONTROLLER");
1469     ctl->add2XML(xml);
1470     xml->endbranch();
1471 }
1472 
1473 
saveXML(string filename,bool yoshiFormat)1474 bool Part::saveXML(string filename, bool yoshiFormat)
1475 {
1476     synth->usingYoshiType = yoshiFormat;
1477     synth->getRuntime().xmlType = TOPLEVEL::XML::Instrument;
1478     XMLwrapper *xml = new XMLwrapper(synth, yoshiFormat);
1479     if (!xml)
1480     {
1481         synth->getRuntime().Log("Part: saveXML failed to instantiate new XMLwrapper");
1482         return false;
1483     }
1484     if (Pname < "!") // this shouldn't be possible
1485         Pname = UNTITLED;
1486     else if (Poriginal.empty() && Pname != UNTITLED)
1487         Poriginal = Pname;
1488 
1489     if (yoshiFormat)
1490     {
1491         filename = setExtension(filename, EXTEN::yoshInst);
1492         add2XML(xml, yoshiFormat);
1493     }
1494     else
1495     {
1496         filename = setExtension(filename, EXTEN::zynInst);
1497         xml->beginbranch("INSTRUMENT");
1498         add2XMLinstrument(xml);
1499         xml->endbranch();
1500     }
1501     bool result = xml->saveXMLfile(filename);
1502     delete xml;
1503     return result;
1504 }
1505 
1506 
loadXMLinstrument(string filename)1507 int Part::loadXMLinstrument(string filename)
1508 {
1509     bool hasYoshi = true;
1510     filename = setExtension(filename, EXTEN::yoshInst);
1511     if (!isRegularFile(filename))
1512     {
1513         hasYoshi = false;
1514         filename = setExtension(filename, EXTEN::zynInst);
1515     }
1516 
1517     XMLwrapper *xml = new XMLwrapper(synth, hasYoshi);
1518     if (!xml)
1519     {
1520         synth->getRuntime().Log("Part: loadXML failed to instantiate new XMLwrapper");
1521         return 0;
1522     }
1523     if (!xml->loadXMLfile(filename))
1524     {
1525         synth->getRuntime().Log("Part: loadXML failed to load instrument file " + filename);
1526         delete xml;
1527         return 0;
1528     }
1529     if (xml->enterbranch("INSTRUMENT") == 0)
1530     {
1531         synth->getRuntime().Log(filename + " is not an instrument file");
1532         delete xml;
1533         return 0;
1534     }
1535     defaultsinstrument();
1536     PyoshiType = xml->information.yoshiType;
1537     Pname = findLeafName(filename);
1538     int chk = findSplitPoint(Pname);
1539     if (chk > 0)
1540         Pname = Pname.substr(chk + 1, Pname.size() - chk - 1);
1541     getfromXMLinstrument(xml);
1542 
1543     if (hasYoshi)
1544     {
1545         Pkeymode = xml->getpar("key_mode", Pkeymode, PART_NORMAL, MIDI_LEGATO);
1546         Pfrand = xml->getpar127("random_detune", Pfrand);
1547         if (Pfrand > 50)
1548             Pfrand = 50;
1549         Pvelrand = xml->getpar127("random_velocity", Pvelrand);
1550         if (Pvelrand > 50)
1551             Pvelrand = 50;
1552         PbreathControl = xml->getparbool("breath_disable", PbreathControl);
1553         if (PbreathControl)
1554             PbreathControl = 255; // impossible value
1555         else
1556             PbreathControl = 2;
1557     }
1558     xml->exitbranch();
1559     if (xml->enterbranch("CONTROLLER"))
1560     {
1561         ctl->getfromXML(xml);
1562         xml->exitbranch();
1563     }
1564     xml->exitbranch();
1565     delete xml;
1566     return 1;
1567 }
1568 
1569 
getfromXMLinstrument(XMLwrapper * xml)1570 void Part::getfromXMLinstrument(XMLwrapper *xml)
1571 {
1572     string tempname;
1573     if (xml->enterbranch("INFO"))
1574     {
1575         Poriginal = xml->getparstr("name");
1576         // counting type numbers but checking the *contents* of type_offset()
1577         info.Pauthor = func::formatTextLines(xml->getparstr("author"), 54);
1578         info.Pcomments = func::formatTextLines(xml->getparstr("comments"), 54);
1579         int found = xml->getpar("type", 0, -20, 255); // should cover all!
1580         int type = 0;
1581         int offset = 0;
1582         while (offset != 255 && offset != found)
1583         {
1584             ++type;
1585             offset = type_offset[type];
1586         }
1587         if (offset == 255)
1588             type = 0; // undefined
1589         info.Ptype = type;
1590 
1591         // The following is surprisingly complex!
1592         if (Pname.empty())
1593             Pname = xml->getparstr("file");
1594 
1595         if (Poriginal == DEFAULT_NAME) // it's an old one
1596             Poriginal = "";
1597         if (Pname.empty()) // it's an older state file
1598         {
1599             if (Poriginal. empty())
1600                 Pname = DEFAULT_NAME;
1601             else
1602                 Pname = Poriginal;
1603         }
1604         else if (Poriginal.empty()) // it's one from zyn
1605             Poriginal = Pname;
1606         if (Pname.empty() && Poriginal == UNTITLED)
1607         {
1608             Pname = UNTITLED;
1609             Poriginal = "";
1610         }
1611         xml->exitbranch();
1612     }
1613 
1614     if (!xml->enterbranch("INSTRUMENT_KIT"))
1615     {
1616         defaultsinstrument();
1617         return;
1618     }
1619     else
1620     {
1621         Pkitmode = xml->getpar127("kit_mode", Pkitmode);
1622         Pkitfade = xml->getparbool("kit_crossfade", Pkitfade);
1623         Pdrummode = xml->getparbool("drum_mode", Pdrummode);
1624 
1625         for (int i = 0; i < NUM_KIT_ITEMS; ++i)
1626         {
1627             if (!xml->enterbranch("INSTRUMENT_KIT_ITEM", i))
1628                 continue;
1629             setkititemstatus(i, xml->getparbool("enabled", kit[i].Penabled));
1630             if (!kit[i].Penabled)
1631             {
1632                 xml->exitbranch();
1633                 continue;
1634             }
1635             kit[i].Pname = xml->getparstr("name");
1636             kit[i].Pmuted = xml->getparbool("muted", kit[i].Pmuted);
1637             kit[i].Pminkey = xml->getpar127("min_key", kit[i].Pminkey);
1638             kit[i].Pmaxkey = xml->getpar127("max_key", kit[i].Pmaxkey);
1639             kit[i].Psendtoparteffect = xml->getpar127("send_to_instrument_effect",
1640                                                       kit[i].Psendtoparteffect);
1641             kit[i].Padenabled = xml->getparbool("add_enabled", kit[i].Padenabled);
1642             if (xml->enterbranch("ADD_SYNTH_PARAMETERS"))
1643             {
1644                 kit[i].adpars->getfromXML(xml);
1645                 xml->exitbranch();
1646             }
1647             kit[i].Psubenabled = xml->getparbool("sub_enabled", kit[i].Psubenabled);
1648             if (xml->enterbranch("SUB_SYNTH_PARAMETERS"))
1649             {
1650                 kit[i].subpars->getfromXML(xml);
1651                 xml->exitbranch();
1652             }
1653             kit[i].Ppadenabled = xml->getparbool("pad_enabled", kit[i].Ppadenabled);
1654             if (xml->enterbranch("PAD_SYNTH_PARAMETERS"))
1655             {
1656                 busy = true;
1657                 kit[i].padpars->getfromXML(xml);
1658                 busy = false;
1659                 xml->exitbranch();
1660             }
1661             xml->exitbranch();
1662         }
1663         xml->exitbranch();
1664     }
1665     if (xml->enterbranch("INSTRUMENT_EFFECTS"))
1666     {
1667         for (int nefx = 0; nefx < NUM_PART_EFX; ++nefx)
1668         {
1669             if (!xml->enterbranch("INSTRUMENT_EFFECT", nefx))
1670                 continue;
1671             if (xml->enterbranch("EFFECT"))
1672             {
1673                 partefx[nefx]->getfromXML(xml);
1674                 xml->exitbranch();
1675             }
1676             Pefxroute[nefx] = xml->getpar("route", Pefxroute[nefx], 0, NUM_PART_EFX);
1677             partefx[nefx]->setdryonly(Pefxroute[nefx] == 2);
1678             Pefxbypass[nefx] = xml->getparbool("bypass", Pefxbypass[nefx]);
1679             xml->exitbranch();
1680         }
1681         xml->exitbranch();
1682     }
1683 }
1684 
1685 
getfromXML(XMLwrapper * xml)1686 void Part::getfromXML(XMLwrapper *xml)
1687 {
1688     Penabled = (xml->getparbool("enabled", Penabled) == 1);
1689 
1690     setVolume(xml->getpar127("volume", Pvolume));
1691     setPan(xml->getpar127("panning", Ppanning));
1692 
1693     Pminkey = xml->getpar127("min_key", Pminkey);
1694     Pmaxkey = xml->getpar127("max_key", Pmaxkey);
1695     Pkeyshift = xml->getpar("key_shift", Pkeyshift, MIN_KEY_SHIFT + 64, MAX_KEY_SHIFT + 64);
1696 
1697     Prcvchn = xml->getpar127("rcv_chn", Prcvchn);
1698 
1699     Pvelsns = xml->getpar127("velocity_sensing", Pvelsns);
1700     Pveloffs = xml->getpar127("velocity_offset", Pveloffs);
1701 
1702     bool Ppolymode = 1;
1703     bool Plegatomode = 0;
1704     Ppolymode = xml->getparbool("poly_mode", Ppolymode);
1705     Plegatomode = xml->getparbool("legato_mode", Plegatomode); // older versions
1706     if (!Plegatomode)
1707         Plegatomode = xml->getpar127("legato_mode", Plegatomode);
1708     if (Plegatomode) // these lines are for backward compatibility
1709         Pkeymode = PART_LEGATO;
1710     else if (Ppolymode)
1711         Pkeymode = PART_NORMAL;
1712     else
1713         Pkeymode = PART_MONO;
1714 
1715     PchannelATchoice = xml->getpar("channel_aftertouch", PchannelATchoice, 0, 255);
1716     PkeyATchoice = xml->getpar("key_aftertouch", PkeyATchoice, 0, 255);
1717 
1718     Pkeylimit = xml->getpar127("key_limit", Pkeylimit);
1719     if (Pkeylimit < 1 || Pkeylimit > POLIPHONY)
1720         Pkeylimit = POLIPHONY;
1721     Pfrand = xml->getpar127("random_detune", Pfrand);
1722     if (Pfrand > 50)
1723         Pfrand = 50;
1724     Pvelrand = xml->getpar127("random_velocity", Pvelrand);
1725     if (Pvelrand > 50)
1726         Pvelrand = 50;
1727     setDestination(xml->getpar127("destination", Paudiodest));
1728 
1729     if (xml->enterbranch("INSTRUMENT"))
1730     {
1731         Pname = ""; // clear out any previous name
1732         getfromXMLinstrument(xml);
1733         xml->exitbranch();
1734     }
1735     if (xml->enterbranch("CONTROLLER"))
1736     {
1737         ctl->getfromXML(xml);
1738         xml->exitbranch();
1739     }
1740 }
1741 
1742 
getLimits(CommandBlock * getData)1743 float Part::getLimits(CommandBlock *getData)
1744 {
1745     float value = getData->data.value;
1746     int request = int(getData->data.type & TOPLEVEL::type::Default);
1747     int control = getData->data.control;
1748     int npart = getData->data.part;
1749 
1750     unsigned char type = 0;
1751 
1752     // part defaults
1753     int min = 0;
1754     float def = 64;
1755     int max = 127;
1756     type |= TOPLEVEL::type::Integer;
1757     unsigned char learnable = TOPLEVEL::type::Learnable;
1758     //cout << "part limits" << endl;
1759     if ((control >= PART::control::volumeRange && control <= PART::control::receivePortamento) || control == PART::control::resetAllControllers)
1760         return ctl->getLimits(getData);
1761 
1762     switch (control)
1763     {
1764         case PART::control::enable:
1765             if (npart == 0)
1766                 def = 1;
1767             else
1768                 def = 0;
1769             max = 1;
1770             break;
1771         case PART::control::enableAdd:
1772             type |= learnable;
1773             if (npart == 0)
1774                 def = 1;
1775             else
1776                 def = 0;
1777             max = 1;
1778             break;
1779         case PART::control::enableSub:
1780         case PART::control::enablePad:
1781             type |= learnable;
1782             def = 0;
1783             max = 1;
1784             break;
1785         case PART::control::enableKitLine:
1786             def = 0;
1787             max = 1;
1788             break;
1789 
1790         case PART::control::volume:
1791             type &= ~TOPLEVEL::type::Integer;
1792             type |= learnable;
1793             def = 96;
1794             break;
1795 
1796         case PART::control::velocitySense:
1797         case PART::control::velocityOffset:
1798             type |= learnable;
1799             break;
1800 
1801         case PART::control::panning:
1802             type &= ~TOPLEVEL::type::Integer;
1803             type |= learnable;
1804             break;
1805 
1806         case PART::control::midiChannel:
1807             min = 0;
1808             def = 0;
1809             max = 16; // disabled
1810             break;
1811 
1812         case PART::control::channelATset:
1813         case PART::control::keyATset:
1814             min = 0;
1815             def = 0;
1816             max = PART::aftertouchType::modulation * 2;
1817             break;
1818 
1819         case PART::control::keyMode:
1820             def = 0;
1821             max = 2;
1822             break;
1823 
1824         case PART::control::portamento:
1825             type |= learnable;
1826             def = 0;
1827             max = 1;
1828             break;
1829 
1830         case PART::control::kitItemMute:
1831             type |= learnable;
1832             def = 0;
1833             max = 1;
1834             break;
1835 
1836         case PART::control::minNote:
1837             def = 0;
1838             break;
1839 
1840         case PART::control::maxNote:
1841             def = 127;
1842             break;
1843 
1844         case PART::control::minToLastKey:
1845         case PART::control::maxToLastKey:
1846         case PART::control::resetMinMaxKey:
1847             def = 0;
1848             max = 0;
1849             break;
1850         case PART::control::kitEffectNum:
1851             def = 1; // may be local to GUI
1852             max = 3;
1853             break;
1854 
1855         case PART::control::maxNotes:
1856             def = 20;
1857             max = POLIPHONY;
1858             break;
1859 
1860         case PART::control::keyShift:
1861             min = -36;
1862             def = 0;
1863             max = 36;
1864             break;
1865 
1866         case PART::control::partToSystemEffect1:
1867         case PART::control::partToSystemEffect2:
1868         case PART::control::partToSystemEffect3:
1869         case PART::control::partToSystemEffect4:
1870             type |= learnable;
1871             def = 0;
1872             break;
1873 
1874         case PART::control::humanise:
1875             type |= learnable;
1876             def = 0;
1877             max = 50;
1878             break;
1879 
1880         case PART::control::humanvelocity:
1881             type |= learnable;
1882             def = 0;
1883             max = 50;
1884             break;
1885 
1886         case PART::control::drumMode:
1887             def = 0;
1888             max = 1;
1889             break;
1890 
1891         case PART::control::kitMode:
1892             def = 0;
1893             max = 3;
1894             break;
1895         case PART::control::effectNumber:
1896             max = 2;
1897             def = 0;
1898             break;
1899         case PART::control::effectType:
1900             def = 0;
1901             break;
1902         case PART::control::effectDestination:
1903             max = 2;
1904             def = 0;
1905             break;
1906         case PART::control::effectBypass:
1907             type |= learnable;
1908             max = 1;
1909             def = 0;
1910             break;
1911 
1912         case PART::control::audioDestination:
1913             min = 1;
1914             def = 1;
1915             max = 3;
1916             break;
1917 
1918         case PART::control::midiModWheel:
1919             type |= learnable;
1920             break;
1921         case PART::control::midiBreath: // not done yet
1922             break;
1923         case PART::control::midiExpression:
1924             type |= learnable;
1925             def = 127;
1926             break;
1927         case PART::control::midiSustain: // not done yet
1928             break;
1929         case PART::control::midiPortamento: // not done yet
1930             break;
1931         case PART::control::midiFilterQ:
1932             type |= learnable;
1933             break;
1934         case PART::control::midiFilterCutoff:
1935             type |= learnable;
1936             break;
1937         case PART::control::midiBandwidth:
1938             type |= learnable;
1939             break;
1940 
1941 // the following have no limits but are here so they don't
1942 // create errors when tested.
1943         case PART::control::instrumentCopyright:
1944             break;
1945         case PART::control::instrumentComments:
1946             break;
1947         case PART::control::instrumentName:
1948             break;
1949             case PART::control::instrumentType:
1950             break;
1951         case PART::control::defaultInstrumentCopyright:
1952             break;
1953 
1954         case 255: // number of parts
1955             min = 16;
1956             def = 16;
1957             max = 64;
1958             break;
1959 
1960         default:
1961             type |= TOPLEVEL::type::Error;
1962             break;
1963     }
1964     getData->data.type = type;
1965     if (type & TOPLEVEL::type::Error)
1966         return 1;
1967 
1968     switch (request)
1969     {
1970         case TOPLEVEL::type::Adjust:
1971             if (value < min)
1972                 value = min;
1973             else if (value > max)
1974                 value = max;
1975         break;
1976         case TOPLEVEL::type::Minimum:
1977             value = min;
1978             break;
1979         case TOPLEVEL::type::Maximum:
1980             value = max;
1981             break;
1982         case TOPLEVEL::type::Default:
1983             value = def;
1984             break;
1985     }
1986     return value;
1987 }
1988