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