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