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 MonoPoly */
23
24 #include <fcntl.h>
25
26 #include "brighton.h"
27 #include "brightonMini.h"
28 #include "brightoninternals.h"
29
30 static int initmem, width;
31
32 static int polyInit();
33 static int polyConfigure();
34 static int polyCallback(brightonWindow *, int, int, float);
35 /*static int keyCallback(void *, int, int, float); */
36 static int polyModCallback(brightonWindow *, int, int, float);
37 static int pmidiCallback(brightonWindow *, int, int, float);
38
39 extern guimain global;
40
41 #include "brightonKeys.h"
42
43 #define FIRST_DEV 0
44 #define DEVICE_COUNT 74
45 #define ACTIVE_DEVS 56
46 #define MEM_START ACTIVE_DEVS
47 #define RADIOSET_1 MEM_START
48 #define RADIOSET_2 (MEM_START + 1)
49 #define RADIOSET_3 53
50
51 #define KEY_PANEL 1
52 #define KEY_HOLD 52
53
54 #define CDIFF 56
55 #define CDIFF2 12
56
57 #define C0 25
58 #define C1 (C0 + CDIFF)
59 #define C2 (C1 + CDIFF + CDIFF2)
60 #define C3 (C2 + CDIFF + CDIFF2)
61 #define C4 (C3 + CDIFF)
62 #define C5 (C4 + CDIFF)
63 #define C6 (C5 + CDIFF)
64 #define C7 (C6 + CDIFF + CDIFF2)
65 #define C8 (C7 + CDIFF + CDIFF2)
66 #define C9 (C8 + CDIFF + CDIFF2)
67 #define C10 (C9 + CDIFF)
68 #define C11 (C10 + CDIFF)
69 #define C12 (C11 + CDIFF + CDIFF2)
70 #define C13 (C12 + CDIFF)
71 #define C14 (C13 + CDIFF)
72 #define C15 (C14 + CDIFF)
73
74 #define R0 115
75 #define R1 (R0 + 205)
76 #define R2 (R1 + 205)
77 #define R3 (R2 + 205)
78
79 #define R3u (R2 + 200)
80 #define R3d (R2 + 310)
81
82 #define S1 60
83 #define S2 100
84 #define S3 90
85 #define B1 15
86 #define B2 60
87
88 #define BOFF 11
89
90 /*
91 * This structure is for device definition. The structure is defined in
92 * include/brighton.h, further definitions in brighton/brightonDevtable.h and
93 * include/brightoninternals.h
94 *
95 * typedef int (*brightonCallback)(int, float);
96 * typedef struct BrightonLocations {
97 * int device; 0=rotary, 1=scale, etc.
98 * float relx, rely; relative position with regards to 1000 by 1000 window
99 * float relw, relh; relative height.
100 * int from, to;
101 * brightonCallback callback; specific to this dev
102 * char *image; bitmap. If zero take a device default.
103 * int flags;
104 * } brightonLocations;
105 *
106 * This example is for a polyBristol type synth interface.
107 */
108 static brightonLocations locations[DEVICE_COUNT] = {
109 /* Osc-1 - 0 */
110 {"Osc-1 Wave", 0, C9, R0, S3, S3, 0, 3, 0, "bitmaps/knobs/knob6.xpm", 0,
111 BRIGHTON_STEPPED},
112 {"Osc-1 Transpose", 0, C10, R0, S3, S3, 0, 3, 0, "bitmaps/knobs/knob6.xpm", 0,
113 BRIGHTON_STEPPED},
114 {"Osc-1 Gain", 0, C11, R0, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
115 /* Osc-2 - 3 */
116 {"Osc-2 Tune", 0, C8, R1, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, BRIGHTON_NOTCH},
117 {"Osc-2 Wave", 0, C9, R1, S3, S3, 0, 3, 0, "bitmaps/knobs/knob6.xpm", 0,
118 BRIGHTON_STEPPED},
119 {"Osc-2 Transpose", 0, C10, R1, S3, S3, 0, 3, 0, "bitmaps/knobs/knob6.xpm", 0,
120 BRIGHTON_STEPPED},
121 {"Osc-2 Gain", 0, C11, R1, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
122 /* Osc-3 - 7 */
123 {"Osc-3 Tune", 0, C8, R2, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, BRIGHTON_NOTCH},
124 {"Osc-3 Wave", 0, C9, R2, S3, S3, 0, 3, 0, "bitmaps/knobs/knob6.xpm", 0,
125 BRIGHTON_STEPPED},
126 {"Osc-3 Transpose", 0, C10, R2, S3, S3, 0, 3, 0, "bitmaps/knobs/knob6.xpm", 0,
127 BRIGHTON_STEPPED},
128 {"Osc-3 Gain", 0, C11, R2, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
129 /* Osc-4 - 11 */
130 {"Osc-3 Wave", 0, C8, R3, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, BRIGHTON_NOTCH},
131 {"Osc-4 Tune", 0, C9, R3, S3, S3, 0, 3, 0, "bitmaps/knobs/knob6.xpm", 0,
132 BRIGHTON_STEPPED},
133 {"Osc-4 Transpose", 0, C10, R3, S3, S3, 0, 3, 0, "bitmaps/knobs/knob6.xpm", 0,
134 BRIGHTON_STEPPED},
135 {"Osc-4 Gain", 0, C11, R3, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
136 /* Filter - 15 */
137 {"VCF-Cutoff", 0, C12, R0, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
138 {"VCF-Resonance", 0, C13, R0, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
139 {"VCF-Env", 0, C14, R0, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
140 {"VCF-KBD", 0, C15, R0, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
141 /* Filter Env - 19 */
142 {"VCF-Attack", 0, C12, R1, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
143 {"VCF-Decay", 0, C13, R1, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
144 {"VCF-Sustain", 0, C14, R1, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
145 {"VCF-Release", 0, C15, R1, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
146 /* Env - 23 */
147 {"VCA-Attack", 0, C12, R2, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
148 {"VCA-Decay", 0, C13, R2, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
149 {"VCA-Sustain", 0, C14, R2, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
150 {"VCA-Release", 0, C15, R2, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
151 /* Volume - 27 env gain and TO BE REASSIGNED */
152 {"Volume", 0, C0, R1, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
153 {"Arpeg Mode", 2, C1, R1, B1, S2, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW},
154 /* Three LFO MG modes - 29 */
155 {"MG-1 Gain", 0, C2, R1, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
156 {"MG-1 Wave", 0, C2, R2, S3, S3, 0, 3, 0, "bitmaps/knobs/knob6.xpm", 0,
157 BRIGHTON_STEPPED},
158 {"MG-2 Gain", 0, C3, R1, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
159 /* 3 PW and PWM - 32 */
160 {"PW-Source", 2, C4, R1, B1, S2, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW},
161 {"PWM", 0, C5, R1, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
162 {"PW", 0, C6, R1, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
163 /* 4, actually 5 mods. - 35 */
164 {"Mod-X-Mod", 0, C3, R2, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
165 {"Mod-Freq", 0, C4, R2, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
166 {"Mod-Source", 2, C5 - 20, R2 + 20, B1, S1, 0, 1, 0,
167 "bitmaps/buttons/sw1.xpm", "bitmaps/buttons/sw2.xpm", BRIGHTON_NOSHADOW},
168 {"Mod-Mode", 2, C5 + BOFF * 2, R2, B1, S2, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW},
169 {"Mod-Sng/Dbl", 2, C5 + BOFF * 5 + 10, R2 + 20, B1, S1, 0, 1, 0,
170 "bitmaps/buttons/sw1.xpm", "bitmaps/buttons/sw2.xpm", BRIGHTON_NOSHADOW},
171 /* Glide, detune - 40 */
172 {"Glide", 0, C7, R0, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
173 {"Detune", 0, C7, R1, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
174 /* Transpose - 42 */
175 {"Transpose", 2, C7 - BOFF, R2, B1, S2, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW},
176 /* Noise - 43 */
177 {"Noise", 0, C12, R3, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
178 /* Trig, Damp - 44 */
179 {"Trigger", 2, C13, R3 + 20, B1, S1, 0, 1, 0,
180 "bitmaps/buttons/sw1.xpm", "bitmaps/buttons/sw2.xpm", BRIGHTON_NOSHADOW},
181 {"Damp", 2, C14, R3 + 20, B1, S1, 0, 1, 0,
182 "bitmaps/buttons/sw1.xpm", "bitmaps/buttons/sw2.xpm", BRIGHTON_NOSHADOW},
183
184 /* Effects - 46 */
185 {"FX on/off", 2, C4 + BOFF, R3 + 20, B1, S1, 0, 1, 0, "bitmaps/buttons/pressoffw.xpm",
186 "bitmaps/buttons/pressonw.xpm", 0},
187
188 /* Master Tune - 47 */
189 {"MasterTuning", 0, C8, R0, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, BRIGHTON_NOTCH},
190 /* Wheel gain */
191 {"Bend-Depth", 0, C0, R2, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
192 {"Bend-Dest", 2, C0, R3, B1, S2, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW},
193 {"ModWheel-Depth", 0, C1, R2, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
194 {"ModWheel-Dest", 2, C1, R3, B1, S2, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW},
195
196 /* Modes */
197 {"Mode-Hold", 2, C2, R3, B1, S1, 0, 1, 0,
198 "bitmaps/buttons/pressoffw.xpm", "bitmaps/buttons/pressonw.xpm", 0},
199 {"Mode-Mono", 2, C2 + BOFF * 2 + 9, R3, B1, S1, 0, 1, 0,
200 "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0},
201 {"Mode-Poly", 2, C3 - 9, R3, B1, S1, 0, 1, 0,
202 "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0},
203 {"Mode-Share", 2, C3 + BOFF * 2, R3, B1, S1, 0, 1, 0,
204 "bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0},
205
206 /* Memories - Save */
207 {"", 2, C5, R3u, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffo.xpm",
208 "bitmaps/buttons/pressono.xpm", BRIGHTON_CHECKBUTTON},
209 {"", 2, C5 + BOFF* 2, R3u, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
210 "bitmaps/buttons/presson.xpm", 0},
211 {"", 2, C5 + BOFF* 4, R3u, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
212 "bitmaps/buttons/presson.xpm", 0},
213 {"", 2, C5 + BOFF* 6, R3u, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
214 "bitmaps/buttons/presson.xpm", 0},
215 {"", 2, C5 + BOFF* 8, R3u, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
216 "bitmaps/buttons/presson.xpm", 0},
217 {"", 2, C5 + BOFF* 10, R3u, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
218 "bitmaps/buttons/presson.xpm", 0},
219 {"", 2, C5 + BOFF* 12, R3u, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
220 "bitmaps/buttons/presson.xpm", 0},
221 {"", 2, C5 + BOFF* 14, R3u, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
222 "bitmaps/buttons/presson.xpm", 0},
223
224 {"", 2, C5 + BOFF* 2, R3d, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
225 "bitmaps/buttons/presson.xpm", 0},
226 {"", 2, C5 + BOFF* 4, R3d, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
227 "bitmaps/buttons/presson.xpm", 0},
228 {"", 2, C5 + BOFF* 6, R3d, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
229 "bitmaps/buttons/presson.xpm", 0},
230 {"", 2, C5 + BOFF* 8, R3d, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
231 "bitmaps/buttons/presson.xpm", 0},
232 {"", 2, C5 + BOFF* 10, R3d, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
233 "bitmaps/buttons/presson.xpm", 0},
234 {"", 2, C5 + BOFF* 12, R3d, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
235 "bitmaps/buttons/presson.xpm", 0},
236 {"", 2, C5 + BOFF* 14, R3d, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
237 "bitmaps/buttons/presson.xpm", 0},
238 /* Load */
239 {"", 2, C5, R3d, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffw.xpm",
240 "bitmaps/buttons/pressonw.xpm", BRIGHTON_CHECKBUTTON},
241
242 /* Midi */
243 {"", 2, C15, R3, B1, S1, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
244 "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON},
245 {"", 2, C15 + BOFF * 2, R3, B1, S1, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
246 "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON},
247 };
248
249 /*
250 */
251
252 /*
253 * This is a set of globals for the main window rendering. Again taken from
254 * include/brighton.h
255 */
256 brightonApp polyApp = {
257 "monopoly",
258 0, /* no blueprint on wood background. */
259 "bitmaps/textures/wood4.xpm",
260 0, /* BRIGHTON_STRETCH, //flags */
261 polyInit,
262 polyConfigure, /* 3 callbacks, unused? */
263 pmidiCallback,
264 destroySynth,
265 {1, 100, 2, 2, 5, 520, 0, 0},
266 750, 400, 0, 0,
267 7,
268 {
269 {
270 "Poly",
271 "bitmaps/blueprints/poly.xpm",
272 "bitmaps/textures/metal4.xpm",
273 BRIGHTON_STRETCH, /* flags */
274 0,
275 0,
276 polyCallback,
277 15, 0, 970, 620,
278 DEVICE_COUNT,
279 locations
280 },
281 {
282 "Keyboard",
283 0,
284 "bitmaps/newkeys/tkbg.xpm", /* flags */
285 0x020|BRIGHTON_STRETCH,
286 0,
287 0,
288 keyCallback,
289 150, 620, 845, 350,
290 KEY_COUNT_3OCTAVE,
291 keys3octave2
292 },
293 {
294 "Mods",
295 "bitmaps/blueprints/polymods.xpm",
296 "bitmaps/textures/metal4.xpm", /* flags */
297 BRIGHTON_REVERSE,
298 0,
299 0,
300 polyModCallback,
301 15, 620, 135, 350,
302 2,
303 mods
304 },
305 {
306 "Side wood",
307 0,
308 "bitmaps/textures/wood4.xpm",
309 BRIGHTON_VERTICAL, /* flags */
310 0,
311 0,
312 0,
313 0, 0, 15, 1000,
314 0,
315 0
316 },
317 {
318 "Side wood",
319 0,
320 "bitmaps/textures/wood.xpm",
321 BRIGHTON_VERTICAL, /* flags */
322 0,
323 0,
324 0,
325 2, 5, 12, 985,
326 0,
327 0
328 },
329 {
330 "Side wood",
331 0,
332 "bitmaps/textures/wood4.xpm",
333 BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /*flags */
334 0,
335 0,
336 0,
337 985, 0, 15, 1000,
338 0,
339 0
340 },
341 {
342 "Side wood",
343 0,
344 "bitmaps/textures/wood.xpm",
345 BRIGHTON_VERTICAL, /* flags */
346 0,
347 0,
348 0,
349 986, 5, 14, 985,
350 0,
351 0
352 }
353 }
354 };
355
356 static void
fixModes(guiSynth * synth)357 fixModes(guiSynth *synth)
358 {
359 brightonEvent event;
360 int mode = 53;
361
362 event.value = 1;
363 /*
364 * Operating modes are not configured when a memory is loaded, as that
365 * does not work correctly. After the memory is loaded, this routine is
366 * called to configure them.
367 */
368 if (synth->mem.param[54] != 0)
369 mode = 54;
370 else if (synth->mem.param[55] != 0)
371 mode = 55;
372
373 brightonParamChange(synth->win, synth->panel, mode, &event);
374 }
375
376 int
ploadMemory(guiSynth * synth,char * algo,char * name,int location,int active,int skip,int flags)377 ploadMemory(guiSynth *synth, char *algo, char *name, int location,
378 int active, int skip, int flags)
379 {
380 loadMemory(synth, "mono", 0, location, synth->mem.active, FIRST_DEV, 0);
381 fixModes(synth);
382 return(0);
383 }
384
385 static int
pmidiCallback(brightonWindow * win,int controller,int value,float n)386 pmidiCallback(brightonWindow *win, int controller, int value, float n)
387 {
388 guiSynth *synth = findSynth(global.synths, win);
389
390 printf("midi callback: %x, %i\n", controller, value);
391
392 switch(controller)
393 {
394 case MIDI_PROGRAM:
395 printf("midi program: %x, %i\n", controller, value);
396 synth->location = value;
397 loadMemory(synth, "mono", 0, synth->bank + synth->location,
398 synth->mem.active, FIRST_DEV, 0);
399 fixModes(synth);
400 break;
401 case MIDI_BANK_SELECT:
402 printf("midi banksel: %x, %i\n", controller, value);
403 synth->bank = value;
404 break;
405 }
406 return(0);
407 }
408
409 static int
polyModCallback(brightonWindow * win,int panel,int index,float value)410 polyModCallback(brightonWindow *win, int panel, int index, float value)
411 {
412 guiSynth *synth = findSynth(global.synths, win);
413
414 /* printf("polyModCallback(%x, %i, %i, %f)\n", synth, panel, index, value); */
415
416 /*
417 * If this is controller 0 it is the frequency control, otherwise a
418 * generic controller 1.
419 */
420 if (index == 0)
421 bristolMidiControl(global.controlfd, synth->midichannel,
422 0, 2, ((int) (value * C_RANGE_MIN_1)) >> 7);
423 else {
424 bristolMidiControl(global.controlfd, synth->midichannel,
425 0, 1, ((int) (value * C_RANGE_MIN_1)) >> 7);
426 }
427 return(0);
428 }
429
430 static void
polyMG2(void * synth,int fd,int chan,int c,int o,int v)431 polyMG2(void *synth, int fd, int chan, int c, int o, int v)
432 {
433 bristolMidiSendMsg(fd, chan, c, o, v);
434 bristolMidiSendMsg(fd, chan, 126, 26, v);
435 }
436
437 static int
polyMidiSendMsg(void * synth,int fd,int chan,int c,int o,int v)438 polyMidiSendMsg(void *synth, int fd, int chan, int c, int o, int v)
439 {
440 bristolMidiSendMsg(fd, chan, c, o, v);
441 return(0);
442 }
443
444 static void
polyTranspose(guiSynth * synth,int fd,int chan,int c,int o,int v)445 polyTranspose(guiSynth *synth, int fd, int chan, int c, int o, int v)
446 {
447 switch (v)
448 {
449 case 0:
450 synth->transpose = 36;
451 break;
452 case 1:
453 synth->transpose = 48;
454 break;
455 case 2:
456 synth->transpose = 60;
457 break;
458 }
459 }
460
461 static void
polyWaveform(guiSynth * synth,int fd,int chan,int c,int o,int v)462 polyWaveform(guiSynth *synth, int fd, int chan, int c, int o, int v)
463 {
464 int offset;
465
466 /*
467 * 0 = tri, 1 = ramp, 2 and 3 are PW
468 */
469 if (c == 34)
470 {
471 /*
472 * Pulse width of all osc.
473 */
474 bristolMidiSendMsg(fd, chan, 0, 0, v);
475 bristolMidiSendMsg(fd, chan, 1, 0, v);
476 bristolMidiSendMsg(fd, chan, 2, 0, v);
477 bristolMidiSendMsg(fd, chan, 8, 0, v);
478 return;
479 }
480
481 if ((offset = 22 + c) > 24)
482 offset = 25;
483
484 switch(v) {
485 case 0:
486 /*
487 * Ramp off, square off, tri on
488 */
489 bristolMidiSendMsg(fd, chan, c, 4, 0);
490 bristolMidiSendMsg(fd, chan, c, 6, 0);
491 bristolMidiSendMsg(fd, chan, c, 5, 1);
492
493 bristolMidiSendMsg(fd, chan, 126, offset, 0);
494 break;
495 case 1:
496 bristolMidiSendMsg(fd, chan, c, 5, 0);
497 bristolMidiSendMsg(fd, chan, c, 6, 0);
498 bristolMidiSendMsg(fd, chan, c, 4, 1);
499
500 bristolMidiSendMsg(fd, chan, 126, offset, 0);
501 break;
502 case 2:
503 bristolMidiSendMsg(fd, chan, c, 4, 0);
504 bristolMidiSendMsg(fd, chan, c, 5, 0);
505 bristolMidiSendMsg(fd, chan, c, 6, 1);
506
507 bristolMidiSendMsg(fd, chan, 126, offset, 1);
508 break;
509 case 3:
510 bristolMidiSendMsg(fd, chan, c, 4, 0);
511 bristolMidiSendMsg(fd, chan, c, 5, 0);
512 bristolMidiSendMsg(fd, chan, c, 6, 1);
513
514 bristolMidiSendMsg(fd, chan, 126, offset, 0);
515 break;
516 }
517 }
518
519 static int
polyMode(guiSynth * synth,int fd,int chan,int c,int o,int v)520 polyMode(guiSynth *synth, int fd, int chan, int c, int o, int v)
521 {
522 brightonEvent event;
523
524 if (c == 52)
525 {
526 bristolMidiSendMsg(global.controlfd, synth->sid, 126, o, v);
527 return(0);
528 }
529
530 if (synth->flags & MEM_LOADING)
531 return(0);
532
533 if (synth->dispatch[RADIOSET_3].other2)
534 return(synth->dispatch[RADIOSET_3].other2 = 0);
535
536 if (synth->dispatch[RADIOSET_3].other1 != -1)
537 {
538 synth->dispatch[RADIOSET_3].other2 = 1;
539
540 if (synth->dispatch[RADIOSET_3].other1 != c)
541 event.value = 0;
542 else
543 event.value = 1;
544
545 brightonParamChange(synth->win, synth->panel,
546 synth->dispatch[RADIOSET_3].other1, &event);
547 }
548 synth->dispatch[RADIOSET_3].other1 = c;
549
550 bristolMidiSendMsg(global.controlfd, synth->sid, 126, o, v);
551
552 return(0);
553 }
554
555 static void
polyMemory(guiSynth * synth,int fd,int chan,int c,int o,int v)556 polyMemory(guiSynth *synth, int fd, int chan, int c, int o, int v)
557 {
558 brightonEvent event;
559
560 /* printf(" polyMemory(B: %i L %i: %i, %i)\n", */
561 /* synth->bank, synth->location, c, o); */
562
563 switch(c) {
564 case 0:
565 saveMemory(synth, "mono", 0, synth->bank + synth->location,
566 FIRST_DEV);
567 return;
568 break;
569 case 15:
570 loadMemory(synth, "mono", 0, synth->bank + synth->location,
571 synth->mem.active, FIRST_DEV, 0);
572 fixModes(synth);
573 return;
574 break;
575 case 1:
576 case 2:
577 case 3:
578 case 4:
579 case 5:
580 case 6:
581 case 7:
582 if (synth->dispatch[RADIOSET_1].other2)
583 {
584 synth->dispatch[RADIOSET_1].other2 = 0;
585 return;
586 }
587 if (synth->dispatch[RADIOSET_1].other1 != -1)
588 {
589 synth->dispatch[RADIOSET_1].other2 = 1;
590
591 if (synth->dispatch[RADIOSET_1].other1 != c)
592 event.value = 0;
593 else
594 event.value = 1;
595
596 brightonParamChange(synth->win, synth->panel,
597 synth->dispatch[RADIOSET_1].other1 + MEM_START, &event);
598 }
599 synth->dispatch[RADIOSET_1].other1 = c;
600 synth->bank = c * 10;
601 break;
602 case 8:
603 case 9:
604 case 10:
605 case 11:
606 case 12:
607 case 13:
608 case 14:
609 if (synth->dispatch[RADIOSET_2].other2)
610 {
611 synth->dispatch[RADIOSET_2].other2 = 0;
612 return;
613 }
614 if (synth->dispatch[RADIOSET_2].other1 != -1)
615 {
616 synth->dispatch[RADIOSET_2].other2 = 1;
617
618 if (synth->dispatch[RADIOSET_2].other1 != c)
619 event.value = 0;
620 else
621 event.value = 1;
622
623 brightonParamChange(synth->win, synth->panel,
624 synth->dispatch[RADIOSET_2].other1 + MEM_START, &event);
625 }
626 synth->dispatch[RADIOSET_2].other1 = c;
627 /* Do radio buttons */
628 synth->location = c - 7;
629 break;
630 }
631 }
632
633 static void
polyEffect(guiSynth * synth,int fd,int chan,int c,int o,int v)634 polyEffect(guiSynth *synth, int fd, int chan, int c, int o, int v)
635 {
636 brightonEvent event;
637
638 /*
639 * If we are turning this on the the original would also force MONO mode
640 * so we should do the same.
641 */
642 if (v != 0)
643 {
644 event.value = 1;
645 brightonParamChange(synth->win, synth->panel, 53, &event);
646 }
647 bristolMidiSendMsg(fd, chan, c, o, v);
648 }
649
650 static void
polyMidi(guiSynth * synth,int fd,int chan,int c,int o,int v)651 polyMidi(guiSynth *synth, int fd, int chan, int c, int o, int v)
652 {
653 int newchan;
654
655 if ((synth->flags & OPERATIONAL) == 0)
656 return;
657
658 if (c == 1) {
659 if ((newchan = synth->midichannel - 1) < 0)
660 {
661 synth->midichannel = 0;
662 return;
663 }
664 } else {
665 if ((newchan = synth->midichannel + 1) >= 16)
666 {
667 synth->midichannel = 15;
668 return;
669 }
670 }
671
672 if (global.libtest == 0)
673 {
674 /*
675 #warning if we do not check for ack then socket might hang on exit
676 * To overcome that we should consider checking a sequence number in
677 * the message library? That is non trivial since it requires that
678 * our midi messges have a 'ack' flag included - we cannot check for
679 * ack here (actually, we could, and in the app is probably the right
680 * place to do it rather than the lib however both would have to be
681 * changed to suppor this - nc).
682 */
683 bristolMidiSendMsg(global.controlfd, synth->sid,
684 127, 0, BRISTOL_MIDICHANNEL|newchan);
685 }
686
687 synth->midichannel = newchan;
688 }
689
690 /*
691 * For the sake of ease of use, links have been placed here to be called
692 * by any of the devices created. They would be better in some other file,
693 * perhaps with this as a dispatch.
694 *
695 * Param refers to the device index in the locations table given below.
696 */
697 static int
polyCallback(brightonWindow * win,int panel,int index,float value)698 polyCallback(brightonWindow * win, int panel, int index, float value)
699 {
700 guiSynth *synth = findSynth(global.synths, win);
701 int sendvalue;
702
703 /*printf("polyCallback(%i, %f): %x\n", index, value, synth); */
704
705 if (synth == 0)
706 return(0);
707
708 if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0))
709 return(0);
710
711 if (polyApp.resources[0].devlocn[index].to == 1.0)
712 sendvalue = value * (CONTROLLER_RANGE - 1);
713 else
714 sendvalue = value;
715
716 synth->mem.param[index] = value;
717
718 if ((!global.libtest) || (index >= ACTIVE_DEVS))
719 synth->dispatch[index].routine(synth,
720 global.controlfd, synth->sid,
721 synth->dispatch[index].controller,
722 synth->dispatch[index].operator,
723 sendvalue);
724
725 #ifdef DEBUG
726 else
727 printf("dispatch[%x,%i](%i, %i, %i, %i, %i)\n", synth, index,
728 global.controlfd, synth->sid,
729 synth->dispatch[index].controller,
730 synth->dispatch[index].operator,
731 sendvalue);
732 #endif
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
polyInit(brightonWindow * win)745 polyInit(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, (int) 0);
754 if (synth == 0)
755 {
756 printf("cannot init\n");
757 return(0);
758 }
759 }
760
761 synth->win = win;
762
763 if ((initmem = synth->location) == 0)
764 initmem = 11;
765
766 printf("Initialise the poly 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 if (!global.libtest)
782 {
783 synth->voices = 1;
784 if ((synth->sid = initConnection(&global, synth)) < 0)
785 return(-1);
786 }
787
788 for (i = 0; i < DEVICE_COUNT; i++)
789 {
790 synth->dispatch[i].routine = polyMidiSendMsg;
791 }
792
793 /* Osc-1 Waveform is a compound operator */
794 dispatch[0].controller = 0;
795 dispatch[0].operator = 0;
796 dispatch[0].routine = (synthRoutine) polyWaveform;
797 dispatch[1].controller = 0;
798 dispatch[1].operator = 1;
799 dispatch[2].controller = 126;
800 dispatch[2].operator = 30;
801 /* Osc-2 Waveform is a compound operator */
802 dispatch[3].controller = 1;
803 dispatch[3].operator = 10;
804 dispatch[4].controller = 1;
805 dispatch[4].operator = 0;
806 dispatch[4].routine = (synthRoutine) polyWaveform;
807 dispatch[5].controller = 1;
808 dispatch[5].operator = 1;
809 dispatch[6].controller = 126;
810 dispatch[6].operator = 31;
811 /* Osc-3 Waveform is a compound operator */
812 dispatch[7].controller = 2;
813 dispatch[7].operator = 10;
814 dispatch[8].controller = 2;
815 dispatch[8].operator = 0;
816 dispatch[8].routine = (synthRoutine) polyWaveform;
817 dispatch[9].controller = 2;
818 dispatch[9].operator = 1;
819 dispatch[10].controller = 126;
820 dispatch[10].operator = 32;
821 /* Osc-4 Waveform is a compound operator and different operator.... */
822 dispatch[11].controller = 8;
823 dispatch[11].operator = 10;
824 dispatch[12].controller = 8;
825 dispatch[12].operator = 0;
826 dispatch[12].routine = (synthRoutine) polyWaveform;
827 dispatch[13].controller = 8;
828 dispatch[13].operator = 1;
829 dispatch[14].controller = 126;
830 dispatch[14].operator = 33;
831
832 /* Filter */
833 dispatch[15].controller = 4;
834 dispatch[15].operator = 0;
835 dispatch[16].controller = 4;
836 dispatch[16].operator = 1;
837 dispatch[17].controller = 4;
838 dispatch[17].operator = 2;
839 dispatch[18].controller = 4;
840 dispatch[18].operator = 3;
841 /* Filter Env */
842 dispatch[19].controller = 3;
843 dispatch[19].operator = 0;
844 dispatch[20].controller = 3;
845 dispatch[20].operator = 1;
846 dispatch[21].controller = 3;
847 dispatch[21].operator = 2;
848 dispatch[22].controller = 3;
849 dispatch[22].operator = 3;
850 /* Env */
851 dispatch[23].controller = 5;
852 dispatch[23].operator = 0;
853 dispatch[24].controller = 5;
854 dispatch[24].operator = 1;
855 dispatch[25].controller = 5;
856 dispatch[25].operator = 2;
857 dispatch[26].controller = 5;
858 dispatch[26].operator = 3;
859 /* Env gain */
860 dispatch[27].controller = 5;
861 dispatch[27].operator = 4;
862 /* This switch reassigned to arpeggiator direction, was for headphone output */
863 dispatch[28].controller = 126;
864 dispatch[28].operator = 28;
865 /* LFO frequencies */
866 dispatch[29].controller = 9;
867 dispatch[29].operator = 0;
868 dispatch[30].controller = 126;
869 dispatch[30].operator = 3;
870 dispatch[31].controller = 10;
871 dispatch[31].operator = 0;
872 /* Needs a dispatcher since it has dual operation - arpeg and LFO2 */
873 dispatch[31].routine = (synthRoutine) polyMG2;
874 /* PWM */
875 dispatch[32].controller = 126;
876 dispatch[32].operator = 4;
877 dispatch[33].controller = 126;
878 dispatch[33].operator = 5;
879 /* PW */
880 dispatch[34].controller = 34;
881 dispatch[34].operator = 34;
882 dispatch[34].routine = (synthRoutine) polyWaveform;
883
884 /* Modulators 35 though 39 NOT DONE */
885 dispatch[35].controller = 126;
886 dispatch[35].operator = 6;
887 dispatch[36].controller = 126;
888 dispatch[36].operator = 7;
889 dispatch[37].controller = 126;
890 dispatch[37].operator = 8;
891 dispatch[38].controller = 126;
892 dispatch[38].operator = 9;
893 dispatch[39].controller = 126;
894 dispatch[39].operator = 10;
895 /* dispatch[35].routine = dispatch[36].routine = dispatch[37].routine = */
896 /* dispatch[38].routine = dispatch[39].routine = (synthRoutine) polyEffect; */
897
898 /* Glide */
899 dispatch[40].controller = 126;
900 dispatch[40].operator = 0;
901
902 /* Detune. */
903 dispatch[41].controller = 126;
904 dispatch[41].operator = 11;
905
906 /* Transpose */
907 dispatch[42].controller = 0;
908 dispatch[42].operator = 0;
909 dispatch[42].routine = (synthRoutine) polyTranspose;
910
911 /* Noise level */
912 dispatch[43].controller = 7;
913 dispatch[43].operator = 0;
914
915 /* Trigger */
916 dispatch[44].controller = 126;
917 dispatch[44].operator = 12;
918 /* Damp */
919 dispatch[45].controller = 126;
920 dispatch[45].operator = 13;
921
922 /* Effects NOT DONE */
923 dispatch[46].controller = 126;
924 dispatch[46].operator = 14;
925 dispatch[46].routine = (synthRoutine) polyEffect;
926
927 /* Global tune */
928 dispatch[47].controller = 126;
929 dispatch[47].operator = 2;
930
931 /* MG1 */
932 dispatch[48].controller = 126;
933 dispatch[48].operator = 15;
934 dispatch[49].controller = 126;
935 dispatch[49].operator = 16;
936 /* MG2 */
937 dispatch[50].controller = 126;
938 dispatch[50].operator = 17;
939 dispatch[51].controller = 126;
940 dispatch[51].operator = 18;
941
942 /*
943 * Hold
944 *
945 * Mono - two button
946 *
947 * Poly - two buttons
948 *
949 * Propose
950 * Mono - fat synth = UNISON
951 * Poly - 4 voice thin synth
952 * Share:
953 * One key all voices (fat synth)
954 * Key keys two notes each (2VCO synth)
955 * Three or more, one note each (thin synth).
956 */
957 dispatch[52].controller = 52;
958 dispatch[52].operator = 27;
959 dispatch[53].controller = 53;
960 dispatch[53].operator = 19;
961 dispatch[54].controller = 54; /* Does not do anything = Unison off */
962 dispatch[54].operator = 20;
963 dispatch[55].controller = 55;
964 dispatch[55].operator = 21;
965 dispatch[52].routine =
966 dispatch[53].routine =
967 dispatch[54].routine =
968 dispatch[55].routine = (synthRoutine) polyMode;
969
970 dispatch[56].controller = 0;
971 dispatch[57].controller = 1;
972 dispatch[58].controller = 2;
973 dispatch[59].controller = 3;
974 dispatch[60].controller = 4;
975 dispatch[61].controller = 5;
976 dispatch[62].controller = 6;
977 dispatch[63].controller = 7;
978 dispatch[64].controller = 8;
979 dispatch[65].controller = 9;
980 dispatch[66].controller = 10;
981 dispatch[67].controller = 11;
982 dispatch[68].controller = 12;
983 dispatch[69].controller = 13;
984 dispatch[70].controller = 14;
985 dispatch[71].controller = 15;
986
987 dispatch[56].routine =
988 dispatch[57].routine =
989 dispatch[58].routine =
990 dispatch[59].routine =
991 dispatch[60].routine =
992 dispatch[61].routine =
993 dispatch[62].routine =
994 dispatch[63].routine =
995 dispatch[64].routine =
996 dispatch[65].routine =
997 dispatch[66].routine =
998 dispatch[67].routine =
999 dispatch[68].routine =
1000 dispatch[69].routine =
1001 dispatch[70].routine =
1002 dispatch[71].routine
1003 = (synthRoutine) polyMemory;
1004
1005 dispatch[RADIOSET_1].other1 = -1;
1006 dispatch[RADIOSET_2].other1 = -1;
1007 dispatch[RADIOSET_3].other1 = -1;
1008
1009 dispatch[72].controller = 1;
1010 dispatch[73].controller = 2;
1011 dispatch[72].routine = dispatch[73].routine =
1012 (synthRoutine) polyMidi;
1013
1014 /* Tune osc-1
1015 bristolMidiSendMsg(global.controlfd, synth->sid, 0, 10, 8192);
1016 */
1017 /*
1018 * We put all the osc on SYNC/MAXgain, but manipulate the sync buffer in the
1019 * engine.
1020 */
1021 bristolMidiSendMsg(global.controlfd, synth->sid, 0, 7, 8192);
1022 bristolMidiSendMsg(global.controlfd, synth->sid, 1, 7, 8192);
1023 bristolMidiSendMsg(global.controlfd, synth->sid, 2, 7, 8192);
1024 bristolMidiSendMsg(global.controlfd, synth->sid, 8, 7, 8192);
1025
1026 bristolMidiSendMsg(global.controlfd, synth->sid, 4, 4, 4);
1027
1028 bristolMidiSendMsg(global.controlfd, synth->sid, 0, 3, C_RANGE_MIN_1);
1029 bristolMidiSendMsg(global.controlfd, synth->sid, 1, 3, C_RANGE_MIN_1);
1030 bristolMidiSendMsg(global.controlfd, synth->sid, 2, 3, C_RANGE_MIN_1);
1031 bristolMidiSendMsg(global.controlfd, synth->sid, 8, 3, C_RANGE_MIN_1);
1032
1033 /* Gain on filter contour */
1034 bristolMidiSendMsg(global.controlfd, synth->sid, 3, 4, C_RANGE_MIN_1);
1035 /* LFO Options */
1036 bristolMidiSendMsg(global.controlfd, synth->sid, 10, 2, 8192);
1037
1038 return(0);
1039 }
1040
1041 /*
1042 * This will be called to make any routine specific parameters available.
1043 */
1044 static int
polyConfigure(brightonWindow * win)1045 polyConfigure(brightonWindow* win)
1046 {
1047 guiSynth *synth = findSynth(global.synths, win);
1048 brightonEvent event;
1049
1050 if (synth == 0)
1051 {
1052 printf("problems going operational\n");
1053 return(-1);
1054 }
1055
1056 if (synth->flags & OPERATIONAL)
1057 return(0);
1058
1059 printf("going operational\n");
1060
1061 synth->flags |= OPERATIONAL;
1062 synth->keypanel = 1;
1063 synth->keypanel2 = -1;
1064 synth->transpose = 36;
1065
1066 if (synth->location == 0)
1067 {
1068 synth->bank = 1;
1069 synth->location = 1;
1070 }
1071
1072 event.value = 1;
1073 brightonParamChange(synth->win, synth->panel, MEM_START + 1, &event);
1074 brightonParamChange(synth->win, synth->panel, MEM_START + 8, &event);
1075
1076 loadMemory(synth, "mono", 0, initmem, synth->mem.active, FIRST_DEV, 0);
1077 fixModes(synth);
1078
1079 brightonPut(win,
1080 "bitmaps/blueprints/monoshade.xpm", 0, 0, win->width, win->height);
1081 width = win->width;
1082
1083 /*
1084 * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only
1085 * occurs on first paint, so we suppress the first paint, and then request
1086 * an expose here.
1087 */
1088 event.type = BRIGHTON_EXPOSE;
1089 event.intvalue = 1;
1090 brightonParamChange(synth->win, KEY_PANEL, -1, &event);
1091
1092 /*
1093 * Touch a key on/off
1094 */
1095 bristolMidiSendMsg(global.controlfd, synth->midichannel,
1096 BRISTOL_EVENT_KEYON, 0, 10 + synth->transpose);
1097 bristolMidiSendMsg(global.controlfd, synth->midichannel,
1098 BRISTOL_EVENT_KEYOFF, 0, 10 + synth->transpose);
1099 configureGlobals(synth);
1100
1101 synth->loadMemory = (loadRoutine) ploadMemory;
1102
1103 return(0);
1104 }
1105
1106