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 /* Korg Poly6 UI */
23 /* Bend depth and modes need to be implemented. */
24
25 #include <fcntl.h>
26
27 #include "brighton.h"
28 #include "brightonMini.h"
29 #include "brightoninternals.h"
30
31 static int initmem, width;
32
33 static int poly6Init();
34 static int poly6Configure();
35 static int poly6Callback(brightonWindow *, int, int, float);
36 static int poly6ModCallback(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 DEVICE_COUNT (53)
44 #define ACTIVE_DEVS (DEVICE_COUNT - 20)
45
46 #define MEM_START ACTIVE_DEVS
47 #define MIDI_START (MEM_START + 18)
48
49 #define P6_BEND 2
50 #define KEY_HOLD 17
51 #define CHORUS (32)
52
53 #define RADIOSET_1 MEM_START
54 #define RADIOSET_2 (MEM_START + 1)
55 #define RADIOSET_3 17 /* MODE */
56
57 #define KEY_PANEL 1
58
59 /*
60 * This structure is for device definition. The structure is defined in
61 * include/brighton.h, further definitions in brighton/brightonDevtable.h and
62 * include/brightoninternals.h
63 *
64 * typedef int (*brightonCallback)(int, float);
65 * typedef struct BrightonLocations {
66 * int device; 0=rotary, 1=scale, etc.
67 * float relx, rely; relative position with regards to 1000 by 1000 window
68 * float relw, relh; relative height.
69 * int from, to;
70 * brightonCallback callback; specific to this dev
71 * char *image; bitmap. If zero take a device default.
72 * int flags;
73 * } brightonLocations;
74 *
75 * This example is for a poly6Bristol type synth interface.
76 */
77 #define R0 200
78 #define R1 465
79
80 #define D0 8
81 #define D1 41
82 #define D2 23
83
84 #define C0 25
85 #define C1 (C0 + D1 + D0)
86 #define C2 (C1 + D1 + D0)
87 #define C3 (C2 + D1)
88 #define C4 (C3 + D1)
89 #define C5 (C4 + D1)
90 #define C6 (C5 + D1)
91 #define C7 (C6 + D1)
92 #define C8 (C7 + D1)
93 #define C9 (C8 + D1)
94 #define C10 (C9 + D1)
95 #define C11 (C10 + D1 + D0)
96 #define C12 (C11 + D1)
97 #define C13 (C12 + D1)
98 #define C14 (C13 + D1)
99
100 #define C15 (C14 + D1 + D0)
101 #define C16 (C15 + D1)
102
103 #define C17 (C16 + D1)
104 #define C18 (C17 + D2)
105 #define C19 (C18 + D2)
106 #define C20 (C19 + D2)
107 #define C21 (C20 + D2)
108 #define C22 (C21 + D2)
109 #define C23 (C22 + D2)
110 #define C24 (C23 + D2)
111 #define C25 (C24 + D2)
112
113 #define C26 (C25 + D2 + 9)
114
115 #define S1 140
116 #define S2 12
117 #define S3 180
118 #define S4 10
119
120 static brightonLocations locations[DEVICE_COUNT] = {
121 {"MasterVolume", 0, C0, R0, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
122 {"MasterTuning", 0, C1, R0, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, BRIGHTON_NOTCH},
123 {"BendDepth", 0, C1, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
124
125 /* VCO 1 */
126 {"OSC-Transpose", 0, C2, R0, S1, S1, 0, 3, 0, "bitmaps/knobs/knob6.xpm", 0,
127 BRIGHTON_STEPPED},
128 {"OSC-WaveForm", 0, C3, R0, S1, S1, 0, 3, 0, "bitmaps/knobs/knob6.xpm", 0,
129 BRIGHTON_STEPPED},
130 {"OSC-PWM", 0, C4, R0, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
131 {"Osc-Tuning", 0, C5, R0, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
132 {"Osc-Subwave", 2, C6 - 5, R0 + 10, S4, S3, 0, 2, 0, 0, 0,
133 BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW},
134
135 /* Noise - Mods 8 */
136 {"Noise", 0, C2, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
137 {"LFO-Freq", 0, C3, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
138 {"LFO-Delay", 0, C4, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
139 {"LFO-Level", 0, C5, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
140 {"LFO-Dest", 2, C6 - 5, R1 + 20, S4, S3, 0, 2, 0, 0, 0,
141 BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW},
142
143 /* Filter 13 */
144 {"VCF-Freq", 0, C7, R0, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
145 {"VCF-Res", 0, C8, R0, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
146 {"VCF-Env", 0, C9, R0, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
147 {"VCF-KBD", 0, C10, R0, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
148
149 /* Mode 17 */
150 {"MODE Hold", 2, C8 + 8, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffw.xpm",
151 "bitmaps/buttons/pressonw.xpm", BRIGHTON_RADIOBUTTON},
152 {"MODE Mono", 2, C9 + 8, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffw.xpm",
153 "bitmaps/buttons/pressonw.xpm", BRIGHTON_RADIOBUTTON},
154 {"MODE Mono", 2, C10 + 8, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffw.xpm",
155 "bitmaps/buttons/pressonw.xpm", BRIGHTON_RADIOBUTTON},
156
157 /* ENV 20 */
158 {"FiltEnv-Attack", 0, C11, R0, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
159 {"FiltEnv-Decay", 0, C12, R0, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
160 {"FiltEnv-Sustain", 0, C13, R0, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
161 {"FiltEnv-Relase", 0, C14, R0, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
162
163 /* ENV 24 */
164 {"Env-Attack", 0, C11, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
165 {"Env-Decay", 0, C12, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
166 {"Env-Sustain", 0, C13, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
167 {"Env-Release", 0, C14, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
168
169 /* Amp - Effects 28 */
170 {"Amp-Env/Gate", 2, C15, R0 + 20, S4, S1 - 20, 0, 1, 0,
171 "bitmaps/buttons/sw1.xpm", "bitmaps/buttons/sw2.xpm", BRIGHTON_NOSHADOW},
172 {"Amp-Gain", 0, C16, R0, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
173 {"Chorus-Mode", 0, C15, R1, S1, S1, 0, 3, 0, "bitmaps/knobs/knob6.xpm", 0,
174 BRIGHTON_STEPPED},
175 {"Chorus-Depth", 0, C16, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
176 /* Glide */
177 {"Glide", 0, C0, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
178
179 /* Memory - MIDI 33 */
180 {"", 2, C17, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffo.xpm",
181 "bitmaps/buttons/pressono.xpm", BRIGHTON_CHECKBUTTON},
182
183 {"", 2, C18, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
184 "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
185 {"", 2, C19, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
186 "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
187 {"", 2, C20, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
188 "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
189 {"", 2, C21, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
190 "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
191 {"", 2, C22, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
192 "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
193 {"", 2, C23, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
194 "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
195 {"", 2, C24, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
196 "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
197 {"", 2, C25, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
198 "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
199
200 {"", 2, C18, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
201 "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
202 {"", 2, C19, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
203 "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
204 {"", 2, C20, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
205 "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
206 {"", 2, C21, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
207 "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
208 {"", 2, C22, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
209 "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
210 {"", 2, C23, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
211 "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
212 {"", 2, C24, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
213 "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
214 {"", 2, C25, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
215 "bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
216 /* Load */
217 {"", 2, C17, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffw.xpm",
218 "bitmaps/buttons/pressonw.xpm", BRIGHTON_CHECKBUTTON},
219
220 {"", 2, C26, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffw.xpm",
221 "bitmaps/buttons/pressonw.xpm", BRIGHTON_CHECKBUTTON},
222 {"", 2, C26, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffw.xpm",
223 "bitmaps/buttons/pressonw.xpm", BRIGHTON_CHECKBUTTON},
224 };
225
226 /*
227 */
228
229 /*
230 * This is a set of globals for the main window rendering. Again taken from
231 * include/brighton.h
232 */
233 brightonApp poly6App = {
234 "poly",
235 0, /* no blueprint on wood background. */
236 "bitmaps/textures/metal6.xpm",
237 BRIGHTON_STRETCH,
238 poly6Init,
239 poly6Configure, /* 3 callbacks, unused? */
240 midiCallback,
241 destroySynth,
242 {6, 100, 2, 2, 5, 520, 0, 0},
243 800, 240, 0, 0,
244 5, /* one panel only */
245 {
246 {
247 "Poly6",
248 "bitmaps/blueprints/poly6.xpm",
249 "bitmaps/textures/metal4.xpm",
250 BRIGHTON_STRETCH, /* flags */
251 0,
252 0,
253 poly6Callback,
254 12, 0, 976, 560,
255 DEVICE_COUNT,
256 locations
257 },
258 {
259 "Keyboard",
260 0,
261 "bitmaps/newkeys/kbg.xpm", /* flags */
262 0x020|BRIGHTON_STRETCH,
263 0,
264 0,
265 keyCallback,
266 105, 550, 908, 435,
267 KEY_COUNT,
268 keys
269 },
270 {
271 "Mods",
272 "bitmaps/blueprints/polymods.xpm",
273 "bitmaps/textures/metal6.xpm", /* flags */
274 BRIGHTON_STRETCH,
275 0,
276 0,
277 poly6ModCallback,
278 15, 550, 90, 435,
279 2,
280 mods
281 },
282 {
283 "Edge",
284 0,
285 "bitmaps/textures/metal4.xpm",
286 BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */
287 0,
288 0,
289 0,
290 0, 0, 15, 995,
291 0,
292 0
293 },
294 {
295 "Edge",
296 0,
297 "bitmaps/textures/metal4.xpm",
298 BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */
299 0,
300 0,
301 0,
302 988, 0, 12, 995,
303 0,
304 0
305 },
306 }
307 };
308
309 static int
midiCallback(brightonWindow * win,int controller,int value,float n)310 midiCallback(brightonWindow *win, int controller, int value, float n)
311 {
312 guiSynth *synth = findSynth(global.synths, win);
313
314 printf("midi callback: %x, %i\n", controller, value);
315
316 switch(controller)
317 {
318 case MIDI_PROGRAM:
319 printf("midi program: %x, %i\n", controller, value);
320 synth->location = value;
321 loadMemory(synth, "poly", 0,
322 synth->bank + synth->location,
323 synth->mem.active, 0, 0);
324 break;
325 case MIDI_BANK_SELECT:
326 printf("midi banksel: %x, %i\n", controller, value);
327 synth->bank = value;
328 break;
329 }
330 return(0);
331 }
332
333 /*static dispatcher dispatch[DEVICE_COUNT]; */
334
335 static int
poly6ModCallback(brightonWindow * win,int panel,int index,float value)336 poly6ModCallback(brightonWindow *win, int panel, int index, float value)
337 {
338 guiSynth *synth = findSynth(global.synths, win);
339 float bend = synth->mem.param[P6_BEND];
340
341 /*printf("poly6ModCallback(%x, %i, %i, %f)\n", synth, panel, index, value); */
342
343 /*
344 * If this is controller 0 it is the frequency control, otherwise a
345 * generic controller 1. The depth of the bend wheel is a parameter, so
346 * we need to scale the value here.
347 */
348 if (index == 0)
349 {
350 /*
351 * Value is between 0 and 1 latching at 0.5. Have to scale the value
352 * and subtrace if from the mid point
353 */
354 bristolMidiSendMsg(global.controlfd, synth->midichannel,
355 BRISTOL_EVENT_PITCH, 0,
356 (int) (((0.5 - bend / 2) + (value * bend)) * C_RANGE_MIN_1));
357 } else {
358 bristolMidiControl(global.controlfd, synth->midichannel,
359 0, 1, ((int) (value * C_RANGE_MIN_1)) >> 7);
360 }
361 return(0);
362 }
363
364 static int
poly6MidiSendMsg(void * synth,int fd,int chan,int c,int o,int v)365 poly6MidiSendMsg(void *synth, int fd, int chan, int c, int o, int v)
366 {
367 /*printf("%i, %i, %i\n", c, o, v); */
368 bristolMidiSendMsg(fd, chan, c, o, v);
369 return(0);
370 }
371
372 static void
poly6Hold(guiSynth * synth)373 poly6Hold(guiSynth *synth)
374 {
375 if (((synth->flags & OPERATIONAL) == 0) || (global.libtest))
376 return;
377
378 if (synth->mem.param[KEY_HOLD])
379 bristolMidiSendMsg(global.controlfd, synth->sid,
380 127, 0, BRISTOL_HOLD|1);
381 else
382 bristolMidiSendMsg(global.controlfd, synth->sid,
383 127, 0, BRISTOL_HOLD|0);
384 }
385
386 static void
fixModes(guiSynth * synth,int fd,int chan,int c,int o,int v)387 fixModes(guiSynth *synth, int fd, int chan, int c, int o, int v)
388 {
389 /*
390 * Look into the memory at 18 and 19 to find the current mode and send it
391 * to the engine.
392 */
393 if (synth->mem.param[18] != 0)
394 bristolMidiSendMsg(fd, chan, 126, 7, 1);
395 else
396 bristolMidiSendMsg(fd, chan, 126, 8, 1);
397
398 poly6Hold(synth);
399 }
400
401 int
poly6loadMemory(guiSynth * synth,char * algo,char * name,int location,int active,int skip,int flags)402 poly6loadMemory(guiSynth *synth, char *algo, char *name, int location,
403 int active, int skip, int flags)
404 {
405 brightonEvent event;
406
407 loadMemory(synth, "poly", 0, location, synth->mem.active, 0, 0);
408 fixModes(synth, synth->sid, synth->midichannel, 0, 0, 0);
409
410 event.type = BRISTOL_FLOAT;
411 event.value = 1;
412 brightonParamChange(synth->win, 0, MEM_START + location / 10, &event);
413 brightonParamChange(synth->win, 0, MEM_START+8+(location % 10), &event);
414
415 return(0);
416 }
417
418 static void
poly6Memory(guiSynth * synth,int fd,int chan,int c,int o,int v)419 poly6Memory(guiSynth *synth, int fd, int chan, int c, int o, int v)
420 {
421 brightonEvent event;
422
423 if (synth->flags & MEM_LOADING)
424 return;
425
426 switch(c) {
427 case 0:
428 saveMemory(synth, "poly", 0,
429 synth->bank + synth->location, 0);
430 return;
431 break;
432 case 17:
433 loadMemory(synth, "poly", 0,
434 synth->bank + synth->location,
435 synth->mem.active, 0, 0);
436 fixModes(synth, fd, chan, c, o, v);
437 return;
438 break;
439 case 1:
440 case 2:
441 case 3:
442 case 4:
443 case 5:
444 case 6:
445 case 7:
446 case 8:
447 if (synth->dispatch[RADIOSET_1].other2)
448 {
449 synth->dispatch[RADIOSET_1].other2 = 0;
450 return;
451 }
452 if (synth->dispatch[RADIOSET_1].other1 != -1)
453 {
454 synth->dispatch[RADIOSET_1].other2 = 1;
455
456 if (synth->dispatch[RADIOSET_1].other1 != c)
457 event.value = 0;
458 else
459 event.value = 1;
460
461 brightonParamChange(synth->win, synth->panel,
462 synth->dispatch[RADIOSET_1].other1 + MEM_START, &event);
463 }
464 synth->dispatch[RADIOSET_1].other1 = c;
465 synth->bank = c * 10;
466 break;
467 case 9:
468 case 10:
469 case 11:
470 case 12:
471 case 13:
472 case 14:
473 case 15:
474 case 16:
475 if (synth->dispatch[RADIOSET_2].other2)
476 {
477 synth->dispatch[RADIOSET_2].other2 = 0;
478 return;
479 }
480 if (synth->dispatch[RADIOSET_2].other1 != -1)
481 {
482 synth->dispatch[RADIOSET_2].other2 = 1;
483
484 if (synth->dispatch[RADIOSET_2].other1 != c)
485 event.value = 0;
486 else
487 event.value = 1;
488
489 brightonParamChange(synth->win, synth->panel,
490 synth->dispatch[RADIOSET_2].other1 + MEM_START, &event);
491 }
492 synth->dispatch[RADIOSET_2].other1 = c;
493 /* Do radio buttons */
494 synth->location = c - 8;
495 break;
496 }
497 }
498
499 static void
poly6PWM(guiSynth * synth,int fd,int chan,int c,int o,int v)500 poly6PWM(guiSynth *synth, int fd, int chan, int c, int o, int v)
501 {
502 /*
503 * This has two functions, it sets the PW of the osc and also the gain
504 * of PWM.
505 */
506 bristolMidiSendMsg(fd, chan, 0, 0, v);
507 bristolMidiSendMsg(fd, chan, 126, 4, v);
508 }
509
510 static void
poly6Waveform(guiSynth * synth,int fd,int chan,int c,int o,int v)511 poly6Waveform(guiSynth *synth, int fd, int chan, int c, int o, int v)
512 {
513 if (c == 1)
514 {
515 /*
516 * Subosc 2 == off
517 */
518 if (v == 2)
519 bristolMidiSendMsg(fd, chan, 1, 6, 0);
520 if (v == 1)
521 {
522 bristolMidiSendMsg(fd, chan, 1, 1, 1);
523 bristolMidiSendMsg(fd, chan, 1, 6, 1);
524 }
525 if (v == 0)
526 {
527 bristolMidiSendMsg(fd, chan, 1, 1, 0);
528 bristolMidiSendMsg(fd, chan, 1, 6, 1);
529 }
530 return;
531 }
532
533 switch(v) {
534 case 0:
535 /*
536 * Ramp off, square off, tri on
537 */
538 bristolMidiSendMsg(fd, chan, 0, 4, 0);
539 bristolMidiSendMsg(fd, chan, 0, 6, 0);
540 bristolMidiSendMsg(fd, chan, 0, 5, 1);
541
542 bristolMidiSendMsg(fd, chan, 126, 5, 0);
543 break;
544 case 1:
545 bristolMidiSendMsg(fd, chan, 0, 5, 0);
546 bristolMidiSendMsg(fd, chan, 0, 6, 0);
547 bristolMidiSendMsg(fd, chan, 0, 4, 1);
548
549 bristolMidiSendMsg(fd, chan, 126, 5, 0);
550 break;
551 case 2:
552 bristolMidiSendMsg(fd, chan, 0, 4, 0);
553 bristolMidiSendMsg(fd, chan, 0, 5, 0);
554 bristolMidiSendMsg(fd, chan, 0, 6, 1);
555
556 bristolMidiSendMsg(fd, chan, 126, 5, 0);
557 break;
558 case 3:
559 bristolMidiSendMsg(fd, chan, 0, 4, 0);
560 bristolMidiSendMsg(fd, chan, 0, 5, 0);
561 bristolMidiSendMsg(fd, chan, 0, 6, 1);
562
563 bristolMidiSendMsg(fd, chan, 126, 5, 1);
564 break;
565 }
566 }
567
568 static int
poly6Midi(guiSynth * synth,int fd,int chan,int c,int o,int v)569 poly6Midi(guiSynth *synth, int fd, int chan, int c, int o, int v)
570 {
571 int newchan;
572
573 if ((synth->flags & OPERATIONAL) == 0)
574 return(0);
575
576 if (c == 1) {
577 if ((newchan = synth->midichannel - 1) < 0)
578 {
579 synth->midichannel = 0;
580 return(0);
581 }
582 } else {
583 if ((newchan = synth->midichannel + 1) >= 15)
584 {
585 synth->midichannel = 15;
586 return(0);
587 }
588 }
589
590 if (global.libtest == 0)
591 {
592 bristolMidiSendMsg(global.controlfd, synth->sid,
593 127, 0, BRISTOL_MIDICHANNEL|newchan);
594 }
595
596 synth->midichannel = newchan;
597
598 return(0);
599 }
600
601 /*
602 * For the sake of ease of use, links have been placed here to be called
603 * by any of the devices created. They would be better in some other file,
604 * perhaps with this as a dispatch.
605 *
606 * Param refers to the device index in the locations table given below.
607 */
608 static int
poly6Callback(brightonWindow * win,int panel,int index,float value)609 poly6Callback(brightonWindow * win, int panel, int index, float value)
610 {
611 guiSynth *synth = findSynth(global.synths, win);
612 int sendvalue;
613
614 /* printf("poly6Callback(%i, %f): %x\n", index, value, synth); */
615
616 if (synth == 0)
617 return(0);
618
619 if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0))
620 return(0);
621
622 if (poly6App.resources[0].devlocn[index].to == 1)
623 sendvalue = value * C_RANGE_MIN_1;
624 else
625 sendvalue = value;
626
627 synth->mem.param[index] = value;
628
629 if ((!global.libtest) || (index >= ACTIVE_DEVS))
630 synth->dispatch[index].routine(synth,
631 global.controlfd, synth->sid,
632 synth->dispatch[index].controller,
633 synth->dispatch[index].operator,
634 sendvalue);
635 #define DEBUG
636 #ifdef DEBUG
637 else
638 printf("dispatch[%p,%i](%i, %i, %i, %i, %i)\n", synth, index,
639 global.controlfd, synth->sid,
640 synth->dispatch[index].controller,
641 synth->dispatch[index].operator,
642 sendvalue);
643 #endif
644
645 return(0);
646 }
647
648 static void
poly6Gain(guiSynth * synth,int fd,int chan,int c,int o,int v)649 poly6Gain(guiSynth *synth, int fd, int chan, int c, int o, int v)
650 {
651 switch (c)
652 {
653 case 6:
654 case 101:
655 /*
656 * Gain controls
657 */
658 bristolMidiSendMsg(global.controlfd, synth->sid, 6, 4,
659 ((int) (synth->mem.param[0] * synth->mem.param[29]
660 * C_RANGE_MIN_1)));
661 break;
662 case 100:
663 /*
664 * This is the attentuator switch, 1 == gate.
665 */
666 if (synth->mem.param[28])
667 {
668 /*
669 * Configure a gate.
670 */
671 bristolMidiSendMsg(global.controlfd, synth->sid, 6, 0, 512);
672 bristolMidiSendMsg(global.controlfd, synth->sid, 6, 1, 16383);
673 bristolMidiSendMsg(global.controlfd, synth->sid, 6, 2, 16383);
674 bristolMidiSendMsg(global.controlfd, synth->sid, 6, 3, 512);
675 } else {
676 /*
677 * Configure the env
678 */
679 bristolMidiSendMsg(global.controlfd, synth->sid, 6, 0,
680 (int) (synth->mem.param[24] * C_RANGE_MIN_1));
681 bristolMidiSendMsg(global.controlfd, synth->sid, 6, 1,
682 (int) (synth->mem.param[25] * C_RANGE_MIN_1));
683 bristolMidiSendMsg(global.controlfd, synth->sid, 6, 2,
684 (int) (synth->mem.param[26] * C_RANGE_MIN_1));
685 bristolMidiSendMsg(global.controlfd, synth->sid, 6, 3,
686 (int) (synth->mem.param[27] * C_RANGE_MIN_1));
687 }
688 break;
689 case 99:
690 if (synth->mem.param[28] == 0)
691 bristolMidiSendMsg(global.controlfd, synth->sid, 6, o, v);
692 bristolMidiSendMsg(global.controlfd, synth->sid, 8, 3, v);
693 break;
694 }
695 }
696
697 static int
poly6Mode(guiSynth * synth,int fd,int chan,int c,int o,int v)698 poly6Mode(guiSynth *synth, int fd, int chan, int c, int o, int v)
699 {
700 brightonEvent event;
701
702 if (synth->flags & MEM_LOADING)
703 return(0);
704
705 if (synth->dispatch[RADIOSET_3].other2)
706 return(synth->dispatch[RADIOSET_3].other2 = 0);
707
708 if (synth->dispatch[RADIOSET_3].other1 != -1)
709 {
710 synth->dispatch[RADIOSET_3].other2 = 1;
711
712 if (synth->dispatch[RADIOSET_3].other1 != c)
713 event.value = 0;
714 else
715 event.value = 1;
716
717 brightonParamChange(synth->win, synth->panel,
718 synth->dispatch[RADIOSET_3].other1, &event);
719 }
720 synth->dispatch[RADIOSET_3].other1 = c;
721
722 /* bristolMidiSendMsg(global.controlfd, synth->sid, 126, o, v); */
723
724 poly6Hold(synth);
725
726 switch (c) {
727 case 18:
728 bristolMidiSendMsg(global.controlfd, synth->sid, 126, 7, 1);
729 break;
730 case 19:
731 bristolMidiSendMsg(global.controlfd, synth->sid, 126, 8, 1);
732 break;
733 }
734 return(0);
735 }
736
737 /*
738 * Any location initialisation required to run the callbacks. For bristol, this
739 * will connect to the engine, and give it some base parameters.
740 * May need to generate some application specific menus.
741 * Will also then make specific requests to some of the devices to alter their
742 * rendering.
743 */
744 static int
poly6Init(brightonWindow * win)745 poly6Init(brightonWindow *win)
746 {
747 guiSynth *synth = findSynth(global.synths, win);
748 dispatcher *dispatch;
749 int i;
750
751 if (synth == 0)
752 {
753 synth = findSynth(global.synths, 0);
754 if (synth == 0)
755 {
756 printf("cannot init\n");
757 return(0);
758 }
759 }
760
761 if ((initmem = synth->location) == 0)
762 initmem = 11;
763
764 synth->win = win;
765
766 printf("Initialise the poly6 link to bristol: %p\n", synth->win);
767
768 synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float));
769 synth->mem.count = DEVICE_COUNT;
770 synth->mem.active = ACTIVE_DEVS;
771 synth->dispatch = (dispatcher *)
772 brightonmalloc(DEVICE_COUNT * sizeof(dispatcher));
773 dispatch = synth->dispatch;
774
775 /*
776 * We really want to have three connection mechanisms. These should be
777 * 1. Unix named sockets.
778 * 2. UDP sockets.
779 * 3. MIDI pipe.
780 */
781
782 if (synth->voices == BRISTOL_VOICECOUNT)
783 synth->voices = 6;
784 if (!global.libtest)
785 if ((synth->sid = initConnection(&global, synth)) < 0)
786 return(-1);
787
788 for (i = 0; i < DEVICE_COUNT; i++)
789 synth->dispatch[i].routine = poly6MidiSendMsg;
790
791 /* Vol tune bend - NOT FINNISHED */
792 dispatch[0].controller = 6;
793 dispatch[0].operator = 4;
794 dispatch[0].routine = (synthRoutine) poly6Gain;
795 dispatch[1].controller = 126;
796 dispatch[1].operator = 1;
797 dispatch[2].controller = 126;
798 dispatch[2].operator = 2;
799
800 /* VCO */
801 dispatch[3].controller = 0;
802 dispatch[3].operator = 1;
803 dispatch[4].controller = 0;
804 dispatch[4].operator = 50;
805 dispatch[4].routine = (synthRoutine) poly6Waveform;
806 dispatch[5].controller = 0;
807 dispatch[5].operator = 0;
808 dispatch[5].routine = (synthRoutine) poly6PWM;
809 dispatch[6].controller = 10;
810 dispatch[6].operator = 0;
811 /* Subosc */
812 dispatch[7].controller = 1;
813 dispatch[7].operator = 0;
814 dispatch[7].routine = (synthRoutine) poly6Waveform;
815 /* Noise */
816 dispatch[8].controller = 7;
817 dispatch[8].operator = 0;
818
819 /* Mods */
820 dispatch[9].controller = 2;
821 dispatch[9].operator = 0;
822 dispatch[10].controller = 8;
823 dispatch[10].operator = 0;
824 dispatch[11].controller = 8;
825 dispatch[11].operator = 4;
826 dispatch[12].controller = 126;
827 dispatch[12].operator = 6;
828
829 /* Filter */
830 dispatch[13].controller = 3;
831 dispatch[13].operator = 0;
832 dispatch[14].controller = 3;
833 dispatch[14].operator = 1;
834 dispatch[15].controller = 3;
835 dispatch[15].operator = 2;
836 dispatch[16].controller = 3;
837 dispatch[16].operator = 3;
838
839 /* MODE NOT DONE */
840 /*
841 * Hold - no key off events
842 * Mono - unison
843 * Poly - poly
844 */
845 dispatch[17].controller = 17;
846 dispatch[17].operator = 1;
847 dispatch[18].controller = 18;
848 dispatch[18].operator = 7;
849 dispatch[19].controller = 19;
850 dispatch[19].operator = 8;
851 dispatch[17].routine = dispatch[18].routine = dispatch[19].routine
852 = (synthRoutine) poly6Mode;
853
854 /* Filter Env */
855 dispatch[20].controller = 4;
856 dispatch[20].operator = 0;
857 dispatch[21].controller = 4;
858 dispatch[21].operator = 1;
859 dispatch[22].controller = 4;
860 dispatch[22].operator = 2;
861 dispatch[23].controller = 4;
862 dispatch[23].operator = 3;
863 /* Env */
864 dispatch[24].controller = 99; /* Will be 6, but interpreted */
865 dispatch[24].operator = 0;
866 dispatch[25].controller = 99;
867 dispatch[25].operator = 1;
868 dispatch[26].controller = 99;
869 dispatch[26].operator = 2;
870 dispatch[27].controller = 99;
871 dispatch[27].operator = 3;
872
873 /* VCA NOT DONE */
874 dispatch[28].controller = 100;
875 dispatch[28].operator = 0;
876 dispatch[29].controller = 101;
877 dispatch[29].operator = 1;
878 dispatch[28].routine = dispatch[29].routine
879 = dispatch[24].routine = dispatch[25].routine
880 = dispatch[26].routine = dispatch[27].routine
881 = (synthRoutine) poly6Gain;
882 /* Effect */
883 dispatch[30].controller = 100;
884 dispatch[30].operator = 0;
885 dispatch[31].controller = 100;
886 dispatch[31].operator = 1;
887
888 dispatch[32].controller = 126;
889 dispatch[32].operator = 0;
890
891 dispatch[MEM_START + 0].controller = 0;
892 dispatch[MEM_START + 1].controller = 1;
893 dispatch[MEM_START + 2].controller = 2;
894 dispatch[MEM_START + 3].controller = 3;
895 dispatch[MEM_START + 4].controller = 4;
896 dispatch[MEM_START + 5].controller = 5;
897 dispatch[MEM_START + 6].controller = 6;
898 dispatch[MEM_START + 7].controller = 7;
899 dispatch[MEM_START + 8].controller = 8;
900 dispatch[MEM_START + 9].controller = 9;
901 dispatch[MEM_START + 10].controller = 10;
902 dispatch[MEM_START + 11].controller = 11;
903 dispatch[MEM_START + 12].controller = 12;
904 dispatch[MEM_START + 13].controller = 13;
905 dispatch[MEM_START + 14].controller = 14;
906 dispatch[MEM_START + 15].controller = 15;
907 dispatch[MEM_START + 16].controller = 16;
908 dispatch[MEM_START + 17].controller = 17;
909
910 dispatch[MEM_START + 0].routine =
911 dispatch[MEM_START + 1].routine =
912 dispatch[MEM_START + 2].routine =
913 dispatch[MEM_START + 3].routine =
914 dispatch[MEM_START + 4].routine =
915 dispatch[MEM_START + 5].routine =
916 dispatch[MEM_START + 6].routine =
917 dispatch[MEM_START + 7].routine =
918 dispatch[MEM_START + 8].routine =
919 dispatch[MEM_START + 9].routine =
920 dispatch[MEM_START + 10].routine =
921 dispatch[MEM_START + 11].routine =
922 dispatch[MEM_START + 12].routine =
923 dispatch[MEM_START + 13].routine =
924 dispatch[MEM_START + 14].routine =
925 dispatch[MEM_START + 15].routine =
926 dispatch[MEM_START + 16].routine =
927 dispatch[MEM_START + 17].routine
928 = (synthRoutine) poly6Memory;
929
930 dispatch[RADIOSET_1].other1 = -1;
931 dispatch[RADIOSET_2].other1 = -1;
932 dispatch[RADIOSET_3].other1 = -1;
933
934 dispatch[MIDI_START].controller = 1;
935 dispatch[MIDI_START + 1].controller = 2;
936 dispatch[MIDI_START].routine = dispatch[MIDI_START + 1].routine =
937 (synthRoutine) poly6Midi;
938
939 /* Put in diverse defaults settings */
940 /* Gain on filter env */
941 bristolMidiSendMsg(global.controlfd, synth->sid, 4, 4, C_RANGE_MIN_1);
942 bristolMidiSendMsg(global.controlfd, synth->sid, 3, 4, 4);
943 /* Waveform subosc */
944 bristolMidiSendMsg(global.controlfd, synth->sid, 1, 0, C_RANGE_MIN_1);
945 bristolMidiSendMsg(global.controlfd, synth->sid, 1, 6, C_RANGE_MIN_1);
946 /* LFO Env parameters. */
947 bristolMidiSendMsg(global.controlfd, synth->sid, 8, 1, 12000);
948 bristolMidiSendMsg(global.controlfd, synth->sid, 8, 2, 16383);
949 bristolMidiSendMsg(global.controlfd, synth->sid, 8, 3, 0);
950 bristolMidiSendMsg(global.controlfd, synth->sid, 8, 4, 16383);
951 bristolMidiSendMsg(global.controlfd, synth->sid, 8, 5, 0);
952
953 return(0);
954 }
955
956 /*
957 * This will be called to make any routine specific parameters available.
958 */
959 static int
poly6Configure(brightonWindow * win)960 poly6Configure(brightonWindow *win)
961 {
962 guiSynth *synth = findSynth(global.synths, win);
963 brightonEvent event;
964
965 if (synth == 0)
966 {
967 printf("problems going operational\n");
968 return(-1);
969 }
970
971 if (synth->flags & OPERATIONAL)
972 return(0);
973
974 printf("going operational\n");
975
976 synth->flags |= OPERATIONAL;
977 synth->keypanel = 1;
978 synth->keypanel2 = -1;
979 synth->transpose = 36;
980
981 brightonPut(win,
982 "bitmaps/blueprints/poly6shade.xpm", 0, 0, win->width, win->height);
983 width = win->width;
984
985 if (synth->location == 0)
986 {
987 synth->bank = 10;
988 synth->location = 1;
989 } else {
990 synth->bank = (synth->location % 100) / 10 * 10;
991 synth->location = synth->location % 10;
992 }
993
994 event.type = BRISTOL_FLOAT;
995 event.value = 1;
996 brightonParamChange(synth->win, synth->panel, MEM_START + synth->bank / 10,
997 &event);
998 brightonParamChange(synth->win, synth->panel, MEM_START+8+synth->location,
999 &event);
1000 /* Poly */
1001 brightonParamChange(synth->win, synth->panel, 19, &event);
1002
1003 loadMemory(synth, "poly", 0, initmem, synth->mem.active, 0, 0);
1004 fixModes(synth, synth->sid, synth->midichannel, 0, 0, 0);
1005
1006 /*
1007 * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only
1008 * occurs on first paint, so we suppress the first paint, and then request
1009 * an expose here.
1010 */
1011 event.type = BRIGHTON_EXPOSE;
1012 event.intvalue = 1;
1013 brightonParamChange(synth->win, KEY_PANEL, -1, &event);
1014 event.type = BRIGHTON_FLOAT;
1015 event.value = 0.1;
1016 brightonParamChange(synth->win, 2, 1, &event);
1017 configureGlobals(synth);
1018
1019 synth->loadMemory = (loadRoutine) poly6loadMemory;
1020
1021 return(0);
1022 }
1023
1024