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 * Notes from the Voyager manual:
24 *
25 * Two filter modes:
26 *
27 * 1. Dual parallel LP, stereo separation, both resonant
28 * 2. Serial HPF/LPF, mono, HPF is non resonant.
29 *
30 * Currently the filter switch is for key envelope velocity. Drop velocity on
31 * this env and use the correct option to select the filter type.
32 *
33 * The mod busses are passed through:
34 *
35 * 1. Wheel Mod
36 * 2. On/Off Pedal
37 *
38 * Release is a scaler of the actual release time. Affects both envelopes.
39 *
40 * Key modes, from control panel (mono only):
41 *
42 * 1. Lowest
43 * 2. Highest
44 * 3. Last key
45 * 4. First key
46 *
47 * Trigger modes, from control panel (mono only):
48 *
49 * 1. Single
50 * 2. Multi
51 */
52
53 #include <fcntl.h>
54
55 #include "brighton.h"
56 #include "brightonMini.h"
57 #include "brightoninternals.h"
58
59 int explorerInit();
60 int explorerConfigure();
61 int explorerCallback(brightonWindow *, int, int, float);
62 static int midiCallback(brightonWindow *, int, int, float);
63
64 extern guimain global;
65
66 extern int empty;
67
68 #include "brightonKeys.h"
69
70 #define KEY_PANEL 1
71
72 #define FIRST_DEV 0
73 #define DEVICE_COUNT 77
74 #define ACTIVE_DEVS 56
75 #define MEM_START (ACTIVE_DEVS + 1)
76
77 #define DISPLAY1 (DEVICE_COUNT - 2)
78 #define DISPLAY2 (DEVICE_COUNT - 1)
79
80 #define S1 85
81
82 #define B1 15
83 #define B2 110
84 #define B3 37
85 #define B4 42
86
87 #define R14 200
88 #define R24 400
89 #define R34 600
90 #define R44 800
91
92 #define R15 200
93 #define R25 350
94 #define R35 500
95 #define R45 650
96 #define R55 800
97
98 #define C1 25
99 #define C2 90
100 #define C3 155
101 #define C4 220
102 #define C5 285
103 #define C6 350
104 #define C6I 395
105
106 #define C7 615
107 #define C8 665
108 #define C9 742
109 #define C10 810
110 #define C11 875
111 #define C12 945
112
113 /*
114 * This structure is for device definition. The structure is defined in
115 * include/brighton.h, further definitions in brighton/brightonDevtable.h and
116 * include/brightoninternals.h
117 *
118 * typedef int (*brightonCallback)(int, float);
119 * typedef struct BrightonLocations {
120 * int device; 0=rotary, 1=scale, etc.
121 * float relx, rely; relative position with regards to 1000 by 1000 window
122 * float relw, relh; relative height.
123 * int from, to;
124 * brightonCallback callback; specific to this dev
125 * char *image; bitmap. If zero take a device default.
126 * int flags;
127 * } brightonLocations;
128 *
129 * This example is for a explorerBristol type synth interface.
130 */
131 static brightonLocations locations[DEVICE_COUNT] = {
132
133 /* LFO and control */
134 {"LFO-Freq", 0, C1 - 7, R14 - 20, S1 + 40, S1 + 40, 0, 1, 0, 0, 0, 0},
135 {"LFO-Sync", 2, C1 - 5, R24 + 25, B3, B4, 0, 3, 0,
136 "bitmaps/buttons/rockerblue.xpm", 0, 0},
137 {"GLOBAL TUNE", 0, C1, R34, S1, S1, 0, 1, 0, 0, 0, BRIGHTON_NOTCH},
138 {"Glide", 0, C1, R44, S1, S1, 0, 1, 0, 0, 0, 0},
139 /* Routing */
140 {"Mod1-Source", 0, C2, R14, S1, S1, 0, 4, 0, 0, 0, 0},
141 {"Mod1-Shape", 0, C2, R24, S1, S1, 0, 3, 0, 0, 0, 0},
142 {"Mod1-Dest", 0, C2, R34, S1, S1, 0, 5, 0, 0, 0, 0},
143 {"Mod1-Gain", 0, C2, R44, S1, S1, 0, 1, 0, 0, 0, 0},
144 {"Mod2-Source", 0, C3, R14, S1, S1, 0, 4, 0, 0, 0, 0},
145 {"Mod2-Shape", 0, C3, R24, S1, S1, 0, 3, 0, 0, 0, 0},
146 {"Mod2-Dest", 0, C3, R34, S1, S1, 0, 5, 0, 0, 0, 0},
147 {"Mod2-Gain", 0, C3, R44, S1, S1, 0, 1, 0, 0, 0, 0},
148 /* Oscillators */
149 {"Osc1-Transpose", 0, C4, R24, S1, S1, 0, 5, 0, 0, 0, 0},
150 {"Osc1-Waveform", 0, C4, R34, S1, S1, 0, 1, 0, 0, 0, 0},
151 {"Osc2-Tuning", 0, C5 - 7, R14 - 20, S1 + 40, S1 + 40, 0, 1, 0, 0, 0, BRIGHTON_NOTCH},
152 {"Osc2-Transpose", 0, C5, R24, S1, S1, 0, 5, 0, 0, 0, 0},
153 {"Osc2-Waveform", 0, C5, R34, S1, S1, 0, 1, 0, 0, 0, 0},
154 {"Osc3-Tuning", 0, C6 - 7, R14 - 20, S1 + 40, S1 + 40, 0, 1, 0, 0, 0, BRIGHTON_NOTCH},
155 {"Osc3-Transpose", 0, C6, R24, S1, S1, 0, 5, 0, 0, 0, 0},
156 {"Osc3-Waveform", 0, C6, R34, S1, S1, 0, 1, 0, 0, 0, 0},
157 /* Osc mod switches */
158 {"Sync-1/2", 2, C4, R44 + 10, B1, B2, 0, 1, 0, 0, 0, BRIGHTON_VERTICAL},
159 {"FM-1/3", 2, C4 + 40, R44 + 10, B1, B2, 0, 1, 0, 0, 0, BRIGHTON_VERTICAL},
160 {"KBD-3", 2, C4 + 95, R44 + 10, B1, B2, 0, 1, 0, 0, 0, BRIGHTON_VERTICAL},
161 {"Freq-3", 2, C4 + 135, R44 + 10, B1, B2, 0, 1, 0, 0, 0, BRIGHTON_VERTICAL},
162 /* Mixer */
163 {"Mix-EXT", 0, C7, R15, S1, S1, 0, 1, 0, 0, 0, 0},
164 {"Mix-O1", 0, C7, R25, S1, S1, 0, 1, 0, 0, 0, 0},
165 {"Mix-O2", 0, C7, R35, S1, S1, 0, 1, 0, 0, 0, 0},
166 {"Mix-O3", 0, C7, R45, S1, S1, 0, 1, 0, 0, 0, 0},
167 {"Mix-NSE", 0, C7, R55, S1, S1, 0, 1, 0, 0, 0, 0},
168 {"Mix-Ext-off", 2, C8, R15 + 25, B3, B4, 0, 1, 0,
169 "bitmaps/buttons/rockerblue.xpm", 0, 0},
170 {"Mix-O1-off", 2, C8, R25 + 25, B3, B4, 0, 1, 0,
171 "bitmaps/buttons/rockerblue.xpm", 0, 0},
172 {"Mix-O2-off", 2, C8, R35 + 25, B3, B4, 0, 1, 0,
173 "bitmaps/buttons/rockerblue.xpm", 0, 0},
174 {"Mix-O3-off", 2, C8, R45 + 25, B3, B4, 0, 1, 0,
175 "bitmaps/buttons/rockerblue.xpm", 0, 0},
176 {"Mix-Nse-off", 2, C8, R55 + 25, B3, B4, 0, 1, 0,
177 "bitmaps/buttons/rockerblue.xpm", 0, 0},
178 /* Filter */
179 {"VCF-Cutoff", 0, C9 - 7, R15 - 25, S1 + 40, S1 + 40, 0, 1, 0, 0, 0, 0},
180 {"VCF-Space", 0, C9, R25, S1, S1, 0, 1, 0, 0, 0, 0},
181 {"VCF-Res", 0, C9, R35, S1, S1, 0, 1, 0, 0, 0, 0},
182 {"VCF-KBD", 0, C9, R45, S1, S1, 0, 1, 0, 0, 0, 0},
183 {"VCF-Mode", 2, C9, R55 + 25, B3, B4, 0, 1, 0, 0, 0, 0},
184 /* Filter envelope */
185 {"VCF-Attack", 0, C10, R15, S1, S1, 0, 1, 0, 0, 0, 0},
186 {"VCF-Decay", 0, C10, R25, S1, S1, 0, 1, 0, 0, 0, 0},
187 {"VCF-Sustain", 0, C10, R35, S1, S1, 0, 1, 0, 0, 0, 0},
188 {"VCF-Release", 0, C10, R45, S1, S1, 0, 1, 0, 0, 0, 0},
189 {"VCF-EnvLevel", 0, C10, R55, S1, S1, 0, 1, 0, 0, 0, 0},
190 /* Amp Envelope */
191 {"VCA-Attack", 0, C11, R15, S1, S1, 0, 1, 0, 0, 0, 0},
192 {"VCA-Decay", 0, C11, R25, S1, S1, 0, 1, 0, 0, 0, 0},
193 {"VCA-Sustain", 0, C11, R35, S1, S1, 0, 1, 0, 0, 0, 0},
194 {"VCA-Release", 0, C11, R45, S1, S1, 0, 1, 0, 0, 0, 0},
195 {"VCA-Veloc", 2, C11, R55 + 25, B3, B4, 0, 1, 0, 0, 0, 0},
196 /* Vol, on/off, glide and release */
197 {"Volume", 0, C12 - 7, R15 - 25 , S1 + 40, S1 + 40, 0, 1, 0, 0, 0, 0},
198 {"On/Off", 2, C12 - 4, R25 + 25, B3, B4, 0, 1, 0, 0, 0, 0},
199 {"LFO-Multi", 2, C12 - 4, R35 + 25, B3, B4, 0, 1, 0,
200 "bitmaps/buttons/rockerwhite.xpm", 0, 0},
201 {"Glide-On", 2, C12 - 4, R45 + 25, B3, B4, 0, 1, 0,
202 "bitmaps/buttons/rockerwhite.xpm", 0, 0},
203 {"Release-On", 2, C12 - 4, R55 + 25, B3, B4, 0, 1, 0,
204 "bitmaps/buttons/rockerwhite.xpm", 0, 0},
205 {"Reserved", 5, 405, 410, 180, 518, 0, 1, 0, "bitmaps/buttons/pointer.xpm", 0, 0},
206 {"Reserved", 5, 405, 410, 180, 518, 0, 1, 0, "bitmaps/buttons/pointer.xpm", 0,
207 BRIGHTON_WITHDRAWN},
208 /* logo */
209 {"", 4, 762, 1037, 240, 140, 0, 1, 0, "bitmaps/images/explorer.xpm", 0, 0},
210
211 /* memories */
212 {"", 2, 418, 225, 17, 78, 0, 1.01, 0,
213 "bitmaps/buttons/pressoff.xpm",
214 "bitmaps/buttons/presson.xpm", 0},
215 {"", 2, 436, 225, 17, 78, 0, 1.01, 0,
216 "bitmaps/buttons/pressoff.xpm",
217 "bitmaps/buttons/presson.xpm", 0},
218 {"", 2, 454, 225, 17, 78, 0, 1.01, 0,
219 "bitmaps/buttons/pressoff.xpm",
220 "bitmaps/buttons/presson.xpm", 0},
221 {"", 2, 472, 225, 17, 78, 0, 1.01, 0,
222 "bitmaps/buttons/pressoff.xpm",
223 "bitmaps/buttons/presson.xpm", 0},
224 {"", 2, 490, 225, 17, 78, 0, 1.01, 0,
225 "bitmaps/buttons/pressoff.xpm",
226 "bitmaps/buttons/presson.xpm", 0},
227 {"", 2, 418, 308, 17, 78, 0, 1.01, 0,
228 "bitmaps/buttons/pressoff.xpm",
229 "bitmaps/buttons/presson.xpm", 0},
230 {"", 2, 436, 308, 17, 78, 0, 1.01, 0,
231 "bitmaps/buttons/pressoff.xpm",
232 "bitmaps/buttons/presson.xpm", 0},
233 {"", 2, 454, 308, 17, 78, 0, 1.01, 0,
234 "bitmaps/buttons/pressoff.xpm",
235 "bitmaps/buttons/presson.xpm", 0},
236 {"", 2, 472, 308, 17, 78, 0, 1.01, 0,
237 "bitmaps/buttons/pressoff.xpm",
238 "bitmaps/buttons/presson.xpm", 0},
239 {"", 2, 490, 308, 17, 78, 0, 1.01, 0,
240 "bitmaps/buttons/pressoff.xpm",
241 "bitmaps/buttons/presson.xpm", 0},
242 {"", 2, 510, 228, 15, 70, 0, 1.01, 0,
243 "bitmaps/buttons/pressoffg.xpm",
244 "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON},
245 {"", 2, 510, 309, 15, 70, 0, 1.01, 0,
246 "bitmaps/buttons/pressoffo.xpm",
247 "bitmaps/buttons/pressono.xpm", BRIGHTON_CHECKBUTTON},
248 {"", 2, 540, 70, 16, 78, 0, 1.01, 0,
249 "bitmaps/buttons/pressoff.xpm",
250 "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON},
251 {"", 2, 540, 145, 16, 78, 0, 1.01, 0,
252 "bitmaps/buttons/pressoff.xpm",
253 "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON},
254 {"", 2, 540, 227, 16, 78, 0, 1.01, 0,
255 "bitmaps/buttons/pressoff.xpm",
256 "bitmaps/buttons/presson.xpm", 0},
257 {"", 2, 540, 308, 16, 78, 0, 1.01, 0,
258 "bitmaps/buttons/pressoff.xpm",
259 "bitmaps/buttons/presson.xpm", 0},
260 /* mem up down */
261 {"", 2, 402, 228, 15, 70, 0, 1.01, 0,
262 "bitmaps/buttons/pressoffg.xpm",
263 "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON},
264 {"", 2, 402, 311, 15, 70, 0, 1.01, 0,
265 "bitmaps/buttons/pressoffg.xpm",
266 "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON},
267 /* displays */
268 {"", 3, 403, 90, 128, 63, 0, 1, 0, 0,
269 "bitmaps/images/alphadisplay3.xpm", 0},
270 {"", 3, 403, 150, 128, 63, 0, 1, 0, 0, 0, 0}
271 };
272 /*
273 * This is a set of globals for the main window rendering. Again taken from
274 * include/brighton.h
275 */
276 brightonApp explorerApp = {
277 "explorer",
278 0, /* no blueprint on wood background. */
279 "bitmaps/textures/wood2.xpm",
280 0, /* or BRIGHTON_STRETCH, default is tesselate */
281 explorerInit,
282 explorerConfigure, /* 3 callbacks, unused? */
283 midiCallback,
284 destroySynth,
285 {1, 100, 2, 2, 5, 520, 0, 0},
286 817, 472, 0, 0,
287 7, /* one panel only */
288 {
289 {
290 "Explorer",
291 "bitmaps/blueprints/explorer.xpm",
292 "bitmaps/textures/metal6.xpm",
293 BRIGHTON_STRETCH, /* flags */
294 0,
295 explorerConfigure,
296 explorerCallback,
297 25, 25, 950, 532,
298 DEVICE_COUNT,
299 locations
300 },
301 {
302 "Keyboard",
303 0,
304 "bitmaps/newkeys/ekbg.xpm", /* flags */
305 0x020|BRIGHTON_STRETCH,
306 0,
307 0,
308 keyCallback,
309 140, 675, 840, 300,
310 KEY_COUNT_3OCTAVE,
311 keys3octave
312 },
313 {
314 "Mods",
315 "bitmaps/blueprints/mods.xpm",
316 "bitmaps/textures/metal6.xpm", /* flags */
317 BRIGHTON_STRETCH,
318 0,
319 0,
320 modCallback,
321 15, 675, 125, 300,
322 2,
323 mods
324 },
325 {
326 "SP0",
327 0,
328 "bitmaps/textures/wood2.xpm",
329 BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */
330 0,
331 0,
332 0,
333 930, 675, 60, 300,
334 0,
335 0
336 },
337 {
338 "SP1",
339 0,
340 "bitmaps/textures/wood2.xpm",
341 BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */
342 0,
343 0,
344 0,
345 0, 0, 15, 1000,
346 0,
347 0
348 },
349 {
350 "SP2",
351 0,
352 "bitmaps/textures/wood2.xpm",
353 BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */
354 0,
355 0,
356 0,
357 985, 0, 15, 1000,
358 0,
359 0
360 },
361 }
362 };
363
364 /*static dispatcher dispatch[DEVICE_COUNT]; */
365
366 static int
midiCallback(brightonWindow * win,int controller,int value,float n)367 midiCallback(brightonWindow *win, int controller, int value, float n)
368 {
369 guiSynth *synth = findSynth(global.synths, win);
370
371 printf("midi callback: %x, %i\n", controller, value);
372
373 switch(controller)
374 {
375 case MIDI_PROGRAM:
376 printf("midi program: %x, %i\n", controller, value);
377 synth->location = value + synth->bank * 10;
378 if (loadMemory(synth, "explorer", 0, synth->location,
379 synth->mem.active, FIRST_DEV, BRISTOL_STAT) < 0)
380 displayText(synth, "FRE", synth->location, DISPLAY1);
381 else
382 displayText(synth, "PRG", synth->location, DISPLAY1);
383 break;
384 case MIDI_BANK_SELECT:
385 printf("midi banksel: %x, %i\n", controller, value);
386 synth->bank = value;
387 synth->location = (synth->location % 10) + value * 10;
388 if (loadMemory(synth, "explorer", 0, synth->location,
389 synth->mem.active, FIRST_DEV, BRISTOL_STAT) < 0)
390 displayText(synth, "FRE", synth->location, DISPLAY1);
391 else
392 displayText(synth, "PRG", synth->location, DISPLAY1);
393 break;
394 }
395 return(0);
396 }
397
398 static int
explorerMidiSendMsg(void * synth,int fd,int chan,int c,int o,int v)399 explorerMidiSendMsg(void *synth, int fd, int chan, int c, int o, int v)
400 {
401 bristolMidiSendMsg(fd, chan, c, o, v);
402 return(0);
403 }
404
405 static void
explorerMemory(guiSynth * synth,int fd,int chan,int c,int o,int v)406 explorerMemory(guiSynth *synth, int fd, int chan, int c, int o, int v)
407 {
408 /* printf("explorerMemory(%i %i %i %i %i)\n", fd, chan, c, o, v); */
409
410 if (synth->flags & MEM_LOADING)
411 return;
412 if ((synth->flags & OPERATIONAL) == 0)
413 return;
414
415 if (synth->dispatch[MEM_START].other2)
416 {
417 synth->dispatch[MEM_START].other2 = 0;
418 return;
419 }
420
421 switch (c) {
422 default:
423 case 0:
424 if (synth->dispatch[MEM_START].other1 != -1)
425 {
426 brightonEvent event;
427 synth->dispatch[MEM_START].other2 = 1;
428
429 if (synth->dispatch[MEM_START].other1 != c)
430 event.value = 0;
431 else
432 event.value = 1;
433
434 brightonParamChange(synth->win, synth->panel,
435 synth->dispatch[MEM_START].other1, &event);
436 }
437 synth->dispatch[MEM_START].other1 = c;
438
439 synth->location = synth->location * 10 + o;
440
441 if (synth->location >= 1000)
442 synth->location = o;
443
444 if (loadMemory(synth, "explorer", 0, synth->location,
445 synth->mem.active, FIRST_DEV, BRISTOL_STAT) < 0)
446 displayText(synth, "FRE", synth->location, DISPLAY1);
447 else
448 displayText(synth, "PRG", synth->location, DISPLAY1);
449 break;
450 case 1:
451 if (loadMemory(synth, "explorer", 0, synth->location,
452 synth->mem.active, FIRST_DEV, 0) < 0)
453 displayText(synth, "FRE", synth->location, DISPLAY2);
454 else
455 displayText(synth, "PRG", synth->location, DISPLAY2);
456 /* synth->location = 0; */
457 break;
458 case 2:
459 saveMemory(synth, "explorer", 0, synth->location, FIRST_DEV);
460 displayText(synth, "PRG", synth->location, DISPLAY2);
461 /* synth->location = 0; */
462 break;
463 case 3:
464 while (loadMemory(synth, "explorer", 0, ++synth->location,
465 synth->mem.active, FIRST_DEV, 0) < 0)
466 {
467 if (synth->location > 999)
468 synth->location = -1;
469 }
470 displayText(synth, "PRG", synth->location, DISPLAY2);
471 break;
472 case 4:
473 while (loadMemory(synth, "explorer", 0, --synth->location,
474 synth->mem.active, FIRST_DEV, 0) < 0)
475 {
476 if (synth->location < 0)
477 synth->location = 999;
478 }
479 displayText(synth, "PRG", synth->location, DISPLAY2);
480 break;
481 }
482 }
483
484 /*
485 * For the sake of ease of use, links have been placed here to be called
486 * by any of the devices created. They would be better in some other file,
487 * perhaps with this as a dispatch.
488 *
489 * Param refers to the device index in the locations table given below.
490 */
491 int
explorerCallback(brightonWindow * win,int panel,int index,float value)492 explorerCallback(brightonWindow * win, int panel, int index, float value)
493 {
494 guiSynth *synth = findSynth(global.synths, win);
495 int sendvalue;
496
497 /* printf("explorerCallback(%i, %i, %f)\n", panel, index, value); */
498
499 if (synth == 0)
500 return(0);
501
502 if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0))
503 return(0);
504 if (index >= DEVICE_COUNT)
505 return(0);
506
507 if (explorerApp.resources[0].devlocn[index].to == 1.0)
508 sendvalue = value * (CONTROLLER_RANGE - 1);
509 else
510 sendvalue = value;
511
512 synth->mem.param[index] = value;
513
514 if ((!global.libtest) || (index >= ACTIVE_DEVS))
515 synth->dispatch[index].routine(synth,
516 global.controlfd, synth->sid,
517 synth->dispatch[index].controller,
518 synth->dispatch[index].operator,
519 sendvalue);
520 else
521 printf("dispatch[%p,%i](%i, %i, %i, %i, %i)\n", synth, index,
522 global.controlfd, synth->sid,
523 synth->dispatch[index].controller,
524 synth->dispatch[index].operator,
525 sendvalue);
526 return(0);
527 }
528
529 static void
explorerMidi(guiSynth * synth,int fd,int chan,int c,int o,int v)530 explorerMidi(guiSynth *synth, int fd, int chan, int c, int o, int v)
531 {
532 printf("explorerMidi(%i %i %i %i %i)\n", fd, chan, c, o, v);
533
534 if ((synth->flags & OPERATIONAL) == 0)
535 return;
536
537 if (synth->dispatch[MEM_START + 14].other1 == MEM_START + 14)
538 {
539 int newchan;
540
541 if (c == 1) {
542 if ((newchan = synth->midichannel - 1) < 0)
543 {
544 synth->midichannel = 0;
545 return;
546 }
547 } else {
548 if ((newchan = synth->midichannel + 1) >= 16)
549 {
550 synth->midichannel = 15;
551 return;
552 }
553 }
554
555 if (global.libtest == 0)
556 bristolMidiSendMsg(global.controlfd, synth->sid,
557 127, 0, BRISTOL_MIDICHANNEL|newchan);
558
559 synth->midichannel = newchan;
560
561 displayText(synth, "CHAN", synth->midichannel + 1, DISPLAY1);
562 } else {
563 if (c == 1) {
564 while (locations[--synth->dispatch[MEM_START + 15].other2].name[0]
565 == '\0')
566 {
567 if (synth->dispatch[MEM_START + 15].other2 < 0)
568 synth->dispatch[MEM_START + 15].other2 = 49;
569 }
570 } else {
571 while (locations[++synth->dispatch[MEM_START + 15].other2].name[0]
572 == '\0')
573 {
574 if (synth->dispatch[MEM_START + 15].other2 >= 49)
575 synth->dispatch[MEM_START + 15].other2 = 0;
576 }
577 }
578 displayText(synth,
579 locations[synth->dispatch[MEM_START + 15].other2].name,
580 synth->dispatch[MEM_START + 15].other2,
581 DISPLAY2);
582 if (synth->dispatch[MEM_START + 15].other1 == 1)
583 {
584 /*printf("PANEL X SELECTOR %i %i = %i %i\n", */
585 /*synth->dispatch[MEM_START + 15].other1, */
586 /*synth->dispatch[MEM_START + 15].other2, */
587 /*synth->dispatch[synth->dispatch[MEM_START + 15].other2].controller, */
588 /*synth->dispatch[synth->dispatch[MEM_START + 15].other2].operator); */
589 synth->dispatch[54].controller =
590 synth->dispatch[
591 synth->dispatch[MEM_START + 15].other2].controller;
592 synth->dispatch[54].operator =
593 synth->dispatch[
594 synth->dispatch[MEM_START + 15].other2].operator;
595 } else {
596 /*printf("PANEL Y SELECTOR %i %i = %i %i\n", */
597 /*synth->dispatch[MEM_START + 15].other1, */
598 /*synth->dispatch[MEM_START + 15].other2, */
599 /*synth->dispatch[synth->dispatch[MEM_START + 15].other2].controller, */
600 /*synth->dispatch[synth->dispatch[MEM_START + 15].other2].operator); */
601 synth->dispatch[55].controller =
602 synth->dispatch[
603 synth->dispatch[MEM_START + 15].other2].controller;
604 synth->dispatch[55].operator =
605 synth->dispatch[
606 synth->dispatch[MEM_START + 15].other2].operator;
607 }
608 }
609 }
610
611 static void
explorerPanelSelect(guiSynth * synth,int fd,int chan,int c,int o,int v)612 explorerPanelSelect(guiSynth *synth, int fd, int chan, int c, int o, int v)
613 {
614
615 /* printf("explorerPanelSelect(%x, %i, %i, %i, %i, %i\n", */
616 /* synth, fd, chan, c, o, v); */
617 /* dispatch[MEM_START + 14] = dispatch[MEM_START + 15] */
618
619 if (synth->dispatch[MEM_START + 14].other2)
620 {
621 synth->dispatch[MEM_START + 14].other2 = 0;
622 return;
623 }
624
625 if (synth->dispatch[MEM_START + 14].other1 != -1)
626 {
627 brightonEvent event;
628 synth->dispatch[MEM_START + 14].other2 = 1;
629
630 if (synth->dispatch[MEM_START + 14].other1 != c)
631 event.value = 0;
632 else
633 event.value = 1;
634
635 brightonParamChange(synth->win, synth->panel,
636 synth->dispatch[MEM_START + 14].other1, &event);
637 }
638 displayText(synth, "CHAN", synth->midichannel + 1, DISPLAY1);
639
640 if (c == MEM_START + 15)
641 {
642 if (synth->dispatch[MEM_START + 15].other1 > 1)
643 synth->dispatch[MEM_START + 15].other1 = 0;
644
645 switch (synth->dispatch[MEM_START + 15].other1) {
646 case 0:
647 default:
648 displayText(synth, "PAN-X",
649 synth->dispatch[MEM_START + 15].other2, DISPLAY1);
650 break;
651 case 1:
652 displayText(synth, "PAN-Y",
653 synth->dispatch[MEM_START + 15].other2, DISPLAY1);
654 break;
655 }
656 synth->dispatch[MEM_START + 15].other1++;
657 }
658 synth->dispatch[MEM_START + 14].other1 = c;
659 }
660
661 /*
662 static void
663 explorerOsc3Transpose(guiSynth *synth)
664 {
665 if (synth->mem.param[23] != 0)
666 bristolMidiSendMsg(global.controlfd, synth->sid, 2, 1,
667 (int) (synth->mem.param[18] / 4));
668 else
669 bristolMidiSendMsg(global.controlfd, synth->sid, 2, 1,
670 (int) synth->mem.param[18]);
671 }
672 */
673
674 static void
explorerFilterMode(guiSynth * synth,int fd,int chan,int o,int c,int v)675 explorerFilterMode(guiSynth *synth, int fd, int chan, int o, int c, int v)
676 {
677 /*
678 * If value is zero we need to configure two H/LPF and clear the MODE
679 * flag (12/12). Otherwise set the flag and configure C/HPF, H/LPF.
680 */
681 if (v == 0) {
682 /*
683 printf("LPF/LPF\n");
684 * FIlter 1 must change to type 4, Houvilainen LPF.
685 */
686 bristolMidiSendMsg(global.controlfd, synth->sid, 4, 4, 4);
687 bristolMidiSendMsg(global.controlfd, synth->sid, 4, 6, 0);
688 } else {
689 /*
690 printf("HPF/LPF\n");
691 * FIlter 1 must change to type 0, Chamberlain and HPF
692 */
693 bristolMidiSendMsg(global.controlfd, synth->sid, 4, 4, 0);
694 bristolMidiSendMsg(global.controlfd, synth->sid, 4, 6, 2);
695 }
696
697 /* And the main routing flag for filter stereo panning */
698 bristolMidiSendMsg(global.controlfd, synth->sid, 12, 12, v);
699 }
700
701 static void
explorerFilter(guiSynth * synth,int fd,int chan,int o,int c,int v)702 explorerFilter(guiSynth *synth, int fd, int chan, int o, int c, int v)
703 {
704 int value;
705
706 /* See if this is the key track or mod */
707 if (c == 3)
708 {
709 bristolMidiSendMsg(global.controlfd, synth->sid, 4, c, v);
710 bristolMidiSendMsg(global.controlfd, synth->sid, 9, c, v);
711
712 return;
713 }
714
715 if (c == 1)
716 {
717 /* Res goes to both LPF but not to the HPF. */
718 bristolMidiSendMsg(global.controlfd, synth->sid, 4, c, v);
719 bristolMidiSendMsg(global.controlfd, synth->sid, 9, c, v);
720
721 return;
722 }
723
724 /*
725 * We have mod and res that just goes to each filter.
726 *
727 * Cutoff and spare are a function of the eachother.
728 */
729 bristolMidiSendMsg(global.controlfd, synth->sid, 9, 0,
730 (int) (synth->mem.param[34] * C_RANGE_MIN_1));
731
732 value = (synth->mem.param[34] + (synth->mem.param[35] - 0.5f))
733 * C_RANGE_MIN_1;
734
735 if (value > C_RANGE_MIN_1)
736 value = C_RANGE_MIN_1;
737 else if (value < 0)
738 value = 0;
739
740 bristolMidiSendMsg(global.controlfd, synth->sid, 4, 0, value);
741 /* bristolMidiSendMsg(global.controlfd, synth->sid, 4, 0, */
742 /* (int) (synth->mem.param[35] * C_RANGE_MIN_1)); */
743 }
744
745 static void
explorerRelease(guiSynth * synth,int fd,int chan,int o,int c,int v)746 explorerRelease(guiSynth *synth, int fd, int chan, int o, int c, int v)
747 {
748 if ((c == 3) || (c == 5)) {
749 /* Filter/APM env release */
750 if (synth->mem.param[53] != 0)
751 bristolMidiSendMsg(global.controlfd, synth->sid, c, 3, v);
752 else
753 bristolMidiSendMsg(global.controlfd, synth->sid, c, 3, v / 10);
754 } else {
755 /* Selection switch */
756 if (synth->mem.param[53] != 0)
757 {
758 bristolMidiSendMsg(global.controlfd, synth->sid, 3, 3,
759 (int) (synth->mem.param[42] * C_RANGE_MIN_1));
760 bristolMidiSendMsg(global.controlfd, synth->sid, 5, 3,
761 (int) (synth->mem.param[47] * C_RANGE_MIN_1));
762 } else {
763 bristolMidiSendMsg(global.controlfd, synth->sid, 3, 3,
764 (int) (synth->mem.param[42] * C_RANGE_MIN_1 / 10));
765 bristolMidiSendMsg(global.controlfd, synth->sid, 5, 3,
766 (int) (synth->mem.param[47] * C_RANGE_MIN_1 / 10));
767 }
768 }
769 }
770
771 static void
explorerGlide(guiSynth * synth)772 explorerGlide(guiSynth *synth)
773 {
774 if (synth->mem.param[52] != 0)
775 bristolMidiSendMsg(global.controlfd, synth->sid, 11, 0,
776 (int) (synth->mem.param[3] * C_RANGE_MIN_1));
777 else
778 bristolMidiSendMsg(global.controlfd, synth->sid, 11, 0, 0);
779 }
780
781 /*
782 * Any location initialisation required to run the callbacks. For bristol, this
783 * will connect to the engine, and give it some base parameters.
784 * May need to generate some application specific menus.
785 * Will also then make specific requests to some of the devices to alter their
786 * rendering.
787 */
788 int
explorerInit(brightonWindow * win)789 explorerInit(brightonWindow *win)
790 {
791 guiSynth *synth = findSynth(global.synths, win);
792 dispatcher *dispatch;
793 int i;
794
795 if (synth == 0)
796 {
797 synth = findSynth(global.synths, 0);
798 if (synth == 0)
799 {
800 printf("cannot init\n");
801 return(0);
802 }
803 }
804
805 synth->win = win;
806
807 printf("Initialise the explorer link to bristol: %p\n", synth->win);
808
809 synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float));
810 synth->mem.count = DEVICE_COUNT;
811 synth->mem.active = ACTIVE_DEVS;
812 synth->dispatch = (dispatcher *)
813 brightonmalloc(DEVICE_COUNT * sizeof(dispatcher));
814 dispatch = synth->dispatch;
815
816 /*
817 * We really want to have three connection mechanisms. These should be
818 * 1. Unix named sockets.
819 * 2. UDP sockets.
820 * 3. MIDI pipe.
821 */
822 if (!global.libtest)
823 if ((synth->sid = initConnection(&global, synth)) < 0)
824 return(-1);
825
826 for (i = 0; i < DEVICE_COUNT; i++)
827 synth->dispatch[i].routine = explorerMidiSendMsg;
828
829 /* tune/glide */
830 dispatch[0].controller = 8;
831 dispatch[0].operator = 0;
832 dispatch[1].controller = 8;
833 dispatch[1].operator = 1;
834 dispatch[2].controller = 10;
835 dispatch[2].operator = 0;
836 dispatch[3].routine = (synthRoutine) explorerGlide;
837
838 /* Bus mods */
839 dispatch[4].controller = 15;
840 dispatch[4].operator = 0;
841 dispatch[5].controller = 15;
842 dispatch[5].operator = 1;
843 dispatch[6].controller = 15;
844 dispatch[6].operator = 2;
845 dispatch[7].controller = 15;
846 dispatch[7].operator = 3;
847 dispatch[8].controller = 16;
848 dispatch[8].operator = 0;
849 dispatch[9].controller = 16;
850 dispatch[9].operator = 1;
851 dispatch[10].controller = 16;
852 dispatch[10].operator = 2;
853 dispatch[11].controller = 16;
854 dispatch[11].operator = 3;
855
856 /* Oscillators */
857 dispatch[12].controller = 0;
858 dispatch[12].operator = 1;
859 dispatch[13].controller = 0;
860 dispatch[13].operator = 0;
861 dispatch[14].controller = 1;
862 dispatch[14].operator = 2;
863 dispatch[15].controller = 1;
864 dispatch[15].operator = 1;
865 dispatch[16].controller = 1;
866 dispatch[16].operator = 0;
867 dispatch[17].controller = 2;
868 dispatch[17].operator = 2;
869 dispatch[18].controller = 2;
870 dispatch[18].operator = 1;
871 dispatch[19].controller = 2;
872 dispatch[19].operator = 0;
873 /* Osc options */
874 dispatch[20].controller = 12;
875 dispatch[20].operator = 9;
876 dispatch[21].controller = 12;
877 dispatch[21].operator = 10;
878 dispatch[22].controller = 12;
879 dispatch[22].operator = 0;
880 dispatch[23].controller = 12;
881 dispatch[23].operator = 8;
882
883 /* MIXER */
884 dispatch[24].controller = 14;
885 dispatch[24].operator = 0;
886 dispatch[25].controller = 0;
887 dispatch[25].operator = 3;
888 dispatch[26].controller = 1;
889 dispatch[26].operator = 3;
890 dispatch[27].controller = 2;
891 dispatch[27].operator = 3;
892 dispatch[28].controller = 12;
893 dispatch[28].operator = 13;
894
895 /* mixer flags */
896 dispatch[29].controller = 12;
897 dispatch[29].operator = 5;
898 dispatch[30].controller = 12;
899 dispatch[30].operator = 2;
900 dispatch[31].controller = 12;
901 dispatch[31].operator = 3;
902 dispatch[32].controller = 12;
903 dispatch[32].operator = 4;
904 dispatch[33].controller = 12;
905 dispatch[33].operator = 6;
906
907 /* Filter */
908 dispatch[34].controller = 4;
909 dispatch[34].operator = 0;
910 dispatch[35].controller = 12;
911 dispatch[35].operator = 12;
912 dispatch[36].controller = 4;
913 dispatch[36].operator = 1;
914 dispatch[37].controller = 4;
915 dispatch[37].operator = 3;
916
917 /* Filter spacing is now in the emulater, not the filter. We also need a */
918 /* filter param dispatcher to configure the two filters together. */
919 /* Dispatcher */
920 dispatch[34].routine =
921 dispatch[35].routine =
922 dispatch[36].routine =
923 dispatch[37].routine = (synthRoutine) explorerFilter;
924
925 dispatch[38].controller = 12;
926 dispatch[38].operator = 12;
927 dispatch[38].routine = (synthRoutine) explorerFilterMode;
928
929 /* Filter ADSR */
930 dispatch[39].controller = 3;
931 dispatch[39].operator = 0;
932 dispatch[40].controller = 3;
933 dispatch[40].operator = 1;
934 dispatch[41].controller = 3;
935 dispatch[41].operator = 2;
936 dispatch[42].controller = 3;
937 dispatch[42].operator = 3;
938 dispatch[42].routine = (synthRoutine) explorerRelease;
939
940 /* velocity from filter control */
941 dispatch[43].controller = 12;
942 dispatch[43].operator = 11;
943
944 /* Amp ADSR */
945 dispatch[44].controller = 5;
946 dispatch[44].operator = 0;
947 dispatch[45].controller = 5;
948 dispatch[45].operator = 1;
949 dispatch[46].controller = 5;
950 dispatch[46].operator = 2;
951 dispatch[47].controller = 5;
952 dispatch[47].operator = 3;
953 dispatch[47].routine = (synthRoutine) explorerRelease;
954 dispatch[48].controller = 5;
955 dispatch[48].operator = 5;
956
957 /* volume, on/off */
958 dispatch[49].controller = 5;
959 dispatch[49].operator = 4;
960 dispatch[50].controller = 12;
961 dispatch[50].operator = 1;
962 dispatch[51].controller = 12;
963 dispatch[51].operator = 7;
964 dispatch[52].routine = (synthRoutine) explorerGlide;
965 dispatch[53].controller = 6;
966 dispatch[53].routine = (synthRoutine) explorerRelease;
967
968 /* Touch panel */
969 dispatch[54].controller = 8;
970 dispatch[54].operator = 0;
971 dispatch[55].controller = 4;
972 dispatch[55].operator = 0;
973
974 /* memory */
975 dispatch[MEM_START].operator = 0;
976 dispatch[MEM_START].controller = MEM_START;
977 dispatch[MEM_START + 1].operator = 1;
978 dispatch[MEM_START + 1].controller = MEM_START + 1;
979 dispatch[MEM_START + 2].operator = 2;
980 dispatch[MEM_START + 2].controller = MEM_START + 2;
981 dispatch[MEM_START + 3].operator = 3;
982 dispatch[MEM_START + 3].controller = MEM_START + 3;
983 dispatch[MEM_START + 4].operator = 4;
984 dispatch[MEM_START + 4].controller = MEM_START + 4;
985 dispatch[MEM_START + 5].operator = 5;
986 dispatch[MEM_START + 5].controller = MEM_START + 5;
987 dispatch[MEM_START + 6].operator = 6;
988 dispatch[MEM_START + 6].controller = MEM_START + 6;
989 dispatch[MEM_START + 7].operator = 7;
990 dispatch[MEM_START + 7].controller = MEM_START + 7;
991 dispatch[MEM_START + 8].operator = 8;
992 dispatch[MEM_START + 8].controller = MEM_START + 8;
993 dispatch[MEM_START + 9].operator = 9;
994 dispatch[MEM_START + 9].controller = MEM_START + 9;
995
996 dispatch[MEM_START + 10].controller = 1;
997 dispatch[MEM_START + 11].controller = 2;
998 dispatch[MEM_START + 16].controller = 3;
999 dispatch[MEM_START + 17].controller = 4;
1000
1001 dispatch[MEM_START + 0].routine = dispatch[MEM_START + 1].routine =
1002 dispatch[MEM_START + 2].routine = dispatch[MEM_START + 3].routine =
1003 dispatch[MEM_START + 4].routine = dispatch[MEM_START + 5].routine =
1004 dispatch[MEM_START + 6].routine = dispatch[MEM_START + 7].routine =
1005 dispatch[MEM_START + 8].routine = dispatch[MEM_START + 9].routine =
1006 dispatch[MEM_START + 10].routine = dispatch[MEM_START + 11].routine =
1007 dispatch[MEM_START + 16].routine = dispatch[MEM_START + 17].routine =
1008 (synthRoutine) explorerMemory;
1009
1010 /* midi */
1011 dispatch[MEM_START + 12].controller = 2;
1012 dispatch[MEM_START + 13].controller = 1;
1013 dispatch[MEM_START + 12].routine = dispatch[MEM_START + 13].routine =
1014 (synthRoutine) explorerMidi;
1015
1016 /* midi/panel selectors */
1017 dispatch[MEM_START + 14].controller = MEM_START + 14;
1018 dispatch[MEM_START + 15].controller = MEM_START + 15;
1019 dispatch[MEM_START + 14].routine = dispatch[MEM_START + 15].routine =
1020 (synthRoutine) explorerPanelSelect;
1021
1022 /* No velocity on filter contour, fixed gain */
1023 bristolMidiSendMsg(global.controlfd, synth->sid, 7, 0, 16000);
1024 bristolMidiSendMsg(global.controlfd, synth->sid, 3, 5, 0);
1025 bristolMidiSendMsg(global.controlfd, synth->sid, 3, 4, 16383);
1026
1027 return(0);
1028 }
1029
1030 /*
1031 * This will be called to make any routine specific parameters available.
1032 */
1033 int
explorerConfigure(brightonWindow * win)1034 explorerConfigure(brightonWindow *win)
1035 {
1036 guiSynth *synth = findSynth(global.synths, win);
1037 brightonEvent event;
1038
1039 if (synth == 0)
1040 {
1041 printf("problems going operational\n");
1042 return(-1);
1043 }
1044
1045 if (synth->flags & OPERATIONAL)
1046 return(0);
1047
1048 printf("going operational\n");
1049
1050 synth->flags |= OPERATIONAL;
1051 synth->keypanel = 1;
1052 synth->keypanel2 = -1;
1053 synth->transpose = 36;
1054
1055 displayText(synth, "CHAN", synth->midichannel + 1, DISPLAY1);
1056
1057 loadMemory(synth, "explorer", 0, synth->location, synth->mem.active,
1058 FIRST_DEV, 0);
1059 displayText(synth, "PRG", synth->location, DISPLAY2);
1060
1061 brightonPut(win,
1062 "bitmaps/blueprints/explorershade.xpm", 0, 0, win->width, win->height);
1063
1064 /*
1065 * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only
1066 * occurs on first paint, so we suppress the first paint, and then request
1067 * an expose here.
1068 */
1069 event.type = BRIGHTON_EXPOSE;
1070 event.intvalue = 1;
1071 brightonParamChange(synth->win, KEY_PANEL, -1, &event);
1072 configureGlobals(synth);
1073
1074 return(0);
1075 }
1076
1077