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
23 #include <fcntl.h>
24
25 #include "brighton.h"
26 #include "brightonMini.h"
27 #include "bristolmidi.h"
28 #include "brightoninternals.h"
29
30 static int miniInit();
31 static int miniConfigure();
32 static int midiCallback(brightonWindow *, int, int, float);
33 static int miniCallback(brightonWindow * , int, int, float);
34
35 extern guimain global;
36
37 #include "brightonKeys.h"
38
39 #define KEY_PANEL 1
40
41 #define FIRST_DEV 0
42 #define DEVICE_COUNT (61 + FIRST_DEV)
43 #define ACTIVE_DEVS (42 + FIRST_DEV)
44
45 #define R1 128
46 #define R5 698
47 #define R3 (R1 + (R5 - R1) / 2)
48 #define R2 (R1 + (R3 - R1) / 2)
49 #define R4 (R3 + (R5 - R3) / 2)
50 #define R6 782
51 #define R7 889
52 #define C1 168
53 #define C2 234
54 #define C3 318
55 #define C4 398
56 #define C5 472
57 #define C6 548
58 #define C7 673
59 #define C8 753
60 #define C9 827
61 #define C10 905
62 #define C11 622
63 #define C12 140
64
65 #define S1 120
66 #define S2 170
67 #define S3 180
68 #define S4 35
69 #define S5 60
70
71 #define B1 40
72 #define B2 16
73 #define B3 110
74
75 /*
76 * This structure is for device definition. The structure is defined in
77 * include/brighton.h, further definitions in brighton/brightonDevtable.h and
78 * include/brightoninternals.h
79 *
80 * typedef int (*brightonCallback)(int, float);
81 * typedef struct BrightonLocations {
82 * int device; 0=rotary, 1=scale, etc.
83 * float relx, rely; relative position with regards to 1000 by 1000 window
84 * float relw, relh; relative height.
85 * int from, to;
86 * brightonCallback callback; specific to this dev
87 * char *image; bitmap. If zero take a device default.
88 * int flags;
89 * } brightonLocations;
90 *
91 * This example is for a miniBristol type synth interface.
92 */
93 static brightonLocations locations[DEVICE_COUNT] = {
94 /* CONTROL */
95 {"Tune", 0, 47, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
96 0, BRIGHTON_NOTCH},
97 {"Glide", 0, 18, R4, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
98 0, 0},
99 {"Mod", 0, 80, R4, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
100 0, 0}, /*3 */
101 /* OSCILATORS */
102 {"Osc1 Transpose", 0, C1, R1, S1, S1, 0, 5, 0, "bitmaps/knobs/knob4.xpm",
103 0, 0},
104 {"Osc2 Transpose", 0, C1, R3, S1, S1, 0, 5, 0, "bitmaps/knobs/knob4.xpm",
105 0, 0},
106 {"Osc3 Transpose", 0, C1, R5, S1, S1, 0, 5, 0, "bitmaps/knobs/knob4.xpm",
107 0, 0},
108 /* {"", 0, C2, 382, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, */
109 {"Osc2 Tuning", 0, C2, 382, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
110 0, BRIGHTON_NOTCH},
111 {"Osc3 Tuning", 0, C2, 660, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
112 0, BRIGHTON_NOTCH},
113 {"Osc1 Waveform", 0, C3, R1, S1, S1, 0, 5, 0, "bitmaps/knobs/knob4.xpm",
114 0, 0},
115 {"Osc2 Waveform", 0, C3, R3, S1, S1, 0, 5, 0, "bitmaps/knobs/knob4.xpm",
116 0, 0},
117 {"Osc3 Waveform", 0, C3, R5, S1, S1, 0, 5, 0, "bitmaps/knobs/knob4.xpm",
118 0, 0}, /*11 */
119 /* MIXER */
120 {"Osc1 Mix lvl", 0, C4, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
121 0, 0},
122 {"Ext Mix lvl", 0, C6, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
123 0, 0},
124 {"Osc2 Mix lvl", 0, C4, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
125 0, 0},
126 {"Noise Mix lvl", 0, C6, R4, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
127 0, 0},
128 {"Osc3 Mix lvl", 0, C4, R5, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
129 0, 0}, /*16 */
130 /* FILTER */
131 {"Filter Freq", 0, C7, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
132 0, 0},
133 {"Filter Emph", 0, C8, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
134 0, 0},
135 {"Filter Contour", 0, C9, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
136 0, 0}, /*19 */
137 /* ADSR */
138 {"Filter Attack", 0, C7, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
139 0, 0},
140 {"Filter Decay", 0, C8, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
141 0, 0},
142 {"Filter Release", 0, C9, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
143 0, 0}, /*22 */
144 /* another ADSR */
145 {"Attack", 0, C7, R5, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
146 0, 0},
147 {"Decay", 0, C8, R5, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
148 0, 0},
149 {"Release", 0, C9, R5, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
150 0, 0}, /*25 */
151 /* MAIN OUT 25 */
152 {"MasterVolume", 0, C10, R1, S3, S3, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
153 0, 0},
154 {"On/Off", 2, C10 + 7, R1 - 92, B1, B1, 0, 1, 0,
155 "bitmaps/buttons/rockerblue.xpm", 0, 0},
156 {"A-440", 2, C10 + 7, R2 + 75, B1, B1, 0, 1, 0,
157 "bitmaps/buttons/rockerblue.xpm", 0, 0}, /*28 */
158 /* MIX BUTTONS - 28 */
159 {"Mix Osc1", 2, C5, R1 + 45, B1, B1, 0, 1, 0,
160 "bitmaps/buttons/rockerblue.xpm", 0, 0},
161 {"Mix Ext", 2, C5, R2 + 45, B1, B1, 0, 1, 0,
162 "bitmaps/buttons/rockerblue.xpm", 0, 0},
163 {"Mix Osc2", 2, C5, R3 + 45, B1, B1, 0, 1, 0,
164 "bitmaps/buttons/rockerblue.xpm", 0, 0},
165 {"Mix Noise", 2, C5, R4 + 45, B1, B1, 0, 1, 0,
166 "bitmaps/buttons/rockerblue.xpm", 0, 0},
167 {"Mix Osc3", 2, C5, R5 + 45, B1, B1, 0, 1, 0,
168 "bitmaps/buttons/rockerblue.xpm", 0, 0}, /*33 */
169 /* NOISE BUTTON - 33 */
170 {"White/Pink", 2, C11 - 6, C6, B2, B3, 0, 1, 0,
171 "bitmaps/buttons/rockerblue.xpm", 0, BRIGHTON_VERTICAL}, /*34 */
172 /* CONTROL BUTTONS - 34 */
173 {"Osc Mod 1", 2, C12 - 22, R2 - 13, B1, B1, 0, 1, 0, 0, 0, 0},
174 {"Osc Mod 2", 2, C12 - 22, R2 + 97, B1, B1, 0, 1, 0, 0, 0, 0},
175 {"Osc 3 LFO", 2, C12 - 9, R5 + 15, B2, B3, 0, 1, 0, 0, 0, BRIGHTON_VERTICAL},
176 {"Release", 2, 78, 765, B1, B1, 0, 1, 0,
177 "bitmaps/buttons/rockerwhite.xpm", 0, 0},
178 {"Multitrig", 2, 78, 825, B1, B1, 0, 1, 0,
179 "bitmaps/buttons/rockerwhite.xpm", 0, 0}, /*39 */
180 /* FILTER BUTTONS - 39 */
181 {"Filter Mod1", 2, C11 - 5, R1 + 30, B1, B1, 0, 1, 0, 0, 0, 0},
182 {"Filter Velocity", 2, C11 - 5, R1 + 170, B1, B1, 0, 1, 0, 0, 0, 0},
183 {"Filter KBD", 2, C11 - 5, R3, B1, B1, 0, 1, 0, 0, 0}, /*42 */
184 /* Memory tablet */
185 {"", 2, R7, R6 - S5 * 3, S4, S5, 0, 1, 0,
186 "bitmaps/digits/L.xpm", 0, BRIGHTON_CHECKBUTTON},
187 {"", 2, R7 + S4 * 2, R6 - S5 * 3, S4, S5, 0, 1, 0,
188 "bitmaps/digits/S.xpm", 0, BRIGHTON_CHECKBUTTON},
189 {"", 2, R7 + S4, R6 - S5 * 3, S4, S5, 0, 1, 0,
190 "bitmaps/digits/0.xpm", 0, BRIGHTON_CHECKBUTTON},
191 {"", 2, R7, R6 - S5 * 2, S4, S5, 0, 1, 0,
192 "bitmaps/digits/1.xpm", 0, BRIGHTON_CHECKBUTTON},
193 {"", 2, R7 + S4, R6 - S5 * 2, S4, S5, 0, 1, 0,
194 "bitmaps/digits/2.xpm", 0, BRIGHTON_CHECKBUTTON},
195 {"", 2, R7 + S4 * 2, R6 - S5 * 2, S4, S5, 0, 1, 0,
196 "bitmaps/digits/3.xpm", 0, BRIGHTON_CHECKBUTTON},
197 {"", 2, R7, R6 - S5, S4, S5, 0, 1, 0,
198 "bitmaps/digits/4.xpm", 0, BRIGHTON_CHECKBUTTON},
199 {"", 2, R7 + S4, R6 - S5, S4, S5, 0, 1, 0,
200 "bitmaps/digits/5.xpm", 0, BRIGHTON_CHECKBUTTON},
201 {"", 2, R7 + S4 * 2, R6 - S5, S4, S5, 0, 1, 0,
202 "bitmaps/digits/6.xpm", 0, BRIGHTON_CHECKBUTTON},
203 {"", 2, R7, R6, S4, S5, 0, 1, 0,
204 "bitmaps/digits/7.xpm", 0, BRIGHTON_CHECKBUTTON},
205 {"", 2, R7 + S4, R6, S4, S5, 0, 1, 0,
206 "bitmaps/digits/8.xpm", 0, BRIGHTON_CHECKBUTTON},
207 {"", 2, R7 + S4 * 2, R6, S4, S5, 0, 1, 0,
208 "bitmaps/digits/9.xpm", 0, BRIGHTON_CHECKBUTTON},
209 /* Up down midi */
210 {"", 2, R7 + S4, 415, S4, S5, 0, 1, 0,
211 "bitmaps/digits/Down.xpm", 0, BRIGHTON_CHECKBUTTON},
212 {"", 2, R7 + S4 * 2, 415, S4, S5, 0, 1, 0,
213 "bitmaps/digits/Up.xpm", 0, BRIGHTON_CHECKBUTTON},
214 /* Up Down memory */
215 {"", 2, R7, R6 + S5, S4, S5, 0, 1, 0,
216 "bitmaps/digits/Down.xpm", 0, BRIGHTON_CHECKBUTTON},
217 {"", 2, R7 + S4 * 2, R6 + S5, S4, S5, 0, 1, 0,
218 "bitmaps/digits/Up.xpm", 0, BRIGHTON_CHECKBUTTON},
219 {"", 3, R7, 430 + S5, 105, 54, 0, 1, 0, 0,
220 "bitmaps/images/alphadisplay3.xpm", 0}, /*display 60 */
221 {"", 3, R7, 425 + S5 + 55, 105, 54, 0, 1, 0, 0,
222 "bitmaps/images/alphadisplay2.xpm", 0}, /*display 60 */
223 {"", 4, 820, 1015, 175, 140, 0, 1, 0,
224 "bitmaps/images/mini.xpm", 0, 0},
225 };
226
227 /*
228 * This is a set of globals for the main window rendering. Again taken from
229 * include/brighton.h
230 */
231 brightonApp miniApp = {
232 "mini",
233 0, /* no blueprint on wood background. */
234 "bitmaps/textures/wood6.xpm",
235 0, /*BRIGHTON_STRETCH, // default is tesselate */
236 miniInit,
237 miniConfigure, /* 3 callbacks, unused? */
238 midiCallback,
239 destroySynth, /* 0, */
240 {1, 100, 2, 2, 5, 520, 0, 0},
241 700, 400, 0, 0, /*/367, */
242 9,
243 {
244 {
245 "Mini",
246 "bitmaps/blueprints/mini.xpm",
247 "bitmaps/textures/metal6.xpm",
248 BRIGHTON_STRETCH, /* flags */
249 0,
250 miniConfigure,
251 miniCallback,
252 15, 25, 970, 570,
253 DEVICE_COUNT,
254 locations
255 },
256 {
257 "Keyboard",
258 0,
259 "bitmaps/newkeys/ekbg.xpm",
260 0x020|BRIGHTON_STRETCH|BRIGHTON_KEY_PANEL,
261 0,
262 0,
263 keyCallback,
264 150, 700, 845, 280,
265 KEY_COUNT_3OCTAVE,
266 keys3octave
267 },
268 {
269 "Mods",
270 "bitmaps/blueprints/mods.xpm",
271 "bitmaps/textures/metal6.xpm", /* flags */
272 BRIGHTON_STRETCH,
273 0,
274 0,
275 modCallback,
276 15, 700, 145, 280,
277 2,
278 mods
279 },
280 {
281 "SP2",
282 0,
283 "bitmaps/textures/wood4.xpm",
284 0, /*BRIGHTON_STRETCH|BRIGHTON_VERTICAL, // flags */
285 0,
286 0,
287 0,
288 15, 0, 970, 25,
289 0,
290 0
291 },
292 {
293 "SP1",
294 0,
295 "bitmaps/textures/wood2.xpm",
296 BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */
297 0,
298 0,
299 0,
300 0, 0, 15, 1000,
301 0,
302 0
303 },
304 {
305 "SP2",
306 0,
307 "bitmaps/textures/wood2.xpm",
308 BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */
309 0,
310 0,
311 0,
312 985, 0, 17, 1000,
313 0,
314 0
315 },
316 {
317 "SP2",
318 0,
319 "bitmaps/textures/wood.xpm",
320 BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */
321 0,
322 0,
323 0,
324 2, 597, 11, 390,
325 0,
326 0
327 },
328 {
329 "SP2",
330 0,
331 "bitmaps/textures/wood.xpm",
332 BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */
333 0,
334 0,
335 0,
336 986, 597, 14, 390,
337 0,
338 0
339 },
340 {
341 "SP2",
342 0,
343 "bitmaps/textures/wood2.xpm",
344 0, /*BRIGHTON_STRETCH|BRIGHTON_VERTICAL, // flags */
345 0,
346 0,
347 0,
348 15, 982, 970, 18,
349 0,
350 0
351 }
352 }
353 };
354
355 static int
midiCallback(brightonWindow * win,int controller,int value,float n)356 midiCallback(brightonWindow *win, int controller, int value, float n)
357 {
358 guiSynth *synth = findSynth(global.synths, win);
359
360 //printf("midi callback: %x, %i\n", controller, value);
361
362 switch(controller)
363 {
364 case MIDI_PROGRAM:
365 //printf("midi program: %x, %i\n", controller, value);
366 synth->location = value + synth->bank * 10;
367 if (loadMemory(synth, synth->resources->name, 0,
368 synth->location, synth->mem.active, FIRST_DEV, 0) < 0)
369 displayText(synth, "FRE", synth->location, FIRST_DEV + 59);
370 else
371 displayText(synth, "PRG", synth->location, FIRST_DEV + 59);
372 break;
373 case MIDI_BANK_SELECT:
374 //printf("midi banksel: %x, %i\n", controller, value);
375 synth->bank = value;
376 synth->location = (synth->location % 10) + value * 10;
377 if (loadMemory(synth, synth->resources->name, 0,
378 synth->location, synth->mem.active, FIRST_DEV, 0) < 0)
379 displayText(synth, "FRE", synth->location, FIRST_DEV + 59);
380 else
381 displayText(synth, "PRG", synth->location, FIRST_DEV + 59);
382 break;
383 }
384 return(0);
385 }
386
387 /*static dispatcher dispatch[DEVICE_COUNT]; */
388
389 static int
miniMidiSendMsg(void * synth,int fd,int chan,int c,int o,int v)390 miniMidiSendMsg(void *synth, int fd, int chan, int c, int o, int v)
391 {
392 bristolMidiSendMsg(fd, chan, c, o, v);
393 return(0);
394 }
395
396 static void
miniDualFilterDecay(guiSynth * synth,int fd,int chan,int c,int o,int v)397 miniDualFilterDecay(guiSynth *synth, int fd, int chan, int c, int o, int v)
398 {
399 bristolMidiSendMsg(fd, chan, c, 1, v);
400
401 if (synth->mem.param[FIRST_DEV + 37])
402 bristolMidiSendMsg(fd, chan, c, 3, v);
403 else
404 bristolMidiSendMsg(fd, chan, c, 3, 1024);
405 }
406
407 static void
miniDualDecay(guiSynth * synth,int fd,int chan,int c,int o,int v)408 miniDualDecay(guiSynth *synth, int fd, int chan, int c, int o, int v)
409 {
410 bristolMidiSendMsg(fd, chan, 5, 1,
411 (int) (synth->mem.param[FIRST_DEV + 23] * C_RANGE_MIN_1));
412
413 if (synth->mem.param[FIRST_DEV + 37])
414 bristolMidiSendMsg(fd, chan, 5, 3,
415 (int) (synth->mem.param[FIRST_DEV + 23] * C_RANGE_MIN_1));
416 else
417 bristolMidiSendMsg(fd, chan, 5, 3, 1024);
418 }
419
420 static void
miniMemory(guiSynth * synth,int fd,int chan,int c,int o,int v)421 miniMemory(guiSynth *synth, int fd, int chan, int c, int o, int v)
422 {
423 /* printf("miniMemory(%i %i %i %i %i)\n", fd, chan, c, o, v); */
424
425 switch (c) {
426 default:
427 case 0:
428 synth->location = synth->location * 10 + o;
429
430 if (synth->location >= 1000)
431 synth->location = o;
432 if (loadMemory(synth, "mini", 0, synth->location,
433 synth->mem.active, FIRST_DEV, BRISTOL_STAT) < 0)
434 displayText(synth, "FRE", synth->location, FIRST_DEV + 59);
435 else
436 displayText(synth, "PRG", synth->location, FIRST_DEV + 59);
437 break;
438 case 1:
439 loadMemory(synth, "mini", 0, synth->location, synth->mem.active,
440 FIRST_DEV, 0);
441 displayText(synth, "PRG", synth->location, FIRST_DEV + 59);
442 /* synth->location = 0; */
443 break;
444 case 2:
445 saveMemory(synth, "mini", 0, synth->location, FIRST_DEV);
446 displayText(synth, "PRG", synth->location, FIRST_DEV + 59);
447 /* synth->location = 0; */
448 break;
449 case 3:
450 while (loadMemory(synth, "mini", 0, --synth->location,
451 synth->mem.active, FIRST_DEV, 0) < 0)
452 {
453 if (synth->location < 0)
454 {
455 synth->location = 1000;
456 break;
457 }
458 }
459 displayText(synth, "PRG", synth->location, FIRST_DEV + 59);
460 break;
461 case 4:
462 while (loadMemory(synth, "mini", 0, ++synth->location,
463 synth->mem.active, FIRST_DEV, 0) < 0)
464 {
465 if (synth->location > 999)
466 {
467 synth->location = -1;
468 break;
469 }
470 }
471 displayText(synth, "PRG", synth->location, FIRST_DEV + 59);
472 break;
473 }
474
475 }
476
477 static void
miniMidi(guiSynth * synth,int fd,int chan,int c,int o,int v)478 miniMidi(guiSynth *synth, int fd, int chan, int c, int o, int v)
479 {
480 int newchan;
481
482 /* printf("miniMidi(%x, %i %i %i %i %i)\n", synth, fd, chan, c, o, v); */
483
484 if ((synth->flags & OPERATIONAL) == 0)
485 return;
486
487 if (c == 1) {
488 if ((newchan = synth->midichannel - 1) < 0)
489 {
490 synth->midichannel = 0;
491 return;
492 }
493 } else {
494 if ((newchan = synth->midichannel + 1) >= 16)
495 {
496 synth->midichannel = 15;
497 return;
498 }
499 }
500
501 if (global.libtest == 0)
502 {
503 bristolMidiSendMsg(global.controlfd, synth->sid,
504 127, 0, BRISTOL_MIDICHANNEL|newchan);
505 }
506
507 synth->midichannel = newchan;
508
509 displayText(synth, "MIDI", newchan + 1, FIRST_DEV + 58);
510 }
511
512 /*
513 * For the sake of ease of use, links have been placed here to be called
514 * by any of the devices created. They would be better in some other file,
515 * perhaps with this as a dispatch.
516 *
517 * Param refers to the device index in the locations table given below.
518 */
519 static int
miniCallback(brightonWindow * win,int panel,int index,float value)520 miniCallback(brightonWindow * win, int panel, int index, float value)
521 {
522 guiSynth *synth = findSynth(global.synths, win);
523 int sendvalue;
524
525 /* printf("miniCallback(%x(%x), %i, %i, %f): %i %x\n", */
526 /* win, synth, panel, index, value, synth); */
527
528 if (synth == 0)
529 return(0);
530
531 if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0))
532 return(0);
533 if (synth->dispatch[index].controller >= DEVICE_COUNT)
534 return(0);
535
536 if (miniApp.resources[0].devlocn[index].to == 1.0)
537 sendvalue = value * (CONTROLLER_RANGE - 1);
538 else
539 sendvalue = value;
540
541 synth->mem.param[index] = value;
542
543 if ((!global.libtest) || (index >= ACTIVE_DEVS))
544 synth->dispatch[index].routine(synth,
545 global.controlfd, synth->sid,
546 synth->dispatch[index].controller,
547 synth->dispatch[index].operator,
548 sendvalue);
549 /*
550 else
551 printf("dispatch[%x,%i](%i, %i, %i, %i, %i)\n", synth, index,
552 global.controlfd, synth->sid,
553 synth->dispatch[index].controller,
554 synth->dispatch[index].operator,
555 sendvalue);
556 */
557
558 return(0);
559 }
560
561 /*
562 * Any location initialisation required to run the callbacks. For bristol, this
563 * will connect to the engine, and give it some base parameters.
564 * May need to generate some application specific menus.
565 * Will also then make specific requests to some of the devices to alter their
566 * rendering.
567 */
568 static int
miniInit(brightonWindow * win)569 miniInit(brightonWindow *win)
570 {
571 guiSynth *synth = findSynth(global.synths, win);
572 dispatcher *dispatch;
573 int i;
574
575 if (synth == 0)
576 {
577 synth = findSynth(global.synths, (int) 0);
578 if (synth == 0)
579 {
580 printf("cannot init\n");
581 return(0);
582 }
583 }
584
585 synth->win = win;
586
587 printf("Initialise the mini link to bristol: %p\n", synth->win);
588
589 synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float));
590 synth->mem.count = DEVICE_COUNT;
591 synth->mem.active = ACTIVE_DEVS;
592 synth->dispatch = (dispatcher *)
593 brightonmalloc(DEVICE_COUNT * sizeof(dispatcher));
594 dispatch = synth->dispatch;
595
596 /*
597 * We really want to have three connection mechanisms. These should be
598 * 1. Unix named sockets.
599 * 2. UDP sockets.
600 * 3. MIDI pipe.
601 */
602 if (!global.libtest)
603 if ((synth->sid = initConnection(&global, synth)) < 0)
604 return(-1);
605
606 for (i = 0; i < DEVICE_COUNT; i++)
607 synth->dispatch[i].routine = miniMidiSendMsg;
608
609 /* Tune, Glide, Modmix */
610 dispatch[FIRST_DEV + 0].controller = 10;
611 dispatch[FIRST_DEV + 0].operator = 0;
612 dispatch[FIRST_DEV + 1].controller = 9;
613 dispatch[FIRST_DEV + 1].operator = 0;
614 dispatch[FIRST_DEV + 2].controller = 11;
615 dispatch[FIRST_DEV + 2].operator = 1;
616
617 /* Osc */
618 dispatch[FIRST_DEV + 3].controller = 0;
619 dispatch[FIRST_DEV + 3].operator = 1;
620 dispatch[FIRST_DEV + 4].controller = 1;
621 dispatch[FIRST_DEV + 4].operator = 1;
622 dispatch[FIRST_DEV + 5].controller = 2;
623 dispatch[FIRST_DEV + 5].operator = 1;
624 dispatch[FIRST_DEV + 6].controller = 1;
625 dispatch[FIRST_DEV + 6].operator = 2;
626 dispatch[FIRST_DEV + 7].controller = 2;
627 dispatch[FIRST_DEV + 7].operator = 2;
628 dispatch[FIRST_DEV + 8].controller = 0;
629 dispatch[FIRST_DEV + 8].operator = 0;
630 dispatch[FIRST_DEV + 9].controller = 1;
631 dispatch[FIRST_DEV + 9].operator = 0;
632 dispatch[FIRST_DEV + 10].controller = 2;
633 dispatch[FIRST_DEV + 10].operator = 0;
634
635 /* MIX */
636 dispatch[FIRST_DEV + 11].controller = 0;
637 dispatch[FIRST_DEV + 11].operator = 3;
638 dispatch[FIRST_DEV + 12].controller = 8;
639 dispatch[FIRST_DEV + 12].operator = 0;
640 dispatch[FIRST_DEV + 13].controller = 1;
641 dispatch[FIRST_DEV + 13].operator = 3;
642 dispatch[FIRST_DEV + 14].controller = 7;
643 dispatch[FIRST_DEV + 14].operator = 0;
644 dispatch[FIRST_DEV + 15].controller = 2;
645 dispatch[FIRST_DEV + 15].operator = 3;
646
647 dispatch[FIRST_DEV + 16].controller = 4;
648 dispatch[FIRST_DEV + 16].operator = 0;
649 dispatch[FIRST_DEV + 17].controller = 4;
650 dispatch[FIRST_DEV + 17].operator = 1;
651 dispatch[FIRST_DEV + 18].controller = 4;
652 dispatch[FIRST_DEV + 18].operator = 2;
653
654 dispatch[FIRST_DEV + 19].controller = 3;
655 dispatch[FIRST_DEV + 19].operator = 0;
656 dispatch[FIRST_DEV + 20].controller = 3;
657 dispatch[FIRST_DEV + 20].operator = 1; /* special */
658 dispatch[FIRST_DEV + 20].routine = (synthRoutine) miniDualFilterDecay;
659 dispatch[FIRST_DEV + 21].controller = 3;
660 dispatch[FIRST_DEV + 21].operator = 2;
661
662 dispatch[FIRST_DEV + 22].controller = 5;
663 dispatch[FIRST_DEV + 22].operator = 0;
664 dispatch[FIRST_DEV + 23].controller = 5;
665 dispatch[FIRST_DEV + 23].operator = 1; /* special */
666 dispatch[FIRST_DEV + 23].routine = (synthRoutine) miniDualDecay;
667 dispatch[FIRST_DEV + 24].controller = 5;
668 dispatch[FIRST_DEV + 24].operator = 2;
669
670 dispatch[FIRST_DEV + 25].controller = 5;
671 dispatch[FIRST_DEV + 25].operator = 4;
672 dispatch[FIRST_DEV + 26].controller = 12;
673 dispatch[FIRST_DEV + 26].operator = 7;
674 dispatch[FIRST_DEV + 27].controller = 12;
675 dispatch[FIRST_DEV + 27].operator = 6;
676
677 dispatch[FIRST_DEV + 28].controller = 12;
678 dispatch[FIRST_DEV + 28].operator = 10;
679 dispatch[FIRST_DEV + 29].controller = 12;
680 dispatch[FIRST_DEV + 29].operator = 13;
681 dispatch[FIRST_DEV + 30].controller = 12;
682 dispatch[FIRST_DEV + 30].operator = 11;
683 dispatch[FIRST_DEV + 31].controller = 12;
684 dispatch[FIRST_DEV + 31].operator = 14;
685 dispatch[FIRST_DEV + 32].controller = 12;
686 dispatch[FIRST_DEV + 32].operator = 12;
687 dispatch[FIRST_DEV + 33].controller = 7;
688 dispatch[FIRST_DEV + 33].operator = 1;
689
690 dispatch[FIRST_DEV + 34].controller = 12;
691 dispatch[FIRST_DEV + 34].operator = 1;
692 dispatch[FIRST_DEV + 35].controller = 12;
693 dispatch[FIRST_DEV + 35].operator = 4;
694 dispatch[FIRST_DEV + 36].controller = 12;
695 dispatch[FIRST_DEV + 36].operator = 0;
696
697 dispatch[FIRST_DEV + 37].routine = (synthRoutine) miniDualDecay;
698 dispatch[FIRST_DEV + 38].controller = 12;
699 dispatch[FIRST_DEV + 38].operator = 15;
700
701 dispatch[FIRST_DEV + 39].controller = 12;
702 dispatch[FIRST_DEV + 39].operator = 2;
703 dispatch[FIRST_DEV + 40].controller = 4;
704 dispatch[FIRST_DEV + 40].operator = 3;
705 dispatch[FIRST_DEV + 41].controller = 5;
706 dispatch[FIRST_DEV + 41].operator = 5;
707
708 dispatch[ACTIVE_DEVS +0].routine = dispatch[ACTIVE_DEVS +1].routine =
709 dispatch[ACTIVE_DEVS +2].routine = dispatch[ACTIVE_DEVS +3].routine =
710 dispatch[ACTIVE_DEVS +4].routine = dispatch[ACTIVE_DEVS +5].routine =
711 dispatch[ACTIVE_DEVS +6].routine = dispatch[ACTIVE_DEVS +7].routine =
712 dispatch[ACTIVE_DEVS +8].routine = dispatch[ACTIVE_DEVS +9].routine =
713 dispatch[ACTIVE_DEVS +10].routine = dispatch[ACTIVE_DEVS +11].routine =
714 dispatch[ACTIVE_DEVS +14].routine = dispatch[ACTIVE_DEVS +15].routine
715 = (synthRoutine) miniMemory;
716
717 dispatch[ACTIVE_DEVS + 0].controller = 1;
718 dispatch[ACTIVE_DEVS + 1].controller = 2;
719 dispatch[ACTIVE_DEVS + 2].operator = 0;
720 dispatch[ACTIVE_DEVS + 3].operator = 1;
721 dispatch[ACTIVE_DEVS + 4].operator = 2;
722 dispatch[ACTIVE_DEVS + 5].operator = 3;
723 dispatch[ACTIVE_DEVS + 6].operator = 4;
724 dispatch[ACTIVE_DEVS + 7].operator = 5;
725 dispatch[ACTIVE_DEVS + 8].operator = 6;
726 dispatch[ACTIVE_DEVS + 9].operator = 7;
727 dispatch[ACTIVE_DEVS + 10].operator = 8;
728 dispatch[ACTIVE_DEVS + 11].operator = 9;
729 dispatch[ACTIVE_DEVS + 14].controller = 3;
730 dispatch[ACTIVE_DEVS + 15].controller = 4;
731
732 dispatch[ACTIVE_DEVS + 12].controller = 1;
733 dispatch[ACTIVE_DEVS + 13].controller = 2;
734 dispatch[ACTIVE_DEVS + 12].routine = dispatch[ACTIVE_DEVS + 13].routine
735 = (synthRoutine) miniMidi;
736
737 /* Tune osc-1 */
738 bristolMidiSendMsg(global.controlfd, synth->sid, 0, 2, 8192);
739 /* Gain on filter contour */
740 bristolMidiSendMsg(global.controlfd, synth->sid, 3, 4,
741 CONTROLLER_RANGE - 1);
742 /*
743 * Filter type, this selects a Houvilainen filter
744 */
745 bristolMidiSendMsg(global.controlfd, synth->sid, 4, 4, 4);
746 /*
747 * Pink filter configuration
748 */
749 bristolMidiSendMsg(global.controlfd, synth->sid, 7, 2, 4096);
750
751 return(0);
752 }
753
754 static void
configureKeylatch(guiSynth * synth)755 configureKeylatch(guiSynth *synth)
756 {
757 if (synth->keypanel < 0)
758 return;
759
760 if (synth->flags & NO_LATCHING_KEYS)
761 {
762 int i, p = synth->keypanel;
763
764 for (i = 0; i < synth->win->app->resources[p].ndevices; i++)
765 synth->win->app->resources[p].devlocn[i].flags
766 |= BRIGHTON_NO_TOGGLE;
767
768 if (synth->keypanel2 < 0)
769 return;
770
771 p = synth->keypanel2;
772
773 for (i = 0; i < synth->win->app->resources[p].ndevices; i++)
774 synth->win->app->resources[p].devlocn[i].flags
775 |= BRIGHTON_NO_TOGGLE;
776 }
777 }
778
779
780 /*
781 * These aught to be moved into a more common file, brightonRoutines.c or
782 * similar.
783 */
784 int
configureGlobals(guiSynth * synth)785 configureGlobals(guiSynth *synth)
786 {
787 if (global.libtest)
788 {
789 int count = 10;
790
791 printf("libtest flagged");
792
793 while (global.libtest)
794 {
795 usleep(100000);
796 if (--count == 0)
797 break;
798 }
799
800 if (count)
801 printf(", cleared\n");
802 else
803 printf("\n");
804 }
805
806 if (!global.libtest)
807 {
808 configureKeylatch(synth);
809
810 if (synth->flags & REQ_MIDI_DEBUG)
811 {
812 bristolMidiSendNRP(global.controlfd, synth->midichannel,
813 BRISTOL_NRP_DEBUG, 1);
814 if (synth->sid2 != 0)
815 bristolMidiSendNRP(global.manualfd, synth->midichannel+1,
816 BRISTOL_NRP_DEBUG, 1);
817 }
818 if (synth->flags & REQ_MIDI_DEBUG2)
819 {
820 bristolMidiSendNRP(global.controlfd, synth->midichannel,
821 BRISTOL_NRP_DEBUG, 2);
822 if (synth->sid2 != 0)
823 bristolMidiSendNRP(global.manualfd, synth->midichannel+1,
824 BRISTOL_NRP_DEBUG, 2);
825 }
826
827 /* Send debug level request to engine and also setup local debugging */
828 bristolMidiSendMsg(global.controlfd, synth->sid,
829 BRISTOL_SYSTEM, 0,
830 BRISTOL_REQ_DEBUG|((synth->flags&REQ_DEBUG_MASK)>>12));
831 if (synth->sid2 != 0)
832 bristolMidiSendMsg(global.manualfd, synth->sid2,
833 BRISTOL_SYSTEM, 0,
834 BRISTOL_REQ_DEBUG|((synth->flags&REQ_DEBUG_MASK)>>12));
835
836 bristolMidiOption(global.controlfd, BRISTOL_NRP_DEBUG,
837 (synth->flags&REQ_DEBUG_MASK)>>12);
838 if (synth->sid2 != 0)
839 bristolMidiOption(global.manualfd, BRISTOL_NRP_DEBUG,
840 (synth->flags&REQ_DEBUG_MASK)>>12);
841
842 bristolMidiSendNRP(global.controlfd, synth->midichannel,
843 BRISTOL_NRP_GLIDE, synth->glide * C_RANGE_MIN_1 / 30);
844 bristolMidiSendNRP(global.controlfd, synth->midichannel,
845 BRISTOL_NRP_GAIN, synth->gain);
846 bristolMidiSendNRP(global.controlfd, synth->midichannel,
847 BRISTOL_NRP_DETUNE, synth->detune);
848 bristolMidiSendRP(global.controlfd, synth->midichannel,
849 MIDI_RP_PW, synth->pwd);
850 bristolMidiSendNRP(global.controlfd, synth->midichannel,
851 BRISTOL_NRP_VELOCITY, synth->velocity);
852 bristolMidiSendNRP(global.controlfd, synth->midichannel,
853 BRISTOL_NRP_LWF, synth->lwf);
854 bristolMidiSendNRP(global.controlfd, synth->midichannel,
855 BRISTOL_NRP_MNL_PREF, synth->notepref);
856 bristolMidiSendNRP(global.controlfd, synth->midichannel,
857 BRISTOL_NRP_MNL_TRIG, synth->notetrig);
858 bristolMidiSendNRP(global.controlfd, synth->midichannel,
859 BRISTOL_NRP_MNL_VELOC, synth->legatovelocity);
860
861 /* Global message forwarding on/off */
862 bristolMidiSendNRP(global.controlfd, synth->midichannel,
863 BRISTOL_NRP_FORWARD, synth->flags & REQ_FORWARD? 1:0);
864 bristolMidiOption(global.controlfd, BRISTOL_NRP_FORWARD,
865 synth->flags & REQ_FORWARD? 1:0);
866
867 if (synth->flags & MIDI_NRP)
868 bristolMidiSendNRP(global.controlfd, synth->midichannel,
869 BRISTOL_NRP_ENABLE_NRP, 1);
870 else
871 bristolMidiSendNRP(global.controlfd, synth->midichannel,
872 BRISTOL_NRP_ENABLE_NRP, 0);
873
874 bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0,
875 BRISTOL_LOWKEY|synth->lowkey);
876 bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0,
877 BRISTOL_HIGHKEY|synth->highkey);
878
879 if (synth->sid2 != 0) {
880 bristolMidiSendNRP(global.controlfd, synth->midichannel+1,
881 BRISTOL_NRP_GLIDE, synth->glide * C_RANGE_MIN_1 / 30);
882 bristolMidiSendNRP(global.controlfd, synth->midichannel+1,
883 BRISTOL_NRP_GAIN, synth->gain);
884 bristolMidiSendNRP(global.controlfd, synth->midichannel+1,
885 BRISTOL_NRP_DETUNE, synth->detune);
886 bristolMidiSendRP(global.controlfd, synth->midichannel+1,
887 MIDI_RP_PW, synth->pwd);
888 bristolMidiSendNRP(global.controlfd, synth->midichannel+1,
889 BRISTOL_NRP_VELOCITY, synth->velocity);
890 bristolMidiSendNRP(global.controlfd, synth->midichannel+1,
891 BRISTOL_NRP_LWF, synth->lwf);
892 if (synth->flags & MIDI_NRP)
893 bristolMidiSendNRP(global.controlfd, synth->midichannel+1,
894 BRISTOL_NRP_ENABLE_NRP, 1);
895 else
896 bristolMidiSendNRP(global.controlfd, synth->midichannel+1,
897 BRISTOL_NRP_ENABLE_NRP, 0);
898
899 bristolMidiSendMsg(global.controlfd, synth->sid2, 127, 0,
900 BRISTOL_LOWKEY|synth->lowkey);
901 bristolMidiSendMsg(global.controlfd, synth->sid2, 127, 0,
902 BRISTOL_HIGHKEY|synth->highkey);
903 }
904
905 if (synth->flags & REQ_LOCAL_FORWARD)
906 {
907 bristolMidiOption(global.controlfd, BRISTOL_NRP_FORWARD, 1);
908 bristolMidiOption(global.controlfd, BRISTOL_NRP_MIDI_GO, 1);
909 bristolMidiOption(global.controlfd, BRISTOL_NRP_REQ_FORWARD, 1);
910 }
911
912 /* Forwarding options for this emulator */
913 if (synth->flags & REQ_REMOTE_FORWARD)
914 bristolMidiSendMsg(global.controlfd, synth->sid,
915 BRISTOL_SYSTEM, 0, BRISTOL_REQ_FORWARD|1);
916
917 /* Forwarding options disabled for second manual, local and remote */
918 if (global.manualfd != 0)
919 {
920 bristolMidiOption(global.manualfd, BRISTOL_NRP_REQ_SYSEX, 1);
921 bristolMidiSendMsg(global.manualfd, synth->sid2,
922 BRISTOL_SYSTEM, 0, BRISTOL_REQ_FORWARD);
923 }
924
925 bristolMidiSendNRP(global.controlfd, synth->midichannel,
926 BRISTOL_NRP_MIDI_GO, 1024);
927 }
928 /*
929 * We should consider seeding the synth with a short note blip
930 if ((global.synths->notepref == BRIGHTON_HNP)
931 || (global.synths->notepref == BRIGHTON_LNP))
932 {
933 sleep(1);
934 bristolMidiSendMsg(global.controlfd,
935 synth->midichannel, BRISTOL_EVENT_KEYON, 0, 5);
936 sleep(1);
937 bristolMidiSendMsg(global.controlfd,
938 synth->midichannel, BRISTOL_EVENT_KEYOFF, 0, 5);
939 }
940 */
941 return(0);
942 }
943
944 /*
945 * This will be called to make any routine specific parameters available.
946 */
947 static int
miniConfigure(brightonWindow * win)948 miniConfigure(brightonWindow *win)
949 {
950 guiSynth *synth = findSynth(global.synths, win);
951 brightonEvent event;
952
953 memset(&event, 0, sizeof(brightonEvent));
954
955 if (synth == 0)
956 {
957 printf("problems going operational\n");
958 return(-1);
959 }
960
961 if (synth->flags & OPERATIONAL)
962 return(0);
963
964 printf("going operational: %p, %p\n", synth, win);
965
966 synth->flags |= OPERATIONAL;
967 synth->transpose = 36;
968 synth->keypanel = KEY_PANEL;
969 synth->keypanel2 = -1;
970
971 /*
972 * We now want to set a couple of parameters provided by switches in the
973 * 0.9 release but configurable per synth. These are detune and gain to
974 * start with. Some of this code could be separated as it is likely to be
975 * common to each synth. These parameters will be sent to the engine using
976 * midi non-registered parameters. These will be sent as NRP-98/99 and Data
977 * Entry-6/38. To simplify the interface we should be able to make one call
978 * send a NRP including the number and its 14 bit value. It is up to the
979 * interface to decide how to send it depending on whether it is a repeat
980 * message or not.
981 */
982 configureGlobals(synth);
983
984 loadMemory(synth, "mini", 0, synth->location, synth->mem.active,
985 FIRST_DEV, 0);
986
987 brightonPut(win, "bitmaps/blueprints/minishade.xpm",
988 0, 0, win->width, win->height);
989
990 /*
991 * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only
992 * occurs on first paint, so we suppress the first paint and then request
993 * an expose here.
994 */
995 event.type = BRIGHTON_EXPOSE;
996 event.intvalue = 1;
997 brightonParamChange(synth->win, KEY_PANEL, -1, &event);
998
999 return(0);
1000 }
1001
1002