1
2 /*
3 * Diverse Bristol audio routines.
4 * Copyright (c) by Nick Copeland <nickycopeland@hotmail.com> 1996,2012
5 *
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
22 #include <fcntl.h>
23 #include <strings.h>
24 #include <sys/time.h>
25
26 #include "brightonMixer.h"
27 #include "brightoninternals.h"
28
29 #define DISPLAY1 (FUNCTION_COUNT - 6)
30 #define DISPLAY2 (FUNCTION_COUNT - 5)
31 #define DISPLAY3 (FUNCTION_COUNT - 4)
32 #define DISPLAY4 (FUNCTION_COUNT - 3)
33 #define DISPLAY5 (FUNCTION_COUNT - 2)
34 #define DISPLAY6 (FUNCTION_COUNT - 1)
35
36 #include "brighton.h"
37 #include "brightonMini.h"
38 #include "brightonMixer.h"
39 #include "brightonMixerMemory.h"
40
41 static char text[128];
42 /*static char scratch[MAX_CHAN_COUNT][16]; */
43 static char memscratch[16];
44
45 static char *removeInterface(guiSynth *);
46 static char *printInterface(guiSynth *);
47 static char *printTrackMenu(guiSynth *);
48 static char *printMidiMenu(guiSynth *);
49 static char *trackDown(guiSynth *);
50 static char *trackUp(guiSynth *);
51 static char *midiDown(guiSynth *);
52 static char *midiUp(guiSynth *);
53 static char *setTrackText(guiSynth *);
54
55 static char *printMemMenu(guiSynth *);
56 static char *memoryBuildList(guiSynth *);
57 static char *memoryList(guiSynth *);
58 static char *memoryShowList(guiSynth *);
59 static char *memoryListUp(guiSynth *);
60 static char *memoryListDown(guiSynth *);
61
62 static char *memorySel1(guiSynth *);
63 static char *memorySel2(guiSynth *);
64 static char *memorySel3(guiSynth *);
65 static char *memorySel4(guiSynth *);
66
67 static char *songSel1(guiSynth *);
68 static char *songSel2(guiSynth *);
69 static char *songSel3(guiSynth *);
70 static char *songSel4(guiSynth *);
71
72 static char *songList(guiSynth *);
73 static char *createSongDir(guiSynth *);
74
75 extern int loadMixerMemory(guiSynth *, char *, int);
76 extern int saveMixerMemory(guiSynth *, char *);
77 extern void displayPanel(guiSynth *, char *, int, int, int);
78 extern int setMixerMemory(mixerMem *, int, int, float *, char *);
79
80 /*
81 * Ok, fixed table sizes, but a kilo of memories will do for now.
82 */
83 #define MIXER_MEM_COUNT 1024
84 int memCount = -1, memIndex = 0;
85 char memList[MIXER_MEM_COUNT][32];
86
87 guiSynth *theSynth;
88
89 /*
90 * We should not really have to rely on timers within the GUI: The engine will
91 * evaluate RMS and Peak signal values for the channels, and save them. The
92 * Midi thread should take these values X times per second (ie, with a timer)
93 * and send a message to the GUI over the interface tap.
94 *
95 * Whenever the GUI gets a VU message it should update the VU meter display.
96 */
97 u_long vuInterval = 100000;
98
99 /*
100 * Need a set of structures that allow a TitleBar strings, 5 substrings,
101 * 2 "next menus" for the Title, 2 "next menus" or otherwise functions.
102 */
103 typedef char *(*MenuFunc)(guiSynth *);
104
105 typedef struct mLine {
106 char title[32];
107 int last, next;
108 MenuFunc lmenuFunc;
109 MenuFunc rmenuFunc;
110 } mLine;
111
112 #define line1 line[0]
113 #define line2 line[1]
114 #define line3 line[2]
115 #define line4 line[3]
116 #define line5 line[4]
117
118 typedef struct Menu {
119 mLine title;
120 mLine line[5];
121 } Menu;
122
123 #define MENU_COUNT 32
124
125 int currentMenu = -1;
126 int currentTrack = 0;
127
setInt0()128 char *setInt0()
129 {
130 vuInterval = 0;
131 return(NULL);
132 }
133
setInt50()134 char *setInt50()
135 {
136 vuInterval = 50000;
137 return(NULL);
138 }
139
setInt100()140 char *setInt100()
141 {
142 vuInterval = 100000;
143 return(NULL);
144 }
145
setInt200()146 char *setInt200()
147 {
148 vuInterval = 200000;
149 return(NULL);
150 }
151
loadShim(guiSynth * synth)152 static char * loadShim(guiSynth *synth)
153 {
154 loadMixerMemory(synth, memscratch, 0);
155 return(NULL);
156 }
157
saveShim(guiSynth * synth)158 static char * saveShim(guiSynth *synth)
159 {
160 saveMixerMemory(synth, memscratch);
161 return(NULL);
162 }
undoShim(guiSynth * synth)163 static char * undoShim(guiSynth *synth)
164 {
165 loadMixerMemory(synth, "revert", 0);
166 return(NULL);
167 }
168
169 Menu functionMenu[MENU_COUNT] = {
170 {
171 {" Main Menu ", 3, 1, 0, 0},
172 {{"Effects Bus ", 1, 2, 0, 0},
173 {"Track VU ", 3, 12, 0, 0},
174 {"Audio Mem ", 13, 14, 0, 0},
175 {"Stats Print ", 15, -1, 0, printInterface},
176 {"Midi Quit ", 17, 16, 0, 0}},
177 },
178 {
179 {" Effects Menu ", 0, 2, 0, 0},
180 {{"Pre 1 Post 1 ", 4, 8, 0, 0},
181 {"Pre 2 Post 2 ", 5, 9, 0, 0},
182 {"Pre 3 Post 3 ", 6, 10, 0, 0},
183 {"Pre 4 Post 4 ", 7, 11, 0, 0},
184 {" Main ", -1, 0, 0, 0}},
185 },
186 {
187 {" Bus Menu ", 1, 3, 0, 0},
188 {{"Effects Bus ", 1, 2, 0, 0},
189 {"Stats ", 3, -1, 0, 0},
190 {" ", -1, -1, 0, 0},
191 {" ", -1, -1, 0, 0},
192 {" Main ", -1, 0, 0, 0}},
193 },
194 {
195 {" Track Menu ", 2, 12, printTrackMenu, 0},
196 {{" ", -1, -1, 0, 0},
197 {"Text: ", -1, -1, 0, 0},
198 {"Down UP ", -1, -1, trackDown, trackUp},
199 {" ", -1, -1, 0, 0},
200 {" MAIN ", -1, 0, setTrackText, 0}},
201 },
202 /* 4: */
203 {
204 {" Pre 1 Menu ", 1, 1, 0, 0},
205 {{"P 1 P 4 ", -1, -1, 0, 0},
206 {"P 2 P 5 ", -1, -1, 0, 0},
207 {"P 3 P 6 ", -1, -1, 0, 0},
208 {"Prev Next ", 11, 5, 0, 0},
209 {" Main ", -1, 0, 0, 0}},
210 },
211 {
212 {" Pre 2 Menu ", 1, 1, 0, 0},
213 {{"P 1 P 4 ", -1, -1, 0, 0},
214 {"P 2 P 5 ", -1, -1, 0, 0},
215 {"P 3 P 6 ", -1, -1, 0, 0},
216 {"Prev next ", 4, 6, 0, 0},
217 {" Main ", -1, 0, 0, 0}},
218 },
219 {
220 {" Pre 3 Menu ", 1, 1, 0, 0},
221 {{"P 1 P 4 ", -1, -1, 0, 0},
222 {"P 2 P 5 ", -1, -1, 0, 0},
223 {"P 3 P 6 ", -1, -1, 0, 0},
224 {"Prev next ", 5, 7, 0, 0},
225 {" Main ", -1, 0, 0, 0}},
226 },
227 {
228 {" Pre 4 Menu ", 1, 1, 0, 0},
229 {{"P 1 P 4 ", -1, -1, 0, 0},
230 {"P 2 P 5 ", -1, -1, 0, 0},
231 {"P 3 P 6 ", -1, -1, 0, 0},
232 {"Prev next ", 6, 8, 0, 0},
233 {" Main ", -1, 0, 0, 0}},
234 },
235 /* 8: */
236 {
237 {" Post 1 Menu ", 1, 1, 0, 0},
238 {{"P 1 P 4 ", -1, -1, 0, 0},
239 {"P 2 P 5 ", -1, -1, 0, 0},
240 {"P 3 P 6 ", -1, -1, 0, 0},
241 {"Prev next ", 7, 9, 0, 0},
242 {" Main ", -1, 0, 0, 0}},
243 },
244 {
245 {" Post 2 Menu ", 1, 1, 0, 0},
246 {{"P 1 P 4 ", -1, -1, 0, 0},
247 {"P 2 P 5 ", -1, -1, 0, 0},
248 {"P 3 P 6 ", -1, -1, 0, 0},
249 {"Prev next ", 8, 10, 0, 0},
250 {" Main ", -1, 0, 0, 0}},
251 },
252 {
253 {" Post 3 Menu ", 1, 1, 0, 0},
254 {{"P 1 P 4 ", -1, -1, 0, 0},
255 {"P 2 P 5 ", -1, -1, 0, 0},
256 {"P 3 P 6 ", -1, -1, 0, 0},
257 {"Prev next ", 9, 11, 0, 0},
258 {" Main ", -1, 0, 0, 0}},
259 },
260 {
261 {" Post 4 Menu ", 1, 1, 0, 0},
262 {{"P 1 P 4 ", -1, -1, 0, 0},
263 {"P 2 P 5 ", -1, -1, 0, 0},
264 {"P 3 P 6 ", -1, -1, 0, 0},
265 {"Prev next ", 10, 4, 0, 0},
266 {" Main ", -1, 0, 0, 0}},
267 },
268 /* 12: */
269 {
270 {" VU Menu ", 3, 13, 0, 0},
271 {{"Interval 50ms ", -1, -1, setInt50, 0},
272 {"Interval 100ms ", -1, -1, setInt100, 0},
273 {"Interval 200ms ", -1, -1, setInt200, 0},
274 {" ", -1, -1, 0, 0},
275 {"Off MAIN ", -1, 0, setInt0, 0}},
276 },
277 {
278 {" Audio Menu ", 12, 14, 0, 0},
279 {{"Effects Bus ", 0, 2, 0, 0},
280 {"Stats ", 0, -1, 0, 0},
281 {" ", -1, -1, 0, 0},
282 {" ", -1, -1, 0, 0},
283 {" MAIN ", -1, 0, 0, 0}},
284 },
285 {
286 {" MEM Menu ", 13, 15, printMemMenu, 0},
287 {{"Name: ", -1, -1, 0, 0},
288 {"Create Song ", -1, -1, createSongDir, 0},
289 {"Load Search ", -1, 20, loadShim, memoryList},
290 {"Save Undo ", -1, -1, saveShim, undoShim},
291 {"Songs MAIN ", 21, 0, songList, 0}},
292 },
293 {
294 {" Stats Menu ", 14, 0, 0, 0},
295 {{"Effects Bus ", 0, 2, 0, 0},
296 {"Stats ", 0, -1, 0, 0},
297 {" ", -1, -1, 0, 0},
298 {" ", -1, -1, 0, 0},
299 {" MAIN ", -1, 0, 0, 0}},
300 },
301 /* 16: */
302 {
303 {" Quit Menu ", 0, 0, 0, 0},
304 {{" ", -1, -1, 0, 0},
305 {" ", -1, -1, 0, 0},
306 {" Really quit? ", -1, -1, 0, 0},
307 {" ", -1, -1, 0, 0},
308 {"No Yes ", 0, 3, 0, removeInterface}},
309 },
310 {
311 {" Midi Menu ", 0, 0, printMidiMenu, 0},
312 {{" ", -1, -1, 0, 0},
313 {"Channel: ", -1, -1, 0, 0},
314 {" Up ", -1, -1, 0, midiUp},
315 {" Down ", -1, -1, 0, midiDown},
316 {" Main ", -1, 0, 0, 0}},
317 },
318 {
319 },
320 {
321 },
322 /* 20: */
323 {
324 {"Back Search Main ", 14, 0, 0, 0},
325 {{" ", 14, 14, memorySel1, memorySel1},
326 {" ", 14, 14, memorySel2, memorySel2},
327 {" ", 14, 14, memorySel3, memorySel3},
328 {" ", 14, 14, memorySel4, memorySel4},
329 {"Down UP ", 20, 20, memoryListUp, memoryListDown}},
330 },
331 {
332 {"Back Songs Main ", 14, 0, 0, 0},
333 {{" ", 20, 20, songSel1, songSel1},
334 {" ", 20, 20, songSel2, songSel2},
335 {" ", 20, 20, songSel3, songSel3},
336 {" ", 20, 20, songSel4, songSel4},
337 {"Down UP ", 21, 21, memoryListUp, memoryListDown}},
338 },
339 {
340 },
341 {
342 },
343 /* 24: */
344 {
345 },
346 {
347 },
348 {
349 },
350 {
351 },
352 /* 28: */
353 {
354 },
355 {
356 },
357 {
358 },
359 {
360 }
361 };
362
363 static void
displayMenu(guiSynth * synth,int panel,int menu)364 displayMenu(guiSynth *synth, int panel, int menu)
365 {
366 if (functionMenu[currentMenu].title.lmenuFunc != 0)
367 {
368 /*
369 * If we have a left function to draw the display, it must do all the
370 * lines.
371 */
372 functionMenu[menu].title.lmenuFunc(synth);
373 return;
374 } else if (functionMenu[currentMenu].title.rmenuFunc != 0) {
375 displayPanel(synth,
376 functionMenu[menu].title.rmenuFunc(synth),
377 0, FUNCTION_PANEL, DISPLAY1);
378 } else {
379 displayPanel(synth,
380 functionMenu[menu].title.title, 0, FUNCTION_PANEL, DISPLAY1);
381 }
382
383 displayPanel(synth,
384 functionMenu[menu].line1.title, 0, FUNCTION_PANEL, DISPLAY2);
385 displayPanel(synth,
386 functionMenu[menu].line2.title, 0, FUNCTION_PANEL, DISPLAY3);
387 displayPanel(synth,
388 functionMenu[menu].line3.title, 0, FUNCTION_PANEL, DISPLAY4);
389 displayPanel(synth,
390 functionMenu[menu].line4.title, 0, FUNCTION_PANEL, DISPLAY5);
391 displayPanel(synth,
392 functionMenu[menu].line5.title, 0, FUNCTION_PANEL, DISPLAY6);
393 }
394
395 int
functionOp(guiSynth * synth,int panel,int index,int operator,float value)396 functionOp(guiSynth *synth, int panel, int index, int operator, float value)
397 {
398 if ((synth->flags && OPERATIONAL) == 0)
399 return(0);
400
401 /* printf("functionOp(%x, %i, %i, %i, %f)\n", */
402 /* synth, panel, index, operator, value); */
403
404 if (currentMenu == -1)
405 {
406 /*
407 * This is to init to the first menu
408 */
409 currentMenu = 0;
410 displayMenu(synth, panel, currentMenu);
411
412 /*
413 * And use the chance to seed the interupts for the VU meter.
414 */
415 theSynth = synth;
416
417 return(0);
418 }
419
420 if ((index == 13) || (index == 24) || (index == 25))
421 {
422 /*
423 * memory buttons, 13 is 'rezero', 24 is load and 25 is save?
424 *
425 * These are bespoke since the generic synth memories use a single
426 * panel of parameters whilst the mixer needs many?
427 */
428 if (index == 25)
429 {
430 if (memCount < 0)
431 memoryBuildList(synth);
432
433 if (++memIndex > memCount)
434 memIndex = 0;
435
436 sprintf(memscratch, "%s", memList[memIndex]);
437 loadMixerMemory(synth, memList[memIndex], 0);
438 currentMenu = 14;
439 printMemMenu(synth);
440
441 return(0);
442 }
443 if (index == 24)
444 {
445 if (memCount < 0)
446 memoryBuildList(synth);
447
448 if (--memIndex < 0)
449 memIndex = memCount;
450
451 sprintf(memscratch, "%s", memList[memIndex]);
452 loadMixerMemory(synth, memList[memIndex], 0);
453 currentMenu = 14;
454 printMemMenu(synth);
455
456 return(0);
457 }
458 if (index == 13)
459 {
460 loadMixerMemory(synth, "revert", 0);
461 return(0);
462 }
463 }
464
465 if ((index >= DISPLAY1) && (index <= DISPLAY5))
466 {
467 /*
468 * If we have an event here it is going to be a keypress.
469 */
470 if (currentMenu == 3)
471 {
472 int i;
473 char scratch[32];
474
475 /*
476 * Track menu, this will be track naming text. Value will be an
477 * ascii char, put it at the end of the string. char 08 and 7f are
478 * delete, ie, remove a character.
479 *
480 * Then print it on line2.
481 */
482 sprintf(scratch, "%s",
483 getMixerMemory((mixerMem *) synth->mem.param,
484 currentTrack + 4, 79));
485 i = strlen(scratch);
486
487 if ((value == 0xff08) || (value == -1))
488 {
489 /*
490 * Should be backspace/delete
491 */
492 if (i > 0)
493 scratch[i - 1] = '\0';
494 } else if (i == 15)
495 /*
496 * If max length then return now
497 */
498 return(0);
499 else {
500 scratch[i] = value;
501 scratch[i + 1] = '\0';
502 }
503 setMixerMemory((mixerMem *) synth->mem.param,
504 currentTrack + 4, 79, 0, scratch);
505 sprintf(text, "Text: %s ", scratch);
506 displayPanel(synth, text, 0, FUNCTION_PANEL, DISPLAY3);
507 setTrackText(synth);
508
509 return(0);
510 }
511 /*
512 * See if we are in the memory menu;
513 */
514 else if (currentMenu == 14)
515 {
516 int i;
517 /*
518 * Track menu, this will be track naming text. Value will be an
519 * ascii char, put it at the end of the string. char 08 and 7f are
520 * delete, ie, remove a character.
521 *
522 * Then print it on line2.
523 */
524 i = strlen(memscratch);
525
526 if ((value == 0xff08) || (value == -1))
527 {
528 if (i > 0)
529 memscratch[i - 1] = '\0';
530 } else if (i == 15)
531 return(0);
532 else {
533 memscratch[i] = value;
534 memscratch[i + 1] = '\0';
535 }
536 sprintf(text, "Name: %s ", memscratch);
537 displayPanel(synth, text, 0, FUNCTION_PANEL, DISPLAY2);
538
539 return(0);
540 } else if ((currentMenu == 20) || (currentMenu == 21)) {
541 int k, j, i = memIndex;
542 /*
543 * This is the search window. Go through the memList looking for
544 * the next entry that starts with the given letter.
545 */
546 for (j = 0; j <= memCount; j ++)
547 {
548 if (++i > memCount)
549 i = 0;
550
551 if (memList[i][0] == value)
552 {
553 memIndex = i;
554 memoryShowList(synth);
555 return(0);
556 }
557 }
558 /*
559 * If we get here then we could not find a match on the first
560 * letter. Lets see about the second letter (not sure why, or if
561 * it really makes sense
562 */
563 i = memIndex;
564 for (j = 0; j <= memCount; j ++)
565 {
566 if (++i > memCount)
567 i = 0;
568
569 if (memList[i][1] == value)
570 {
571 memIndex = i;
572 memoryShowList(synth);
573 return(0);
574 }
575 }
576 /*
577 * If that failed then I personally think we should look for any
578 * entry that contains the given character. We might consider
579 * dropping the last search.
580 */
581 i = memIndex;
582 for (j = 0; j <= memCount; j++)
583 {
584 if (++i > memCount)
585 i = 0;
586
587 for (k = 0; memList[i][k] != '\0'; k++)
588 {
589 if (memList[i][k] == value)
590 {
591 memIndex = i;
592 memoryShowList(synth);
593 return(0);
594 }
595 }
596 }
597 }
598
599 return(0);
600 }
601
602 /*
603 * Title back
604 *
605 * Apart from the title, the rest of the lines can be put into procedures
606 * so that we can call the code with an index, as it is now an array.
607 *
608 * This is damn ugly. How was it not made into a case or a structured
609 * array of calls?
610 */
611 if (operator == 0)
612 {
613 if (functionMenu[currentMenu].title.last != -1)
614 {
615 currentMenu = functionMenu[currentMenu].title.last;
616 displayMenu(synth, panel, currentMenu);
617 }
618 } else if (operator == 1) {
619 /*
620 * Title forward
621 */
622 if (functionMenu[currentMenu].title.next != -1)
623 {
624 currentMenu = functionMenu[currentMenu].title.next;
625 displayMenu(synth, panel, currentMenu);
626 }
627 } else if (operator == 2) {
628 /*
629 * Line 1 back
630 */
631 if (functionMenu[currentMenu].line1.lmenuFunc != 0)
632 {
633 functionMenu[currentMenu].line1.lmenuFunc(synth);
634
635 return(0);
636 }
637 if (functionMenu[currentMenu].line1.last != -1)
638 {
639 currentMenu = functionMenu[currentMenu].line1.last;
640 displayMenu(synth, panel, currentMenu);
641 }
642 } else if (operator == 7) {
643 /*
644 * Line 1 forward
645 */
646 if (functionMenu[currentMenu].line1.rmenuFunc != 0)
647 {
648 functionMenu[currentMenu].line1.rmenuFunc(synth);
649
650 return(0);
651 }
652 if (functionMenu[currentMenu].line1.next != -1)
653 {
654 currentMenu = functionMenu[currentMenu].line1.next;
655 displayMenu(synth, panel, currentMenu);
656 }
657 } else if (operator == 3) {
658 /*
659 * Line 2 back
660 */
661 if (functionMenu[currentMenu].line2.lmenuFunc != 0)
662 {
663 functionMenu[currentMenu].line2.lmenuFunc(synth);
664
665 return(0);
666 }
667 if (functionMenu[currentMenu].line2.last != -1)
668 {
669 currentMenu = functionMenu[currentMenu].line2.last;
670 displayMenu(synth, panel, currentMenu);
671 }
672 } else if (operator == 8) {
673 /*
674 * Line 2 forward
675 */
676 if (functionMenu[currentMenu].line2.rmenuFunc != 0)
677 {
678 functionMenu[currentMenu].line2.rmenuFunc(synth);
679
680 return(0);
681 }
682 if (functionMenu[currentMenu].line2.next != -1)
683 {
684 currentMenu = functionMenu[currentMenu].line2.next;
685 displayMenu(synth, panel, currentMenu);
686 }
687 } else if (operator == 4) {
688 /*
689 * Line 3 back
690 */
691 if (functionMenu[currentMenu].line3.lmenuFunc != 0)
692 {
693 functionMenu[currentMenu].line3.lmenuFunc(synth);
694
695 return(0);
696 }
697 if (functionMenu[currentMenu].line3.last != -1)
698 {
699 currentMenu = functionMenu[currentMenu].line3.last;
700 displayMenu(synth, panel, currentMenu);
701 }
702 } else if (operator == 9) {
703 /*
704 * Line 3 forward
705 */
706 if (functionMenu[currentMenu].line3.rmenuFunc != 0)
707 {
708 functionMenu[currentMenu].line3.rmenuFunc(synth);
709
710 return(0);
711 }
712 if (functionMenu[currentMenu].line3.next != -1)
713 {
714 currentMenu = functionMenu[currentMenu].line3.next;
715 displayMenu(synth, panel, currentMenu);
716 }
717 } else if (operator == 5) {
718 /*
719 * Line 4 back
720 */
721 if (functionMenu[currentMenu].line4.lmenuFunc != 0)
722 {
723 functionMenu[currentMenu].line4.lmenuFunc(synth);
724
725 return(0);
726 }
727 if (functionMenu[currentMenu].line4.last != -1)
728 {
729 currentMenu = functionMenu[currentMenu].line4.last;
730 displayMenu(synth, panel, currentMenu);
731 }
732 } else if (operator == 10) {
733 if (functionMenu[currentMenu].line4.rmenuFunc != 0)
734 {
735 functionMenu[currentMenu].line4.rmenuFunc(synth);
736
737 return(0);
738 }
739 /*
740 * Line 4 forward
741 */
742 if (functionMenu[currentMenu].line4.next != -1)
743 {
744 currentMenu = functionMenu[currentMenu].line4.next;
745 displayMenu(synth, panel, currentMenu);
746 }
747 } else if (operator == 6) {
748 /*
749 * Line 5 back
750 */
751 if (functionMenu[currentMenu].line5.lmenuFunc != 0)
752 {
753 functionMenu[currentMenu].line5.lmenuFunc(synth);
754
755 return(0);
756 }
757 if (functionMenu[currentMenu].line5.last != -1)
758 {
759 currentMenu = functionMenu[currentMenu].line5.last;
760 displayMenu(synth, panel, currentMenu);
761 }
762 } else if (operator == 11) {
763 if (functionMenu[currentMenu].line5.rmenuFunc != 0)
764 {
765 functionMenu[currentMenu].line5.rmenuFunc(synth);
766
767 return(0);
768 }
769 /*
770 * Line 5 forward
771 */
772 if (functionMenu[currentMenu].line5.next != -1)
773 {
774 currentMenu = functionMenu[currentMenu].line5.next;
775 displayMenu(synth, panel, currentMenu);
776 }
777 }
778 return(0);
779 }
780
781 static char *
printInterface(guiSynth * synth)782 printInterface(guiSynth *synth)
783 {
784 /*
785 * Export image to bitmap file.
786 */
787 brightonXpmWrite(synth->win, "/tmp/mixer.xpm");
788
789 return(NULL);
790 }
791
792 #warning - fixed track configuration at 16 tracks.
793 static char *
trackDown(guiSynth * synth)794 trackDown(guiSynth *synth)
795 {
796 if (--currentTrack < 0)
797 currentTrack = 15;
798
799 printTrackMenu(synth);
800 return(NULL);
801 }
802
803 static char *
trackUp(guiSynth * synth)804 trackUp(guiSynth *synth)
805 {
806 if (++currentTrack == 16)
807 currentTrack = 0;
808
809 printTrackMenu(synth);
810 return(NULL);
811 }
812
813 static char *
midiUp(guiSynth * synth)814 midiUp(guiSynth *synth)
815 {
816 if (++synth->midichannel == 16)
817 synth->midichannel = 15;
818
819 printMidiMenu(synth);
820 return(NULL);
821 }
822
823 static char *
midiDown(guiSynth * synth)824 midiDown(guiSynth *synth)
825 {
826 if (--synth->midichannel < 0)
827 synth->midichannel = 0;
828
829 printMidiMenu(synth);
830 return(NULL);
831 }
832
833 static char *
setTrackText(guiSynth * synth)834 setTrackText(guiSynth *synth)
835 {
836 char scratch[32];
837
838 sprintf(scratch, "%s", getMixerMemory((mixerMem *) synth->mem.param, currentTrack + 4, 79));
839
840 displayPanel(synth, scratch, 0, currentTrack + 4, PARAM_COUNT - 1);
841 /*
842 * Looks ugly? The issue is that the channels use contiguous store in the
843 * gui, but I have to separate this into the memories.
844 */
845 setMixerMemory((mixerMem *) synth->mem.param, CHAN_PANEL, 79 + (currentTrack * 80), 0, scratch);
846 return(NULL);
847 }
848
849 static char *
printTrackMenu(guiSynth * synth)850 printTrackMenu(guiSynth *synth)
851 {
852 char scratch[32];
853
854 if ((currentTrack + 4) < 0)
855 return(NULL);
856
857 sprintf(scratch, "%s", getMixerMemory((mixerMem *) synth->mem.param, currentTrack + 4, 79));
858
859 /*
860 * Create text for track display
861 */
862 sprintf(text, " Track %i Menu ", currentTrack + 1);
863 displayPanel(synth, text, 0, FUNCTION_PANEL, DISPLAY1);
864
865 displayPanel(synth,
866 functionMenu[3].line[0].title, 0, FUNCTION_PANEL, DISPLAY2);
867
868 sprintf(text, "Text: %s ", scratch);
869 displayPanel(synth, text, 0, FUNCTION_PANEL, DISPLAY3);
870
871 displayPanel(synth,
872 functionMenu[3].line[2].title, 0, FUNCTION_PANEL, DISPLAY4);
873 displayPanel(synth,
874 functionMenu[3].line[3].title, 0, FUNCTION_PANEL, DISPLAY5);
875 displayPanel(synth,
876 functionMenu[3].line[4].title, 0, FUNCTION_PANEL, DISPLAY6);
877 return(NULL);
878 }
879
880
881 static char *
songSel1(guiSynth * synth)882 songSel1(guiSynth *synth)
883 {
884 currentMenu = 20;
885 /*
886 * Set the current song to the given name and then print the list of
887 * songs in that directory
888 */
889 loadMixerMemory(synth, memList[memIndex], 1);
890 memoryList(synth);
891 return(NULL);
892 }
893 static char *
songSel2(guiSynth * synth)894 songSel2(guiSynth *synth)
895 {
896 currentMenu = 20;
897
898 memIndex += 1;
899 if (memIndex > memCount) memIndex -= memCount + 1;
900 loadMixerMemory(synth, memList[memIndex], 1);
901 memoryList(synth);
902 return(NULL);
903 }
904 static char *
songSel3(guiSynth * synth)905 songSel3(guiSynth *synth)
906 {
907 currentMenu = 20;
908 memIndex += 2;
909 if (memIndex > memCount) memIndex -= memCount + 1;
910 loadMixerMemory(synth, memList[memIndex], 1);
911 memoryList(synth);
912 return(NULL);
913 }
914 static char *
songSel4(guiSynth * synth)915 songSel4(guiSynth *synth)
916 {
917 currentMenu = 20;
918 memIndex += 3;
919 if (memIndex > memCount) memIndex -= memCount + 1;
920 loadMixerMemory(synth, memList[memIndex], 1);
921 memoryList(synth);
922 return(NULL);
923 }
924
925 static char *
createSongDir(guiSynth * synth)926 createSongDir(guiSynth *synth)
927 {
928 loadMixerMemory(synth, memscratch, 2);
929 return(NULL);
930 }
931
932 static char *
memorySel1(guiSynth * synth)933 memorySel1(guiSynth *synth)
934 {
935 currentMenu = 14;
936
937 sprintf(memscratch, "%s", memList[memIndex]);
938
939 printMemMenu(synth);
940 return(NULL);
941 }
942 static char *
memorySel2(guiSynth * synth)943 memorySel2(guiSynth *synth)
944 {
945 currentMenu = 14;
946
947 memIndex += 1;
948 if (memIndex > memCount) memIndex -= memCount + 1;
949 sprintf(memscratch, "%s", memList[memIndex]);
950
951 printMemMenu(synth);
952 return(NULL);
953 }
954 static char *
memorySel3(guiSynth * synth)955 memorySel3(guiSynth *synth)
956 {
957 currentMenu = 14;
958
959 memIndex += 2;
960 if (memIndex > memCount) memIndex -= memCount + 1;
961 sprintf(memscratch, "%s", memList[memIndex]);
962
963 printMemMenu(synth);
964 return(NULL);
965 }
966 static char *
memorySel4(guiSynth * synth)967 memorySel4(guiSynth *synth)
968 {
969 currentMenu = 14;
970
971 memIndex += 3;
972 if (memIndex > memCount) memIndex -= memCount + 1;
973 sprintf(memscratch, "%s", memList[memIndex]);
974
975 printMemMenu(synth);
976 return(NULL);
977 }
978
979 static char *
songBuildList(guiSynth * synth)980 songBuildList(guiSynth *synth)
981 {
982 char *entry;
983
984 memCount = -1;
985
986 while ((entry = getMixerMemory((mixerMem *) synth->mem.param, MM_GETLIST, 1)) != 0)
987 sprintf(memList[++memCount], "%s", entry);
988 /*while ((entry = ((char *) mixerMemory(synth, MM_GET, MM_GETLIST, 1, 0)))
989 != 0)
990 sprintf(memList[++memCount], "%s", entry); */
991 return(NULL);
992 }
993
994 static char *
memoryBuildList(guiSynth * synth)995 memoryBuildList(guiSynth *synth)
996 {
997 char *entry;
998
999 memCount = -1;
1000
1001 while ((entry = (getMixerMemory((mixerMem *) synth->mem.param, MM_GETLIST, 0))) != 0)
1002 sprintf(memList[++memCount], "%s", entry);
1003 return(NULL);
1004 }
1005
1006 static char *
songShowList(guiSynth * synth)1007 songShowList(guiSynth *synth)
1008 {
1009 int mi = memIndex;
1010
1011 if (memCount < 0)
1012 songBuildList(synth);
1013
1014 /*
1015 * Then show the memory entries in the panel from the list with the
1016 * given index
1017 */
1018 sprintf(text, "%s", functionMenu[21].title.title);
1019 displayPanel(synth, text, 0, FUNCTION_PANEL, DISPLAY1);
1020
1021 displayPanel(synth, memList[mi], 0, FUNCTION_PANEL, DISPLAY2);
1022 if (mi++ >= memCount) mi = 0;
1023 displayPanel(synth, memList[mi], 0, FUNCTION_PANEL, DISPLAY3);
1024 if (mi++ >= memCount) mi = 0;
1025 displayPanel(synth, memList[mi], 0, FUNCTION_PANEL, DISPLAY4);
1026 if (mi++ >= memCount) mi = 0;
1027 displayPanel(synth, memList[mi], 0, FUNCTION_PANEL, DISPLAY5);
1028
1029 displayPanel(synth,
1030 functionMenu[21].line[4].title, 0, FUNCTION_PANEL, DISPLAY6);
1031 return(NULL);
1032 }
1033
1034 static char *
memoryShowList(guiSynth * synth)1035 memoryShowList(guiSynth *synth)
1036 {
1037 int mi = memIndex;
1038
1039 if (memCount < 0)
1040 memoryBuildList(synth);
1041
1042 /*
1043 * Then show the memory entries in the panel from the list with the
1044 * given index
1045 */
1046 sprintf(text, "%s", functionMenu[20].title.title);
1047 displayPanel(synth, text, 0, FUNCTION_PANEL, DISPLAY1);
1048
1049 displayPanel(synth, memList[mi], 0, FUNCTION_PANEL, DISPLAY2);
1050 if (mi++ >= memCount) mi = 0;
1051 displayPanel(synth, memList[mi], 0, FUNCTION_PANEL, DISPLAY3);
1052 if (mi++ >= memCount) mi = 0;
1053 displayPanel(synth, memList[mi], 0, FUNCTION_PANEL, DISPLAY4);
1054 if (mi++ >= memCount) mi = 0;
1055 displayPanel(synth, memList[mi], 0, FUNCTION_PANEL, DISPLAY5);
1056
1057 displayPanel(synth,
1058 functionMenu[20].line[4].title, 0, FUNCTION_PANEL, DISPLAY6);
1059 return(NULL);
1060 }
1061
1062 static char *
songList(guiSynth * synth)1063 songList(guiSynth *synth)
1064 {
1065 /*
1066 * We need to build a list of the memories in our default directory.
1067 * This should become a few routines, one that builds that list and two
1068 * that allow us to scroll up and down it.
1069 */
1070 songBuildList(synth);
1071
1072 songShowList(synth);
1073
1074 currentMenu = 21;
1075 return(NULL);
1076 }
1077
1078 static char *
memoryList(guiSynth * synth)1079 memoryList(guiSynth *synth)
1080 {
1081 /*
1082 * We need to build a list of the memories in our default directory.
1083 * This should become a few routines, one that builds that list and two
1084 * that allow us to scroll up and down it.
1085 */
1086 memoryBuildList(synth);
1087
1088 memoryShowList(synth);
1089
1090 currentMenu = 20;
1091 return(NULL);
1092 }
1093
1094 static char *
memoryListDown(guiSynth * synth)1095 memoryListDown(guiSynth *synth)
1096 {
1097 /*
1098 * Cycle upwards though our list and show the names.
1099 */
1100 if (++memIndex > memCount)
1101 memIndex = 0;
1102
1103 memoryShowList(synth);
1104
1105 return(NULL);
1106 }
1107
1108 static char *
memoryListUp(guiSynth * synth)1109 memoryListUp(guiSynth *synth)
1110 {
1111 /*
1112 * Cycle downwards though our list and show the names.
1113 */
1114 if (--memIndex < 0)
1115 memIndex = memCount;
1116
1117 memoryShowList(synth);
1118
1119 return(0);
1120 }
1121
1122 static char *
printMemMenu(guiSynth * synth)1123 printMemMenu(guiSynth *synth)
1124 {
1125 /*
1126 * Create text for track display
1127 displayPanel(synth, " Mem Menu ",
1128 0, FUNCTION_PANEL, DISPLAY1);
1129 */
1130 displayPanel(synth, functionMenu[14].title.title,
1131 0, FUNCTION_PANEL, DISPLAY1);
1132
1133 sprintf(text, "Name: %s ", memscratch);
1134 displayPanel(synth, text, 0, FUNCTION_PANEL, DISPLAY2);
1135
1136 displayPanel(synth,
1137 functionMenu[14].line[1].title, 0, FUNCTION_PANEL, DISPLAY3);
1138 displayPanel(synth,
1139 functionMenu[14].line[2].title, 0, FUNCTION_PANEL, DISPLAY4);
1140 displayPanel(synth,
1141 functionMenu[14].line[3].title, 0, FUNCTION_PANEL, DISPLAY5);
1142 displayPanel(synth,
1143 functionMenu[14].line[4].title, 0, FUNCTION_PANEL, DISPLAY6);
1144 return(NULL);
1145 }
1146
1147 static char *
printMidiMenu(guiSynth * synth)1148 printMidiMenu(guiSynth *synth)
1149 {
1150 /*
1151 * Create text for track display
1152 */
1153 displayPanel(synth, " Midi Menu ",
1154 0, FUNCTION_PANEL, DISPLAY1);
1155
1156 displayPanel(synth,
1157 functionMenu[17].line[0].title,
1158 0, FUNCTION_PANEL, DISPLAY2);
1159
1160 sprintf(text, "Channel: %i ", synth->midichannel + 1);
1161 displayPanel(synth, text, 0, FUNCTION_PANEL, DISPLAY3);
1162
1163 displayPanel(synth,
1164 functionMenu[17].line[2].title, 0, FUNCTION_PANEL, DISPLAY4);
1165 displayPanel(synth,
1166 functionMenu[17].line[3].title, 0, FUNCTION_PANEL, DISPLAY5);
1167 displayPanel(synth,
1168 functionMenu[17].line[4].title, 0, FUNCTION_PANEL, DISPLAY6);
1169 return(NULL);
1170 }
1171
1172 static char *
removeInterface(guiSynth * synth)1173 removeInterface(guiSynth *synth)
1174 {
1175 /*
1176 * Exit application, completely.
1177 */
1178 brightonRemoveInterface(synth->win);
1179 return(NULL);
1180 }
1181
1182 brightonEvent event;
1183
1184 int
doAlarm()1185 doAlarm()
1186 {
1187 event.type = BRIGHTON_FLOAT;
1188 event.value = 0.0;
1189
1190 /* brightonSendEvent((void *) theSynth->win, 2, DISPLAY1 - 1, &event); */
1191 return(0);
1192 }
1193
1194