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 "brightoninternals.h"
28
29 static int initmem;
30
31 static int prophetInit();
32 static int prophetConfigure();
33 static int prophetCallback(brightonWindow *, int, int, float);
34 /*static int keyCallback(void *, int, int, float); */
35 /*static int modCallback(void *, int, int, float); */
36 static int midiCallback(brightonWindow *, int, int, float);
37
38 extern guimain global;
39
40 #include "brightonKeys.h"
41
42 #define FIRST_DEV 0
43 #define DEVICE_COUNT (65 + FIRST_DEV)
44 #define ACTIVE_DEVS (47 + FIRST_DEV)
45 #define DISPLAY_DEV (64 + FIRST_DEV)
46 #define RADIOSET_1 50
47
48 #define KEY_PANEL 1
49
50 #define R1 140
51 #define RB1 160
52 #define R2 425
53 #define RB2 445
54 #define R3 710
55 #define RB3 730
56
57 #define C1 20
58 #define C2 70
59 #define CB1 60
60 #define CB2 90
61 #define C3 120
62 #define C4 150
63 #define C5 180
64
65 #define C6 235
66 #define CB6 275
67 #define CB7 305
68 #define C7 340
69 #define CB8 390
70
71 #define C9 280
72 #define CB9 330
73 #define CB10 360
74 #define CB11 390
75 #define C10 430
76 #define CB12 480
77 #define CB13 510
78
79 #define C11 442
80 #define C12 490
81 #define C13 538
82
83 #define C14 595
84 #define C15 642
85 #define C16 688
86 #define C17 735
87
88 #define C18 800
89 #define C19 850
90 #define C20 900
91 #define C21 950
92
93 #define C22 877
94
95 #define S1 120
96
97 #define B1 14
98 #define B2 80
99
100 /*
101 * This structure is for device definition. The structure is defined in
102 * include/brighton.h, further definitions in brighton/brightonDevtable.h and
103 * include/brightoninternals.h
104 *
105 * typedef int (*brightonCallback)(int, float);
106 * typedef struct BrightonLocations {
107 * int device; 0=rotary, 1=scale, etc.
108 * float relx, rely; relative position with regards to 1000 by 1000 window
109 * float relw, relh; relative height.
110 * int from, to;
111 * brightonCallback callback; specific to this dev
112 * char *image; bitmap. If zero take a device default.
113 * int flags;
114 * } brightonLocations;
115 *
116 * This example is for a prophetBristol type synth interface.
117 */
118 static brightonLocations locations[DEVICE_COUNT] = {
119 /* poly mod */
120 {"PolyMod-Filt", 0, C1, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0|BRIGHTON_HALFSHADOW},
121 {"PolyMod-OscB", 0, C2, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0|BRIGHTON_HALFSHADOW},
122 {"PolyMod2Freq-A", 2, C3, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
123 "bitmaps/buttons/presson.xpm", 0},
124 {"PolyMod2PW-A", 2, C4, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
125 "bitmaps/buttons/presson.xpm", 0},
126 {"PolyMod2Filt", 2, C5, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
127 "bitmaps/buttons/presson.xpm", 0},
128 /* lfo */
129 {"LFO-Freq", 0, C2, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
130 {"LFO-Ramp", 2, C3, RB2, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
131 "bitmaps/buttons/presson.xpm", 0},
132 {"LFO-Tri", 2, C4, RB2, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
133 "bitmaps/buttons/presson.xpm", 0},
134 {"LFO-Square", 2, C5, RB2, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
135 "bitmaps/buttons/presson.xpm", 0},
136 /* wheel mod */
137 {"Wheel-Mix", 0, C1, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
138 {"Wheel-FreqA", 2, CB1, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
139 "bitmaps/buttons/presson.xpm", 0},
140 {"Wheel-FreqB", 2, CB2, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
141 "bitmaps/buttons/presson.xpm", 0},
142 {"Wheel-PW-A", 2, C3, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
143 "bitmaps/buttons/presson.xpm", 0},
144 {"Wheel-PW-B", 2, C4, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
145 "bitmaps/buttons/presson.xpm", 0},
146 {"Wheel-Filt", 2, C5, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
147 "bitmaps/buttons/presson.xpm", 0},
148 /* osc a */
149 {"OscA-Transpose", 0, C6, R1, S1, S1, 0, 5, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
150 {"OscA-Ramp", 2, CB6, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
151 "bitmaps/buttons/presson.xpm", 0},
152 {"OscA-Pulse", 2, CB7, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
153 "bitmaps/buttons/presson.xpm", 0},
154 {"OscA-PW", 0, C7, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
155 {"OscA-Sync", 2, CB8, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
156 "bitmaps/buttons/presson.xpm", 0},
157 /* osc b */
158 {"OscB-Transpose", 0, C6, R2, S1, S1, 0, 5, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
159 {"OscB-Tuning", 0, C9, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, BRIGHTON_NOTCH},
160 {"OscB-Ramp", 2, CB9, RB2, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
161 "bitmaps/buttons/presson.xpm", 0},
162 {"OscB-Tri", 2, CB10, RB2, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
163 "bitmaps/buttons/presson.xpm", 0},
164 {"OscB-Pulse", 2, CB11, RB2, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
165 "bitmaps/buttons/presson.xpm", 0},
166 {"OscB-PW", 0, C10, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
167 {"OscB-LFO", 2, CB12, RB2, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
168 "bitmaps/buttons/presson.xpm", 0},
169 {"OscB-KBD", 2, CB13, RB2, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
170 "bitmaps/buttons/presson.xpm", 0},
171 /* glide, etc */
172 {"Glide", 0, C6, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
173 {"Unison", 2, CB7, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
174 "bitmaps/buttons/presson.xpm", 0},
175 /* mixer */
176 {"Mix-OscA", 0, C11, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
177 {"Mix-OscB", 0, C12, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
178 {"Mix-Noise", 0, C13, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
179 /* filter + env */
180 {"VCF-Cutoff", 0, C14, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
181 {"VCF-Resonance", 0, C15, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
182 {"VCF-Env", 0, C16, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
183 {"VCF-KBD", 2, C17 + 6, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
184 "bitmaps/buttons/presson.xpm", 0},
185 {"VCF-Attack", 0, C14, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
186 {"VCF-Decay", 0, C15, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
187 {"VCF-Sustain", 0, C16, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
188 {"VCF-Release", 0, C17, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
189 /* main env */
190 {"VCA-Attack", 0, C18, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
191 {"VCA-Decay", 0, C19, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
192 {"VCA-Sustain", 0, C20, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
193 {"VCA-Release", 0, C21, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
194 /* tune + vol */
195 {"MasterTuning", 0, C18, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob3.xpm", 0, BRIGHTON_NOTCH},
196 {"MasterVolume", 0, C22, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob3.xpm", 0, 0},
197 {"Release", 2, C18 + 7, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
198 "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON},
199 {"A-440", 2, C19 + 7, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
200 "bitmaps/buttons/pressong.xpm", 0},
201 {"Tune", 2, C21 + 10, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
202 "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON},
203 /* memories */
204 {"", 2, C14 + 10, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
205 "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
206 {"", 2, C14 + 30, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
207 "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
208 {"", 2, C14 + 50, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
209 "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
210 {"", 2, C14 + 70, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
211 "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
212 {"", 2, C14 + 90, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
213 "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
214 {"", 2, C14 + 110, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
215 "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
216 {"", 2, C14 + 130, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
217 "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
218 {"", 2, C14 + 150, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
219 "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
220 {"", 2, CB8, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
221 "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON},
222 {"", 2, CB8 + 30, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffo.xpm",
223 "bitmaps/buttons/pressono.xpm", BRIGHTON_CHECKBUTTON},
224 {"", 2, CB8 + 60, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
225 "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON},
226 /* Midi, perhaps eventually file import/export buttons */
227 {"", 2, C20 + 10, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
228 "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON},
229 {"", 2, C21 + 10, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
230 "bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON},
231 /* */
232 {"", 4, 850, 1025, 130, 130, 0, 1, 0, "bitmaps/images/prophet.xpm", 0, 0},
233 /* Display */
234 {"", 3, CB8 + 85, RB3, 120, B2, 0, 1, 0, 0,
235 "bitmaps/images/alphadisplay3.xpm", 0}
236 };
237
238 /*
239 */
240
241 /*
242 * This is a set of globals for the main window rendering. Again taken from
243 * include/brighton.h
244 */
245 brightonApp prophetApp = {
246 "prophet",
247 0, /* no blueprint on wood background. */
248 "bitmaps/textures/wood3.xpm",
249 0, /* BRIGHTON_STRETCH, //flags */
250 prophetInit,
251 prophetConfigure, /* 3 callbacks, unused? */
252 midiCallback,
253 destroySynth,
254 {5, 100, 2, 2, 5, 520, 0, 0},
255 745, 310, 0, 0,
256 7,
257 {
258 {
259 "Prophet",
260 "bitmaps/blueprints/prophet.xpm",
261 "bitmaps/textures/metal5.xpm",
262 0, /*BRIGHTON_STRETCH, // flags */
263 0,
264 0,
265 prophetCallback,
266 15, 25, 970, 540,
267 DEVICE_COUNT,
268 locations
269 },
270 {
271 "Keyboard",
272 0,
273 "bitmaps/newkeys/kbg.xpm", /* flags */
274 0x020|BRIGHTON_STRETCH,
275 0,
276 0,
277 keyCallback,
278 110, 660, 899, 320,
279 KEY_COUNT,
280 keysprofile
281 },
282 {
283 "Mods",
284 "bitmaps/blueprints/prophetmod.xpm",
285 "bitmaps/textures/metal5.xpm", /* flags */
286 0,
287 0,
288 0,
289 modCallback,
290 15, 660, 95, 320,
291 2,
292 mods
293 },
294 {
295 "Wood side",
296 0,
297 "bitmaps/textures/wood4.xpm",
298 BRIGHTON_VERTICAL, /* flags */
299 0,
300 0,
301 0,
302 0, 0, 15, 1000,
303 0,
304 0
305 },
306 {
307 "Wood side",
308 0,
309 "bitmaps/textures/wood3.xpm",
310 BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */
311 0,
312 0,
313 0,
314 2, 4, 13, 992,
315 0,
316 0
317 },
318 {
319 "Wood side",
320 0,
321 "bitmaps/textures/wood4.xpm",
322 BRIGHTON_VERTICAL, /*flags */
323 0,
324 0,
325 0,
326 985, 0, 15, 1000,
327 0,
328 0
329 },
330 {
331 "Wood side",
332 0,
333 "bitmaps/textures/wood3.xpm",
334 BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /*flags */
335 0,
336 0,
337 0,
338 986, 4, 13, 992,
339 0,
340 0
341 }
342 }
343 };
344
345 static int
midiCallback(brightonWindow * win,int controller,int value,float n)346 midiCallback(brightonWindow *win, int controller, int value, float n)
347 {
348 guiSynth *synth = findSynth(global.synths, win);
349
350 printf("midi callback: %x, %i\n", controller, value);
351
352 switch(controller)
353 {
354 case MIDI_PROGRAM:
355 printf("midi program: %x, %i\n", controller, value);
356 synth->location = value;
357 loadMemory(synth, "prophet", 0, synth->bank + synth->location,
358 synth->mem.active, FIRST_DEV, 0);
359 break;
360 case MIDI_BANK_SELECT:
361 printf("midi banksel: %x, %i\n", controller, value);
362 synth->bank = value;
363 break;
364 }
365 return(0);
366 }
367
368 /*static dispatcher dispatch[DEVICE_COUNT]; */
369
370 static int
prophetMidiSendMsg(void * synth,int fd,int chan,int c,int o,int v)371 prophetMidiSendMsg(void *synth, int fd, int chan, int c, int o, int v)
372 {
373 bristolMidiSendMsg(fd, chan, c, o, v);
374 return(0);
375 }
376
377 static void
multiTune(guiSynth * synth,int fd,int chan,int c,int o,int v)378 multiTune(guiSynth *synth, int fd, int chan, int c, int o, int v)
379 {
380 brightonEvent event;
381
382 /*
383 * Configures all the tune settings to zero (ie, 0.5). Do the Osc-A first,
384 * since it is not visible, and then request the GUI to configure Osc-B.
385 */
386 bristolMidiSendMsg(fd, synth->sid, 0, 2, 8191);
387 event.type = BRIGHTON_FLOAT;
388 event.value = 0.5;
389 brightonParamChange(synth->win, synth->panel, FIRST_DEV + 45, &event);
390 brightonParamChange(synth->win, synth->panel, FIRST_DEV + 21, &event);
391 }
392
393 static void
keyTracking(guiSynth * synth,int fd,int chan,int c,int o,int v)394 keyTracking(guiSynth *synth, int fd, int chan, int c, int o, int v)
395 {
396 bristolMidiSendMsg(fd, synth->sid, 4, 3, v / 2);
397 }
398
399 static void
midiRelease(guiSynth * synth,int fd,int chan,int c,int o,int v)400 midiRelease(guiSynth *synth, int fd, int chan, int c, int o, int v)
401 {
402 if (!global.libtest)
403 {
404 bristolMidiSendMsg(fd, synth->sid, 127, 0,
405 BRISTOL_ALL_NOTES_OFF);
406 }
407 }
408
409 static void
prophetMemory(guiSynth * synth,int fd,int chan,int c,int o,int v)410 prophetMemory(guiSynth *synth, int fd, int chan, int c, int o, int v)
411 {
412 brightonEvent event;
413
414 if (synth->flags & MEM_LOADING)
415 return;
416 if ((synth->flags & OPERATIONAL) == 0)
417 return;
418
419 if (synth->dispatch[RADIOSET_1].other2)
420 {
421 synth->dispatch[RADIOSET_1].other2 = 0;
422 return;
423 }
424
425 switch (c) {
426 default:
427 case 0:
428 /*
429 * We want to make these into memory buttons. To do so we need to
430 * know what the last active button was, and deactivate its
431 * display, then send any message which represents the most
432 * recently configured value. Since this is a memory button we do
433 * not have much issue with the message, but we are concerned with
434 * the display.
435 */
436 if (synth->dispatch[RADIOSET_1].other1 != -1)
437 {
438 synth->dispatch[RADIOSET_1].other2 = 1;
439
440 if (synth->dispatch[RADIOSET_1].other1 != o)
441 event.value = 0;
442 else
443 event.value = 1;
444
445 brightonParamChange(synth->win, synth->panel,
446 synth->dispatch[RADIOSET_1].other1 + 49, &event);
447 }
448 synth->dispatch[RADIOSET_1].other1 = o;
449
450 if (synth->flags & BANK_SELECT) {
451 if ((synth->bank * 10 + o * 10) >= 1000)
452 {
453 synth->location = o;
454 synth->flags &= ~BANK_SELECT;
455
456 if (loadMemory(synth, "prophet", 0,
457 synth->bank + synth->location, synth->mem.active,
458 FIRST_DEV, BRISTOL_STAT) < 0)
459 displayText(synth, "FRE", synth->bank + synth->location,
460 DISPLAY_DEV);
461 else
462 displayText(synth, "PRG", synth->bank + synth->location,
463 DISPLAY_DEV);
464 } else {
465 synth->bank = synth->bank * 10 + o * 10;
466 displayText(synth, "BANK", synth->bank + synth->location,
467 DISPLAY_DEV);
468 }
469 } else {
470 if (synth->bank < 10)
471 synth->bank = 10;
472 synth->location = o;
473 if (loadMemory(synth, "prophet", 0,
474 synth->bank + synth->location, synth->mem.active,
475 FIRST_DEV, BRISTOL_STAT) < 0)
476 displayText(synth, "FRE", synth->bank + synth->location,
477 DISPLAY_DEV);
478 else
479 displayText(synth, "PRG", synth->bank + synth->location,
480 DISPLAY_DEV);
481 }
482 break;
483 case 1:
484 if (synth->bank < 10)
485 synth->bank = 10;
486 if (synth->location == 0)
487 synth->location = 1;
488 if (loadMemory(synth, "prophet", 0, synth->bank + synth->location,
489 synth->mem.active, FIRST_DEV, 0) < 0)
490 displayText(synth, "FRE", synth->bank + synth->location,
491 DISPLAY_DEV);
492 else
493 displayText(synth, "PRG", synth->bank + synth->location,
494 DISPLAY_DEV);
495 synth->flags &= ~BANK_SELECT;
496 break;
497 case 2:
498 if (synth->bank < 10)
499 synth->bank = 10;
500 if (synth->location == 0)
501 synth->location = 1;
502 saveMemory(synth, "prophet", 0, synth->bank + synth->location,
503 FIRST_DEV);
504 displayText(synth, "PRG", synth->bank + synth->location,
505 DISPLAY_DEV);
506 synth->flags &= ~BANK_SELECT;
507 break;
508 case 3:
509 if (synth->flags & BANK_SELECT) {
510 synth->flags &= ~BANK_SELECT;
511 if (loadMemory(synth, "prophet", 0,
512 synth->bank + synth->location, synth->mem.active,
513 FIRST_DEV, BRISTOL_STAT) < 0)
514 displayText(synth, "FRE", synth->bank + synth->location,
515 DISPLAY_DEV);
516 else
517 displayText(synth, "PRG", synth->bank + synth->location,
518 DISPLAY_DEV);
519 } else {
520 synth->bank = 0;
521 displayText(synth, "BANK", synth->bank, DISPLAY_DEV);
522 synth->flags |= BANK_SELECT;
523 }
524 break;
525 }
526 /* printf(" prophetMemory(B: %i L %i: %i)\n", */
527 /* synth->bank, synth->location, o); */
528 }
529
530 static int
prophetMidi(guiSynth * synth,int fd,int chan,int c,int o,int v)531 prophetMidi(guiSynth *synth, int fd, int chan, int c, int o, int v)
532 {
533 int newchan;
534
535 if ((synth->flags & OPERATIONAL) == 0)
536 return(0);
537
538 if (c == 1) {
539 if ((newchan = synth->midichannel - 1) < 0)
540 {
541 synth->midichannel = 0;
542 return(0);
543 }
544 } else {
545 if ((newchan = synth->midichannel + 1) >= 16)
546 {
547 synth->midichannel = 15;
548 return(0);
549 }
550 }
551
552 if (global.libtest == 0)
553 {
554 bristolMidiSendMsg(global.controlfd, synth->sid,
555 127, 0, BRISTOL_MIDICHANNEL|newchan);
556 }
557
558 synth->midichannel = newchan;
559
560 /* printf("P: going to display: %x, %x\n", synth, synth->win); */
561 /* displayText(synth, "MIDI", synth->midichannel + 1, DISPLAY_DEV); */
562
563 return(0);
564 }
565
566 /*
567 * For the sake of ease of use, links have been placed here to be called
568 * by any of the devices created. They would be better in some other file,
569 * perhaps with this as a dispatch.
570 *
571 * Param refers to the device index in the locations table given below.
572 */
573 static int
prophetCallback(brightonWindow * win,int panel,int index,float value)574 prophetCallback(brightonWindow * win, int panel, int index, float value)
575 {
576 guiSynth *synth = findSynth(global.synths, win);
577 int sendvalue;
578
579 /*printf("prophetCallback(%i, %f): %x\n", index, value, synth); */
580
581 if (synth == 0)
582 return(0);
583
584 if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0))
585 return(0);
586
587 if (prophetApp.resources[0].devlocn[index].to == 1.0)
588 sendvalue = value * (CONTROLLER_RANGE - 1);
589 else
590 sendvalue = value;
591
592 synth->mem.param[index] = value;
593
594 if ((!global.libtest) || (index >= ACTIVE_DEVS))
595 synth->dispatch[index].routine(synth,
596 global.controlfd, synth->sid,
597 synth->dispatch[index].controller,
598 synth->dispatch[index].operator,
599 sendvalue);
600
601 #ifdef DEBUG
602 else
603 printf("dispatch[%p,%i](%i, %i, %i, %i, %i)\n", synth, index,
604 global.controlfd, synth->sid,
605 synth->dispatch[index].controller,
606 synth->dispatch[index].operator,
607 sendvalue);
608 #endif
609
610 return(0);
611 }
612
613 /*
614 * Any location initialisation required to run the callbacks. For bristol, this
615 * will connect to the engine, and give it some base parameters.
616 * May need to generate some application specific menus.
617 * Will also then make specific requests to some of the devices to alter their
618 * rendering.
619 */
620 static int
prophetInit(brightonWindow * win)621 prophetInit(brightonWindow *win)
622 {
623 guiSynth *synth = findSynth(global.synths, win);
624 dispatcher *dispatch;
625 int i;
626
627 if (synth == 0)
628 {
629 synth = findSynth(global.synths, (int) 0);
630 if (synth == 0)
631 {
632 printf("cannot init\n");
633 return(0);
634 }
635 }
636
637 if ((initmem = synth->location) == 0)
638 initmem = 11;
639
640 synth->win = win;
641
642 printf("Initialise the prophet link to bristol: %p\n", synth->win);
643
644 synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float));
645 synth->mem.count = DEVICE_COUNT;
646 synth->mem.active = ACTIVE_DEVS;
647 synth->dispatch = (dispatcher *)
648 brightonmalloc(DEVICE_COUNT * sizeof(dispatcher));
649 dispatch = synth->dispatch;
650
651 /*
652 * We really want to have three connection mechanisms. These should be
653 * 1. Unix named sockets.
654 * 2. UDP sockets.
655 * 3. MIDI pipe.
656 */
657 if (!global.libtest)
658 {
659 if ((synth->sid = initConnection(&global, synth)) < 0)
660 return(-1);
661 }
662
663 for (i = 0; i < DEVICE_COUNT; i++)
664 {
665 synth->dispatch[i].routine = prophetMidiSendMsg;
666 }
667
668 dispatch[FIRST_DEV].controller = 126;
669 dispatch[FIRST_DEV].operator = 6;
670 dispatch[FIRST_DEV + 1].controller = 126;
671 dispatch[FIRST_DEV + 1].operator = 7;
672 dispatch[FIRST_DEV + 2].controller = 126;
673 dispatch[FIRST_DEV + 2].operator = 8;
674 dispatch[FIRST_DEV + 3].controller = 126;
675 dispatch[FIRST_DEV + 3].operator = 9;
676 dispatch[FIRST_DEV + 4].controller = 126;
677 dispatch[FIRST_DEV + 4].operator = 10;
678
679 /*
680 * This is for prophetDCO as LFO. Should change to true LFO. One parameter
681 * for freq (0) and the rest are then mix parameters.
682 */
683 dispatch[FIRST_DEV + 5].controller = 2;
684 dispatch[FIRST_DEV + 5].operator = 0;
685 dispatch[FIRST_DEV + 6].controller = 126;
686 dispatch[FIRST_DEV + 6].operator = 24;
687 dispatch[FIRST_DEV + 7].controller = 126;
688 dispatch[FIRST_DEV + 7].operator = 25;
689 dispatch[FIRST_DEV + 8].controller = 126;
690 dispatch[FIRST_DEV + 8].operator = 26;
691
692 dispatch[FIRST_DEV + 9].controller = 126;
693 dispatch[FIRST_DEV + 9].operator = 11;
694 dispatch[FIRST_DEV + 10].controller = 126;
695 dispatch[FIRST_DEV + 10].operator = 12;
696 dispatch[FIRST_DEV + 11].controller = 126;
697 dispatch[FIRST_DEV + 11].operator = 13;
698 dispatch[FIRST_DEV + 12].controller = 126;
699 dispatch[FIRST_DEV + 12].operator = 14;
700 dispatch[FIRST_DEV + 13].controller = 126;
701 dispatch[FIRST_DEV + 13].operator = 15;
702 dispatch[FIRST_DEV + 14].controller = 126;
703 dispatch[FIRST_DEV + 14].operator = 16;
704
705 dispatch[FIRST_DEV + 15].controller = 0;
706 dispatch[FIRST_DEV + 15].operator = 1;
707 dispatch[FIRST_DEV + 16].controller = 0;
708 dispatch[FIRST_DEV + 16].operator = 4;
709 dispatch[FIRST_DEV + 17].controller = 0;
710 dispatch[FIRST_DEV + 17].operator = 6;
711 dispatch[FIRST_DEV + 18].controller = 0;
712 dispatch[FIRST_DEV + 18].operator = 0;
713 dispatch[FIRST_DEV + 19].controller = 0;
714 dispatch[FIRST_DEV + 19].operator = 7;
715
716 dispatch[FIRST_DEV + 20].controller = 1;
717 dispatch[FIRST_DEV + 20].operator = 1;
718 dispatch[FIRST_DEV + 21].controller = 1;
719 dispatch[FIRST_DEV + 21].operator = 2;
720 dispatch[FIRST_DEV + 22].controller = 1;
721 dispatch[FIRST_DEV + 22].operator = 4;
722 dispatch[FIRST_DEV + 23].controller = 1;
723 dispatch[FIRST_DEV + 23].operator = 5;
724 dispatch[FIRST_DEV + 24].controller = 1;
725 dispatch[FIRST_DEV + 24].operator = 6;
726 dispatch[FIRST_DEV + 25].controller = 1;
727 dispatch[FIRST_DEV + 25].operator = 0;
728 dispatch[FIRST_DEV + 26].controller = 126;
729 dispatch[FIRST_DEV + 26].operator = 18;
730 dispatch[FIRST_DEV + 27].controller = 126;
731 dispatch[FIRST_DEV + 27].operator = 19;
732
733 dispatch[FIRST_DEV + 28].controller = 126;
734 dispatch[FIRST_DEV + 28].operator = 0;
735 dispatch[FIRST_DEV + 29].controller = 126;
736 dispatch[FIRST_DEV + 29].operator = 1;
737
738 dispatch[FIRST_DEV + 30].controller = 126;
739 dispatch[FIRST_DEV + 30].operator = 20;
740 dispatch[FIRST_DEV + 31].controller = 126;
741 dispatch[FIRST_DEV + 31].operator = 21;
742 dispatch[FIRST_DEV + 32].controller = 126;
743 dispatch[FIRST_DEV + 32].operator = 22;
744
745 dispatch[FIRST_DEV + 33].controller = 4;
746 dispatch[FIRST_DEV + 33].operator = 0;
747 dispatch[FIRST_DEV + 34].controller = 4;
748 dispatch[FIRST_DEV + 34].operator = 1;
749 dispatch[FIRST_DEV + 35].controller = 126;
750 dispatch[FIRST_DEV + 35].operator = 23;
751 dispatch[FIRST_DEV + 36].controller = 4;
752 dispatch[FIRST_DEV + 36].operator = 3;
753 dispatch[FIRST_DEV + 36].routine = (synthRoutine) keyTracking;
754 dispatch[FIRST_DEV + 37].controller = 3;
755 dispatch[FIRST_DEV + 37].operator = 0;
756 dispatch[FIRST_DEV + 38].controller = 3;
757 dispatch[FIRST_DEV + 38].operator = 1;
758 dispatch[FIRST_DEV + 39].controller = 3;
759 dispatch[FIRST_DEV + 39].operator = 2;
760 dispatch[FIRST_DEV + 40].controller = 3;
761 dispatch[FIRST_DEV + 40].operator = 3;
762
763 dispatch[FIRST_DEV + 41].controller = 5;
764 dispatch[FIRST_DEV + 41].operator = 0;
765 dispatch[FIRST_DEV + 42].controller = 5;
766 dispatch[FIRST_DEV + 42].operator = 1;
767 dispatch[FIRST_DEV + 43].controller = 5;
768 dispatch[FIRST_DEV + 43].operator = 2;
769 dispatch[FIRST_DEV + 44].controller = 5;
770 dispatch[FIRST_DEV + 44].operator = 3;
771
772 dispatch[FIRST_DEV + 45].controller = 126;
773 dispatch[FIRST_DEV + 45].operator = 2;
774 dispatch[FIRST_DEV + 46].controller = 5;
775 dispatch[FIRST_DEV + 46].operator = 4;
776
777 dispatch[FIRST_DEV + 47].controller = 1;
778 dispatch[FIRST_DEV + 47].operator = 1;
779 dispatch[FIRST_DEV + 47].routine = (synthRoutine) midiRelease;
780 dispatch[FIRST_DEV + 48].controller = 126;
781 dispatch[FIRST_DEV + 48].operator = 3;
782 dispatch[FIRST_DEV + 49].controller = 1;
783 dispatch[FIRST_DEV + 49].operator = 1;
784 dispatch[FIRST_DEV + 49].routine = (synthRoutine) multiTune;
785
786 dispatch[FIRST_DEV + 50].operator = 1;
787 dispatch[FIRST_DEV + 51].operator = 2;
788 dispatch[FIRST_DEV + 52].operator = 3;
789 dispatch[FIRST_DEV + 53].operator = 4;
790 dispatch[FIRST_DEV + 54].operator = 5;
791 dispatch[FIRST_DEV + 55].operator = 6;
792 dispatch[FIRST_DEV + 56].operator = 7;
793 dispatch[FIRST_DEV + 57].operator = 8;
794
795 dispatch[FIRST_DEV + 58].controller = 1;
796 dispatch[FIRST_DEV + 59].controller = 2;
797 dispatch[FIRST_DEV + 60].controller = 3;
798
799 dispatch[FIRST_DEV + 50].routine =
800 dispatch[FIRST_DEV + 51].routine =
801 dispatch[FIRST_DEV + 52].routine =
802 dispatch[FIRST_DEV + 53].routine =
803 dispatch[FIRST_DEV + 54].routine =
804 dispatch[FIRST_DEV + 55].routine =
805 dispatch[FIRST_DEV + 56].routine =
806 dispatch[FIRST_DEV + 57].routine =
807 dispatch[FIRST_DEV + 58].routine =
808 dispatch[FIRST_DEV + 59].routine =
809 dispatch[FIRST_DEV + 60].routine
810 = (synthRoutine) prophetMemory;
811
812 dispatch[FIRST_DEV + 61].routine = dispatch[FIRST_DEV + 62].routine =
813 (synthRoutine) prophetMidi;
814 dispatch[FIRST_DEV + 61].controller = 1;
815 dispatch[FIRST_DEV + 62].controller = 2;
816
817 dispatch[RADIOSET_1].other1 = -1;
818
819 /* Tune osc-1 */
820 bristolMidiSendMsg(global.controlfd, synth->sid, 0, 2, 8192);
821 /* Gain on filter contour */
822 bristolMidiSendMsg(global.controlfd, synth->sid, 3, 4,
823 CONTROLLER_RANGE - 1);
824 bristolMidiSendMsg(global.controlfd, synth->sid, 4, 4, 4);
825 bristolMidiSendMsg(global.controlfd, synth->sid, 126, 36, C_RANGE_MIN_1);
826
827 return(0);
828 }
829
830 /*
831 * This will be called to make any routine specific parameters available.
832 */
833 static int
prophetConfigure(brightonWindow * win)834 prophetConfigure(brightonWindow* win)
835 {
836 guiSynth *synth = findSynth(global.synths, win);
837 brightonEvent event;
838
839 if (synth == 0)
840 {
841 printf("problems going operational\n");
842 return(-1);
843 }
844
845 if (synth->flags & OPERATIONAL)
846 return(0);
847
848 printf("going operational\n");
849
850 synth->flags |= OPERATIONAL;
851 synth->keypanel = 1;
852 synth->keypanel2 = -1;
853 synth->transpose = 36;
854
855 if (synth->location == 0)
856 {
857 synth->bank = 10;
858 synth->location = 1;
859 }
860 loadMemory(synth, "prophet", 0, initmem, synth->mem.active, FIRST_DEV, 0);
861
862 brightonPut(win,
863 "bitmaps/blueprints/prophetshade.xpm", 0, 0, win->width, win->height);
864
865 /*
866 * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only
867 * occurs on first paint, so we suppress the first paint, and then request
868 * an expose here.
869 */
870 event.type = BRIGHTON_EXPOSE;
871 event.intvalue = 1;
872 brightonParamChange(synth->win, KEY_PANEL, -1, &event);
873 configureGlobals(synth);
874 return(0);
875 }
876
877