1 // Copyright 2013 Emilie Gillet.
2 //
3 // Author: Emilie Gillet (emilie.o.gillet@gmail.com)
4 //
5 // Permission is hereby granted, free of charge, to any person obtaining a copy
6 // of this software and associated documentation files (the "Software"), to deal
7 // in the Software without restriction, including without limitation the rights
8 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 // copies of the Software, and to permit persons to whom the Software is
10 // furnished to do so, subject to the following conditions:
11 //
12 // The above copyright notice and this permission notice shall be included in
13 // all copies or substantial portions of the Software.
14 //
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 // THE SOFTWARE.
22 //
23 // See http://creativecommons.org/licenses/MIT/ for more information.
24 //
25 // -----------------------------------------------------------------------------
26 //
27 // Parameter definitions.
28 
29 #include "yarns/settings.h"
30 
31 #include <algorithm>
32 #include <cstring>
33 
34 namespace yarns {
35 
36 const char* const layout_values[] = {
37   "1M", "2M", "4M", "2P", "4P", "2>", "4>", "8>", "4T", "4V", "3+1"
38 };
39 
40 const char* const clock_division_values[] = {
41   "/1", "/2", "/3", "/4", "/6", "/8", "12", "16", "24", "32", "48", "96"
42 };
43 
44 const char* const midi_out_mode_values[] = {
45   "OFF", "THRU", "ARP/SEQ"
46 };
47 
48 const char* const boolean_values[] = {
49   "OFF", "ON"
50 };
51 
52 const char* const voicing_allocation_mode_values[] = {
53   "MONO", "POLY", "CYCLIC", "RANDOM", "VELO", "SORTED", "U1 UNISON",
54   "U2 UNISON 2", "STEAL MOST RECENT"
55 };
56 
57 const char* const sequencer_arp_direction_values[] = {
58   "UP", "DN", "UD", "RANDOM", "PLAYED", "CHORD"
59 };
60 
61 const char* const voicing_aux_cv_values[] = {
62   "VELOCITY", "MODULATION", "AT", "BREATH", "PEDAL", "BEND", "VIBRATO LFO", "LFO"
63 };
64 
65 const char* const legato_mode_values[] = {
66   "OFF", "AUTO PORTAMENTO", "ON"
67 };
68 
69 const char* const voicing_oscillator_values[] = {
70   "OF", "\x88\x88", "\x8C\x8C", "\x8C_", "/\\", "SINE", "**"
71 };
72 
73 const char* const voicing_allocation_priority_values[] = {
74   "LAST", "LOW", "HIGH"
75 };
76 
77 const char* const trigger_shape_values[] = {
78   "SQ", "LINEAR", "EXPO", "RING", "STEP", "BURST"
79 };
80 
81 const char* const note_values[] = {
82   "C ", "Db", "D", "Eb", "E ", "F ", "Gb", "G ", "Ab", "A ", "Bb", "B "
83 };
84 
85 const char* const tuning_system_values[] = {
86   "EQUAL TEMPERAMENT",
87   "JUST INTONATION",
88   "PYTHAGOREAN",
89   "EB 1/4",
90   "E 1/4",
91   "EA 1/4",
92   "01 BHAIRAV",
93   "02 GUNAKRI",
94   "03 MARWA",
95   "04 SHREE",
96   "05 PURVI",
97   "06 BILAWAL",
98   "07 YAMAN",
99   "08 KAFI",
100   "09 BHIMPALASREE",
101   "10 DARBARI",
102   "11 BAGESHREE",
103   "12 RAGESHREE",
104   "13 KHAMAJ",
105   "14 MI MAL",
106   "15 PARAMESHWARI",
107   "16 RANGESHWARI",
108   "17 GANGESHWARI",
109   "18 KAMESHWARI",
110   "19 PA KAFI",
111   "20 NATBHAIRAV",
112   "21 M.KAUNS",
113   "22 BAIRAGI",
114   "23 B.TODI",
115   "24 CHANDRADEEP",
116   "25 KAUSHIK TODI",
117   "26 JOGESHWARI",
118   "27 RASIA",
119   "CUSTOM"
120 };
121 
122 const char* const tuning_factor_values[] = {
123   "OFF",
124   "0 ",
125   "18 1/8",
126   "14 1/4",
127   "38 3/8",
128   "12 1/2",
129   "58 5/8",
130   "34 3/4",
131   "78 7/8",
132   "1  1/1",
133   "54 5/4",
134   "32 3/2",
135   "2  2/1",
136   "ALPHA"
137 };
138 
139 /* static */
140 const Setting Settings::settings_[] = {
141   {
142     "LA", "LAYOUT",
143     SETTING_DOMAIN_MULTI, { MULTI_LAYOUT, 0 },
144     SETTING_UNIT_ENUMERATION, LAYOUT_MONO, LAYOUT_LAST - 1, layout_values,
145     0, 1,
146   },
147   {
148     "PA", "PART",
149     SETTING_DOMAIN_GLOBAL, { GLOBAL_ACTIVE_PART, 0 },
150     SETTING_UNIT_INDEX, 0, 3, NULL,
151     0, 0,
152   },
153   {
154     "PA", "PART",
155     SETTING_DOMAIN_GLOBAL, { GLOBAL_ACTIVE_PART, 0 },
156     SETTING_UNIT_INDEX, 0, 1, NULL,
157     0, 0,
158   },
159   {
160     "TE", "TEMPO",
161     SETTING_DOMAIN_MULTI, { MULTI_CLOCK_TEMPO, 0 },
162     SETTING_UNIT_TEMPO, 39, 240, NULL,
163     0, 2,
164   },
165   {
166     "SW", "SWING",
167     SETTING_DOMAIN_MULTI, { MULTI_CLOCK_SWING, 0 },
168     SETTING_UNIT_UINT8, 0, 99, NULL,
169     0, 3,
170   },
171   {
172     "I/", "INPUT CLK DIV",
173     SETTING_DOMAIN_MULTI, { MULTI_CLOCK_INPUT_DIVISION, 0 },
174     SETTING_UNIT_UINT8, 1, 4, NULL,
175     0, 0,
176   },
177   {
178     "O/", "OUTPUT CLK DIV",
179     SETTING_DOMAIN_MULTI, { MULTI_CLOCK_OUTPUT_DIVISION, 0 },
180     SETTING_UNIT_ENUMERATION, 0, 11, clock_division_values,
181     0, 0,
182   },
183   {
184     "B-", "BAR DURATION",
185     SETTING_DOMAIN_MULTI, { MULTI_CLOCK_BAR_DURATION, 0 },
186     SETTING_UNIT_BAR_DURATION, 0, kMaxBarDuration + 1, NULL,
187     0, 0,
188   },
189   {
190     "NU", "NUDGE 1ST TICK",
191     SETTING_DOMAIN_MULTI, { MULTI_CLOCK_NUDGE_FIRST_TICK, 0 },
192     SETTING_UNIT_ENUMERATION, 0, 1, boolean_values,
193     0, 0,
194   },
195   {
196     "MS", "CLOCK MANUAL START",
197     SETTING_DOMAIN_MULTI, { MULTI_CLOCK_MANUAL_START, 0 },
198     SETTING_UNIT_ENUMERATION, 0, 1, boolean_values,
199     0, 0,
200   },
201   {
202     "C>", "CLOCK OUTPUT",
203     SETTING_DOMAIN_MULTI, { MULTI_CLOCK_OVERRIDE, 0 },
204     SETTING_UNIT_ENUMERATION, 0, 1, boolean_values,
205     0, 0,
206   },
207   {
208     "CH", "CHANNEL",
209     SETTING_DOMAIN_PART, { PART_MIDI_CHANNEL, 0 },
210     SETTING_UNIT_MIDI_CHANNEL, 0, 16, NULL,
211     0, 4,
212   },
213   {
214     "N>", "NOTE>",
215     SETTING_DOMAIN_PART, { PART_MIDI_MIN_NOTE, 0 },
216     SETTING_UNIT_UINT8, 0, 127, NULL,
217     16, 5,
218   },
219   {
220     "N<", "NOTE<",
221     SETTING_DOMAIN_PART, { PART_MIDI_MAX_NOTE, 0 },
222     SETTING_UNIT_UINT8, 0, 127, NULL,
223     17, 6,
224   },
225   {
226     "NO", "NOTE",
227     SETTING_DOMAIN_PART, { PART_MIDI_MIN_NOTE, PART_MIDI_MAX_NOTE },
228     SETTING_UNIT_UINT8, 0, 127, NULL,
229     0, 0,
230   },
231   {
232     "V<", "VELO<",
233     SETTING_DOMAIN_PART, { PART_MIDI_MIN_VELOCITY, 0 },
234     SETTING_UNIT_UINT8, 0, 127, NULL,
235     0, 0,
236   },
237   {
238     "V>", "VELO>",
239     SETTING_DOMAIN_PART, { PART_MIDI_MAX_VELOCITY, 0 },
240     SETTING_UNIT_UINT8, 0, 127, NULL,
241     0, 0,
242   },
243   {
244     ">>", "OUTPUT MIDI MODE",
245     SETTING_DOMAIN_PART, { PART_MIDI_OUT_MODE, 0 },
246     SETTING_UNIT_ENUMERATION, 0, 2, midi_out_mode_values,
247     0, 7,
248   },
249   {
250     "VO", "VOICING",
251     SETTING_DOMAIN_PART, { PART_VOICING_ALLOCATION_MODE, 0 },
252     SETTING_UNIT_ENUMERATION, 1, VOICE_ALLOCATION_MODE_LAST - 1,
253     voicing_allocation_mode_values,
254     18, 8,
255   },
256   {
257     "NP", "NOTE PRIORITY",
258     SETTING_DOMAIN_PART, { PART_VOICING_ALLOCATION_PRIORITY, 0 },
259     SETTING_UNIT_ENUMERATION, 0, 2, voicing_allocation_priority_values,
260     19, 9,
261   },
262   {
263     "PO", "PORTAMENTO",
264     SETTING_DOMAIN_PART, { PART_VOICING_PORTAMENTO, 0 },
265     SETTING_UNIT_PORTAMENTO, 0, 101, NULL,
266     5, 10,
267   },
268   {
269     "LG", "LEGATO MODE",
270     SETTING_DOMAIN_PART, { PART_VOICING_LEGATO_MODE, 0 },
271     SETTING_UNIT_ENUMERATION, 0, 2, legato_mode_values,
272     20, 11,
273   },
274   {
275     "BR", "BEND RANGE",
276     SETTING_DOMAIN_PART, { PART_VOICING_PITCH_BEND_RANGE, 0 },
277     SETTING_UNIT_UINT8, 0, 24, NULL,
278     21, 12,
279   },
280   {
281     "VR", "VIBRATO RANGE",
282     SETTING_DOMAIN_PART, { PART_VOICING_VIBRATO_RANGE, 0 },
283     SETTING_UNIT_UINT8, 0, 12, NULL,
284     22, 13,
285   },
286   {
287     "VS", "VIBRATO SPEED",
288     SETTING_DOMAIN_PART, { PART_VOICING_MODULATION_RATE, 0 },
289     SETTING_UNIT_VIBRATO_SPEED, 0, 109, NULL,
290     23, 14,
291   },
292   {
293     "TT", "TRANSPOSE",
294     SETTING_DOMAIN_PART, { PART_VOICING_TUNING_TRANSPOSE, 0 },
295     SETTING_UNIT_INT8, -36, 36, NULL,
296     24, 15,
297   },
298   {
299     "TF", "FINE TUNING",
300     SETTING_DOMAIN_PART, { PART_VOICING_TUNING_FINE, 0 },
301     SETTING_UNIT_INT8, -64, 64, NULL,
302     25, 16,
303   },
304   {
305     "TR", "TUNING ROOT",
306     SETTING_DOMAIN_PART, { PART_VOICING_TUNING_ROOT, 0 },
307     SETTING_UNIT_ENUMERATION, 0, 11, note_values,
308     26, 17,
309   },
310   {
311     "TS", "TUNING SYSTEM",
312     SETTING_DOMAIN_PART, { PART_VOICING_TUNING_SYSTEM, 0 },
313     SETTING_UNIT_ENUMERATION, 0, TUNING_SYSTEM_LAST - 1,
314     tuning_system_values,
315     27, 18,
316   },
317   {
318     "T-", "TRIG DURATION",
319     SETTING_DOMAIN_PART, { PART_VOICING_TRIGGER_DURATION, 0 },
320     SETTING_UNIT_UINT8, 1, 99, NULL,
321     28, 19,
322   },
323   {
324     "T*", "TRIG VELOCITY SCALE",
325     SETTING_DOMAIN_PART, { PART_VOICING_TRIGGER_SCALE, 0 },
326     SETTING_UNIT_ENUMERATION, 0, 1, boolean_values,
327     29, 20,
328   },
329   {
330     "T\x88", "TRIG SHAPE",
331     SETTING_DOMAIN_PART, { PART_VOICING_TRIGGER_SHAPE, 0 },
332     SETTING_UNIT_ENUMERATION, 0, 5, trigger_shape_values,
333     30, 21,
334   },
335   {
336     "CV", "CV OUT",
337     SETTING_DOMAIN_PART, { PART_VOICING_AUX_CV, 0 },
338     SETTING_UNIT_ENUMERATION, 0, 7, voicing_aux_cv_values,
339     31, 22,
340   },
341   {
342     "3>", "CV OUT 3",
343     SETTING_DOMAIN_PART, { PART_VOICING_AUX_CV, 0 },
344     SETTING_UNIT_ENUMERATION, 0, 7, voicing_aux_cv_values,
345     31, 22,
346   },
347   {
348     "4>", "CV OUT 4",
349     SETTING_DOMAIN_PART, { PART_VOICING_AUX_CV_2, 0 },
350     SETTING_UNIT_ENUMERATION, 0, 7, voicing_aux_cv_values,
351     72, 0,
352   },
353   {
354     "OS", "OSCILLATOR",
355     SETTING_DOMAIN_PART, { PART_VOICING_AUDIO_MODE, 0 },
356     SETTING_UNIT_ENUMERATION, 0, 6, voicing_oscillator_values,
357     71, 23,
358   },
359   {
360     "C/", "CLOCK DIV",
361     SETTING_DOMAIN_PART, { PART_SEQUENCER_CLOCK_DIVISION, 0 },
362     SETTING_UNIT_ENUMERATION, 0, 11, clock_division_values,
363     102, 24,
364   },
365   {
366     "G-", "GATE LENGTH",
367     SETTING_DOMAIN_PART, { PART_SEQUENCER_GATE_LENGTH, 0 },
368     SETTING_UNIT_UINT8, 1, 48, NULL,
369     103, 25,
370   },
371   {
372     "AR", "ARP RANGE",
373     SETTING_DOMAIN_PART, { PART_SEQUENCER_ARP_RANGE, 0 },
374     SETTING_UNIT_UINT8, 0, 4, NULL,
375     104, 26,
376   },
377   {
378     "RG", "RHYTHMIC GENERATOR",
379     SETTING_DOMAIN_PART, { PART_SEQUENCER_ARP_RANGE, 0 },
380     SETTING_UNIT_ENUMERATION, 0, 1, boolean_values,
381     0, 0,
382   },
383   {
384     "AD", "ARP DIRECTION",
385     SETTING_DOMAIN_PART, { PART_SEQUENCER_ARP_DIRECTION, 0 },
386     SETTING_UNIT_ENUMERATION, 0, ARPEGGIATOR_DIRECTION_LAST - 1,
387     sequencer_arp_direction_values,
388     0, 0,
389   },
390   {
391     // Variant without the CHORD option.
392     "AD", "ARP DIRECTION",
393     SETTING_DOMAIN_PART, { PART_SEQUENCER_ARP_DIRECTION, 0 },
394     SETTING_UNIT_ENUMERATION, 0, ARPEGGIATOR_DIRECTION_LAST - 2,
395     sequencer_arp_direction_values,
396     105, 27,
397   },
398   {
399     "AP", "ARP PATTERN",
400     SETTING_DOMAIN_PART, { PART_SEQUENCER_ARP_PATTERN, 0 },
401     SETTING_UNIT_INDEX, 0, 21, NULL,
402     106, 28,
403   },
404   {
405     "RP", "RHYTHMIC PATTERN",
406     SETTING_DOMAIN_PART, { PART_SEQUENCER_ARP_PATTERN, 0 },
407     SETTING_UNIT_INDEX, 0, 21, NULL,
408     0, 0,
409   },
410   {
411     "E-", "EUCLIDEAN LENGTH",
412     SETTING_DOMAIN_PART, { PART_SEQUENCER_EUCLIDEAN_LENGTH, 0 },
413     SETTING_UNIT_UINT8, 0, 32, NULL,
414     107, 29,
415   },
416   {
417     "EF", "EUCLIEAN FILL",
418     SETTING_DOMAIN_PART, { PART_SEQUENCER_EUCLIDEAN_FILL, 0 },
419     SETTING_UNIT_UINT8, 0, 32, NULL,
420     108, 30,
421   },
422   {
423     "ER", "EUCLIEAN ROTATE",
424     SETTING_DOMAIN_PART, { PART_SEQUENCER_EUCLIDEAN_ROTATE, 0 },
425     SETTING_UNIT_UINT8, 0, 32, NULL,
426     109, 31,
427   },
428   {
429     "RC", "REMOTE CONTROL CHANNEL",
430     SETTING_DOMAIN_MULTI, { MULTI_REMOTE_CONTROL_CHANNEL, 0 },
431     SETTING_UNIT_MIDI_CHANNEL_OFF, 0, 16, NULL,
432     0, 0,
433   },
434   {
435     "T*", "TUNING FACTOR",
436     SETTING_DOMAIN_PART, { PART_VOICING_TUNING_FACTOR, 0 },
437     SETTING_UNIT_ENUMERATION, 0, 13,
438     tuning_factor_values,
439     0, 0,
440   }
441 };
442 
443 const SettingIndex mono_menu[] = {
444   SETTING_LAYOUT,
445   SETTING_CLOCK_TEMPO,
446   SETTING_CLOCK_SWING,
447   SETTING_CLOCK_INPUT_DIVISION,
448   SETTING_CLOCK_OUTPUT_DIVISION,
449   SETTING_CLOCK_BAR_DURATION,
450   SETTING_CLOCK_NUDGE_FIRST_TICK,
451   SETTING_CLOCK_MANUAL_START,
452   SETTING_MIDI_CHANNEL,
453   SETTING_MIDI_OUT_MODE,
454   SETTING_VOICING_ALLOCATION_PRIORITY,
455   SETTING_VOICING_LEGATO_MODE,
456   SETTING_VOICING_PORTAMENTO,
457   SETTING_VOICING_PITCH_BEND_RANGE,
458   SETTING_VOICING_VIBRATO_RANGE,
459   SETTING_VOICING_MODULATION_RATE,
460   SETTING_VOICING_TRIGGER_DURATION,
461   SETTING_VOICING_CV_OUT_3,
462   SETTING_VOICING_CV_OUT_4,
463   SETTING_VOICING_AUDIO_MODE,
464   SETTING_SEQUENCER_CLOCK_DIVISION,
465   SETTING_SEQUENCER_GATE_LENGTH,
466   SETTING_SEQUENCER_ARP_RANGE,
467   SETTING_SEQUENCER_ARP_DIRECTION_NO_CHORD,
468   SETTING_SEQUENCER_ARP_PATTERN,
469   SETTING_SEQUENCER_EUCLIDEAN_LENGTH,
470   SETTING_SEQUENCER_EUCLIDEAN_FILL,
471   SETTING_SEQUENCER_EUCLIDEAN_ROTATE,
472   SETTING_VOICING_TUNING_TRANSPOSE,
473   SETTING_VOICING_TUNING_FINE,
474   SETTING_VOICING_TUNING_SYSTEM,
475   SETTING_VOICING_TUNING_ROOT,
476   SETTING_VOICING_TUNING_FACTOR,
477   SETTING_REMOTE_CONTROL_CHANNEL,
478   SETTING_LAST
479 };
480 
481 const SettingIndex dual_mono_menu[] = {
482   SETTING_LAYOUT,
483   SETTING_CLOCK_TEMPO,
484   SETTING_CLOCK_SWING,
485   SETTING_CLOCK_INPUT_DIVISION,
486   SETTING_CLOCK_OUTPUT_DIVISION,
487   SETTING_CLOCK_BAR_DURATION,
488   SETTING_CLOCK_NUDGE_FIRST_TICK,
489   SETTING_CLOCK_MANUAL_START,
490   SETTING_ACTIVE_PART_2,
491   SETTING_MIDI_CHANNEL,
492   SETTING_MIDI_OUT_MODE,
493   SETTING_VOICING_ALLOCATION_PRIORITY,
494   SETTING_VOICING_LEGATO_MODE,
495   SETTING_VOICING_PORTAMENTO,
496   SETTING_VOICING_PITCH_BEND_RANGE,
497   SETTING_VOICING_VIBRATO_RANGE,
498   SETTING_VOICING_MODULATION_RATE,
499   SETTING_VOICING_CV_OUT,
500   SETTING_VOICING_AUDIO_MODE,
501   SETTING_SEQUENCER_CLOCK_DIVISION,
502   SETTING_SEQUENCER_GATE_LENGTH,
503   SETTING_SEQUENCER_ARP_RANGE,
504   SETTING_SEQUENCER_ARP_DIRECTION,
505   SETTING_SEQUENCER_ARP_PATTERN,
506   SETTING_SEQUENCER_EUCLIDEAN_LENGTH,
507   SETTING_SEQUENCER_EUCLIDEAN_FILL,
508   SETTING_SEQUENCER_EUCLIDEAN_ROTATE,
509   SETTING_VOICING_TUNING_TRANSPOSE,
510   SETTING_VOICING_TUNING_FINE,
511   SETTING_VOICING_TUNING_SYSTEM,
512   SETTING_VOICING_TUNING_ROOT,
513   SETTING_VOICING_TUNING_FACTOR,
514   SETTING_REMOTE_CONTROL_CHANNEL,
515   SETTING_LAST
516 };
517 
518 const SettingIndex quad_mono_menu[] = {
519   SETTING_LAYOUT,
520   SETTING_CLOCK_TEMPO,
521   SETTING_CLOCK_SWING,
522   SETTING_CLOCK_INPUT_DIVISION,
523   SETTING_CLOCK_OVERRIDE,
524   SETTING_CLOCK_OUTPUT_DIVISION,
525   SETTING_CLOCK_BAR_DURATION,
526   SETTING_CLOCK_NUDGE_FIRST_TICK,
527   SETTING_CLOCK_MANUAL_START,
528   SETTING_ACTIVE_PART_4,
529   SETTING_MIDI_CHANNEL,
530   SETTING_MIDI_OUT_MODE,
531   SETTING_VOICING_ALLOCATION_PRIORITY,
532   SETTING_VOICING_LEGATO_MODE,
533   SETTING_VOICING_PORTAMENTO,
534   SETTING_VOICING_PITCH_BEND_RANGE,
535   SETTING_VOICING_VIBRATO_RANGE,
536   SETTING_VOICING_MODULATION_RATE,
537   SETTING_VOICING_AUDIO_MODE,
538   SETTING_SEQUENCER_CLOCK_DIVISION,
539   SETTING_SEQUENCER_GATE_LENGTH,
540   SETTING_SEQUENCER_ARP_RANGE,
541   SETTING_SEQUENCER_ARP_DIRECTION,
542   SETTING_SEQUENCER_ARP_PATTERN,
543   SETTING_SEQUENCER_EUCLIDEAN_LENGTH,
544   SETTING_SEQUENCER_EUCLIDEAN_FILL,
545   SETTING_SEQUENCER_EUCLIDEAN_ROTATE,
546   SETTING_VOICING_TUNING_TRANSPOSE,
547   SETTING_VOICING_TUNING_FINE,
548   SETTING_VOICING_TUNING_SYSTEM,
549   SETTING_VOICING_TUNING_ROOT,
550   SETTING_VOICING_TUNING_FACTOR,
551   SETTING_REMOTE_CONTROL_CHANNEL,
552   SETTING_LAST
553 };
554 
555 const SettingIndex dual_poly_menu[] = {
556   SETTING_LAYOUT,
557   SETTING_CLOCK_TEMPO,
558   SETTING_CLOCK_SWING,
559   SETTING_CLOCK_INPUT_DIVISION,
560   SETTING_CLOCK_OUTPUT_DIVISION,
561   SETTING_CLOCK_BAR_DURATION,
562   SETTING_CLOCK_NUDGE_FIRST_TICK,
563   SETTING_CLOCK_MANUAL_START,
564   SETTING_MIDI_CHANNEL,
565   SETTING_MIDI_OUT_MODE,
566   SETTING_VOICING_ALLOCATION_MODE,
567   SETTING_VOICING_PORTAMENTO,
568   SETTING_VOICING_PITCH_BEND_RANGE,
569   SETTING_VOICING_VIBRATO_RANGE,
570   SETTING_VOICING_MODULATION_RATE,
571   SETTING_VOICING_CV_OUT_3,
572   SETTING_VOICING_CV_OUT_4,
573   SETTING_VOICING_AUDIO_MODE,
574   SETTING_SEQUENCER_CLOCK_DIVISION,
575   SETTING_SEQUENCER_GATE_LENGTH,
576   SETTING_SEQUENCER_ARP_RANGE,
577   SETTING_SEQUENCER_ARP_DIRECTION,
578   SETTING_SEQUENCER_ARP_PATTERN,
579   SETTING_SEQUENCER_EUCLIDEAN_LENGTH,
580   SETTING_SEQUENCER_EUCLIDEAN_FILL,
581   SETTING_SEQUENCER_EUCLIDEAN_ROTATE,
582   SETTING_VOICING_TUNING_TRANSPOSE,
583   SETTING_VOICING_TUNING_FINE,
584   SETTING_VOICING_TUNING_SYSTEM,
585   SETTING_VOICING_TUNING_ROOT,
586   SETTING_VOICING_TUNING_FACTOR,
587   SETTING_REMOTE_CONTROL_CHANNEL,
588   SETTING_LAST
589 };
590 
591 const SettingIndex quad_poly_menu[] = {
592   SETTING_LAYOUT,
593   SETTING_CLOCK_TEMPO,
594   SETTING_CLOCK_SWING,
595   SETTING_CLOCK_INPUT_DIVISION,
596   SETTING_CLOCK_OVERRIDE,
597   SETTING_CLOCK_OUTPUT_DIVISION,
598   SETTING_CLOCK_BAR_DURATION,
599   SETTING_CLOCK_NUDGE_FIRST_TICK,
600   SETTING_CLOCK_MANUAL_START,
601   SETTING_MIDI_CHANNEL,
602   SETTING_MIDI_OUT_MODE,
603   SETTING_VOICING_ALLOCATION_MODE,
604   SETTING_VOICING_PORTAMENTO,
605   SETTING_VOICING_PITCH_BEND_RANGE,
606   SETTING_VOICING_VIBRATO_RANGE,
607   SETTING_VOICING_MODULATION_RATE,
608   SETTING_VOICING_AUDIO_MODE,
609   SETTING_SEQUENCER_CLOCK_DIVISION,
610   SETTING_SEQUENCER_GATE_LENGTH,
611   SETTING_SEQUENCER_ARP_RANGE,
612   SETTING_SEQUENCER_ARP_DIRECTION,
613   SETTING_SEQUENCER_ARP_PATTERN,
614   SETTING_SEQUENCER_EUCLIDEAN_LENGTH,
615   SETTING_SEQUENCER_EUCLIDEAN_FILL,
616   SETTING_SEQUENCER_EUCLIDEAN_ROTATE,
617   SETTING_VOICING_TUNING_TRANSPOSE,
618   SETTING_VOICING_TUNING_FINE,
619   SETTING_VOICING_TUNING_SYSTEM,
620   SETTING_VOICING_TUNING_ROOT,
621   SETTING_VOICING_TUNING_FACTOR,
622   SETTING_REMOTE_CONTROL_CHANNEL,
623   SETTING_LAST
624 };
625 
626 const SettingIndex dual_polychained_menu[] = {
627   SETTING_LAYOUT,
628   SETTING_CLOCK_TEMPO,
629   SETTING_CLOCK_SWING,
630   SETTING_CLOCK_INPUT_DIVISION,
631   SETTING_CLOCK_OUTPUT_DIVISION,
632   SETTING_CLOCK_BAR_DURATION,
633   SETTING_CLOCK_NUDGE_FIRST_TICK,
634   SETTING_CLOCK_MANUAL_START,
635   SETTING_MIDI_CHANNEL,
636   SETTING_MIDI_OUT_MODE,
637   SETTING_VOICING_PORTAMENTO,
638   SETTING_VOICING_PITCH_BEND_RANGE,
639   SETTING_VOICING_VIBRATO_RANGE,
640   SETTING_VOICING_MODULATION_RATE,
641   SETTING_VOICING_CV_OUT_3,
642   SETTING_VOICING_CV_OUT_4,
643   SETTING_VOICING_AUDIO_MODE,
644   SETTING_SEQUENCER_CLOCK_DIVISION,
645   SETTING_SEQUENCER_GATE_LENGTH,
646   SETTING_SEQUENCER_ARP_RANGE,
647   SETTING_SEQUENCER_ARP_DIRECTION,
648   SETTING_SEQUENCER_ARP_PATTERN,
649   SETTING_SEQUENCER_EUCLIDEAN_LENGTH,
650   SETTING_SEQUENCER_EUCLIDEAN_FILL,
651   SETTING_SEQUENCER_EUCLIDEAN_ROTATE,
652   SETTING_VOICING_TUNING_TRANSPOSE,
653   SETTING_VOICING_TUNING_FINE,
654   SETTING_VOICING_TUNING_SYSTEM,
655   SETTING_VOICING_TUNING_ROOT,
656   SETTING_VOICING_TUNING_FACTOR,
657   SETTING_REMOTE_CONTROL_CHANNEL,
658   SETTING_LAST
659 };
660 
661 const SettingIndex quad_polychained_menu[] = {
662   SETTING_LAYOUT,
663   SETTING_CLOCK_TEMPO,
664   SETTING_CLOCK_SWING,
665   SETTING_CLOCK_INPUT_DIVISION,
666   SETTING_CLOCK_OUTPUT_DIVISION,
667   SETTING_CLOCK_BAR_DURATION,
668   SETTING_CLOCK_NUDGE_FIRST_TICK,
669   SETTING_CLOCK_MANUAL_START,
670   SETTING_MIDI_CHANNEL,
671   SETTING_MIDI_OUT_MODE,
672   SETTING_VOICING_PORTAMENTO,
673   SETTING_VOICING_PITCH_BEND_RANGE,
674   SETTING_VOICING_VIBRATO_RANGE,
675   SETTING_VOICING_MODULATION_RATE,
676   SETTING_VOICING_CV_OUT_3,
677   SETTING_VOICING_CV_OUT_4,
678   SETTING_VOICING_AUDIO_MODE,
679   SETTING_SEQUENCER_CLOCK_DIVISION,
680   SETTING_SEQUENCER_GATE_LENGTH,
681   SETTING_SEQUENCER_ARP_RANGE,
682   SETTING_SEQUENCER_ARP_DIRECTION,
683   SETTING_SEQUENCER_ARP_PATTERN,
684   SETTING_SEQUENCER_EUCLIDEAN_LENGTH,
685   SETTING_SEQUENCER_EUCLIDEAN_FILL,
686   SETTING_SEQUENCER_EUCLIDEAN_ROTATE,
687   SETTING_VOICING_TUNING_TRANSPOSE,
688   SETTING_VOICING_TUNING_FINE,
689   SETTING_VOICING_TUNING_SYSTEM,
690   SETTING_VOICING_TUNING_ROOT,
691   SETTING_VOICING_TUNING_FACTOR,
692   SETTING_REMOTE_CONTROL_CHANNEL,
693   SETTING_LAST
694 };
695 
696 const SettingIndex octal_polychained_menu[] = {
697   SETTING_LAYOUT,
698   SETTING_CLOCK_TEMPO,
699   SETTING_CLOCK_SWING,
700   SETTING_CLOCK_INPUT_DIVISION,
701   SETTING_CLOCK_OVERRIDE,
702   SETTING_CLOCK_OUTPUT_DIVISION,
703   SETTING_CLOCK_BAR_DURATION,
704   SETTING_CLOCK_NUDGE_FIRST_TICK,
705   SETTING_CLOCK_MANUAL_START,
706   SETTING_MIDI_CHANNEL,
707   SETTING_MIDI_OUT_MODE,
708   SETTING_VOICING_PORTAMENTO,
709   SETTING_VOICING_PITCH_BEND_RANGE,
710   SETTING_VOICING_VIBRATO_RANGE,
711   SETTING_VOICING_MODULATION_RATE,
712   SETTING_VOICING_AUDIO_MODE,
713   SETTING_SEQUENCER_CLOCK_DIVISION,
714   SETTING_SEQUENCER_GATE_LENGTH,
715   SETTING_SEQUENCER_ARP_RANGE,
716   SETTING_SEQUENCER_ARP_DIRECTION,
717   SETTING_SEQUENCER_ARP_PATTERN,
718   SETTING_SEQUENCER_EUCLIDEAN_LENGTH,
719   SETTING_SEQUENCER_EUCLIDEAN_FILL,
720   SETTING_SEQUENCER_EUCLIDEAN_ROTATE,
721   SETTING_VOICING_TUNING_TRANSPOSE,
722   SETTING_VOICING_TUNING_FINE,
723   SETTING_VOICING_TUNING_SYSTEM,
724   SETTING_VOICING_TUNING_ROOT,
725   SETTING_VOICING_TUNING_FACTOR,
726   SETTING_REMOTE_CONTROL_CHANNEL,
727   SETTING_LAST
728 };
729 
730 const SettingIndex quad_triggers_menu[] = {
731   SETTING_LAYOUT,
732   SETTING_CLOCK_TEMPO,
733   SETTING_CLOCK_SWING,
734   SETTING_CLOCK_INPUT_DIVISION,
735   SETTING_CLOCK_OUTPUT_DIVISION,
736   SETTING_CLOCK_BAR_DURATION,
737   SETTING_CLOCK_NUDGE_FIRST_TICK,
738   SETTING_CLOCK_MANUAL_START,
739   SETTING_ACTIVE_PART_4,
740   SETTING_MIDI_CHANNEL,
741   SETTING_MIDI_NOTE,
742   SETTING_MIDI_OUT_MODE,
743   SETTING_VOICING_TRIGGER_DURATION,
744   SETTING_VOICING_TRIGGER_SCALE,
745   SETTING_VOICING_TRIGGER_SHAPE,
746   SETTING_SEQUENCER_CLOCK_DIVISION,
747   SETTING_SEQUENCER_RHYTHM_GENERATOR,
748   SETTING_SEQUENCER_RHYTHM_PATTERN,
749   SETTING_SEQUENCER_EUCLIDEAN_LENGTH,
750   SETTING_SEQUENCER_EUCLIDEAN_FILL,
751   SETTING_SEQUENCER_EUCLIDEAN_ROTATE,
752   SETTING_REMOTE_CONTROL_CHANNEL,
753   SETTING_LAST
754 };
755 
756 const SettingIndex three_one_menu[] = {
757   SETTING_LAYOUT,
758   SETTING_CLOCK_TEMPO,
759   SETTING_CLOCK_SWING,
760   SETTING_CLOCK_INPUT_DIVISION,
761   SETTING_CLOCK_OUTPUT_DIVISION,
762   SETTING_CLOCK_BAR_DURATION,
763   SETTING_CLOCK_NUDGE_FIRST_TICK,
764   SETTING_CLOCK_MANUAL_START,
765   SETTING_ACTIVE_PART_2,
766   SETTING_MIDI_CHANNEL,
767   SETTING_MIDI_OUT_MODE,
768   SETTING_VOICING_ALLOCATION_MODE,
769   SETTING_VOICING_ALLOCATION_PRIORITY,
770   SETTING_VOICING_LEGATO_MODE,
771   SETTING_VOICING_PORTAMENTO,
772   SETTING_VOICING_PITCH_BEND_RANGE,
773   SETTING_VOICING_VIBRATO_RANGE,
774   SETTING_VOICING_MODULATION_RATE,
775   SETTING_VOICING_AUDIO_MODE,
776   SETTING_SEQUENCER_CLOCK_DIVISION,
777   SETTING_SEQUENCER_GATE_LENGTH,
778   SETTING_SEQUENCER_ARP_RANGE,
779   SETTING_SEQUENCER_ARP_DIRECTION,
780   SETTING_SEQUENCER_ARP_PATTERN,
781   SETTING_SEQUENCER_EUCLIDEAN_LENGTH,
782   SETTING_SEQUENCER_EUCLIDEAN_FILL,
783   SETTING_SEQUENCER_EUCLIDEAN_ROTATE,
784   SETTING_VOICING_TUNING_TRANSPOSE,
785   SETTING_VOICING_TUNING_FINE,
786   SETTING_VOICING_TUNING_SYSTEM,
787   SETTING_VOICING_TUNING_ROOT,
788   SETTING_VOICING_TUNING_FACTOR,
789   SETTING_REMOTE_CONTROL_CHANNEL,
790   SETTING_LAST
791 };
792 
793 const SettingIndex quad_voltages_menu[] = {
794   SETTING_LAYOUT,
795   SETTING_ACTIVE_PART_4,
796   SETTING_MIDI_CHANNEL,
797   SETTING_VOICING_CV_OUT,
798   SETTING_CLOCK_TEMPO,
799   SETTING_CLOCK_SWING,
800   SETTING_CLOCK_INPUT_DIVISION,
801   SETTING_CLOCK_OVERRIDE,
802   SETTING_CLOCK_OUTPUT_DIVISION,
803   SETTING_CLOCK_BAR_DURATION,
804   SETTING_CLOCK_NUDGE_FIRST_TICK,
805   SETTING_CLOCK_MANUAL_START,
806   SETTING_REMOTE_CONTROL_CHANNEL,
807   SETTING_LAST
808 };
809 
810 const SettingIndex* const Settings::menus_[] = {
811   mono_menu,
812   dual_mono_menu,
813   quad_mono_menu,
814   dual_poly_menu,
815   quad_poly_menu,
816   dual_polychained_menu,
817   quad_polychained_menu,
818   octal_polychained_menu,
819   quad_triggers_menu,
820   quad_voltages_menu,
821   three_one_menu
822 };
823 
Init()824 void Settings::Init() {
825   global_.active_part = 0;
826 
827   // Build tables used to convert from a CC to a parameter number.
828   std::fill(&part_cc_map_[0], &part_cc_map_[128], 0xff);
829   std::fill(&remote_control_cc_map_[0], &remote_control_cc_map_[128], 0xff);
830 
831   for (uint8_t i = 0; i < SETTING_LAST; ++i) {
832     const Setting& setting = settings_[i];
833     if (setting.part_cc) {
834       if (setting.domain != SETTING_DOMAIN_PART) while (1);
835       part_cc_map_[setting.part_cc] = i;
836     }
837     if (setting.remote_control_cc) {
838       uint8_t num_instances = setting.domain == SETTING_DOMAIN_PART ? 4 : 1;
839       for (uint8_t j = 0; j < num_instances; ++j) {
840         remote_control_cc_map_[setting.remote_control_cc + j * 32] = i;
841       }
842     }
843   }
844 }
845 
Set(uint8_t address,uint8_t value)846 void Settings::Set(uint8_t address, uint8_t value) {
847   uint8_t* bytes;
848   bytes = static_cast<uint8_t*>(static_cast<void*>(&global_));
849   bytes[address] = value;
850 }
851 
SetFromCC(uint8_t part_index,uint8_t controller,uint8_t value)852 void Settings::SetFromCC(
853     uint8_t part_index,
854     uint8_t controller,
855     uint8_t value) {
856   uint8_t* map = part_index == 0xff ? remote_control_cc_map_ : part_cc_map_;
857   uint8_t part = part_index == 0xff ? controller >> 5 : part_index;
858   uint8_t setting_index = map[controller];
859   if (setting_index != 0xff) {
860     const Setting& setting = settings_[setting_index];
861     Set(setting, &part, setting.Scale(value));
862   }
863 }
864 
Set(const Setting & setting,uint8_t * part,uint8_t value)865 void Settings::Set(const Setting& setting, uint8_t* part, uint8_t value) {
866   switch (setting.domain) {
867     case SETTING_DOMAIN_GLOBAL:
868       Set(setting.address[0], value);
869       break;
870 
871     case SETTING_DOMAIN_MULTI:
872       multi.Set(setting.address[0], value);
873       if (*part >= multi.num_active_parts()) {
874         *part = multi.num_active_parts() - 1;
875       }
876       break;
877 
878     case SETTING_DOMAIN_PART:
879       multi.mutable_part(*part)->Set(setting.address[0], value);
880       // When the module is configured in *triggers* mode, each part is mapped
881       // to a single note. To edit this setting, both the "note min" and
882       // "note max" parameters are simultaneously changed to the same value.
883       // This is a bit more user friendly than letting the user set note min
884       // and note max to the same value.
885       if (setting.address[1]) {
886         multi.mutable_part(*part)->Set(setting.address[1], value);
887       }
888       break;
889   }
890 }
891 
Set(const Setting & setting,uint8_t value)892 void Settings::Set(const Setting& setting, uint8_t value) {
893   Set(setting, &global_.active_part, value);
894 }
895 
Get(const Setting & setting) const896 uint8_t Settings::Get(const Setting& setting) const {
897   uint8_t value = 0;
898   switch (setting.domain) {
899     case SETTING_DOMAIN_GLOBAL:
900       value = Get(setting.address[0]);
901       break;
902 
903     case SETTING_DOMAIN_MULTI:
904       value = multi.Get(setting.address[0]);
905       break;
906 
907     case SETTING_DOMAIN_PART:
908       value = multi.part(global_.active_part).Get(setting.address[0]);
909       break;
910   }
911   return value;
912 }
913 
Print(const Setting & setting,char * buffer) const914 void Settings::Print(const Setting& setting, char* buffer) const {
915   uint8_t value = Get(setting);
916   switch (setting.unit) {
917     case SETTING_UNIT_UINT8:
918       PrintInteger(buffer, value);
919       break;
920 
921     case SETTING_UNIT_INT8:
922       {
923         int8_t value_signed = value;
924         if (value_signed >= 0) {
925           PrintInteger(buffer, value_signed);
926         } else if (value_signed > -10){
927           PrintInteger(buffer, -value_signed);
928           buffer[0] = '-';
929         } else {
930           PrintInteger(buffer, -value_signed);
931           buffer[2] = ' ';
932           buffer[3] = '-';
933           buffer[4] = buffer[0];
934           buffer[5] = buffer[1];
935           buffer[6] = '\0';
936         }
937       }
938       break;
939 
940     case SETTING_UNIT_INDEX:
941       PrintInteger(buffer, value + 1);
942       break;
943 
944     case SETTING_UNIT_BAR_DURATION:
945       if (value <= kMaxBarDuration) {
946         PrintInteger(buffer, value);
947       } else {
948         strcpy(buffer, "oo");
949       }
950       break;
951 
952     case SETTING_UNIT_TEMPO:
953       if (value == 39) {
954         strcpy(buffer, "EXTERNAL");
955       } else {
956         PrintInteger(buffer, value);
957       }
958       break;
959 
960     case SETTING_UNIT_MIDI_CHANNEL:
961       if (value == 0x10) {
962         strcpy(buffer, "ALL");
963       } else {
964         PrintInteger(buffer, value + 1);
965       }
966       break;
967 
968     case SETTING_UNIT_MIDI_CHANNEL_OFF:
969       if (value == 0x00) {
970         strcpy(buffer, "OFF");
971       } else {
972         PrintInteger(buffer, value);
973       }
974       break;
975 
976     case SETTING_UNIT_VIBRATO_SPEED:
977       if (value < 100) {
978         PrintInteger(buffer, value);
979       } else {
980         strcpy(buffer, clock_division_values[value - 100]);
981       }
982       break;
983 
984     case SETTING_UNIT_PORTAMENTO:
985       if (value <= 50) {
986         PrintInteger(buffer, value);
987       } else {
988         PrintInteger(buffer, value - 51);
989       }
990       if (buffer[0] == ' ') {
991         buffer[0] = (value <= 50) ? 'T' : 'R';
992       }
993       break;
994 
995     case SETTING_UNIT_ENUMERATION:
996       strcpy(buffer, setting.values[value]);
997       break;
998 
999     default:
1000       strcpy(buffer, "??");
1001   }
1002 }
1003 
Increment(const Setting & setting,int16_t increment)1004 void Settings::Increment(const Setting& setting, int16_t increment) {
1005   int16_t value = Get(setting);
1006   if (setting.unit == SETTING_UNIT_INT8) {
1007     value = static_cast<int8_t>(value);
1008   }
1009   value += increment;
1010   if (value < setting.min_value) {
1011     value = setting.min_value;
1012   } else if (value > setting.max_value) {
1013     value = setting.max_value;
1014   }
1015   Set(setting, static_cast<uint8_t>(value));
1016 }
1017 
1018 /* static */
PrintInteger(char * buffer,uint8_t number)1019 void Settings::PrintInteger(char* buffer, uint8_t number) {
1020   buffer[1] = '0' + (number % 10);
1021   number /= 10;
1022   buffer[0] = number ? '0' + (number % 10) : ' ';
1023   number /= 10;
1024   buffer[2] = '\0';
1025 }
1026 
1027 /* extern */
1028 Settings settings;
1029 
1030 }  // namespace yarns