1 /*
2     Data2Text.cpp - conversion of commandBlock entries to text
3 
4     Copyright 2021 Will Godfrey
5 
6     This file is part of yoshimi, which is free software: you can redistribute
7     it and/or modify it under the terms of the GNU Library General Public
8     License as published by the Free Software Foundation; either version 2 of
9     the License, or (at your option) any later version.
10 
11     yoshimi is distributed in the hope that it will be useful, but WITHOUT ANY
12     WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13     FOR A PARTICULAR PURPOSE.   See the GNU General Public License (version 2 or
14     later) for more details.
15 
16     You should have received a copy of the GNU General Public License along with
17     yoshimi; if not, write to the Free Software Foundation, Inc., 51 Franklin
18     Street, Fifth Floor, Boston, MA  02110-1301, USA.
19 
20  */
21 
22 #include "Interface/Data2Text.h"
23 #include "Interface/TextLists.h"
24 #include "Misc/SynthEngine.h"
25 #include "Misc/TextMsgBuffer.h"
26 #include "Misc/FormatFuncs.h"
27 #include "Misc/NumericFuncs.h"
28 
29 using std::string;
30 using std::to_string;
31 
32 using func::string2int;
33 using func::stringCaps;
34 using func::bpm2text;
35 
DataText()36 DataText::DataText() :
37     synth(nullptr),
38     showValue(false),
39     yesno(false),
40     textMsgBuffer(TextMsgBuffer::instance())
41 {
42 }
43 
withValue(std::string resolved,unsigned char type,bool showValue,bool addValue,float value)44 std::string DataText::withValue(std::string resolved, unsigned char type, bool showValue, bool addValue, float value)
45 {
46     if (!addValue)
47         return resolved;
48 
49     if (yesno)
50     {
51         if (value)
52             resolved += " - on";
53         else
54             resolved += " - off";
55         return resolved;
56     }
57 
58     if (showValue)
59     {
60         resolved += " Value ";
61         if (type & TOPLEVEL::type::Integer)
62             resolved += to_string(lrint(value));
63         else
64             resolved += to_string(value);
65         return resolved;
66     }
67 
68     return resolved;
69 }
70 
resolveAll(SynthEngine * _synth,CommandBlock * getData,bool addValue)71 string DataText::resolveAll(SynthEngine *_synth, CommandBlock *getData, bool addValue)
72 {
73     SynthEngine *synth = _synth;
74     float value = getData->data.value;
75     unsigned char type = getData->data.type;
76     unsigned char control = getData->data.control;
77     unsigned char npart = getData->data.part;
78     unsigned char kititem = getData->data.kit;
79     unsigned char engine = getData->data.engine;
80     unsigned char insert = getData->data.insert;
81 
82     if (control == TOPLEVEL::control::textMessage) // special case for simple messages
83     {
84         synth->getRuntime().Log(textMsgBuffer.fetch(lrint(value)));
85         synth->getRuntime().finishedCLI = true;
86         return "";
87     }
88 
89     showValue = true;
90     yesno = false;
91     string commandName;
92 
93    // this is unique and placed here to avoid Xruns
94     if (npart == TOPLEVEL::section::scales && control <= SCALES::control::retune)
95         synth->setAllPartMaps();
96 
97     if (npart == TOPLEVEL::section::vector)
98     {
99         commandName = resolveVector(getData, addValue);
100         return withValue(commandName, type, showValue, addValue, value);
101     }
102     if (npart == TOPLEVEL::section::scales)
103     {
104         commandName = resolveMicrotonal(getData, addValue);
105         return withValue(commandName, type, showValue, addValue, value);
106     }
107     if (npart == TOPLEVEL::section::config)
108     {
109         commandName = resolveConfig(getData, addValue);
110         return withValue(commandName, type, showValue, addValue, value);
111     }
112     if (npart == TOPLEVEL::section::bank)
113     {
114         commandName = resolveBank(getData, addValue);
115         return withValue(commandName, type, showValue, addValue, value);
116     }
117     if (npart == TOPLEVEL::section::midiIn || npart == TOPLEVEL::section::main)
118     {
119         commandName = resolveMain(getData, addValue);
120         return withValue(commandName, type, showValue, addValue, value);
121     }
122 
123     if (npart == TOPLEVEL::section::systemEffects || npart == TOPLEVEL::section::insertEffects)
124     {
125         commandName = resolveEffects(getData, addValue);
126         return withValue(commandName, type, showValue, addValue, value);
127     }
128 
129     if ((kititem >= EFFECT::type::none && kititem <= EFFECT::type::dynFilter) || (control >= PART::control::effectNumber && control <= PART::control::effectBypass && kititem == UNUSED))
130     {
131         commandName = resolveEffects(getData, addValue);
132         return withValue(commandName, type, showValue, addValue, value);
133     }
134 
135     if (npart >= NUM_MIDI_PARTS)
136         return "Invalid part " + to_string(int(npart) + 1);
137 
138     if (kititem >= NUM_KIT_ITEMS && kititem < UNUSED)
139         return "Invalid kit " + to_string(int(kititem) + 1);
140 
141     if (kititem == UNUSED || insert == TOPLEVEL::insert::kitGroup)
142     {
143         commandName = resolvePart(getData, addValue);
144         return withValue(commandName, type, showValue, addValue, value);
145     }
146 
147     if (engine == PART::engine::padSynth)
148     {
149         switch(insert)
150         {
151             case UNUSED:
152                 commandName = resolvePad(getData, addValue);
153                 break;
154             case TOPLEVEL::insert::LFOgroup:
155                 commandName = resolveLFO(getData, addValue);
156                 break;
157             case TOPLEVEL::insert::filterGroup:
158                 commandName = resolveFilter(getData, addValue);
159                 break;
160             case TOPLEVEL::insert::envelopeGroup:
161                 commandName = resolveEnvelope(getData, addValue);
162                 break;
163             case TOPLEVEL::insert::envelopePoints:
164                 commandName = resolveEnvelope(getData, addValue);
165                 break;
166             case TOPLEVEL::insert::envelopePointChange:
167                 commandName = resolveEnvelope(getData, addValue);
168                 break;
169             case TOPLEVEL::insert::oscillatorGroup:
170                 commandName = resolveOscillator(getData, addValue);
171                 break;
172             case TOPLEVEL::insert::harmonicAmplitude:
173                 commandName = resolveOscillator(getData, addValue);
174                 break;
175             case TOPLEVEL::insert::harmonicPhaseBandwidth:
176                 commandName = resolveOscillator(getData, addValue);
177                 break;
178             case TOPLEVEL::insert::resonanceGroup:
179                 commandName = resolveResonance(getData, addValue);
180                 break;
181             case TOPLEVEL::insert::resonanceGraphInsert:
182                 commandName = resolveResonance(getData, addValue);
183                 break;
184         }
185         return withValue(commandName, type, showValue, addValue, value);
186     }
187 
188     if (engine == PART::engine::subSynth)
189     {
190         switch (insert)
191         {
192             case UNUSED:
193                 commandName = resolveSub(getData, addValue);
194                 break;
195             case TOPLEVEL::insert::harmonicAmplitude:
196                 commandName = resolveSub(getData, addValue);
197                 break;
198             case TOPLEVEL::insert::harmonicPhaseBandwidth:
199                 commandName = resolveSub(getData, addValue);
200                 break;
201             case TOPLEVEL::insert::filterGroup:
202                 commandName = resolveFilter(getData, addValue);
203                 break;
204             case TOPLEVEL::insert::envelopeGroup:
205                 commandName = resolveEnvelope(getData, addValue);
206                 break;
207             case TOPLEVEL::insert::envelopePoints:
208                 commandName = resolveEnvelope(getData, addValue);
209                 break;
210             case TOPLEVEL::insert::envelopePointChange:
211                 commandName = resolveEnvelope(getData, addValue);
212                 break;
213         }
214         return withValue(commandName, type, showValue, addValue, value);
215     }
216 
217     if (engine >= PART::engine::addVoice1)
218     {
219         switch (insert)
220         {
221             case UNUSED:
222                 commandName = resolveAddVoice(getData, addValue);
223                 break;
224             case TOPLEVEL::insert::LFOgroup:
225                 commandName = resolveLFO(getData, addValue);
226                 break;
227             case TOPLEVEL::insert::filterGroup:
228                 commandName = resolveFilter(getData, addValue);
229                 break;
230             case TOPLEVEL::insert::envelopeGroup:
231                 commandName = resolveEnvelope(getData, addValue);
232                 break;
233             case TOPLEVEL::insert::envelopePoints:
234                 commandName = resolveEnvelope(getData, addValue);
235                 break;
236             case TOPLEVEL::insert::envelopePointChange:
237                 commandName = resolveEnvelope(getData, addValue);
238                 break;
239             case TOPLEVEL::insert::oscillatorGroup:
240                 commandName = resolveOscillator(getData, addValue);
241                 break;
242             case TOPLEVEL::insert::harmonicAmplitude:
243                 commandName = resolveOscillator(getData, addValue);
244                 break;
245             case TOPLEVEL::insert::harmonicPhaseBandwidth:
246                 commandName = resolveOscillator(getData, addValue);
247                 break;
248         }
249         return withValue(commandName, type, showValue, addValue, value);
250     }
251 
252     if (engine == PART::engine::addSynth)
253     {
254         switch (insert)
255         {
256             case UNUSED:
257                 commandName = resolveAdd(getData, addValue);
258                 break;
259             case TOPLEVEL::insert::LFOgroup:
260                 commandName = resolveLFO(getData, addValue);
261                 break;
262             case TOPLEVEL::insert::filterGroup:
263                 commandName = resolveFilter(getData, addValue);
264                 break;
265             case TOPLEVEL::insert::envelopeGroup:
266                 commandName = resolveEnvelope(getData, addValue);
267                 break;
268             case TOPLEVEL::insert::envelopePoints:
269                 commandName = resolveEnvelope(getData, addValue);
270                 break;
271             case TOPLEVEL::insert::envelopePointChange:
272                 commandName = resolveEnvelope(getData, addValue);
273                 break;
274             case TOPLEVEL::insert::resonanceGroup:
275                 commandName = resolveResonance(getData, addValue);
276                 break;
277             case TOPLEVEL::insert::resonanceGraphInsert:
278                 commandName = resolveResonance(getData, addValue);
279                 break;
280         }
281     }
282     return withValue(commandName, type, showValue, addValue, value);
283 }
284 
285 
resolveVector(CommandBlock * getData,bool addValue)286 string DataText::resolveVector(CommandBlock *getData, bool addValue)
287 {
288     int value_int = lrint(getData->data.value);
289     unsigned char control = getData->data.control;
290     unsigned int chan = getData->data.insert;
291 
292     bool isFeature = false;
293     string contstr = "";
294     switch (control)
295     {
296         case VECTOR::control::name:
297             showValue = false;
298             contstr = "Name " + textMsgBuffer.fetch(value_int);
299             break;
300 
301         case VECTOR::control::Xcontroller:
302             contstr = "Controller";
303             break;
304         case VECTOR::control::XleftInstrument:
305             contstr = "Left Instrument";
306             break;
307         case VECTOR::control::XrightInstrument:
308             contstr = "Right Instrument";
309             break;
310         case VECTOR::control::Xfeature0:
311         case VECTOR::control::Yfeature0:
312             contstr = "Volume";
313             isFeature = true;
314             break;
315         case VECTOR::control::Xfeature1:
316         case VECTOR::control::Yfeature1:
317             contstr = "Panning";
318             isFeature = true;
319             break;
320         case VECTOR::control::Xfeature2:
321         case VECTOR::control::Yfeature2:
322             contstr = "Filter";
323             isFeature = true;
324             break;
325         case VECTOR::control::Xfeature3:
326         case VECTOR::control::Yfeature3:
327             contstr = "Modulation";
328             isFeature = true;
329             break;
330 
331         case VECTOR::control::Ycontroller:
332             contstr = "Controller";
333             break;
334         case VECTOR::control::YupInstrument:
335             contstr = "Up Instrument";
336             break;
337         case VECTOR::control::YdownInstrument:
338             contstr = "Down Instrument";
339             break;
340 
341         case VECTOR::control::erase:
342             showValue = false;
343             if (chan > NUM_MIDI_CHANNELS)
344                 contstr = "all channels";
345             else
346                 contstr = "chan " + to_string(chan + 1);
347             if (addValue)
348                 return("Vector cleared on " + contstr);
349             break;
350 
351         case 127:
352             break;
353 
354         default:
355             showValue = false;
356             contstr = "Unrecognised";
357     }
358 
359     if (control == VECTOR::control::undefined)
360     {
361         showValue = false;
362         return("Vector " + contstr + " set to " + to_string(chan + 1));
363     }
364     string name = "Vector Chan " + to_string(chan + 1) + " ";
365     if (control == 127)
366         name += " all ";
367     else if (control >= VECTOR::control::Ycontroller)
368         name += "Y ";
369     else if (control >= VECTOR::control::Xcontroller)
370         name += "X ";
371 
372     if (isFeature)
373     {
374         showValue = false;
375         switch (value_int)
376         {
377             case 0:
378                 contstr += " off";
379                 break;
380             case 1:
381                 contstr += " on";
382                 break;
383             case 2:
384                 contstr += " reverse";
385                 break;
386         }
387     }
388 
389     return (name + contstr);
390 }
391 
392 
resolveMicrotonal(CommandBlock * getData,bool addValue)393 string DataText::resolveMicrotonal(CommandBlock *getData, bool addValue)
394 {
395     int value = getData->data.value;
396     unsigned char control = getData->data.control;
397     unsigned char parameter = getData->data.parameter;
398 
399     string contstr = "";
400     switch (control)
401     {
402         case SCALES::control::refFrequency:
403             if (addValue)
404             {
405                 if (parameter >= 21 && parameter <= 84)
406                     contstr = noteslist[parameter - 21];
407                 else
408                     contstr = to_string(parameter);
409             }
410             contstr += " Frequency";
411             break;
412         case SCALES::control::refNote:
413             showValue = false;
414             contstr = "Ref note ";
415             if (addValue)
416             {
417                 contstr += to_string(value);
418                 if (value >= 21 && value <= 84)
419                     contstr = contstr + " " + noteslist[value - 21];
420             }
421             break;
422         case SCALES::control::invertScale:
423             contstr = "Invert Keys";
424             yesno = true;
425             break;
426         case SCALES::control::invertedScaleCenter:
427             contstr = "Key Center";
428             break;
429         case SCALES::control::scaleShift:
430             contstr = "Scale Shift";
431             break;
432         case SCALES::control::enableMicrotonal:
433             contstr = "Enable Microtonal";
434             yesno = true;
435             break;
436 
437         case SCALES::control::enableKeyboardMap:
438             contstr = "Enable Keyboard Mapping";
439             yesno = true;
440             break;
441         case SCALES::control::lowKey:
442             contstr = "Keyboard First Note";
443             break;
444         case SCALES::control::middleKey:
445             contstr = "Keyboard Middle Note";
446             break;
447         case SCALES::control::highKey:
448             contstr = "Keyboard Last Note";
449             break;
450 
451         case SCALES::control::tuning:
452             contstr = "Tuning ";
453             showValue = false;
454             break;
455         case SCALES::control::keyboardMap:
456             contstr = "Keymap ";
457             showValue = false;
458             break;
459         case SCALES::control::importScl:
460             contstr = "Tuning Import ";
461             showValue = false;
462             break;
463         case SCALES::control::importKbm:
464             contstr = "Keymap Import ";
465             showValue = false;
466             break;
467 
468         case SCALES::control::name:
469             contstr = "Name: ";
470             if (addValue)
471                 contstr += textMsgBuffer.fetch(lrint(value));
472             showValue = false;
473             break;
474         case SCALES::control::comment:
475             contstr = "Description: ";
476             if (addValue)
477                 contstr += textMsgBuffer.fetch(lrint(value));
478             showValue = false;
479             break;
480         case SCALES::control::retune:
481             contstr = "Retune";
482             showValue = false;
483             break;
484 
485         case SCALES::control::clearAll:
486             contstr = "Clear all settings";
487             showValue = false;
488             break;
489 
490         default:
491             showValue = false;
492             contstr = "Unrecognised";
493 
494     }
495 
496     if (value < 1 &&
497         (
498            control == SCALES::control::tuning
499         || control == SCALES::control::keyboardMap
500         || control == SCALES::control::importScl
501         || control == SCALES::control::importKbm
502         ))
503     { // errors :@(
504         switch (value)
505         {
506             case 0:
507                 contstr += "Empty entry";
508                 break;
509             case -1:
510                 contstr += "Value too small";
511                 break;
512             case -2:
513                 contstr += "Invalid entry";
514                 break;
515             case -3:
516                 contstr += "File not found";
517                 break;
518             case -4:
519                 contstr += "Empty file";
520                 break;
521             case -5:
522                 contstr += "Short or corrupted file";
523                 break;
524             case -6:
525                 if (control == SCALES::control::tuning || control == SCALES::control::importScl)
526                     contstr += "Invalid octave size";
527                 else
528                     contstr += "Invalid keymap size";
529                 break;
530             case -7:
531                 contstr += "Invalid note number";
532                 break;
533             case -8:
534                 contstr += "Out of range";
535                 break;
536         }
537     }
538 
539     return ("Scales " + contstr);
540 }
541 
resolveConfig(CommandBlock * getData,bool addValue)542 string DataText::resolveConfig(CommandBlock *getData, bool addValue)
543 {
544     float value = getData->data.value;
545     unsigned char control = getData->data.control;
546     unsigned char kititem = getData->data.kit;
547     unsigned char parameter = getData->data.parameter;
548     bool write = getData->data.type & TOPLEVEL::type::Write;
549     int value_int = lrint(value);
550     bool value_bool = _SYS_::F2B(value);
551 
552     string contstr = "";
553     switch (control)
554     {
555         case CONFIG::control::oscillatorSize:
556             contstr = "AddSynth oscillator size";
557             break;
558         case CONFIG::control::bufferSize:
559             contstr = "Internal buffer size";
560             break;
561         case CONFIG::control::padSynthInterpolation:
562             contstr = "PadSynth interpolation ";
563             if (addValue)
564             {
565                 if (value_bool)
566                     contstr += "cubic";
567                 else
568                     contstr += "linear";
569             }
570             showValue = false;
571             break;
572         case CONFIG::control::virtualKeyboardLayout:
573             contstr = "Virtual keyboard ";
574             if (addValue)
575             {
576                 switch (value_int)
577                 {
578                     case 0:
579                         contstr += "QWERTY";
580                         break;
581                     case 1:
582                         contstr += "Dvorak";
583                         break;
584                     case 2:
585                         contstr += "QWERTZ";
586                         break;
587                     case 3:
588                         contstr += "AZERTY";
589                         break;
590                 }
591             }
592             showValue = false;
593             break;
594         case CONFIG::control::XMLcompressionLevel:
595             contstr = "XML compression";
596             break;
597         case CONFIG::control::reportsDestination:
598             contstr = "Reports to ";
599             if (addValue)
600             {
601                 if (value_bool)
602                     contstr += "Console window";
603                 else
604                     contstr += "stdout";
605             }
606             showValue = false;
607             break;
608         case CONFIG::control::logTextSize:
609             contstr = "Console text size";
610             break;
611         case CONFIG::control::savedInstrumentFormat:
612             contstr = "Saved instrument format ";
613             if (addValue)
614             {
615                 switch (value_int)
616                 {
617                     case 1:
618                         contstr += "Legacy (.xiz)";
619                         break;
620                     case 2:
621                         contstr += "Yoshimi (.xiy)";
622                         break;
623                     case 3:
624                         contstr += "Both";
625                         break;
626                 }
627             }
628             showValue = false;
629             break;
630         case CONFIG::control::defaultStateStart:
631             contstr += "Autoload default state";
632             yesno = true;
633             break;
634         case CONFIG::control::enableSinglePath:
635             contstr += "Single master instance";
636             yesno = true;
637             break;
638         case CONFIG::control::hideNonFatalErrors:
639             contstr += "Hide non-fatal errors";
640             yesno = true;
641             break;
642         case CONFIG::control::showSplash:
643             contstr += "Show splash screen";
644             yesno = true;
645             break;
646         case CONFIG::control::logInstrumentLoadTimes:
647             contstr += "Log instrument load times";
648             yesno = true;
649             break;
650         case CONFIG::control::logXMLheaders:
651             contstr += "Log XML headers";
652             yesno = true;
653             break;
654         case CONFIG::control::saveAllXMLdata:
655             contstr += "Save ALL XML data";
656             yesno = true;
657             break;
658         case CONFIG::control::enableGUI:
659             contstr += "Enable GUI";
660             yesno = true;
661             break;
662         case CONFIG::control::enableCLI:
663             contstr += "Enable CLI";
664             yesno = true;
665             break;
666         case CONFIG::control::enableAutoInstance:
667             contstr += "Enable auto instance";
668             yesno = true;
669             break;
670         case CONFIG::control::enableHighlight:
671             contstr += "Enable bank highlight";
672             yesno = true;
673             break;
674         case CONFIG::control::historyLock:
675         {
676             string group[] = {"Instrument", "Patchset", "Scale", "State", "Vector", "Mlearn"};
677             contstr = "History lock " + group[kititem];
678             yesno = true;
679             break;
680         }
681         case CONFIG::control::exposeStatus:
682             showValue = false;
683             contstr += "Show CLI context ";
684             if (addValue)
685             {
686                 switch (value_int)
687                 {
688                     case 0:
689                         contstr += "off";
690                         break;
691                     case 1:
692                         contstr += "on";
693                         break;
694                     case 2:
695                         contstr += "prompt";
696                         break;
697                     default:
698                         contstr += "unrecognised";
699                         break;
700                 }
701             }
702             break;
703 
704         case CONFIG::control::readAudio:
705             contstr += "Audio Destination ";
706             if (addValue)
707             {
708                 switch (value_int)
709                 {
710                     case 1:
711                         contstr += "JACK";
712                         break;
713                     case 2:
714                         contstr += "ALSA";
715                         break;
716                     default:
717                         contstr += "None";
718                 }
719                 showValue = false;
720             }
721             break;
722 
723         case CONFIG::control::readMIDI:
724             contstr += "MIDI Source ";
725             if (addValue)
726             {
727                 switch (value_int)
728                 {
729                     case 1:
730                         contstr += "JACK";
731                         break;
732                     case 2:
733                         contstr += "ALSA";
734                         break;
735                     default:
736                         contstr += "None";
737                 }
738                 showValue = false;
739             }
740             break;
741         case CONFIG::control::jackMidiSource:
742             contstr += "JACK MIDI source: ";
743             if (addValue)
744                 contstr += textMsgBuffer.fetch(value_int);
745             showValue = false;
746             break;
747         case CONFIG::control::jackPreferredMidi:
748             contstr += "Start with JACK MIDI";
749             yesno = true;
750             break;
751         case CONFIG::control::jackServer:
752             contstr += "JACK server: ";
753             if (addValue)
754                 contstr += textMsgBuffer.fetch(value_int);
755             showValue = false;
756             break;
757         case CONFIG::control::jackPreferredAudio:
758             contstr += "Start with JACK audio";
759             yesno = true;
760             break;
761         case CONFIG::control::jackAutoConnectAudio:
762             contstr += "Auto-connect to JACK server";
763             yesno = true;
764             break;
765 
766         case CONFIG::control::alsaMidiSource:
767             contstr += "ALSA MIDI source: ";
768             if (addValue)
769                 contstr += textMsgBuffer.fetch(value_int);
770             showValue = false;
771             break;
772         case CONFIG::control::alsaPreferredMidi:
773             contstr += "Start with ALSA MIDI";
774             yesno = true;
775             break;
776         case CONFIG::control::alsaMidiType:
777             contstr += "ALSA MIDI connection type ";
778             switch (value_int)
779             {
780                 case 0:
781                     contstr += "Fixed";
782                     break;
783                 case 1:
784                     contstr += "Search";
785                     break;
786                 default:
787                     contstr += "External";
788                     break;
789             }
790             showValue = false;
791             break;
792         case CONFIG::control::alsaAudioDevice:
793             contstr += "ALSA audio device: ";
794             if (addValue)
795                 contstr += textMsgBuffer.fetch(value_int);
796             showValue = false;
797             break;
798         case CONFIG::control::alsaPreferredAudio:
799             contstr += "Start with ALSA audio";
800             yesno = true;
801             break;
802         case CONFIG::control::alsaSampleRate:
803             contstr += "ALSA sample rate: ";
804             if (addValue)
805             {
806                 switch (value_int)
807                 { // this is a hack :(
808                     case 0:
809                     case 192000:
810                         contstr += "0 (192000)";
811                         break;
812                     case 1:
813                     case 96000:
814                         contstr += "1 (96000)";
815                         break;
816                     case 2:
817                     case 48000:
818                         contstr += "2 (48000)";
819                         break;
820                     case 3:
821                     case 44100:
822                         contstr += "3 (44100)";
823                         break;
824                 }
825             }
826             showValue = false;
827             break;
828 
829         case CONFIG::control::addPresetRootDir:
830             contstr += "Preset root add";
831             if (addValue)
832                 contstr += textMsgBuffer.fetch(value_int);
833             showValue = false;
834             break;
835         case CONFIG::control::removePresetRootDir:
836             contstr += "Preset root unlinked ";
837             if (addValue)
838                 contstr += textMsgBuffer.fetch(value_int);
839             showValue = false;
840             break;
841         case CONFIG::control::currentPresetRoot:
842             contstr += "Current preset root ";
843             if (addValue)
844                 contstr += textMsgBuffer.fetch(value_int);
845             showValue = false;
846             break;
847 
848         case CONFIG::control::bankRootCC:
849             contstr += "Bank root CC ";
850             if (addValue)
851             {
852                 if (parameter != UNUSED)
853                     contstr += textMsgBuffer.fetch(parameter);
854                 else
855                 {
856                     switch (value_int)
857                     {
858                         case 0:
859                             contstr += "MSB";
860                             break;
861                         case 32:
862                             contstr += "LSB";
863                             break;
864                         default:
865                             contstr += "OFF";
866                     }
867                 }
868             }
869             showValue = false;
870             break;
871 
872         case CONFIG::control::bankCC:
873             contstr += "Bank CC ";
874             if (addValue)
875             {
876                 if (parameter != UNUSED)
877                     contstr += textMsgBuffer.fetch(parameter);
878                 else
879                 {
880                     switch (value_int)
881                     {
882                         case 0:
883                             contstr += "MSB";
884                             break;
885                         case 32:
886                             contstr += "LSB";
887                             break;
888                         default:
889                             contstr += "OFF";
890                     }
891                 }
892             }
893             showValue = false;
894             break;
895         case CONFIG::control::enableProgramChange:
896             contstr += "Enable program change";
897             yesno = true;
898             break;
899         case CONFIG::control::extendedProgramChangeCC:
900             if (addValue)
901             {
902             if (parameter != UNUSED)
903             {
904                 string test = textMsgBuffer.fetch(parameter);
905                 contstr += ("Extended program change CC in use by "  + test);
906             }
907             else if (value == 128)
908             {
909                 contstr += ("Extended program change disabled");
910             }
911             else
912                 contstr += "CC for extended program change ";
913             contstr += to_string(value_int);
914             }
915             showValue = false;
916             break;
917         case CONFIG::control::ignoreResetAllCCs:
918             contstr += "Ignore 'reset all CCs'";
919             yesno = true;
920             break;
921         case CONFIG::control::logIncomingCCs:
922             contstr += "Log incoming CCs";
923             yesno = true;
924             break;
925         case CONFIG::control::showLearnEditor:
926             contstr += "Auto-open GUI MIDI-learn editor";
927             yesno = true;
928             break;
929 
930         case CONFIG::control::enableNRPNs:
931             contstr += "Enable NRPN";
932             yesno = true;
933             break;
934 
935         case CONFIG::control::saveCurrentConfig:
936         {
937             string name = textMsgBuffer.fetch(value_int);
938             if (write)
939                 contstr += ("save" + name);
940             else
941             {
942                 contstr += "Condition - ";
943                  if (synth->getRuntime().configChanged)
944                      contstr += "DIRTY";
945                  else
946                      contstr += "CLEAN";
947             }
948             showValue = false;
949             break;
950         }
951         default:
952             contstr = "Unrecognised";
953             break;
954     }
955 
956     return ("Config " + contstr);
957 }
958 
959 
resolveBank(CommandBlock * getData,bool)960 string DataText::resolveBank(CommandBlock *getData, bool)
961 {
962     int value_int = lrint(getData->data.value);
963     int control = getData->data.control;
964     int kititem = getData->data.kit;
965     int engine = getData->data.engine;
966     int insert = getData->data.insert;
967     string name = textMsgBuffer.fetch(value_int);
968     string contstr = "";
969     showValue = false;
970     switch(control)
971     {
972         case BANK::control::renameInstrument:
973         {
974             contstr = "Instrument Rename" + name;
975             break;
976         }
977         case BANK::control::saveInstrument:
978         {
979             contstr = "Instrument Save to slot " + name;
980             break;
981         }
982         case BANK::control::deleteInstrument:
983             contstr = "Instrument delete" + name;
984             break;
985         case BANK::control::selectFirstInstrumentToSwap:
986             contstr = "Set Instrument ID " + to_string(insert + 1) + "  Bank ID " + to_string(kititem) + "  Root ID " + to_string(engine) + " for swap";
987             break;
988         case BANK::control::selectSecondInstrumentAndSwap:
989             if (name == "")
990                 name = "ped with Instrument ID " + to_string(insert + 1) + "  Bank ID " + to_string(kititem) + "  Root ID " + to_string(engine);
991             contstr = "Swap" + name;
992             break;
993 
994         case BANK::control::selectBank:
995             contstr = name;
996             break;
997         case BANK::control::renameBank:
998             contstr = name;
999             break;
1000         case BANK::control::createBank:
1001             contstr = name;
1002             break;
1003         case BANK::control::findBankSize:
1004             if (value_int == UNUSED)
1005                 contstr = " Bank " + to_string(kititem) + " does not exist.";
1006             else if (value_int == 0)
1007                 contstr = " Bank " + to_string(kititem) + " is empty.";
1008             else
1009                 contstr = " Bank " + to_string(kititem) + " contains " + to_string(value_int) + " instruments";
1010             showValue = false;
1011             break;
1012 
1013         case BANK::control::selectFirstBankToSwap:
1014             contstr = "Set Bank ID " + to_string(kititem) + "  Root ID " + to_string(engine) + " for swap";
1015             break;
1016         case BANK::control::selectSecondBankAndSwap:
1017             if (name == "")
1018                 name = "ped with Bank ID " + to_string(kititem) + "  Root ID " + to_string(engine);
1019             contstr = "Swap" + name;
1020             break;
1021         case BANK::control::selectRoot:
1022             contstr = name;
1023             break;
1024 
1025         case BANK::control::changeRootId:
1026             contstr = "Root ID changed " + to_string(engine) + " > " + to_string(value_int);
1027             break;
1028 
1029         case BANK::control::addNamedRoot:
1030             if (value_int == UNUSED)
1031                 contstr = name;
1032             else if (kititem != UNUSED)
1033                 contstr = "Created Bank Root " + name;
1034             else
1035                 contstr = "Link Bank Root " + name;
1036             break;
1037 
1038         case BANK::control::deselectRoot:
1039             if (value_int == UNUSED)
1040                 contstr = "Bank Root " + to_string(kititem) + " does not exist";
1041             else
1042                 contstr = "Unlinked Bank Root " + to_string(kititem);
1043             showValue = false;
1044             break;
1045 
1046         default:
1047             contstr = "Unrecognised";
1048             break;
1049     }
1050     return ("Bank " + contstr);
1051 }
1052 
resolveMain(CommandBlock * getData,bool addValue)1053 string DataText::resolveMain(CommandBlock *getData, bool addValue)
1054 {
1055     float value = getData->data.value;
1056     int value_int = lrint(value);
1057 
1058     unsigned char control = getData->data.control;
1059     unsigned char kititem = getData->data.kit;
1060     unsigned char engine = getData->data.engine;
1061 
1062     string name;
1063     string contstr = "";
1064     if (getData->data.part == TOPLEVEL::section::midiIn)
1065     {
1066         switch (control)
1067         {
1068             case MIDI::control::noteOn:
1069                 showValue = false;
1070                 break;
1071             case MIDI::control::noteOff:
1072                 showValue = false;
1073                 break;
1074             case MIDI::control::controller:
1075                 contstr = "CC " + to_string(int(engine)) + " ";
1076                 break;
1077             case MIDI::control::bankChange:
1078                 showValue = false;
1079                 contstr = textMsgBuffer.fetch(value_int);
1080                 break;
1081         }
1082         return contstr;
1083     }
1084 
1085     switch (control)
1086     {
1087         case MAIN::control::volume:
1088             contstr = "Volume";
1089             break;
1090 
1091         case MAIN::control::partNumber:
1092             showValue = false;
1093             contstr = "Part Number " + to_string(value_int + 1);
1094             break;
1095         case MAIN::control::availableParts:
1096             contstr = "Available Parts";
1097             break;
1098 
1099         case MAIN::control::panLawType:
1100             contstr = "Panning Law ";
1101             if (addValue)
1102             {
1103                 switch (value_int)
1104                 {
1105                     case MAIN::panningType::cut:
1106                         contstr += "cut";
1107                         break;
1108                     case MAIN::panningType::normal:
1109                         contstr += "default";
1110                         break;
1111                     case MAIN::panningType::boost:
1112                         contstr += "boost";
1113                         break;
1114                     default:
1115                         contstr += "unrecognised";
1116                 }
1117             }
1118             showValue = false;
1119             break;
1120         case MAIN::control::detune:
1121             contstr = "Detune";
1122             break;
1123         case MAIN::control::keyShift:
1124             contstr = "Key Shift";
1125             break;
1126         case MAIN::control::mono:
1127             contstr = "Master Mono/Stereo ";
1128             showValue = false;
1129             if (addValue)
1130             {
1131                 if (value_int)
1132                     contstr += "Mono";
1133                 else
1134                     contstr += "Stereo";
1135             }
1136             break;
1137 
1138         case MAIN::control::reseed:
1139             showValue = false;
1140             contstr += "reseeded to " + to_string(value_int);
1141             break;
1142 
1143         case MAIN::control::soloType:
1144             showValue = false;
1145             contstr = "Chan 'solo' Switch ";
1146             if (addValue)
1147             {
1148                 switch (value_int)
1149                 {
1150                     case MIDI::SoloType::Disabled:
1151                         contstr += "Off";
1152                         break;
1153                     case MIDI::SoloType::Row:
1154                         contstr += "Row";
1155                         break;
1156                     case MIDI::SoloType::Column:
1157                         contstr += "Column";
1158                         break;
1159                     case MIDI::SoloType::Loop:
1160                         contstr += "Loop";
1161                         break;
1162                     case MIDI::SoloType::TwoWay:
1163                         contstr += "Twoway";
1164                         break;
1165                     case MIDI::SoloType::Channel:
1166                         contstr += "Channel";
1167                         break;
1168                 }
1169             }
1170             break;
1171         case MAIN::control::soloCC:
1172             showValue = false;
1173             contstr = "Chan 'solo' Switch CC ";
1174             if (addValue)
1175             {
1176                 if (value_int > 127)
1177                     contstr += "undefined - set type first";
1178                 else
1179                     contstr += to_string(value_int);
1180             }
1181             break;
1182 
1183         case MAIN::control::exportBank:
1184             showValue = false;
1185             contstr = "Bank Export" + textMsgBuffer.fetch(value_int);
1186             break;
1187 
1188         case MAIN::control::importBank:
1189             showValue = false;
1190             contstr = "Bank Import" + textMsgBuffer.fetch(value_int);
1191             break;
1192 
1193         case MAIN::control::deleteBank:
1194             showValue = false;
1195             contstr = "Bank delete" + textMsgBuffer.fetch(value_int);
1196             break;
1197 
1198         case MAIN::control::loadInstrumentFromBank:
1199             showValue = false;
1200             contstr = "Part " + to_string (int(kititem + 1)) + " load" + textMsgBuffer.fetch(value_int);
1201             break;
1202         case MAIN::control::loadInstrumentByName:
1203             showValue = false;
1204             contstr = "Part " + to_string (int(kititem + 1)) + " load" + textMsgBuffer.fetch(value_int);
1205             break;
1206 
1207         case MAIN::control::saveNamedInstrument:
1208             showValue = false;
1209             contstr = "Instrument Save" + textMsgBuffer.fetch(value_int);
1210             break;
1211 
1212         case MAIN::control::loadNamedPatchset:
1213             showValue = false;
1214             contstr = "Patchset Load" + textMsgBuffer.fetch(value_int);
1215             break;
1216 
1217         case MAIN::control::saveNamedPatchset:
1218             showValue = false;
1219             contstr = "Patchset Save" + textMsgBuffer.fetch(value_int);
1220             break;
1221 
1222         case MAIN::control::loadNamedVector:
1223             showValue = false;
1224             name = textMsgBuffer.fetch(value_int);
1225             contstr = "Vector Load" + name;
1226             break;
1227 
1228         case MAIN::control::saveNamedVector:
1229             showValue = false;
1230             name = textMsgBuffer.fetch(value_int);
1231             contstr = "Vector Save" + name;
1232             break;
1233 
1234         case MAIN::control::loadNamedScale:
1235             showValue = false;
1236             name = textMsgBuffer.fetch(value_int);
1237             contstr = "Scale Load" + name;
1238             break;
1239 
1240         case MAIN::control::saveNamedScale:
1241             showValue = false;
1242             name = textMsgBuffer.fetch(value_int);
1243             contstr = "Scale Save" + name;
1244             break;
1245 
1246         case MAIN::control::loadNamedState:
1247             showValue = false;
1248             name = textMsgBuffer.fetch(value_int);
1249             contstr = "State Load" + name;
1250             break;
1251 
1252         case MAIN::control::saveNamedState:
1253             showValue = false;
1254             contstr = "State Save" + textMsgBuffer.fetch(value_int);
1255             break;
1256 
1257         case MAIN::control::loadFileFromList:
1258             showValue = false;
1259             contstr = "Load Recent" + textMsgBuffer.fetch(value_int);
1260             break;
1261 
1262         case MAIN::control::defaultPart:
1263             showValue = false;
1264             contstr = "Part " + to_string(value_int + 1) + " cleared";
1265             break;
1266 
1267         case MAIN::control::exportPadSynthSamples:
1268             showValue = false;
1269             contstr = "PadSynth Samples Save" + textMsgBuffer.fetch(value_int);
1270             break;
1271 
1272         case MAIN::control::masterReset:
1273             showValue = false;
1274             contstr = "Reset All";
1275             break;
1276         case MAIN::control::masterResetAndMlearn:
1277             showValue = false;
1278             contstr = "Reset All including MIDI-learn";
1279             break;
1280 
1281         case MAIN::control::openManual:
1282             showValue = false;
1283             contstr = "Open manual in reader " + textMsgBuffer.fetch(value_int);
1284             break;
1285 
1286         case MAIN::control::startInstance:
1287             showValue = false;
1288             contstr = "Start new instance " + to_string(value_int);
1289             break;
1290         case MAIN::control::stopInstance:
1291             showValue = false;
1292             contstr = "Close instance - " + textMsgBuffer.fetch(value_int);
1293             break;
1294 
1295         case MAIN::control::stopSound:
1296             showValue = false;
1297             contstr = "Sound Stopped";
1298             break;
1299 
1300         case MAIN::control::readPartPeak:
1301             showValue = false;
1302             if (engine == 1)
1303                 contstr = "Part R";
1304             else
1305                 contstr = "Part L";
1306             contstr += to_string(int(kititem));
1307             if (value < 0.0f)
1308                 contstr += " silent ";
1309             contstr += (" peak level " + to_string(value));
1310             break;
1311 
1312         case MAIN::control::readMainLRpeak:
1313             showValue = false;
1314             if (kititem == 1)
1315                 contstr = "Right";
1316             else
1317                 contstr = "Left";
1318             contstr += (" peak level " + to_string(value));
1319             break;
1320 
1321         case MAIN::control::readMainLRrms:
1322             showValue = false;
1323             if (kititem == 1)
1324                 contstr = "Right";
1325             else
1326                 contstr = "Left";
1327             contstr += (" RMS level " + to_string(value));
1328             break;
1329 
1330         default:
1331             showValue = false;
1332             contstr = "Unrecognised";
1333     }
1334 
1335     return ("Main " + contstr);
1336 }
1337 
1338 
resolveAftertouch(bool type,int value,bool addValue)1339 string DataText::resolveAftertouch(bool type, int value, bool addValue)
1340 {
1341     std::string contstr;
1342     if (type)
1343         contstr = "ChannelAT";
1344     else
1345         contstr = "KeyAT";
1346     if (!addValue)
1347         return contstr;
1348 
1349     if (value == PART::aftertouchType::off)
1350         contstr += " Off";
1351     else
1352     {
1353         if (value & PART::aftertouchType::filterCutoff)
1354         {
1355             contstr += "\n Filter Cutoff";
1356             if (value & PART::aftertouchType::filterCutoffDown)
1357                 contstr += " Down";
1358         }
1359         if (value & PART::aftertouchType::filterQ)
1360         {
1361             contstr += "\n Peak";
1362             if (value & PART::aftertouchType::filterQdown)
1363                 contstr += " Down";
1364         }
1365         if (value & PART::aftertouchType::pitchBend)
1366         {
1367             contstr += "\n Bend";
1368             if (value & PART::aftertouchType::pitchBendDown)
1369                 contstr += " Down";
1370         }
1371         if (value & PART::aftertouchType::volume)
1372             contstr += "\n Volume";
1373         if (value & PART::aftertouchType::modulation)
1374             contstr += "\n Modulation";
1375     }
1376     return contstr;
1377 }
1378 
1379 
resolvePart(CommandBlock * getData,bool addValue)1380 string DataText::resolvePart(CommandBlock *getData, bool addValue)
1381 {
1382     float value = getData->data.value;
1383     unsigned char control = getData->data.control;
1384     unsigned char npart = getData->data.part;
1385     unsigned char kititem = getData->data.kit;
1386     unsigned char engine = getData->data.engine;
1387     unsigned char insert = getData->data.insert;
1388     unsigned char parameter = getData->data.parameter;
1389     unsigned char effNum = engine;
1390 
1391     bool kitType = (insert == TOPLEVEL::insert::kitGroup);
1392     int value_int = lrint(value);
1393     bool value_bool = _SYS_::F2B(value);
1394 
1395     if (control == UNUSED)
1396         return "Number of parts";
1397 
1398     string kitnum;
1399     if (kitType)
1400         kitnum = " Kit " + to_string(kititem + 1) + " ";
1401     else
1402         kitnum = " ";
1403 
1404     string group = "";
1405 
1406     if (kititem != UNUSED)
1407     {
1408         switch (engine)
1409         {
1410             case PART::engine::addSynth:
1411                 group = "AddSynth ";
1412                 break;
1413             case PART::engine::subSynth:
1414                 group = "SubSynth ";
1415                 break;
1416             case PART::engine::padSynth:
1417                 group = "PadSynth ";
1418                 break;
1419         }
1420     }
1421 
1422     string contstr = "";
1423     switch (control)
1424     {
1425         case PART::control::enable:
1426             contstr += " Enable";
1427             yesno = true;
1428             break;
1429         case PART::control::enableAdd:
1430             contstr += "AddSynth Enable";
1431             yesno = true;
1432             break;
1433         case PART::control::enableSub:
1434             contstr += "SubSynth Enable";
1435             yesno = true;
1436             break;
1437         case PART::control::enablePad:
1438             contstr += "PadSynth Enable";
1439             yesno = true;
1440             break;
1441         case PART::control::enableKitLine:
1442             contstr += " Enable";
1443             yesno = true;
1444             break;
1445 
1446         case PART::control::volume:
1447             contstr = "Volume";
1448             break;
1449         case PART::control::velocitySense:
1450             contstr = "Velocity Sense";
1451             break;
1452         case PART::control::panning:
1453             contstr = "Panning";
1454             break;
1455         case PART::control::velocityOffset:
1456             contstr = "Velocity Offset";
1457             break;
1458         case PART::control::midiChannel:
1459             showValue = false;
1460             contstr = "Midi CH ";
1461             if (addValue)
1462             {
1463                 contstr += to_string(value_int + 1);
1464                 if (value_int >= NUM_MIDI_CHANNELS * 2)
1465                     contstr += " Midi ignored";
1466                 else if (value_int >= NUM_MIDI_CHANNELS)
1467                     contstr = contstr + " Note off only from CH " + to_string(value_int + 1 - NUM_MIDI_CHANNELS);
1468             }
1469             break;
1470         case PART::control::keyMode:
1471             showValue = false;
1472             contstr = "Mode ";
1473             if (addValue)
1474             {
1475                 if (value_int == 0)
1476                     contstr += "Poly";
1477                 else if (value_int == 1)
1478                     contstr += "Mono";
1479                 else if (value_int >= 2)
1480                     contstr += "Legato";
1481             }
1482             break;
1483         case PART::control::channelATset:
1484             showValue = false;
1485             contstr = resolveAftertouch(true, value_int, addValue);
1486             if (parameter != UNUSED)
1487                 contstr = contstr + "\n" + resolveAftertouch(false, parameter, addValue);
1488             break;
1489         case PART::control::keyATset:
1490             showValue = false;
1491             contstr = resolveAftertouch(false, value_int, addValue);
1492             if (parameter != UNUSED)
1493                 contstr = contstr + "\n" + resolveAftertouch(true, parameter, addValue);
1494             break;
1495         case PART::control::portamento:
1496             contstr = "Portamento Enable";
1497             yesno = true;
1498             break;
1499 
1500         case PART::control::kitItemMute:
1501             if (kitType)
1502             {
1503                 contstr = "Mute";
1504                 yesno = true;
1505             }
1506             break;
1507 
1508         case PART::control::minNote:
1509             contstr = "Min Note";
1510             break;
1511         case PART::control::maxNote:
1512             contstr = "Max Note";
1513             break;
1514         case PART::control::minToLastKey: // always return actual value
1515             contstr = "Min To Last";
1516             break;
1517         case PART::control::maxToLastKey: // always return actual value
1518             contstr = "Max To Last";
1519             break;
1520         case PART::control::resetMinMaxKey:
1521             contstr = "Full Key Range";
1522             showValue = false;
1523             break;
1524 
1525         case PART::control::kitEffectNum:
1526             if (value_int == 0)
1527                 contstr = "Effect Off";
1528             else
1529                 contstr = "Effect Number " + to_string(value_int);
1530             showValue = false;
1531             break;
1532 
1533         case PART::control::maxNotes:
1534             contstr = "Key Limit";
1535             break;
1536         case PART::control::keyShift:
1537             contstr = "Key Shift";
1538             break;
1539 
1540         case PART::control::partToSystemEffect1:
1541             contstr = "Effect Send 1";
1542             break;
1543         case PART::control::partToSystemEffect2:
1544             contstr = "Effect Send 2";
1545             break;
1546         case PART::control::partToSystemEffect3:
1547             contstr = "Effect Send 3";
1548             break;
1549         case PART::control::partToSystemEffect4:
1550             contstr = "Effect Send 4";
1551             break;
1552 
1553         case PART::control::humanise:
1554             contstr = "Humanise Pitch";
1555             break;
1556 
1557         case PART::control::humanvelocity:
1558             contstr = "Humanise Velocity";
1559             break;
1560 
1561         case PART::control::drumMode:
1562             contstr = "Drum Mode";
1563             yesno = true;
1564             break;
1565         case PART::control::kitMode:
1566             contstr = "Kit Mode ";
1567             showValue = false;
1568             if (addValue)
1569             {
1570                 switch(value_int)
1571                 {
1572                     case 0:
1573                         contstr += "off";
1574                         break;
1575                     case 1:
1576                         contstr += "multi";
1577                         break;
1578                     case 2:
1579                         contstr += "single";
1580                         break;
1581                     case 3:
1582                         contstr += "crossfade";
1583                         break;
1584                 }
1585             }
1586             break;
1587 
1588         case PART::control::effectNumber:
1589             contstr = "Effect Number " + to_string(value_int);
1590             showValue = false;
1591             break;
1592         case PART::control::effectType:
1593             contstr = "Effect " + to_string(effNum + 1) + " Type";
1594             break;
1595         case PART::control::effectDestination:
1596             contstr = "Effect " + to_string(effNum + 1) + " Destination";
1597             break;
1598         /*case PART::control::effectBypass:
1599             contstr = "Bypass Effect "+ to_string(effNum + 1);
1600             break;*/
1601 
1602         case PART::control::audioDestination:
1603             contstr = "Audio destination ";
1604             showValue = false;
1605             if (addValue)
1606             {
1607                 switch(value_int)
1608                 {
1609                     case 3:
1610                         contstr += "both";
1611                         break;
1612                     case 2:
1613                         contstr += "part";
1614                         break;
1615                     case 1:
1616                         contstr += "main";
1617                         break;
1618                     default:
1619                         contstr += "main";
1620                         break;
1621                 }
1622             }
1623             break;
1624 
1625         case PART::control::instrumentCopyright:
1626             showValue = false;
1627             contstr = "Copyright: " + textMsgBuffer.fetch(value_int);
1628             break;
1629         case PART::control::instrumentComments:
1630             showValue = false;
1631             contstr = "Comment: " + textMsgBuffer.fetch(value_int);
1632             break;
1633         case PART::control::instrumentName:
1634             showValue = false;
1635             contstr = "Name is: " + textMsgBuffer.fetch(value_int);
1636             break;
1637         case PART::control::instrumentType:
1638             showValue = false;
1639             contstr = "Type is: " + type_list[value_int];
1640             break;
1641         case PART::control::defaultInstrumentCopyright:
1642             showValue = false;
1643             contstr = "Copyright ";
1644             if (parameter == 0)
1645                 contstr += "load:\n";
1646             else
1647                 contstr += "save:\n";
1648             contstr += textMsgBuffer.fetch(value_int);
1649             break;
1650         case PART::control::resetAllControllers:
1651             showValue = false;
1652             contstr = "Cleared controllers";
1653             break;
1654 
1655         case PART::control::partBusy:
1656             showValue = false;
1657             if (value_bool)
1658                 contstr = "is busy";
1659             else
1660                 contstr = "is free";
1661             break;
1662 
1663     }
1664     if (!contstr.empty())
1665         return ("Part " + to_string(npart + 1) + kitnum + group + contstr);
1666 
1667     switch (control)
1668     {
1669             case PART::control::volumeRange:
1670             contstr = "Vol Range"; // not the *actual* volume
1671             break;
1672         case PART::control::volumeEnable:
1673             contstr = "Vol Enable";
1674             yesno = true;
1675             break;
1676         case PART::control::panningWidth:
1677             contstr = "Pan Width";
1678             break;
1679         case PART::control::modWheelDepth:
1680             contstr = "Mod Wheel Range";
1681             break;
1682         case PART::control::exponentialModWheel:
1683             contstr = "Exponent Mod Wheel";
1684             yesno = true;
1685             break;
1686         case PART::control::bandwidthDepth:
1687             contstr = "Bandwidth range";
1688             break;
1689         case PART::control::exponentialBandwidth:
1690             contstr = "Exponent Bandwidth";
1691             yesno = true;
1692             break;
1693         case PART::control::expressionEnable:
1694             contstr = "Expression Enable";
1695             yesno = true;
1696             break;
1697         case PART::control::FMamplitudeEnable:
1698             contstr = "FM Amp Enable";
1699             yesno = true;
1700             break;
1701         case PART::control::sustainPedalEnable:
1702             contstr = "Sustain Ped Enable";
1703             yesno = true;
1704             break;
1705         case PART::control::pitchWheelRange:
1706             contstr = "Pitch Wheel Range";
1707             break;
1708         case PART::control::filterQdepth:
1709             contstr = "Filter Q Range";
1710             break;
1711         case PART::control::filterCutoffDepth:
1712             contstr = "Filter Cutoff Range";
1713             break;
1714         case PART::control::breathControlEnable:
1715             yesno = true;
1716             contstr = "Breath Control";
1717             yesno = true;
1718             break;
1719 
1720         case PART::control::resonanceCenterFrequencyDepth:
1721             contstr = "Res Cent Freq Range";
1722             break;
1723         case PART::control::resonanceBandwidthDepth:
1724             contstr = "Res Band Range";
1725             break;
1726 
1727         case PART::control::portamentoTime:
1728             contstr = "Time";
1729             break;
1730         case PART::control::portamentoTimeStretch:
1731             contstr = "Time Stretch";
1732             break;
1733         case PART::control::portamentoThreshold:
1734             contstr = "Threshold Gate";
1735             break;
1736         case PART::control::portamentoThresholdType:
1737             contstr = "Threshold Gate Type ";
1738             showValue = false;
1739             if (value_int == 0)
1740                 contstr += ">= start";
1741             else
1742                 contstr += "< end";
1743             break;
1744         case PART::control::enableProportionalPortamento:
1745             contstr = "Prop Enable";
1746             yesno = true;
1747             break;
1748         case PART::control::proportionalPortamentoRate:
1749             contstr = "Prop Rate";
1750             break;
1751         case PART::control::proportionalPortamentoDepth:
1752             contstr = "Prop depth";
1753             break;
1754         case PART::control::receivePortamento:
1755             contstr = "Receive";
1756             yesno = true;
1757             break;
1758     }
1759     if (!contstr.empty())
1760         return ("Part " + to_string(npart + 1) + kitnum + "Controller " + contstr);
1761 
1762     string name = "MIDI ";
1763     switch (control)
1764     {
1765             case PART::control::midiModWheel:
1766             contstr = "Modulation";
1767             break;
1768         case PART::control::midiBreath:
1769             ; // not yet
1770             break;
1771         case PART::control::midiExpression:
1772             contstr = "Expression";
1773             break;
1774         case PART::control::midiSustain:
1775             ; // not yet
1776             break;
1777         case PART::control::midiPortamento:
1778             ; // not yet
1779             break;
1780         case PART::control::midiFilterQ:
1781             contstr = "Filter Q";
1782             break;
1783         case PART::control::midiFilterCutoff:
1784             contstr = "Filter Cutoff";
1785             break;
1786         case PART::control::midiBandwidth:
1787             contstr = "Bandwidth";
1788             break;
1789         case PART::control::midiFMamp:
1790             contstr = "FM Amp";
1791             break;
1792         case PART::control::midiResonanceCenter:
1793             contstr = "Resonance Cent";
1794             break;
1795         case PART::control::midiResonanceBandwidth:
1796             contstr = "Resonance Band";
1797             break;
1798 
1799         default:
1800             showValue = false;
1801             name = "";
1802             contstr = "Unrecognised";
1803     }
1804     return ("Part " + to_string(npart + 1) + kitnum + name + contstr);
1805 }
1806 
1807 
resolveAdd(CommandBlock * getData,bool addValue)1808 string DataText::resolveAdd(CommandBlock *getData, bool addValue)
1809 {
1810     float value = getData->data.value;
1811     unsigned char control = getData->data.control;
1812     unsigned char npart = getData->data.part;
1813     unsigned char kititem = getData->data.kit;
1814 
1815     string contstr = "";
1816 
1817     switch (control)
1818     {
1819         case ADDSYNTH::control::volume:
1820             contstr = "Volume";
1821             break;
1822         case ADDSYNTH::control::velocitySense:
1823             contstr = "Velocity Sense";
1824             break;
1825 
1826         case ADDSYNTH::control::panning:
1827             contstr = "Panning";
1828             break;
1829         case ADDSYNTH::control::enableRandomPan:
1830             contstr = "Random Pan";
1831             yesno = true;
1832             break;
1833         case ADDSYNTH::control::randomWidth:
1834             contstr = "Random Width";
1835             break;
1836 
1837         case ADDSYNTH::control::detuneFrequency:
1838             contstr = "Detune";
1839             break;
1840 
1841         case ADDSYNTH::control::octave:
1842             contstr = "Octave";
1843             break;
1844         case ADDSYNTH::control::detuneType:
1845             contstr = "Detune Type ";
1846             showValue = false;
1847             if (addValue)
1848                 contstr += detuneType [int(value)];
1849             break;
1850         case ADDSYNTH::control::coarseDetune:
1851             contstr = "Coarse Det";
1852             break;
1853         case ADDSYNTH::control::relativeBandwidth:
1854             contstr = "Relative Bandwidth";
1855             break;
1856 
1857         case ADDSYNTH::control::stereo:
1858             contstr = "Stereo";
1859             yesno = true;
1860             break;
1861         case ADDSYNTH::control::randomGroup:
1862             contstr = "Rnd Grp";
1863             yesno = true;
1864             break;
1865 
1866         case ADDSYNTH::control::dePop:
1867             contstr = "De Pop";
1868             break;
1869         case ADDSYNTH::control::punchStrength:
1870             contstr = "Punch Strength";
1871             break;
1872         case ADDSYNTH::control::punchDuration:
1873             contstr = "Punch Time";
1874             break;
1875         case ADDSYNTH::control::punchStretch:
1876             contstr = "Punch Stretch";
1877             break;
1878         case ADDSYNTH::control::punchVelocity:
1879             contstr = "Punch Velocity";
1880             break;
1881 
1882         default:
1883             showValue = false;
1884             contstr = "Unrecognised";
1885     }
1886 
1887     return ("Part " + to_string(npart + 1) + " Kit " + to_string(kititem + 1) + " AddSynth " + contstr);
1888 }
1889 
1890 
resolveAddVoice(CommandBlock * getData,bool addValue)1891 string DataText::resolveAddVoice(CommandBlock *getData, bool addValue)
1892 {
1893     float value = getData->data.value;
1894     unsigned char control = getData->data.control;
1895     unsigned char npart = getData->data.part;
1896     unsigned char kititem = getData->data.kit;
1897     unsigned char engine = getData->data.engine;
1898 
1899     int value_int = lrint(value);
1900     int nvoice;
1901     if (engine >= PART::engine::addMod1)
1902         nvoice = engine - PART::engine::addMod1;
1903     else
1904         nvoice = engine - PART::engine::addVoice1;
1905 
1906     string contstr = "";
1907 
1908     switch (control)
1909     {
1910         case ADDVOICE::control::volume:
1911             contstr = "Volume";
1912             break;
1913         case ADDVOICE::control::velocitySense:
1914             contstr = "Velocity Sense";
1915             break;
1916         case ADDVOICE::control::panning:
1917             contstr = "Panning";
1918             break;
1919         case ADDVOICE::control::enableRandomPan:
1920             contstr = "Random Pan";
1921             yesno = true;
1922             break;
1923         case ADDVOICE::control::randomWidth:
1924             contstr = "Random Width";
1925             break;
1926 
1927         case ADDVOICE::control::invertPhase:
1928             contstr = "Minus";
1929             yesno = true;
1930             break;
1931         case ADDVOICE::control::enableAmplitudeEnvelope:
1932             contstr = "Amp Enable Env";
1933             yesno = true;
1934             break;
1935         case ADDVOICE::control::enableAmplitudeLFO:
1936             contstr = "Amp Enable LFO";
1937             yesno = true;
1938             break;
1939 
1940         case ADDVOICE::control::modulatorType:
1941             contstr = "Modulator Type ";
1942             if (addValue)
1943             {
1944                 showValue = false;
1945                 contstr += addmodnameslist[value_int];
1946             }
1947             break;
1948         case ADDVOICE::control::externalModulator:
1949             if (addValue)
1950             {
1951                 showValue = false;
1952                 if (value_int < 0)
1953                     contstr = "Local";
1954                 else
1955                     contstr = "Modulator Source Voice " + to_string(value_int + 1);
1956             }
1957             break;
1958 
1959         case ADDVOICE::control::externalOscillator:
1960             if (addValue)
1961             {
1962                 showValue = false;
1963                 if (value_int < 0)
1964                     contstr = "Local";
1965                 else
1966                     contstr = "Source " + to_string(value_int + 1);
1967             }
1968             break;
1969 
1970         case ADDVOICE::control::detuneFrequency:
1971             contstr = "Detune";
1972             break;
1973         case ADDVOICE::control::equalTemperVariation:
1974             contstr = "Equal Temper";
1975             break;
1976         case ADDVOICE::control::baseFrequencyAs440Hz:
1977             contstr = "440Hz";
1978             yesno = true;
1979             break;
1980         case ADDVOICE::control::octave:
1981             contstr = "Octave";
1982             break;
1983         case ADDVOICE::control::detuneType:
1984             contstr = "Detune Type ";
1985             showValue = false;
1986             if (addValue)
1987                 contstr += stringCaps(detuneType [int(value)], 1);
1988             break;
1989         case ADDVOICE::control::coarseDetune:
1990             contstr = "Coarse Detune";
1991             break;
1992         case ADDVOICE::control::pitchBendAdjustment:
1993             contstr = "Bend Adj";
1994             break;
1995         case ADDVOICE::control::pitchBendOffset:
1996             contstr = "Offset Hz";
1997             break;
1998         case ADDVOICE::control::enableFrequencyEnvelope:
1999             contstr = "Freq Enable Env";
2000             yesno = true;
2001             break;
2002         case ADDVOICE::control::enableFrequencyLFO:
2003             contstr = "Freq Enable LFO";
2004             yesno = true;
2005             break;
2006 
2007         case ADDVOICE::control::unisonFrequencySpread:
2008             contstr = "Unison Freq Spread";
2009             break;
2010         case ADDVOICE::control::unisonPhaseRandomise:
2011             contstr = "Unison Phase Rnd";
2012             break;
2013         case ADDVOICE::control::unisonStereoSpread:
2014             contstr = "Unison Stereo";
2015             break;
2016         case ADDVOICE::control::unisonVibratoDepth:
2017             contstr = "Unison Vibrato";
2018             break;
2019         case ADDVOICE::control::unisonVibratoSpeed:
2020             contstr = "Unison Vib Speed";
2021             break;
2022         case ADDVOICE::control::unisonSize:
2023             contstr = "Unison Size";
2024             break;
2025         case ADDVOICE::control::unisonPhaseInvert:
2026             showValue = false;
2027             contstr = "Unison Invert " + unisonPhase[value_int];
2028             break;
2029         case ADDVOICE::control::enableUnison:
2030             contstr = "Unison Enable";
2031             yesno = true;
2032             break;
2033 
2034         case ADDVOICE::control::bypassGlobalFilter:
2035             contstr = "Filter Bypass Global";
2036             yesno = true;
2037             break;
2038         case ADDVOICE::control::enableFilter:
2039             contstr = "Filter Enable";
2040             yesno = true;
2041             break;
2042         case ADDVOICE::control::enableFilterEnvelope:
2043             contstr = "Filter Enable Env";
2044             yesno = true;
2045             break;
2046         case ADDVOICE::control::enableFilterLFO:
2047             contstr = "Filter Enable LFO";
2048             yesno = true;
2049             break;
2050 
2051         case ADDVOICE::control::modulatorAmplitude:
2052             contstr = "Modulator Volume";
2053             break;
2054         case ADDVOICE::control::modulatorVelocitySense:
2055             contstr = "Modulator Vel Sense";
2056             break;
2057         case ADDVOICE::control::modulatorHFdamping:
2058             contstr = "Modulator HF Damping";
2059             break;
2060 
2061         case ADDVOICE::control::enableModulatorAmplitudeEnvelope:
2062             contstr = "Modulator Amp Enable Env";
2063             yesno = true;
2064             break;
2065 
2066         case ADDVOICE::control::modulatorDetuneFrequency:
2067             contstr = "Modulator Detune";
2068             break;
2069         case ADDVOICE::control::modulatorFrequencyAs440Hz:
2070             contstr = "Modulator 440Hz";
2071             yesno = true;
2072             break;
2073         case ADDVOICE::control::modulatorDetuneFromBaseOsc:
2074             contstr = "Modulator Follow voice";
2075             yesno = true;
2076             break;
2077         case ADDVOICE::control::modulatorOctave:
2078             contstr = "Modulator Octave";
2079             break;
2080         case ADDVOICE::control::modulatorDetuneType:
2081             contstr = "Modulator Detune Type ";
2082             showValue = false;
2083             if (addValue)
2084                 contstr += detuneType [int(value)];
2085             break;
2086         case ADDVOICE::control::modulatorCoarseDetune:
2087             contstr = "Modulator Coarse Detune";
2088             break;
2089         case ADDVOICE::control::enableModulatorFrequencyEnvelope: // local, external
2090             contstr = "Modulator Freq Enable Env";
2091             yesno = true;
2092             break;
2093 
2094         case ADDVOICE::control::modulatorOscillatorPhase:
2095             contstr = "Modulator Osc Phase";
2096             break;
2097         case ADDVOICE::control::modulatorOscillatorSource:
2098             if (addValue)
2099             {
2100                 showValue = false;
2101                 if (value_int < 0)
2102                     contstr = "Modulator Internal";
2103                 else
2104                     contstr = "Modulator Osc from " + to_string(value_int + 1);
2105             }
2106             break;
2107 
2108         case ADDVOICE::control::delay:
2109             contstr = "Delay";
2110             break;
2111         case ADDVOICE::control::enableVoice:
2112             contstr = "Enable";
2113             yesno = true;
2114             break;
2115         case ADDVOICE::control::enableResonance:
2116             contstr = "Resonance Enable";
2117             yesno = true;
2118             break;
2119         case ADDVOICE::control::voiceOscillatorPhase:
2120             contstr = "Osc Phase";
2121             break;
2122         case ADDVOICE::control::voiceOscillatorSource:
2123             if (addValue)
2124             {
2125                 showValue = false;
2126                 if (value_int < 0)
2127                     contstr = "Internal";
2128                 else
2129                     contstr = "from " + to_string(value_int + 1);
2130             }
2131             break;
2132         case ADDVOICE::control::soundType:
2133             contstr = "Sound type";
2134             break;
2135 
2136         default:
2137             showValue = false;
2138             contstr = "Unrecognised";
2139     }
2140 
2141     return ("Part " + to_string(npart + 1) + " Kit " + to_string(kititem + 1) + " Add Voice " + to_string(nvoice + 1) + " " + contstr);
2142 }
2143 
2144 
resolveSub(CommandBlock * getData,bool addValue)2145 string DataText::resolveSub(CommandBlock *getData, bool addValue)
2146 {
2147     float value = getData->data.value;
2148     unsigned char control = getData->data.control;
2149     unsigned char npart = getData->data.part;
2150     unsigned char kititem = getData->data.kit;
2151     unsigned char insert = getData->data.insert;
2152 
2153     int value_int = int(value);
2154 
2155     if (insert == TOPLEVEL::insert::harmonicAmplitude || insert == TOPLEVEL::insert::harmonicPhaseBandwidth)
2156     {
2157         string Htype;
2158         if (insert == TOPLEVEL::insert::harmonicAmplitude)
2159             Htype = " Amplitude";
2160         else
2161             Htype = " Bandwidth";
2162 
2163         return ("Part " + to_string(npart + 1) + " Kit " + to_string(kititem + 1) + " SubSynth Harmonic " + to_string(control + 1) + Htype);
2164     }
2165 
2166     string name = "";
2167 
2168     string contstr = "";
2169     switch (control)
2170     {
2171         case SUBSYNTH::control::volume:
2172             contstr = "Volume";
2173             break;
2174         case SUBSYNTH::control::velocitySense:
2175             contstr = "Velocity Sense";
2176             break;
2177         case SUBSYNTH::control::panning:
2178             contstr = "Panning";
2179             break;
2180         case SUBSYNTH::control::enableRandomPan:
2181             contstr = "Random Pan";
2182             yesno = true;
2183             break;
2184         case SUBSYNTH::control::randomWidth:
2185             contstr = "Random Width";
2186             break;
2187 
2188         case SUBSYNTH::control::bandwidth:
2189             contstr = "Bandwidth"; // it's the actual bandwidth control
2190             break;
2191         case SUBSYNTH::control::bandwidthScale:
2192             contstr = "Bandwidth Band Scale";
2193             break;
2194         case SUBSYNTH::control::enableBandwidthEnvelope:
2195             contstr = "Bandwidth Env Enab";
2196             yesno = true;
2197             break;
2198 
2199         case SUBSYNTH::control::detuneFrequency:
2200             contstr = "Detune";
2201             break;
2202         case SUBSYNTH::control::equalTemperVariation:
2203             contstr = "Equal Temper";
2204             break;
2205         case SUBSYNTH::control::baseFrequencyAs440Hz:
2206             contstr = "440Hz";
2207             yesno = true;
2208             break;
2209         case SUBSYNTH::control::octave:
2210             contstr = "Octave";
2211             break;
2212         case SUBSYNTH::control::detuneType:
2213             contstr = "Detune Type ";
2214             showValue = false;
2215             if (addValue)
2216                 contstr += detuneType [value_int];
2217             break;
2218         case SUBSYNTH::control::coarseDetune:
2219             contstr = "Coarse Detune";
2220             break;
2221         case SUBSYNTH::control::pitchBendAdjustment:
2222             contstr = "Bend Adj";
2223             break;
2224         case SUBSYNTH::control::pitchBendOffset:
2225             contstr = "Offset Hz";
2226             break;
2227         case SUBSYNTH::control::enableFrequencyEnvelope:
2228             contstr = "Frequency Env Enab";
2229             yesno = true;
2230             break;
2231 
2232         case SUBSYNTH::control::overtoneParameter1:
2233             contstr = "Overtones Par 1";
2234             break;
2235         case SUBSYNTH::control::overtoneParameter2:
2236             contstr = "Overtones Par 2";
2237             break;
2238         case SUBSYNTH::control::overtoneForceHarmonics:
2239             contstr = "Overtones Force H";
2240             break;
2241         case SUBSYNTH::control::overtonePosition:
2242             contstr = "Overtones Position " + subPadPosition[value_int];
2243             showValue = false;
2244             break;
2245 
2246         case SUBSYNTH::control::enableFilter:
2247             contstr = "Filter Enable";
2248             yesno = true;
2249             break;
2250 
2251         case SUBSYNTH::control::filterStages:
2252             contstr = "Filt Stages";
2253             break;
2254         case SUBSYNTH::control::magType:
2255             contstr = "Mag Type " + subMagType [value_int];
2256             showValue = false;
2257             break;
2258         case SUBSYNTH::control::startPosition:
2259             contstr = "Start ";
2260             showValue = false;
2261             switch (value_int)
2262             {
2263                 case 0:
2264                     contstr += "Zero";
2265                     break;
2266                 case 1:
2267                     contstr += "Random";
2268                     break;
2269                 case 2:
2270                     contstr += "Maximum";
2271                     break;
2272             }
2273             break;
2274 
2275         case SUBSYNTH::control::clearHarmonics:
2276             contstr = "Clear Harmonics";
2277             showValue = false;
2278             break;
2279 
2280         case SUBSYNTH::control::stereo:
2281             contstr = "Stereo";
2282             yesno = true;
2283             break;
2284 
2285         default:
2286             showValue = false;
2287             contstr = "Unrecognised";
2288     }
2289 
2290     return ("Part " + to_string(npart + 1) + " Kit " + to_string(kititem + 1) + " SubSynth " + contstr);
2291 }
2292 
2293 
resolvePad(CommandBlock * getData,bool addValue)2294 string DataText::resolvePad(CommandBlock *getData, bool addValue)
2295 {
2296     float value = getData->data.value;
2297     unsigned char type = getData->data.type;
2298     unsigned char control = getData->data.control;
2299     unsigned char npart = getData->data.part;
2300     unsigned char kititem = getData->data.kit;
2301     bool write = (type & TOPLEVEL::type::Write) > 0;
2302 
2303     int value_int = int(value);
2304 
2305     string contstr = "";
2306     switch (control)
2307     {
2308         case PADSYNTH::control::volume:
2309             contstr = "Volume";
2310             break;
2311         case PADSYNTH::control::velocitySense:
2312             contstr = "Velocity Sense";
2313             break;
2314         case PADSYNTH::control::panning:
2315             contstr = "Panning";
2316             break;
2317         case PADSYNTH::control::enableRandomPan:
2318             contstr = "Random Pan";
2319             yesno = true;
2320             break;
2321         case PADSYNTH::control::randomWidth:
2322             contstr = "Random Width";
2323             break;
2324 
2325         case PADSYNTH::control::detuneFrequency:
2326             contstr = "Detune";
2327             break;
2328         case PADSYNTH::control::equalTemperVariation:
2329             contstr = "Equal Temper";
2330             break;
2331         case PADSYNTH::control::baseFrequencyAs440Hz:
2332             contstr = "440Hz";
2333             yesno = true;
2334             break;
2335         case PADSYNTH::control::octave:
2336             contstr = "Octave";
2337             break;
2338         case PADSYNTH::control::detuneType:
2339             contstr = "Detune Type ";
2340             showValue = false;
2341             if (addValue)
2342                 contstr += detuneType [int(value)];
2343             break;
2344         case PADSYNTH::control::coarseDetune:
2345             contstr = "Coarse Detune";
2346             break;
2347 
2348         case PADSYNTH::control::pitchBendAdjustment:
2349             contstr = "Bend Adjust";
2350             break;
2351         case PADSYNTH::control::pitchBendOffset:
2352             contstr = "Offset Hz";
2353             break;
2354         case PADSYNTH::control::stereo:
2355             contstr = "Stereo";
2356             yesno = true;
2357             break;
2358         case PADSYNTH::control::dePop:
2359             contstr = "De Pop";
2360             break;
2361         case PADSYNTH::control::punchStrength:
2362             contstr = "Punch Strength";
2363             break;
2364         case PADSYNTH::control::punchDuration:
2365             contstr = "Punch Time";
2366             break;
2367         case PADSYNTH::control::punchStretch:
2368             contstr = "Punch Stretch";
2369             break;
2370         case PADSYNTH::control::punchVelocity:
2371             contstr = "Punch Velocity";
2372             break;
2373 
2374             case PADSYNTH::control::applyChanges:
2375             showValue = false;
2376             contstr = "Changes Applied ";
2377             if (addValue)
2378             {
2379                 if (value_int != 0)
2380                     contstr += "Yes";
2381                 else
2382                     contstr += "No";
2383             }
2384             break;
2385     }
2386     if (!contstr.empty())
2387         return ("Part " + to_string(npart + 1) + " Kit " + to_string(kititem + 1) + " PadSynth " + contstr);
2388 
2389     switch (control)
2390     {
2391         case PADSYNTH::control::overtoneParameter1:
2392             contstr = "Overtones Par 1";
2393             break;
2394         case PADSYNTH::control::overtoneParameter2:
2395             contstr = "Overtones Par 2";
2396             break;
2397         case PADSYNTH::control::overtoneForceHarmonics:
2398             contstr = "Overtones Force H";
2399             break;
2400         case PADSYNTH::control::overtonePosition:
2401             contstr = "Position " + subPadPosition[value_int];
2402             showValue = false;
2403             break;
2404 
2405         case PADSYNTH::control::bandwidth:
2406             contstr = "Bandwidth";
2407             break;
2408         case PADSYNTH::control::bandwidthScale:
2409             contstr = "Bandwidth Scale";
2410             break;
2411         case PADSYNTH::control::spectrumMode:
2412             contstr = "Spectrum Mode";
2413             break;
2414     }
2415     if (!contstr.empty())
2416     {
2417         if (write)
2418             contstr += " - Need to Apply";
2419         return ("Part " + to_string(npart + 1) + " Kit " + to_string(kititem + 1) + " PadSynth " + contstr);
2420     }
2421 
2422     switch (control)
2423     {
2424         case PADSYNTH::control::baseWidth:
2425             contstr = "Width";
2426             break;
2427         case PADSYNTH::control::frequencyMultiplier:
2428             contstr = "Freq Mult";
2429             break;
2430         case PADSYNTH::control::modulatorStretch:
2431             contstr = "Str";
2432             break;
2433         case PADSYNTH::control::modulatorFrequency:
2434             contstr = "Freq";
2435             break;
2436         case PADSYNTH::control::size:
2437             contstr = "Size";
2438             break;
2439         case PADSYNTH::control::baseType:
2440             contstr = "Type";
2441             break;
2442         case PADSYNTH::control::harmonicSidebands:
2443             contstr = "Halves";
2444             break;
2445         case PADSYNTH::control::spectralWidth:
2446             contstr = "Amp Par 1";
2447             break;
2448         case PADSYNTH::control::spectralAmplitude:
2449             contstr = "Amp Par 2";
2450             break;
2451         case PADSYNTH::control::amplitudeMultiplier:
2452             contstr = "Amp Mult";
2453             break;
2454         case PADSYNTH::control::amplitudeMode:
2455             contstr = "Amp Mode";
2456             break;
2457         case PADSYNTH::control::autoscale: //
2458             contstr = "Autoscale";
2459             yesno = true;
2460             break;
2461     }
2462     if (!contstr.empty())
2463     {
2464         contstr = "Harmonic Base " + contstr;
2465         if (write)
2466             contstr += " - Need to Apply";
2467         return ("Part " + to_string(npart + 1) + " Kit " + to_string(kititem + 1) + " PadSynth " + contstr);
2468     }
2469 
2470     switch (control)
2471     {
2472         case PADSYNTH::control::harmonicBase:
2473             contstr = "Base";
2474             break;
2475         case PADSYNTH::control::samplesPerOctave:
2476             contstr = "samp/Oct";
2477             break;
2478         case PADSYNTH::control::numberOfOctaves:
2479             contstr = "Num Oct";
2480             break;
2481         case PADSYNTH::control::sampleSize:
2482             break;
2483 
2484         default:
2485             showValue = false;
2486             contstr = "Unrecognised";
2487     }
2488     if (contstr != "Unrecognised")
2489         contstr = "Harmonic Samples " + contstr;
2490     if (write && contstr != "Unrecognised")
2491         contstr += " - Need to Apply";
2492     return ("Part " + to_string(npart + 1) + " Kit " + to_string(kititem + 1) + " PadSynth " + contstr);
2493 }
2494 
2495 
resolveOscillator(CommandBlock * getData,bool addValue)2496 string DataText::resolveOscillator(CommandBlock *getData, bool addValue)
2497 {
2498     float value = getData->data.value;
2499     unsigned char type = getData->data.type;
2500     unsigned char control = getData->data.control;
2501     unsigned char npart = getData->data.part;
2502     unsigned char kititem = getData->data.kit;
2503     unsigned char engine = getData->data.engine;
2504     unsigned char insert = getData->data.insert;
2505     bool write = (type & TOPLEVEL::type::Write) > 0;
2506     int value_int = int(value);
2507 
2508     string isPad = "";
2509     string eng_name;
2510     if (engine == PART::engine::padSynth)
2511     {
2512         eng_name = " PadSynth";
2513         if (write)
2514             isPad = " - Need to Apply";
2515     }
2516     else
2517     {
2518         int eng;
2519         if (engine >= PART::engine::addMod1)
2520             eng = engine - PART::engine::addMod1;
2521         else
2522             eng = engine - PART::engine::addVoice1;
2523         eng_name = " Add Voice " + to_string(eng + 1);
2524         if (engine >= PART::engine::addMod1)
2525             eng_name += " Modulator";
2526     }
2527 
2528     if (insert == TOPLEVEL::insert::harmonicAmplitude)
2529     {
2530         return ("Part " + to_string(npart + 1) + " Kit " + to_string(kititem + 1) + eng_name + " Harmonic " + to_string((int)control + 1) + " Amplitude" + isPad);
2531     }
2532     else if (insert == TOPLEVEL::insert::harmonicPhaseBandwidth)
2533     {
2534         return ("Part " + to_string(npart + 1) + " Kit " + to_string(kititem + 1) + eng_name + " Harmonic " + to_string((int)control + 1) + " Phase" + isPad);
2535     }
2536 
2537     string contstr;
2538     switch (control)
2539     {
2540         case OSCILLATOR::control::phaseRandomness:
2541             contstr = "Random";
2542             break;
2543         case OSCILLATOR::control::magType:
2544             contstr = "Mag Type";
2545             break;
2546         case OSCILLATOR::control::harmonicAmplitudeRandomness:
2547             contstr = "Harm Rnd";
2548             break;
2549         case OSCILLATOR::control::harmonicRandomnessType:
2550             contstr = "Harm Rnd Type";
2551             break;
2552 
2553         case OSCILLATOR::control::clearHarmonics:
2554             contstr = "Clear Harmonics";
2555             break;
2556         case OSCILLATOR::control::convertToSine:
2557             contstr = "Conv To Sine";
2558             break;
2559     }
2560     if (!contstr.empty())
2561     {
2562         return ("Part " + to_string(npart + 1) + " Kit " + to_string(kititem + 1) + eng_name + " Oscillator " + contstr + isPad);
2563     }
2564 
2565     switch(control)
2566     {
2567         case OSCILLATOR::control::baseFunctionParameter:
2568             contstr = "Par";
2569             break;
2570         case OSCILLATOR::control::baseFunctionType:
2571             contstr = "Type ";
2572             showValue = false;
2573             if (addValue)
2574                 contstr += stringCaps(waveformlist[int(value) * 2], 1);
2575             break;
2576         case OSCILLATOR::control::baseModulationParameter1:
2577             contstr = "Mod Par 1";
2578             break;
2579         case OSCILLATOR::control::baseModulationParameter2:
2580             contstr = "Mod Par 2";
2581             break;
2582         case OSCILLATOR::control::baseModulationParameter3:
2583             contstr = "Mod Par 3";
2584             break;
2585         case OSCILLATOR::control::baseModulationType:
2586             contstr = "Mod Type";
2587             break;
2588 
2589         case OSCILLATOR::control::autoClear: // this is local to the GUI
2590             break;
2591     }
2592     if (!contstr.empty())
2593     {
2594         return ("Part " + to_string(npart + 1) + " Kit " + to_string(kititem + 1) + eng_name + " Base Func " + contstr + isPad);
2595     }
2596 
2597     switch(control)
2598     {
2599         case OSCILLATOR::control::useAsBaseFunction:
2600             contstr = "Osc As Base";
2601             break;
2602         case OSCILLATOR::control::waveshapeParameter:
2603             contstr = "Waveshape Par";
2604             break;
2605         case OSCILLATOR::control::waveshapeType:
2606             contstr = "Waveshape Type";
2607             break;
2608         case OSCILLATOR::control::filterParameter1:
2609             contstr = "Osc Filt Par 1";
2610             break;
2611         case OSCILLATOR::control::filterParameter2:
2612             contstr = "Osc Filt Par 2";
2613             break;
2614         case OSCILLATOR::control::filterBeforeWaveshape:
2615             contstr = "Osc Filt B4 Waveshape";
2616             break;
2617         case OSCILLATOR::control::filterType:
2618             contstr = "Osc Filt Type ";
2619             if (addValue)
2620             {
2621                 showValue = false;
2622                 contstr += filtertype[value_int];
2623             }
2624             break;
2625         case OSCILLATOR::control::modulationParameter1:
2626             contstr = "Osc Mod Par 1";
2627             break;
2628         case OSCILLATOR::control::modulationParameter2:
2629             contstr = "Osc Mod Par 2";
2630             break;
2631         case OSCILLATOR::control::modulationParameter3:
2632             contstr = "Osc Mod Par 3";
2633             break;
2634         case OSCILLATOR::control::modulationType:
2635             contstr = "Osc Mod Type";
2636             break;
2637         case OSCILLATOR::control::spectrumAdjustParameter:
2638             contstr = "Osc Spect Par";
2639             break;
2640         case OSCILLATOR::control::spectrumAdjustType:
2641             contstr = "Osc Spect Type";
2642             break;
2643     }
2644     if (!contstr.empty())
2645     {
2646         return ("Part " + to_string(npart + 1) + " Kit " + to_string(kititem + 1) + eng_name + " Base Mods " + contstr + isPad);
2647     }
2648 
2649     switch(control)
2650     {
2651         case OSCILLATOR::control::harmonicShift:
2652             contstr = "Shift";
2653             break;
2654         case OSCILLATOR::control::clearHarmonicShift:
2655             contstr = "Reset";
2656             break;
2657         case OSCILLATOR::control::shiftBeforeWaveshapeAndFilter:
2658             contstr = "B4 Waveshape & Filt";
2659             break;
2660         case OSCILLATOR::control::adaptiveHarmonicsParameter:
2661             contstr = "Adapt Param";
2662             break;
2663         case OSCILLATOR::control::adaptiveHarmonicsBase:
2664             contstr = "Adapt Base Freq";
2665             break;
2666         case OSCILLATOR::control::adaptiveHarmonicsPower:
2667             contstr = "Adapt Power";
2668             break;
2669         case OSCILLATOR::control::adaptiveHarmonicsType:
2670             contstr = "Adapt Type";
2671             break;
2672 
2673         default:
2674             showValue = false;
2675             contstr = "Unrecognised";
2676     }
2677 
2678     return ("Part " + to_string(npart + 1) + " Kit " + to_string(kititem + 1) + eng_name + " Harm Mods " + contstr + isPad);
2679 }
2680 
2681 
resolveResonance(CommandBlock * getData,bool addValue)2682 string DataText::resolveResonance(CommandBlock *getData, bool addValue)
2683 {
2684     int value = int(getData->data.value + 0.5f);
2685     unsigned char type = getData->data.type;
2686     unsigned char control = getData->data.control;
2687     unsigned char npart = getData->data.part;
2688     unsigned char kititem = getData->data.kit;
2689     unsigned char engine = getData->data.engine;
2690     unsigned char insert = getData->data.insert;
2691     unsigned char parameter = getData->data.parameter;
2692     bool write = (type & TOPLEVEL::type::Write) > 0;
2693 
2694     string name;
2695     string isPad = "";
2696     if (engine == PART::engine::padSynth)
2697     {
2698         name = " PadSynth";
2699         if (write)
2700             isPad = " - Need to Apply";
2701     }
2702     else
2703         name = " AddSynth";
2704 
2705     if (insert == TOPLEVEL::insert::resonanceGraphInsert)
2706     {
2707         if (write == true && engine == PART::engine::padSynth)
2708             isPad = " - Need to Apply";
2709         return ("Part " + to_string(npart + 1) + " Kit " + to_string(kititem + 1) + name + " Resonance Point " + to_string(parameter + 1) + isPad);
2710     }
2711 
2712     if (write == true && engine == PART::engine::padSynth && control != PADSYNTH::control::applyChanges)
2713         isPad = " - Need to Apply";
2714     string contstr;
2715     switch (control)
2716     {
2717         case RESONANCE::control::maxDb:
2718             contstr = "Max dB";
2719             break;
2720         case RESONANCE::control::centerFrequency:
2721             contstr = "Center Freq";
2722             break;
2723         case RESONANCE::control::octaves:
2724             contstr = "Octaves";
2725             break;
2726 
2727         case RESONANCE::control::enableResonance:
2728             contstr = "Enable";
2729             yesno = true;
2730             break;
2731 
2732         case RESONANCE::control::randomType:
2733             contstr = "Random";
2734             showValue = false;
2735             if (addValue)
2736             {
2737                 if (value == 0)
2738                     contstr += " - coarse";
2739                 else if (value == 1)
2740                     contstr += " - medium";
2741                 else
2742                     contstr += " - fine";
2743             }
2744             break;
2745 
2746         case RESONANCE::control::interpolatePeaks:
2747             contstr = "Interpolate Peaks";
2748             showValue = false;
2749             if (addValue && value == 0)
2750                 contstr += " - smooth";
2751             else
2752                 contstr += " - linear";
2753             break;
2754         case RESONANCE::control::protectFundamental:
2755             contstr = "Protect Fundamental";
2756             yesno = true;
2757             break;
2758 
2759         case RESONANCE::control::clearGraph:
2760             showValue = false;
2761             contstr = "Clear";
2762             break;
2763         case RESONANCE::control::smoothGraph:
2764             showValue = false;
2765             contstr = "Smooth";
2766             break;
2767 
2768         default:
2769             showValue = false;
2770             contstr = "Unrecognised";
2771     }
2772 
2773     return ("Part " + to_string(npart + 1) + " Kit " + to_string(kititem + 1) + name + " Resonance " + contstr + isPad);
2774 }
2775 
2776 
resolveLFO(CommandBlock * getData,bool addValue)2777 string DataText::resolveLFO(CommandBlock *getData, bool addValue)
2778 {
2779     int value_int = int(getData->data.value);
2780     unsigned char control = getData->data.control;
2781     unsigned char npart = getData->data.part;
2782     unsigned char kititem = getData->data.kit;
2783     unsigned char engine = getData->data.engine;
2784     unsigned char insertParam = getData->data.parameter;
2785 
2786     string name;
2787     string lfo;
2788 
2789     if (engine == PART::engine::addSynth)
2790         name = " AddSynth";
2791     else if (engine == PART::engine::padSynth)
2792         name = " PadSynth";
2793     else if (engine >= PART::engine::addVoice1)
2794     {
2795         int nvoice = engine - PART::engine::addVoice1;
2796         name = " Add Voice " + to_string(nvoice + 1);
2797     }
2798 
2799     switch (insertParam)
2800     {
2801         case TOPLEVEL::insertType::amplitude:
2802             lfo = " Amp";
2803             break;
2804         case TOPLEVEL::insertType::frequency:
2805             lfo = " Freq";
2806             break;
2807         case TOPLEVEL::insertType::filter:
2808             lfo = " Filt";
2809             break;
2810     }
2811 
2812     string contstr;
2813     switch (control)
2814     {
2815         case LFOINSERT::control::speed:
2816             if (getData->data.offset == 1 && addValue == true)
2817             {
2818                 float value = getData->data.value;
2819                 contstr += bpm2text(value);
2820                 showValue = false;
2821             }
2822             else
2823                 contstr = "Freq";
2824             break;
2825         case LFOINSERT::control::depth:
2826             contstr = "Depth";
2827             break;
2828         case LFOINSERT::control::delay:
2829             contstr = "Delay";
2830             break;
2831         case LFOINSERT::control::start:
2832             contstr = "Start";
2833             break;
2834         case LFOINSERT::control::amplitudeRandomness:
2835             contstr = "Amp Rand";
2836             break;
2837         case LFOINSERT::control::type:
2838         {
2839             contstr = "Type ";
2840             showValue = false;
2841             if (addValue)
2842                 contstr += stringCaps(LFOtype[value_int], 1);
2843             break;
2844         }
2845         case LFOINSERT::control::continuous:
2846             contstr = "Cont";
2847             yesno = true;
2848             break;
2849         case LFOINSERT::control::bpm:
2850             contstr = "BPM";
2851             yesno = true;
2852             break;
2853         case LFOINSERT::control::frequencyRandomness:
2854             contstr = "Freq Rand";
2855             break;
2856         case LFOINSERT::control::stretch:
2857             contstr = "Stretch";
2858             break;
2859 
2860         default:
2861             showValue = false;
2862             contstr = "Unrecognised";
2863     }
2864 
2865     return ("Part " + to_string(npart + 1) + " Kit " + to_string(kititem + 1) + name + lfo + " LFO " + contstr);
2866 }
2867 
2868 
resolveFilter(CommandBlock * getData,bool addValue)2869 string DataText::resolveFilter(CommandBlock *getData, bool addValue)
2870 {
2871     int value_int = int(getData->data.value);
2872     unsigned char control = getData->data.control;
2873     unsigned char npart = getData->data.part;
2874     unsigned char kititem = getData->data.kit;
2875     unsigned char engine = getData->data.engine;
2876 
2877     int nseqpos = getData->data.parameter;
2878     int nformant = getData->data.parameter;
2879     int nvowel = getData->data.offset;
2880 
2881     string name;
2882 
2883     if (engine == PART::engine::addSynth)
2884         name = " AddSynth";
2885     else if (engine == PART::engine::subSynth)
2886         name = " SubSynth";
2887     else if (engine == PART::engine::padSynth)
2888         name = " PadSynth";
2889     else if (engine >= PART::engine::addVoice1)
2890         name = " Adsynth Voice " + to_string((engine - PART::engine::addVoice1) + 1);
2891     string contstr;
2892     switch (control)
2893     {
2894         case FILTERINSERT::control::centerFrequency:
2895             contstr = "Cent Freq";
2896             break;
2897         case FILTERINSERT::control::Q:
2898             contstr = "Q";
2899             break;
2900         case FILTERINSERT::control::frequencyTracking:
2901             contstr = "Freq Track";
2902             break;
2903         case FILTERINSERT::control::velocitySensitivity:
2904             contstr = "Velocity Sense";
2905             break;
2906         case FILTERINSERT::control::velocityCurve:
2907             contstr = "Velocity Sense Curve";
2908             break;
2909         case FILTERINSERT::control::gain:
2910             contstr = "Gain";
2911             break;
2912         case FILTERINSERT::control::stages:
2913             showValue = false;
2914             contstr = "Stages " + to_string(value_int + 1);
2915             break;
2916         case FILTERINSERT::control::baseType:
2917             contstr = "Filt Cat ";
2918             showValue = false;
2919             switch (value_int)
2920             {
2921                 case 0:
2922                     contstr += "Analog";
2923                     break;
2924                 case 1:
2925                     contstr += "Form";
2926                     break;
2927                 case 2:
2928                     contstr += "StVar";
2929                     break;
2930                 default:
2931                     contstr += "unrecognised";
2932                     break;
2933             }
2934             break;
2935         case FILTERINSERT::control::analogType:
2936         {
2937             contstr = "An Type ";
2938             showValue = false;
2939             int idx = 0;
2940             if (addValue)
2941             {
2942                 while (filterlist [idx] != "l1")
2943                     idx += 2;
2944                 contstr += filterlist [idx + (value_int * 2)];
2945             }
2946             break;
2947         }
2948         case FILTERINSERT::control::stateVariableType:
2949         {
2950             contstr = "SV Type";
2951             int idx = 0;
2952             if (addValue)
2953             {
2954                 while (filterlist [idx] != "low")
2955                     idx += 2;
2956                 contstr += filterlist [idx + (value_int * 2)];
2957             }
2958             break;
2959         }
2960         case FILTERINSERT::control::frequencyTrackingRange:
2961             contstr = "Freq Track Offs";
2962             yesno = true;
2963             break;
2964         case FILTERINSERT::control::formantSlowness:
2965             contstr = "Form Morph";
2966             break;
2967         case FILTERINSERT::control::formantClearness:
2968             contstr = "Form Lucidity";
2969             break;
2970         case FILTERINSERT::control::formantFrequency:
2971             contstr = "Form Freq";
2972             break;
2973         case FILTERINSERT::control::formantQ:
2974             contstr = "Form Q";
2975             break;
2976         case FILTERINSERT::control::formantAmplitude:
2977             contstr = "Form Amp";
2978             break;
2979         case FILTERINSERT::control::formantStretch:
2980             contstr = "Form Stretch";
2981             break;
2982         case FILTERINSERT::control::formantCenter:
2983             contstr = "Form Cent Freq";
2984             break;
2985         case FILTERINSERT::control::formantOctave:
2986             contstr = "Form Octave";
2987             break;
2988 
2989         case FILTERINSERT::control::numberOfFormants:
2990             contstr = "Formants";
2991             break;
2992         case FILTERINSERT::control::vowelNumber:
2993             contstr = "Vowel Num";
2994             break;
2995         case FILTERINSERT::control::formantNumber:
2996             contstr = "Formant Num";
2997             break;
2998         case FILTERINSERT::control::sequenceSize:
2999             contstr = "Seq Size";
3000             break;
3001         case FILTERINSERT::control::sequencePosition:
3002             contstr = "Seq Pos";
3003             break;
3004         case FILTERINSERT::control::vowelPositionInSequence:
3005             contstr = "Vowel";
3006             break;
3007         case FILTERINSERT::control::negateInput:
3008             contstr = "Neg Input";
3009             yesno = true;
3010             break;
3011 
3012         default:
3013             showValue = false;
3014             contstr = "Unrecognised";
3015     }
3016     string extra = "";
3017     if (control >= FILTERINSERT::control::formantFrequency && control <= FILTERINSERT::control::formantAmplitude)
3018         extra = "Vowel " + to_string(nvowel) + " Formant " + to_string(nformant) + " ";
3019     else if (control == FILTERINSERT::control::vowelPositionInSequence)
3020         extra = "Seq Pos " + to_string(nseqpos) + " ";
3021 
3022     return ("Part " + to_string(npart + 1) + " Kit " + to_string(kititem + 1) + name + " Filter " + extra + contstr);
3023 }
3024 
3025 
resolveEnvelope(CommandBlock * getData,bool)3026 string DataText::resolveEnvelope(CommandBlock *getData, bool)
3027 {
3028     int value = lrint(getData->data.value);
3029     bool write = (getData->data.type & TOPLEVEL::type::Write) > 0;
3030     unsigned char control = getData->data.control;
3031     unsigned char npart = getData->data.part;
3032     unsigned char kititem = getData->data.kit;
3033     unsigned char engine = getData->data.engine;
3034     unsigned char insert = getData->data.insert;
3035     unsigned char insertParam = getData->data.parameter;
3036     int miscmsg = getData->data.miscmsg;
3037 
3038     string env;
3039     string name;
3040     if (engine == PART::engine::addSynth)
3041         name = " AddSynth";
3042     else if (engine == PART::engine::subSynth)
3043         name = " SubSynth";
3044 
3045     else if (engine == PART::engine::padSynth)
3046         name = " PadSynth";
3047     else if (engine >= PART::engine::addVoice1)
3048     {
3049         name = " Add Voice ";
3050         int nvoice;
3051         if (engine >= PART::engine::addMod1)
3052             nvoice = engine - PART::engine::addMod1;
3053         else
3054             nvoice = engine - PART::engine::addVoice1;
3055         name += to_string(nvoice + 1);
3056         if (engine >= PART::engine::addMod1)
3057             name += " Modulator";
3058     }
3059 
3060     switch(insertParam)
3061     {
3062         case TOPLEVEL::insertType::amplitude:
3063             env = " Amp";
3064             break;
3065         case TOPLEVEL::insertType::frequency:
3066             env = " Freq";
3067             break;
3068         case TOPLEVEL::insertType::filter:
3069             env = " Filt";
3070             break;
3071         case TOPLEVEL::insertType::bandwidth:
3072             env = " Band";
3073             break;
3074     }
3075 
3076     if (insert == TOPLEVEL::insert::envelopePoints)
3077     {
3078         if (!write)
3079         {
3080             return ("Freemode add/remove is write only. Current points " + to_string(int(miscmsg)));
3081         }
3082         if (miscmsg != UNUSED)
3083             return ("Part " + to_string(int(npart + 1)) + " Kit " + to_string(int(kititem + 1)) + name  + env + " Env Added Freemode Point " + to_string(int(control & 0x3f)) + " X increment " + to_string(int(miscmsg)) + " Y");
3084         else
3085         {
3086             showValue = false;
3087             return ("Part " + to_string(int(npart + 1)) + " Kit " + to_string(int(kititem + 1)) + name  + env + " Env Removed Freemode Point " +  to_string(int(control)) + "  Remaining " +  to_string(value));
3088         }
3089     }
3090 
3091     if (insert == TOPLEVEL::insert::envelopePointChange)
3092     {
3093         return ("Part " + to_string(int(npart + 1)) + " Kit " + to_string(int(kititem + 1)) + name  + env + " Env Freemode Point " +  to_string(int(control)) + " X increment " + to_string(int(miscmsg)) + " Y");
3094     }
3095 
3096     string contstr;
3097     switch (control)
3098     {
3099         case ENVELOPEINSERT::control::attackLevel:
3100             contstr = "Attack Level";
3101             break;
3102         case ENVELOPEINSERT::control::attackTime:
3103             contstr = "Attack Time";
3104             break;
3105         case ENVELOPEINSERT::control::decayLevel:
3106             contstr = "Decay Level";
3107             break;
3108         case ENVELOPEINSERT::control::decayTime:
3109             contstr = "Decay Time";
3110             break;
3111         case ENVELOPEINSERT::control::sustainLevel:
3112             contstr = "Sustain Level";
3113             break;
3114         case ENVELOPEINSERT::control::releaseLevel:
3115             contstr = "Release Level";
3116             break;
3117         case ENVELOPEINSERT::control::releaseTime:
3118             contstr = "Release Time";
3119             break;
3120         case ENVELOPEINSERT::control::stretch:
3121             contstr = "Stretch";
3122             break;
3123 
3124         case ENVELOPEINSERT::control::forcedRelease:
3125             contstr = "frcR";
3126             yesno = true;
3127             break;
3128         case ENVELOPEINSERT::control::linearEnvelope:
3129             contstr = "L";
3130             yesno = true;
3131             break;
3132 
3133         case ENVELOPEINSERT::control::edit:
3134             contstr = "Edit";
3135             break;
3136 
3137         case ENVELOPEINSERT::control::enableFreeMode:
3138             contstr = "Freemode";
3139             yesno = true;
3140             break;
3141         case ENVELOPEINSERT::control::points:
3142             contstr = "Points";
3143             break;
3144         case ENVELOPEINSERT::control::sustainPoint:
3145             contstr = "Sust";
3146             break;
3147 
3148         default:
3149             showValue = false;
3150             contstr = "Unrecognised";
3151     }
3152 
3153     return ("Part " + to_string(npart + 1) + " Kit " + to_string(int(kititem + 1)) + name  + env + " Env " + contstr);
3154 }
3155 
3156 
resolveEffects(CommandBlock * getData,bool addValue)3157 string DataText::resolveEffects(CommandBlock *getData, bool addValue)
3158 {
3159     int value = lrint(getData->data.value);
3160     unsigned char control = getData->data.control;
3161     unsigned char npart = getData->data.part;
3162     unsigned char kititem = getData->data.kit;
3163     unsigned char effnum = getData->data.engine;
3164     unsigned char insert = getData->data.insert;
3165     unsigned char parameter = getData->data.parameter;
3166     unsigned char offset = getData->data.offset;
3167 
3168     string name;
3169     string actual;
3170     if (npart == TOPLEVEL::section::systemEffects)
3171         name = "System";
3172     else if (npart == TOPLEVEL::section::insertEffects)
3173         name = "Insert";
3174     else
3175         name = "Part " + to_string(npart + 1);
3176 
3177     if (kititem == EFFECT::type::dynFilter && getData->data.insert != UNUSED)
3178     {
3179         if (npart == TOPLEVEL::section::systemEffects)
3180             name = "System";
3181         else if (npart == TOPLEVEL::section::insertEffects)
3182             name = "Insert";
3183         else name = "Part " + to_string(npart + 1);
3184         name += " Effect " + to_string(effnum + 1);
3185 
3186         name += " DynFilter ~ Filter ";
3187         switch (control)
3188         {
3189             case 0:
3190                 name += "C Freq";
3191                 break;
3192             case 1:
3193                 name += "Q";
3194                 break;
3195             case 5:
3196                 name += "Gain";
3197                 break;
3198             case 2:
3199                 name += "FreqTrk";
3200                 break;
3201             default:
3202                 name += "unrecognised";
3203                 break;
3204         }
3205         return name;
3206     }
3207 
3208     name += " Effect " + to_string(effnum + 1);
3209 
3210     string effname = "";
3211     if (npart < NUM_MIDI_PARTS && (control == PART::control::effectNumber || control == PART::control::effectDestination || control == PART::control::effectBypass))
3212     {
3213         if (control == PART::control::effectNumber)
3214             name = "Set " + name;
3215         else if (control == PART::control::effectDestination)
3216         {
3217             effname = " sent to ";
3218             if (value == 0)
3219                 effname += "next effect";
3220             else if (value == 1)
3221                 effname += "part out";
3222             else if (value == 2)
3223                 effname += "dry out";
3224         }
3225         if (control == PART::control::effectBypass)
3226         {
3227             effname = " Bypass";
3228             showValue = false;
3229             if (addValue)
3230             {
3231                 if (value)
3232                     effname += " - on";
3233                 else
3234                     effname += " - off";
3235             }
3236         }
3237         else
3238             showValue = false;
3239         return (name + effname);
3240     }
3241     else if (npart >= TOPLEVEL::section::systemEffects && kititem == UNUSED)
3242     {
3243         string contstr;
3244         string second = "";
3245         if (npart == TOPLEVEL::section::systemEffects)
3246         {
3247             if (insert == TOPLEVEL::insert::systemEffectSend)
3248             {
3249                 contstr = " from Effect " + to_string(effnum + 1);
3250                 second = " to Effect " + to_string(control + 1);
3251                 return (name + contstr + second);
3252             }
3253             if (control == EFFECT::sysIns::effectEnable)
3254             {
3255                 contstr += " Enable";
3256                 if (addValue)
3257                 {
3258                     showValue = false;
3259                     if (value > 0)
3260                         contstr += " - on";
3261                     else
3262                         contstr += " - off";
3263                 }
3264                 return (name + contstr);
3265             }
3266 
3267         }
3268         if (npart == TOPLEVEL::section::insertEffects && control == EFFECT::sysIns::effectDestination)
3269         {
3270             contstr = " To ";
3271             if (value == -2)
3272                 contstr += "Master out";
3273             else if (value == -1)
3274                 contstr = " - off";
3275             else
3276             {
3277                 contstr += "Part ";
3278                 second = to_string(value + 1);
3279             }
3280             showValue = false;
3281             return ("Send " + name + contstr + second);
3282         }
3283         if (control == EFFECT::sysIns::effectNumber)
3284         {
3285             name = "Set " + name;
3286             showValue = false;
3287             return (name + effname);
3288         }
3289     }
3290     string contstr = "";
3291     if ((npart < NUM_MIDI_PARTS && control == PART::control::effectType) || (npart > TOPLEVEL::section::main && kititem == UNUSED && control == EFFECT::sysIns::effectType))
3292     {
3293         name += " set to";
3294         kititem = value | EFFECT::type::none; // TODO fix this!
3295         showValue = false;
3296     }
3297     else
3298         contstr = ""; //" Control " + to_string(control + 1);
3299     string controlType = "";
3300     int ref = control; // we frequently modify this
3301     bool isBPM = (ref == 2 && offset == 1);
3302     //std::cout << "isbpm " << int(isBPM) << std::endl;
3303     switch (kititem)
3304     {
3305         case EFFECT::type::none:
3306             effname = " None";
3307             contstr = " ";
3308             break;
3309         case EFFECT::type::reverb:
3310         {
3311             if (ref > 4) // there is no 5 or 6 in the list names
3312                 ref -= 2;
3313             effname = " Reverb ";
3314             controlType = reverblist[(ref) * 2];
3315             if (control == 10 && addValue == true)// && offset > 0)
3316             {
3317                 showValue = false;
3318                 switch (value)
3319                 {
3320                     case 0:
3321                         contstr = " Random ";
3322                         break;
3323                     case 1:
3324                         contstr = " Freeverb ";
3325                         break;
3326                     case 2:
3327                         contstr = " Bandwidth ";
3328                         break;
3329                 }
3330             }
3331             break;
3332         }
3333         case EFFECT::type::echo:
3334             effname = " Echo ";
3335             if (ref > 6) // there is no 7-16 in the list names
3336                 ref -= 10;
3337             controlType = echolist[ref * 2];
3338             if (addValue & isBPM)
3339             {
3340                 showValue = false;
3341                 contstr += (" " + bpm2text(float(value) / 127.0f));
3342             }
3343             break;
3344         case EFFECT::type::chorus:
3345         {
3346             effname = " Chorus ";
3347             if (ref > 10) // there is no 11-16 in the list names
3348                 ref -= 6;
3349             else if (ref > 9) // there is no 10 in the list names
3350                 ref --;
3351             controlType = choruslist[ref * 2];
3352             if (addValue == true && offset > 0)
3353             {
3354                 if (control == 4)
3355                 {
3356                     showValue = false;
3357                     if (value)
3358                         contstr = " Triangle";
3359                     else
3360                         contstr = " Sine";
3361                 }
3362                 else if (control == 11)
3363                 {
3364                     showValue = false;
3365                     if (value)
3366                         contstr += " - on";
3367                     else
3368                         contstr+= " - off";
3369                 }
3370                 else if (addValue & isBPM)
3371                 {
3372                     showValue = false;
3373                     contstr += (" " + bpm2text(float(value) / 127.0f));
3374                 }
3375             }
3376             break;
3377         }
3378         case EFFECT::type::phaser:
3379             effname = " Phaser ";
3380             if (ref > 14) // there is no 15-16 in the list names
3381                 ref -= 2;
3382             controlType = phaserlist[ref * 2];
3383             if (addValue == true && offset > 0)
3384             {
3385                 switch (control)
3386                 {
3387                     case 4:
3388                         showValue = false;
3389                         if (value)
3390                             contstr = " Triangle";
3391                         else
3392                             contstr = " Sine";
3393                         break;
3394                     case 10:
3395                     case 12:
3396                     case 14:
3397                         showValue = false;
3398                         if (value)
3399                             contstr = " - on";
3400                         else
3401                         contstr = " - off";
3402                         break;
3403                 }
3404                 if (addValue & isBPM)
3405                 {
3406                     showValue = false;
3407                     contstr += (" " + bpm2text(float(value) / 127.0f));
3408                 }
3409             }
3410             break;
3411         case EFFECT::type::alienWah:
3412             effname = " AlienWah ";
3413             if (ref > 10) // there is no 11-16 in the list names
3414                 ref -= 6;
3415             controlType = alienwahlist[ref * 2];
3416             if (control == 4 && addValue == true  && offset > 0)
3417             {
3418                 showValue = false;
3419                 if (value)
3420                     contstr = " Triangle";
3421                 else
3422                     contstr = " Sine";
3423             }
3424             if (addValue & isBPM)
3425             {
3426                 showValue = false;
3427                 contstr += (" " + bpm2text(float(value) / 127.0f));
3428             }
3429             break;
3430         case EFFECT::type::distortion:
3431         {
3432             effname = " Distortion ";
3433             if (ref > 5) // there is an extra line in the list names
3434                 ++ ref;
3435             if (addValue == true && offset > 0)
3436             {
3437                 switch (ref)
3438                 {
3439                     case 5:
3440                         contstr = " " + stringCaps(effdistypes[value], 1);
3441                         showValue = false;
3442                         break;
3443                     case 11:
3444                     {
3445                         contstr = " Pre dist.";
3446                         if (value)
3447                             contstr += " - on";
3448                         else
3449                             contstr+= " - off";
3450                         showValue = false;
3451                         break;
3452                     }
3453                     case 7:
3454                     case 10:
3455                     {
3456                         if (value)
3457                             contstr += " - on";
3458                         else
3459                             contstr+= " - off";
3460                         showValue = false;
3461                         break;
3462                     }
3463                 }
3464             }
3465             controlType = distortionlist[ref * 2];
3466             break;
3467         }
3468         case EFFECT::type::eq:
3469         {
3470             effname = " EQ ";
3471             if (control > 1)
3472             {
3473                 if (offset)
3474                     effname += "(Band " + to_string(int(parameter)) + ") ";
3475                 if (ref > 10)
3476                     ref -= 7;
3477                 else    // there is no 3 to 9 in the list names
3478                 {       // but there is an extra line after 10
3479                     ref -= 8;
3480                     if (addValue == true && offset > 0)
3481                     {
3482                         showValue = false;
3483                         contstr = " " + stringCaps(eqtypes[value], 1);
3484                     }
3485                 }
3486             }
3487             controlType = eqlist[ref * 2];
3488             break;
3489         }
3490         case EFFECT::type::dynFilter:
3491             effname = " DynFilter ";
3492             if (ref > 10) // there is no 11-16 in the list names
3493                 ref -= 6;
3494             controlType = dynfilterlist[ref * 2];
3495             if (addValue == true && offset > 0)
3496             {
3497                 if (control == 4)
3498                 {
3499                     showValue = false;
3500                     if (value)
3501                         contstr = " Triangle";
3502                     else
3503                         contstr = " Sine";
3504                 }
3505                 else if (control == 8)
3506                 {
3507                     showValue = false;
3508                     if (value)
3509                         contstr += " - on";
3510                     else
3511                         contstr+= " - off";
3512                 }
3513             }
3514             if (addValue & isBPM)
3515             {
3516                 showValue = false;
3517                 contstr += (" " + bpm2text(float(value) / 127.0f));
3518             }
3519             break;
3520 
3521         default:
3522             showValue = false;
3523             contstr = " Unrecognised";
3524     }
3525     //std::cout << "control " << int(control) << std::endl;
3526     if (control == EFFECT::control::preset && kititem != EFFECT::type::eq)
3527     {
3528         contstr = " Preset " + to_string (value + 1);
3529         showValue = false;
3530     }
3531     else if (offset)
3532     {
3533         controlType = controlType.substr(0, controlType.find(' '));
3534         effname += stringCaps(controlType , 1);
3535     }
3536 
3537 
3538     return (name + effname + contstr);
3539 }
3540