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
28 static int initmem;
29
30 static int obxInit();
31 static int obxConfigure();
32 static int obxCallback(brightonWindow *, int, int, float);
33 /*static int keyCallback(void *, int, int, float); */
34 static int obxModCallback(brightonWindow *, int, int, float);
35 static int obxMidiCallback(brightonWindow *, int, int, float);
36
37 extern guimain global;
38
39 #include "brightonKeys.h"
40 #include "brightoninternals.h"
41
42 #define FIRST_DEV 0
43 #define DEVICE_COUNT 65
44 #define ACTIVE_DEVS 43
45 #define OBX_DEVS 46 /* Have to account for the manual options. */
46 #define MEM_START (OBX_DEVS - 1)
47 #define RADIOSET_1 MEM_START
48 #define RADIOSET_2 (MEM_START + 1)
49 #define RADIOSET_3 (MEM_START + 2)
50 #define DISPLAY_DEV (DEVICE_COUNT - 1)
51
52 #define KEY_PANEL 1
53
54 /*
55 * This structure is for device definition. The structure is defined in
56 * include/brighton.h, further definitions in brighton/brightonDevtable.h and
57 * include/brightoninternals.h
58 *
59 * typedef int (*brightonCallback)(int, float);
60 * typedef struct BrightonLocations {
61 * int device; 0=rotary, 1=scale, etc.
62 * float relx, rely; relative position with regards to 1000 by 1000 window
63 * float relw, relh; relative height.
64 * int from, to;
65 * brightonCallback callback; specific to this dev
66 * char *image; bitmap. If zero take a device default.
67 * int flags;
68 * } brightonLocations;
69 *
70 * This example is for a obxBristol type synth interface.
71 */
72 #define S1 110
73 #define S2 17
74 #define S3 70
75
76 #define BO 10
77 #define B2 6
78
79 #define R1 200
80 #define R2 430
81 #define R3 600
82 #define R3b 600
83 #define R4 780
84
85 #define C1 50
86 #define C2 66
87 #define C3 100
88
89 #define C4 175
90
91 #define C5 242
92 #define C6 300
93 #define C7 354
94
95 #define C8 415
96 #define C9 475
97 #define C10 535
98
99 #define C11 590
100 #define C12 650
101 #define C13 710
102
103 #define C11b 750
104 #define C12b 800
105 #define C13b 850
106
107 #define C14 775
108 #define C15 825
109 #define C16 875
110 #define C17 925
111
112 /* memories */
113 #define MD 23
114 #define C20 (C8 + MD + MD/2)
115 #define C21 (C20 + MD)
116 #define C22 (C21 + MD)
117 #define C23 (C22 + MD)
118 #define C24 (C23 + MD)
119 #define C25 (C24 + MD)
120 #define C26 (C25 + MD)
121 #define C27 (C26 + MD)
122
123 #define C28 (C27 + MD + MD/2)
124 #define C29 (C28 + MD)
125 #define C30 (C29 + MD)
126 #define C31 (C30 + MD)
127 #define C32 (C31 + MD)
128 #define C33 (C32 + MD)
129 #define C34 (C33 + MD)
130 #define C35 (C34 + MD)
131
132 #define C36 (C35 + MD + MD/2)
133
134 static brightonLocations locations[DEVICE_COUNT] = {
135 /* 0 - control */
136 {"Glide", 0, C4, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm",
137 "bitmaps/knobs/alpharotary.xpm", 0},
138 {"Unison", 2, C4 + B2, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
139 "bitmaps/buttons/presson.xpm", 0},
140 {"Osc2-Detune", 0, C4, R3b, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm",
141 "bitmaps/knobs/alpharotary.xpm", 0},
142 /* 3 - mods */
143 {"LFO-Freq", 0, C5, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm",
144 "bitmaps/knobs/alpharotary.xpm", 0},
145 {"LFO-Sine", 2, C5 + B2, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
146 "bitmaps/buttons/presson.xpm", 0},
147 {"LFO-Square", 2, C5 + B2, R3, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
148 "bitmaps/buttons/presson.xpm", 0},
149 {"LFO-S/H", 2, C5 + B2, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
150 "bitmaps/buttons/presson.xpm", 0},
151
152 {"LFO-FM-Depth", 0, C6, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm",
153 "bitmaps/knobs/alpharotary.xpm", 0},
154 {"LFO-FM-Osc1", 2, C6 + B2, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
155 "bitmaps/buttons/presson.xpm", 0},
156 {"LFO-FM-Osc2", 2, C6 + B2, R3, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
157 "bitmaps/buttons/presson.xpm", 0},
158 {"LFO-FM-Filt", 2, C6 + B2, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
159 "bitmaps/buttons/presson.xpm", 0},
160
161 {"LFO-PWM-Depth", 0, C7, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm",
162 "bitmaps/knobs/alpharotary.xpm", 0},
163 {"LFO-PWM-Osc1", 2, C7 + B2, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
164 "bitmaps/buttons/presson.xpm", 0},
165 {"LFO-PWM-Osc2", 2, C7 + B2, R3, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
166 "bitmaps/buttons/presson.xpm", 0},
167 /* 14 - oscillators: */
168 {"Osc1-Transpose", 0, C8, R1, S1, S1, 0, 5, 0, "bitmaps/knobs/knob5.xpm",
169 "bitmaps/knobs/alpharotary.xpm", 0},
170 {"Osc-PW", 0, C9, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm",
171 "bitmaps/knobs/alpharotary.xpm", 0},
172 {"Osc2-Tune", 0, C10, R1, S1, S1, 0, 47, 0, "bitmaps/knobs/knob5.xpm",
173 "bitmaps/knobs/alpharotary.xpm", 0},
174 {"Osc1-Saw", 2, C8 - 8, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
175 "bitmaps/buttons/presson.xpm", 0},
176 {"Osc1-PW-CLI!", 2, C8 + 17, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
177 "bitmaps/buttons/presson.xpm", 0},
178 {"Osc-CrossMod", 2, C9 - 8, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
179 "bitmaps/buttons/presson.xpm", 0},
180 {"Osc-Sync", 2, C9 + 17, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
181 "bitmaps/buttons/presson.xpm", 0},
182 {"Osc1-Saw", 2, C10 - 8, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
183 "bitmaps/buttons/presson.xpm", 0},
184 {"Osc1-Pulse", 2, C10 + 17, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
185 "bitmaps/buttons/presson.xpm", 0},
186 /* 23 - filter */
187 {"VCF-Cutoff", 0, C11, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm",
188 "bitmaps/knobs/alpharotary.xpm", 0},
189 {"VCF-Resonance", 0, C12, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm",
190 "bitmaps/knobs/alpharotary.xpm", 0},
191 {"VCF-ModLevel", 0, C13, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm",
192 "bitmaps/knobs/alpharotary.xpm", 0},
193 {"MixOsc1", 2, C11 - 8, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
194 "bitmaps/buttons/presson.xpm", 0},
195 {"VCF-KBD", 2, C11 + 17, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
196 "bitmaps/buttons/presson.xpm", 0},
197 {"MixOsc2-Half", 2, C12 - 8, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
198 "bitmaps/buttons/presson.xpm", 0},
199 {"MixOsc2-Full", 2, C12 + 17, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
200 "bitmaps/buttons/presson.xpm", 0},
201 {"MixNoise-Half", 2, C13 - 8, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
202 "bitmaps/buttons/presson.xpm", 0},
203 {"MixNoise-Full", 2, C13 + 17, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
204 "bitmaps/buttons/presson.xpm", 0},
205 /* 32 - envelope */
206 {"VCF-Attack", 0, C14, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm",
207 "bitmaps/knobs/alpharotary.xpm", 0},
208 {"VCF-Decay", 0, C15, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm",
209 "bitmaps/knobs/alpharotary.xpm", 0},
210 {"VCF-Sustain", 0, C16, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm",
211 "bitmaps/knobs/alpharotary.xpm", 0},
212 {"VCF-Release", 0, C17, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm",
213 "bitmaps/knobs/alpharotary.xpm", 0},
214
215 {"VCA-Attack", 0, C14, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm",
216 "bitmaps/knobs/alpharotary.xpm", 0},
217 {"VCA-Decay", 0, C15, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm",
218 "bitmaps/knobs/alpharotary.xpm", 0},
219 {"VCA-Sustain", 0, C16, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm",
220 "bitmaps/knobs/alpharotary.xpm", 0},
221 {"VCA-Release", 0, C17, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm",
222 "bitmaps/knobs/alpharotary.xpm", 0},
223
224 /* According to the original, these are not saved. Volume will be, and */
225 /* reset should be.. */
226 {"MasterVolume", 0, C2 + BO, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm",
227 "bitmaps/knobs/alpharotary.xpm", 0},
228 {"Reset", 2, C3 + BO, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
229 "bitmaps/buttons/presson.xpm", 0},
230 /* Total 42 parameters. */
231 {"Auto", 2, C1, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
232 "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON},
233 {"", 2, C2 + BO * 3/2, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
234 "bitmaps/buttons/presson.xpm", 0},
235 /* {"", 2, C3 + BO, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", */
236 /* "bitmaps/buttons/presson.xpm", 0}, */
237 {"", 0, C2 + BO, R3b, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm",
238 "bitmaps/knobs/alpharotary.xpm", BRIGHTON_NOTCH},
239 /*46 */
240 /* Programmer */
241 {"", 2, C8, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
242 "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON},
243
244 {"", 2, C20, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
245 "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON},
246 {"", 2, C21, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
247 "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON},
248 {"", 2, C22, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
249 "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON},
250 {"", 2, C23, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
251 "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON},
252 {"", 2, C24, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
253 "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON},
254 {"", 2, C25, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
255 "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON},
256 {"", 2, C26, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
257 "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON},
258 {"", 2, C27, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
259 "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON},
260 {"", 2, C28, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
261 "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON},
262 {"", 2, C29, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
263 "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON},
264 {"", 2, C30, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
265 "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON},
266 {"", 2, C31, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
267 "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON},
268 {"", 2, C32, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
269 "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON},
270 {"", 2, C33, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
271 "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON},
272 {"", 2, C34, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
273 "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON},
274 {"", 2, C35, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
275 "bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON},
276
277 {"", 2, C36, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
278 "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON},
279
280 {"", 2, C17 - 10, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
281 "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON},
282 {"", 2, C17 + MD, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
283 "bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON},
284 };
285
286 #define OBX_MODCOUNT 5
287 static brightonLocations obxMods[OBX_MODCOUNT] = {
288 {"", 1, 385, 200, 100, 468, 0, 1, 0,
289 "bitmaps/knobs/sliderblack.xpm", 0, BRIGHTON_CENTER},
290 {"", 1, 520, 200, 100, 468, 0, 1, 0,
291 "bitmaps/knobs/sliderblack.xpm", 0, 0},
292
293 {"", 2, 180, 800, 130, 140, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
294 "bitmaps/buttons/presson.xpm", 0},
295 {"", 2, 450, 800, 130, 140, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
296 "bitmaps/buttons/presson.xpm", 0},
297 {"", 2, 690, 800, 130, 140, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
298 "bitmaps/buttons/presson.xpm", 0}
299 };
300
301 /*
302 * This is a set of globals for the main window rendering. Again taken from
303 * include/brighton.h
304 */
305 brightonApp obxApp = {
306 "obx",
307 0, /* no blueprint on wood background. */
308 "bitmaps/textures/metal6.xpm",
309 BRIGHTON_STRETCH, /*flags */
310 obxInit,
311 obxConfigure, /* 3 callbacks, unused? */
312 obxMidiCallback,
313 destroySynth,
314 {5, 100, 2, 2, 5, 520, 0, 0},
315 770, 350, 0, 0,
316 6, /* Panel count */
317 {
318 {
319 "OBX",
320 "bitmaps/blueprints/obx.xpm",
321 "bitmaps/textures/metal6.xpm",
322 BRIGHTON_STRETCH|BRIGHTON_REVERSE, /* flags */
323 0,
324 0,
325 obxCallback,
326 14, 130, 970, 520,
327 DEVICE_COUNT,
328 locations
329 },
330 {
331 "Keyboard",
332 0,
333 "bitmaps/newkeys/kbg.xpm", /* flags */
334 0x020|BRIGHTON_STRETCH,
335 0,
336 0,
337 keyCallback,
338 155, 690, 854, 290,
339 KEY_COUNT,
340 keys
341 },
342 {
343 "Mods",
344 "bitmaps/blueprints/obxmod.xpm",
345 "bitmaps/textures/metal5.xpm", /* flags */
346 0,
347 0,
348 0,
349 obxModCallback, /* Needs to be obxModCallback */
350 17, 690, 136, 290,
351 OBX_MODCOUNT,
352 obxMods
353 },
354 {
355 "Logo",
356 "bitmaps/blueprints/obxlogo.xpm",
357 0,
358 BRIGHTON_STRETCH, /*flags */
359 0,
360 0,
361 0,
362 15, 0, 970, 130,
363 0,
364 0
365 },
366 {
367 "Edge",
368 0,
369 "bitmaps/images/rhodes.xpm",
370 BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */
371 0,
372 0,
373 0,
374 0, 0, 15, 1000,
375 0,
376 0
377 },
378 {
379 "Edge",
380 0,
381 "bitmaps/images/rhodes.xpm",
382 BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /*flags */
383 0,
384 0,
385 0,
386 985, 0, 15, 1000,
387 0,
388 0
389 },
390 }
391 };
392
393 static int
obxKeyLoadMemory(guiSynth * synth,char * algo,char * name,int location,int active,int skip,int flags)394 obxKeyLoadMemory(guiSynth *synth, char *algo, char *name, int location,
395 int active, int skip, int flags)
396 {
397 brightonEvent event;
398
399 synth->flags |= MEM_LOADING;
400
401 loadMemory(synth, "obx", 0, location, synth->mem.active, FIRST_DEV, 0);
402
403 /*
404 * We now need to force the PW of the two oscillators?
405 */
406 bristolMidiSendMsg(synth->sid, synth->midichannel,
407 0, 0, (int) synth->mem.param[15]);
408 bristolMidiSendMsg(synth->sid, synth->midichannel,
409 1, 0, (int) synth->mem.param[ACTIVE_DEVS-1]);
410
411 event.value = 0;
412 brightonParamChange(synth->win, 0, ACTIVE_DEVS-1, &event);
413
414 synth->flags &= ~MEM_LOADING;
415 return(0);
416 }
417
418 static void
obxLoadMemory(guiSynth * synth,int fd,int chan,int c,int o,int v)419 obxLoadMemory(guiSynth *synth, int fd, int chan, int c, int o, int v)
420 {
421 brightonEvent event;
422
423 synth->flags |= MEM_LOADING;
424
425 loadMemory(synth, "obx", 0, synth->bank * 10 + synth->location,
426 synth->mem.active, FIRST_DEV, 0);
427
428 /*
429 * We now need to force the PW of the two oscillators?
430 */
431 bristolMidiSendMsg(fd, chan, 0, 0, (int) synth->mem.param[15]);
432 bristolMidiSendMsg(fd, chan, 1, 0, (int) synth->mem.param[ACTIVE_DEVS-1]);
433
434 event.value = 0;
435 brightonParamChange(synth->win, 0, ACTIVE_DEVS-1, &event);
436
437 synth->flags &= ~MEM_LOADING;
438 }
439
440 static int
obxMidiCallback(brightonWindow * win,int controller,int value,float n)441 obxMidiCallback(brightonWindow *win, int controller, int value, float n)
442 {
443 guiSynth *synth = findSynth(global.synths, win);
444
445 printf("midi callback: %x, %i\n", controller, value);
446
447 switch(controller)
448 {
449 case MIDI_PROGRAM:
450 printf("midi program: %x, %i\n", controller, value);
451 synth->location = value;
452 /* loadMemory(synth, "obx", 0, synth->bank + synth->location, */
453 /* synth->mem.active, FIRST_DEV, 0); */
454 obxLoadMemory(synth, global.controlfd, synth->midichannel, 0, 0, 0);
455 break;
456 case MIDI_BANK_SELECT:
457 printf("midi banksel: %x, %i\n", controller, value);
458 synth->bank = value;
459 break;
460 }
461 return(0);
462 }
463
464 static int narrow = 0;
465 static int osc2 = 0;
466
467 static int
obxModCallback(brightonWindow * win,int panel,int index,float value)468 obxModCallback(brightonWindow *win, int panel, int index, float value)
469 {
470 guiSynth *synth = findSynth(global.synths, win);
471 int sendvalue;
472
473 /* printf("obxModCallback(%x, %i, %i, %f)\n", synth, panel, index, value); */
474
475 /*
476 * If this is controller 0 it is the frequency control, otherwise a
477 * generic controller 1.
478 */
479 switch (index) {
480 case 0:
481 if (narrow != 0)
482 sendvalue = C_RANGE_MIN_1 / 2 +
483 (int) (((value - 0.5) / 3) * C_RANGE_MIN_1);
484 else
485 sendvalue = (int) ((value * C_RANGE_MIN_1));
486 if (osc2 == 0)
487 bristolMidiSendMsg(global.controlfd, synth->sid, 0, 11,
488 sendvalue);
489 bristolMidiSendMsg(global.controlfd, synth->sid, 1, 11, sendvalue);
490 break;
491 case 1:
492 /*
493 * Not sure why this should work, and it probably doesn't. It is
494 * the 'mod' controller but appears to affect Osc-1 tranpose
495 */
496 if (narrow != 0)
497 /*sendvalue = (int) ((value * C_RANGE_MIN_1)) >> 3; */
498 sendvalue = C_RANGE_MIN_1 / 2 +
499 (int) (((value - 0.5) / 3) * C_RANGE_MIN_1);
500 else
501 sendvalue = (int) ((value * C_RANGE_MIN_1));
502 bristolMidiSendMsg(global.controlfd, synth->midichannel,
503 2, 0, sendvalue);
504 break;
505 case 2: /* Narrow */
506 if (value != 0.0)
507 narrow = 4;
508 else
509 narrow = 0;
510 break;
511 case 3: /* Osc2 */
512 /*
513 * This switch is a bit of a pain, it controls whether Osc-2 is
514 * affected by the pitchbend. This means we have to use another
515 * modulation method for case 0 above since the existing method
516 * is global. This is painful as it means we need another param
517 * on the prophetdco.....
518 * May remap the button for single/multi LFO?
519 bristolMidiSendMsg(global.controlfd, synth->sid,
520 126, 22, (int) value);
521 */
522 osc2 = value;
523 break;
524 case 4: /* Transpose */
525 if (value != 0.0)
526 synth->transpose = 48;
527 else
528 synth->transpose = 36;
529 break;
530 }
531 return(0);
532 }
533
534 #define KEY_HOLD (FIRST_DEV + 43)
535
536 static void
obxHold(guiSynth * synth)537 obxHold(guiSynth *synth)
538 {
539 if ((synth->flags & OPERATIONAL) == 0)
540 return;
541
542 /*printf("obxHold %x\n", synth); */
543
544 if (synth->mem.param[KEY_HOLD])
545 bristolMidiSendMsg(global.controlfd, synth->sid,
546 127, 0, BRISTOL_HOLD|1);
547 else
548 bristolMidiSendMsg(global.controlfd, synth->sid,
549 127, 0, BRISTOL_HOLD|0);
550 }
551
552 static int dreset = 0;
553 static int d1 = 0;
554 static int d2 = 0;
555
556 /*
557 * If controller #41 has value zero then we configure the release rates, else
558 * we use the shortest release rate.
559 */
560 static void
obxDecay(void * synth,int fd,int chan,int c,int o,int v)561 obxDecay(void *synth, int fd, int chan, int c, int o, int v)
562 {
563 if (c == 41)
564 {
565 if (v == 0)
566 {
567 /*
568 * Set values to their current settings
569 */
570 dreset = 0;
571 bristolMidiSendMsg(fd, chan, 3, 3, d1);
572 bristolMidiSendMsg(fd, chan, 5, 3, d2);
573 } else {
574 /*
575 * Set values to minimum release time
576 */
577 dreset = 1;
578 bristolMidiSendMsg(fd, chan, 3, 3, 20);
579 bristolMidiSendMsg(fd, chan, 5, 3, 20);
580 }
581 } else {
582 if (dreset == 0)
583 bristolMidiSendMsg(fd, chan, c, o, v);
584
585 if (c == 3)
586 d1 = v;
587 else
588 d2 = v;
589 }
590 }
591
592 static int pwSelect = 0;
593 /*
594 * We need to see if for any given oscillator none of the wave buttons are
595 * selected. If this is the case then select triangle. Else disable tri and
596 * configure the selected values.
597 */
598 static void
obxWaveform(guiSynth * synth,int fd,int chan,int c,int o,int v)599 obxWaveform(guiSynth *synth, int fd, int chan, int c, int o, int v)
600 {
601 /*
602 * See if this is the PW parameter.
603 */
604 if (c == 15)
605 {
606 if (synth->flags & MEM_LOADING)
607 return;
608 synth->mem.param[15] = v;
609 if (pwSelect == 0) {
610 bristolMidiSendMsg(fd, chan, 0, 0, v);
611 } else {
612 synth->mem.param[ACTIVE_DEVS - 1] = v;
613 bristolMidiSendMsg(fd, chan, 1, 0, v);
614 }
615 return;
616 }
617
618 /*
619 * See if we need to set PW selector
620 */
621 if (o == 6)
622 {
623 /*
624 * If the sqr is being selected, then PW will modify this oscillator,
625 * and if going off then it will cotrol the other
626 */
627 if (v != 0)
628 pwSelect = c;
629 else
630 pwSelect = 1 - c;
631 }
632
633 /*
634 * If the value is '1' we can just set the desired wave and disable tri.
635 */
636 if (v != 0)
637 {
638 bristolMidiSendMsg(fd, chan, c, o, v);
639 bristolMidiSendMsg(fd, chan, c, 5, 0);
640 } else {
641 bristolMidiSendMsg(fd, chan, c, o, v);
642 if (c == 0)
643 {
644 if ((synth->mem.param[17] == 0) &&
645 (synth->mem.param[18] == 0))
646 bristolMidiSendMsg(fd, chan, c, 5, 1);
647 } else {
648 if ((synth->mem.param[21] == 0) &&
649 (synth->mem.param[22] == 0))
650 bristolMidiSendMsg(fd, chan, c, 5, 1);
651 }
652 }
653 }
654
655 static int
obxMidiSendMsg(void * synth,int fd,int chan,int c,int o,int v)656 obxMidiSendMsg(void *synth, int fd, int chan, int c, int o, int v)
657 {
658 bristolMidiSendMsg(fd, chan, c, o, v);
659 return(0);
660 }
661
662 static void
multiTune(guiSynth * synth,int fd,int chan,int c,int o,int v)663 multiTune(guiSynth *synth, int fd, int chan, int c, int o, int v)
664 {
665 brightonEvent event;
666
667 if (synth->flags & MEM_LOADING)
668 return;
669
670 /*
671 * Configures all the tune settings to zero (ie, 0.5).
672 * We have master tune, id 44 and Osc-2 detune, id 2.
673 */
674 event.type = BRIGHTON_FLOAT;
675 event.value = 0.5;
676 brightonParamChange(synth->win, synth->panel, FIRST_DEV + 2,
677 &event);
678 brightonParamChange(synth->win, synth->panel, FIRST_DEV + 44,
679 &event);
680 }
681
682 /*
683 * The OB-X does not have a lot of memories, just 8 banks of 8 memories. This
684 * is a bit sparse for the emulater but it keeps the interface easy. Will be
685 * two sets of buttons, one for the bank, one for the index, then load and
686 * save. Load and Save will be intermittent and the banks radio buttons.
687 */
688 static void
obxMemory(guiSynth * synth,int fd,int chan,int c,int o,int v)689 obxMemory(guiSynth *synth, int fd, int chan, int c, int o, int v)
690 {
691 brightonEvent event;
692
693 /*printf("obxMemory(%i, %i, %i, %i)\n", chan, c, o, v); */
694
695 switch (c) {
696 case 16:
697 /* Load */
698 /*
699 synth->flags |= MEM_LOADING;
700 loadMemory(synth, "obx", 0, synth->bank * 10 + synth->location,
701 synth->mem.active, FIRST_DEV, 0);
702 * We now need to force the PW of the two oscillators?
703 bristolMidiSendMsg(fd, chan, 0, 0,
704 (int) synth->mem.param[15]);
705 bristolMidiSendMsg(fd, chan, 1, 0,
706 (int) synth->mem.param[ACTIVE_DEVS-1]);
707
708 event.value = 0;
709 brightonParamChange(synth->win, 0, ACTIVE_DEVS-1, &event);
710
711 synth->flags &= ~MEM_LOADING;
712 */
713 obxLoadMemory(synth, fd, chan, c, o, v);
714 break;
715 case 17:
716 /* Save */
717 saveMemory(synth, "obx", 0, synth->bank * 10 + synth->location, 0);
718 break;
719 case 0:
720 case 1:
721 case 2:
722 case 3:
723 case 4:
724 case 5:
725 case 6:
726 case 7:
727 if (synth->dispatch[RADIOSET_1].other2)
728 {
729 synth->dispatch[RADIOSET_1].other2 = 0;
730 return;
731 }
732
733 if (synth->dispatch[RADIOSET_1].other1 != -1)
734 {
735 synth->dispatch[RADIOSET_1].other2 = 1;
736
737 if (synth->dispatch[RADIOSET_1].other1 != o)
738 event.value = 0;
739 else
740 event.value = 1;
741
742 brightonParamChange(synth->win, synth->panel,
743 synth->dispatch[RADIOSET_1].other1, &event);
744 }
745 synth->dispatch[RADIOSET_1].other1 = o;
746
747 synth->bank = c + 1;
748
749 break;
750 case 8:
751 case 9:
752 case 10:
753 case 11:
754 case 12:
755 case 13:
756 case 14:
757 case 15:
758 if (synth->dispatch[RADIOSET_2].other2)
759 {
760 synth->dispatch[RADIOSET_2].other2 = 0;
761 return;
762 }
763
764 if (synth->dispatch[RADIOSET_2].other1 != -1)
765 {
766 synth->dispatch[RADIOSET_2].other2 = 1;
767
768 if (synth->dispatch[RADIOSET_2].other1 != o)
769 event.value = 0;
770 else
771 event.value = 1;
772
773 brightonParamChange(synth->win, synth->panel,
774 synth->dispatch[RADIOSET_2].other1, &event);
775 }
776 synth->dispatch[RADIOSET_2].other1 = o;
777
778 synth->location = c - 7;
779
780 break;
781 }
782
783 /*printf(" obxMemory(B: %i, L: %i, %i, %i)\n", */
784 /*synth->bank, synth->location, synth->bank * 8 + synth->location, o); */
785 }
786
787 static void
obxMidi(guiSynth * synth,int fd,int chan,int c,int o,int v)788 obxMidi(guiSynth *synth, int fd, int chan, int c, int o, int v)
789 {
790 int newchan;
791
792 if ((synth->flags & OPERATIONAL) == 0)
793 return;
794
795 if (c == 1) {
796 if ((newchan = synth->midichannel - 1) < 0)
797 {
798 synth->midichannel = 0;
799 return;
800 }
801 } else {
802 if ((newchan = synth->midichannel + 1) >= 16)
803 {
804 synth->midichannel = 15;
805 return;
806 }
807 }
808
809 if (global.libtest == 0)
810 {
811 bristolMidiSendMsg(global.controlfd, synth->sid,
812 127, 0, BRISTOL_MIDICHANNEL|newchan);
813 }
814
815 synth->midichannel = newchan;
816 }
817
818 /*
819 * For the sake of ease of use, links have been placed here to be called
820 * by any of the devices created. They would be better in some other file,
821 * perhaps with this as a dispatch.
822 *
823 * Param refers to the device index in the locations table given below.
824 */
825 static int
obxCallback(brightonWindow * win,int panel,int index,float value)826 obxCallback(brightonWindow *win, int panel, int index, float value)
827 {
828 guiSynth *synth = findSynth(global.synths, win);
829 int sendvalue;
830
831 /* printf("obxCallback(%i, %f): %x\n", index, value, synth); */
832
833 if (synth == 0)
834 return(0);
835
836 if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0))
837 return(0);
838
839 if (obxApp.resources[0].devlocn[index].to == 1.0)
840 sendvalue = value * C_RANGE_MIN_1;
841 else
842 sendvalue = value;
843
844 synth->mem.param[index] = value;
845
846 if ((!global.libtest) || (index >= ACTIVE_DEVS))
847 synth->dispatch[index].routine(synth,
848 global.controlfd, synth->sid,
849 synth->dispatch[index].controller,
850 synth->dispatch[index].operator,
851 sendvalue);
852
853 #ifdef DEBUG
854 else
855 printf("dispatch[%x,%i](%i, %i, %i, %i, %i)\n", synth, index,
856 global.controlfd, synth->sid,
857 synth->dispatch[index].controller,
858 synth->dispatch[index].operator,
859 sendvalue);
860 #endif
861
862 return(0);
863 }
864
865 /*
866 * Any location initialisation required to run the callbacks. For bristol, this
867 * will connect to the engine, and give it some base parameters.
868 * May need to generate some application specific menus.
869 * Will also then make specific requests to some of the devices to alter their
870 * rendering.
871 */
872 static int
obxInit(brightonWindow * win)873 obxInit(brightonWindow *win)
874 {
875 guiSynth *synth = findSynth(global.synths, win);
876 dispatcher *dispatch;
877 int i;
878
879 if (synth == 0)
880 {
881 synth = findSynth(global.synths, 0);
882 if (synth == 0)
883 {
884 printf("cannot init\n");
885 return(0);
886 }
887 }
888
889 if ((initmem = synth->location) == 0)
890 initmem = 11;
891
892 synth->win = win;
893
894 printf("Initialise the obx link to bristol: %p\n", synth->win);
895
896 synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float));
897 synth->mem.count = DEVICE_COUNT;
898 synth->mem.active = ACTIVE_DEVS;
899 synth->dispatch = (dispatcher *)
900 brightonmalloc(DEVICE_COUNT * sizeof(dispatcher));
901 dispatch = synth->dispatch;
902
903 /*
904 * We really want to have three connection mechanisms. These should be
905 * 1. Unix named sockets.
906 * 2. UDP sockets.
907 * 3. MIDI pipe.
908 */
909 if (!global.libtest)
910 {
911 if ((synth->sid = initConnection(&global, synth)) < 0)
912 return(-1);
913 }
914
915 for (i = 0; i < DEVICE_COUNT; i++)
916 synth->dispatch[i].routine = obxMidiSendMsg;
917
918 /* Glide and Unison, done */
919 dispatch[FIRST_DEV].controller = 126;
920 dispatch[FIRST_DEV].operator = 0;
921 dispatch[FIRST_DEV + 1].controller = 126;
922 dispatch[FIRST_DEV + 1].operator = 1;
923 dispatch[FIRST_DEV + 2].controller = 1;
924 dispatch[FIRST_DEV + 2].operator = 10;
925
926 /* LFO - operator 2 parameters - Done */
927 dispatch[FIRST_DEV + 3].controller = 2;
928 dispatch[FIRST_DEV + 3].operator = 0;
929 dispatch[FIRST_DEV + 4].controller = 126;
930 dispatch[FIRST_DEV + 4].operator = 19;
931 dispatch[FIRST_DEV + 5].controller = 126;
932 dispatch[FIRST_DEV + 5].operator = 20;
933 /* S/H - this should be a routing switch. */
934 dispatch[FIRST_DEV + 6].controller = 126;
935 dispatch[FIRST_DEV + 6].operator = 21;
936
937 /* Depth Osc/Osc/Filt - routing control/switches */
938 dispatch[FIRST_DEV + 7].controller = 126;
939 dispatch[FIRST_DEV + 7].operator = 4;
940 dispatch[FIRST_DEV + 8].controller = 126;
941 dispatch[FIRST_DEV + 8].operator = 5;
942 dispatch[FIRST_DEV + 9].controller = 126;
943 dispatch[FIRST_DEV + 9].operator = 6;
944 dispatch[FIRST_DEV + 10].controller = 126;
945 dispatch[FIRST_DEV + 10].operator = 7;
946
947 /* PWM Osc/Osc - routing control/switches */
948 dispatch[FIRST_DEV + 11].controller = 126;
949 dispatch[FIRST_DEV + 11].operator = 8;
950 dispatch[FIRST_DEV + 12].controller = 126;
951 dispatch[FIRST_DEV + 12].operator = 9;
952 dispatch[FIRST_DEV + 13].controller = 126;
953 dispatch[FIRST_DEV + 13].operator = 10;
954
955 /* Osc - Some routing switches. */
956 dispatch[FIRST_DEV + 14].controller = 0;
957 dispatch[FIRST_DEV + 14].operator = 1;
958 /* PWM - needs to adjust both oscillators, so need a dispatcher. */
959 dispatch[FIRST_DEV + 15].controller = 15;
960 dispatch[FIRST_DEV + 15].operator = 1;
961 dispatch[FIRST_DEV + 16].controller = 1;
962 dispatch[FIRST_DEV + 16].operator = 9;
963 /* Saw/Square. May need dispatch for tri when both off */
964 dispatch[FIRST_DEV + 17].controller = 0;
965 dispatch[FIRST_DEV + 17].operator = 4;
966 dispatch[FIRST_DEV + 18].controller = 0;
967 dispatch[FIRST_DEV + 18].operator = 6;
968 /* Crossmod and sync - routing switches */
969 dispatch[FIRST_DEV + 19].controller = 126;
970 dispatch[FIRST_DEV + 19].operator = 11;
971 dispatch[FIRST_DEV + 20].controller = 1;
972 dispatch[FIRST_DEV + 20].operator = 7;
973 /* Saw/Square. May need dispatch for tri when both off */
974 dispatch[FIRST_DEV + 21].controller = 1;
975 dispatch[FIRST_DEV + 21].operator = 4;
976 dispatch[FIRST_DEV + 22].controller = 1;
977 dispatch[FIRST_DEV + 22].operator = 6;
978 /* Osc waveforms need a dispatcher to enable tri with both buttons off. */
979 dispatch[FIRST_DEV + 15].routine =
980 dispatch[FIRST_DEV + 17].routine =
981 dispatch[FIRST_DEV + 18].routine =
982 dispatch[FIRST_DEV + 21].routine =
983 dispatch[FIRST_DEV + 22].routine =
984 (synthRoutine) obxWaveform;
985
986 /* Filter - some routing switches */
987 dispatch[FIRST_DEV + 23].controller = 4;
988 dispatch[FIRST_DEV + 23].operator = 0;
989 dispatch[FIRST_DEV + 24].controller = 4;
990 dispatch[FIRST_DEV + 24].operator = 1;
991 dispatch[FIRST_DEV + 25].controller = 4;
992 dispatch[FIRST_DEV + 25].operator = 2;
993 /* Routing switches. Need to check on KBD tracking though */
994 dispatch[FIRST_DEV + 26].controller = 126;
995 dispatch[FIRST_DEV + 26].operator = 12;
996 dispatch[FIRST_DEV + 27].controller = 4;
997 dispatch[FIRST_DEV + 27].operator = 3;
998 dispatch[FIRST_DEV + 28].controller = 126;
999 dispatch[FIRST_DEV + 28].operator = 14;
1000 dispatch[FIRST_DEV + 29].controller = 126;
1001 dispatch[FIRST_DEV + 29].operator = 15;
1002 dispatch[FIRST_DEV + 30].controller = 126;
1003 dispatch[FIRST_DEV + 30].operator = 16;
1004 dispatch[FIRST_DEV + 31].controller = 126;
1005 dispatch[FIRST_DEV + 31].operator = 17;
1006
1007 /* Envelopes */
1008 dispatch[FIRST_DEV + 32].controller = 3;
1009 dispatch[FIRST_DEV + 32].operator = 0;
1010 dispatch[FIRST_DEV + 33].controller = 3;
1011 dispatch[FIRST_DEV + 33].operator = 1;
1012 dispatch[FIRST_DEV + 34].controller = 3;
1013 dispatch[FIRST_DEV + 34].operator = 2;
1014 dispatch[FIRST_DEV + 35].controller = 3;
1015 dispatch[FIRST_DEV + 35].operator = 3;
1016 dispatch[FIRST_DEV + 36].controller = 5;
1017 dispatch[FIRST_DEV + 36].operator = 0;
1018 dispatch[FIRST_DEV + 37].controller = 5;
1019 dispatch[FIRST_DEV + 37].operator = 1;
1020 dispatch[FIRST_DEV + 38].controller = 5;
1021 dispatch[FIRST_DEV + 38].operator = 2;
1022 dispatch[FIRST_DEV + 39].controller = 5;
1023 dispatch[FIRST_DEV + 39].operator = 3;
1024 /* We need a separate dispatcher for the decay, since the reset button */
1025 /* will affect the value. */
1026 dispatch[FIRST_DEV + 35].routine =
1027 dispatch[FIRST_DEV + 39].routine =
1028 (synthRoutine) obxDecay;
1029
1030 /* Master volume - gain of envelope? */
1031 dispatch[FIRST_DEV + 40].controller = 5;
1032 dispatch[FIRST_DEV + 40].operator = 4;
1033 /* Reset of 'release' DONE */
1034 dispatch[FIRST_DEV + 41].controller = 41;
1035 dispatch[FIRST_DEV + 41].operator = 0;
1036 dispatch[FIRST_DEV + 41].routine =
1037 (synthRoutine) obxDecay;
1038 /* Autotune */
1039 dispatch[FIRST_DEV + 42].routine = (synthRoutine) multiTune;
1040 /* Hold - DONE (stole from Juno.....) */
1041 dispatch[FIRST_DEV + 43].routine = (synthRoutine) obxHold;
1042 /* Master tune - Done. */
1043 dispatch[FIRST_DEV + 44].controller = 126;
1044 dispatch[FIRST_DEV + 44].operator = 2;
1045
1046 /* Memories. */
1047 dispatch[MEM_START + 0].controller = 16;
1048 dispatch[MEM_START + 1].controller = 0;
1049 dispatch[MEM_START + 2].controller = 1;
1050 dispatch[MEM_START + 3].controller = 2;
1051 dispatch[MEM_START + 4].controller = 3;
1052 dispatch[MEM_START + 5].controller = 4;
1053 dispatch[MEM_START + 6].controller = 5;
1054 dispatch[MEM_START + 7].controller = 6;
1055 dispatch[MEM_START + 8].controller = 7;
1056 dispatch[MEM_START + 9].controller = 8;
1057 dispatch[MEM_START + 10].controller = 9;
1058 dispatch[MEM_START + 11].controller = 10;
1059 dispatch[MEM_START + 12].controller = 11;
1060 dispatch[MEM_START + 13].controller = 12;
1061 dispatch[MEM_START + 14].controller = 13;
1062 dispatch[MEM_START + 15].controller = 14;
1063 dispatch[MEM_START + 16].controller = 15;
1064 dispatch[MEM_START + 17].controller = 17;
1065
1066 dispatch[MEM_START + 0].operator = MEM_START + 0;
1067 dispatch[MEM_START + 1].operator = MEM_START + 1;
1068 dispatch[MEM_START + 2].operator = MEM_START + 2;
1069 dispatch[MEM_START + 3].operator = MEM_START + 3;
1070 dispatch[MEM_START + 4].operator = MEM_START + 4;
1071 dispatch[MEM_START + 5].operator = MEM_START + 5;
1072 dispatch[MEM_START + 6].operator = MEM_START + 6;
1073 dispatch[MEM_START + 7].operator = MEM_START + 7;
1074 dispatch[MEM_START + 8].operator = MEM_START + 8;
1075 dispatch[MEM_START + 9].operator = MEM_START + 9;
1076 dispatch[MEM_START + 10].operator = MEM_START + 10;
1077 dispatch[MEM_START + 11].operator = MEM_START + 11;
1078 dispatch[MEM_START + 12].operator = MEM_START + 12;
1079 dispatch[MEM_START + 13].operator = MEM_START + 13;
1080 dispatch[MEM_START + 14].operator = MEM_START + 14;
1081 dispatch[MEM_START + 15].operator = MEM_START + 15;
1082 dispatch[MEM_START + 16].operator = MEM_START + 16;
1083 dispatch[MEM_START + 17].operator = MEM_START + 17;
1084
1085 dispatch[MEM_START + 0].routine =
1086 dispatch[MEM_START + 1].routine =
1087 dispatch[MEM_START + 2].routine =
1088 dispatch[MEM_START + 3].routine =
1089 dispatch[MEM_START + 4].routine =
1090 dispatch[MEM_START + 5].routine =
1091 dispatch[MEM_START + 6].routine =
1092 dispatch[MEM_START + 7].routine =
1093 dispatch[MEM_START + 8].routine =
1094 dispatch[MEM_START + 9].routine =
1095 dispatch[MEM_START + 10].routine =
1096 dispatch[MEM_START + 11].routine =
1097 dispatch[MEM_START + 12].routine =
1098 dispatch[MEM_START + 13].routine =
1099 dispatch[MEM_START + 14].routine =
1100 dispatch[MEM_START + 15].routine =
1101 dispatch[MEM_START + 16].routine =
1102 dispatch[MEM_START + 17].routine =
1103 (synthRoutine) obxMemory;
1104
1105 dispatch[FIRST_DEV + 63].routine = dispatch[FIRST_DEV + 64].routine =
1106 (synthRoutine) obxMidi;
1107 dispatch[FIRST_DEV + 63].controller = 1;
1108 dispatch[FIRST_DEV + 64].controller = 2;
1109
1110 dispatch[RADIOSET_1].other1 = -1;
1111 dispatch[RADIOSET_2].other1 = -1;
1112
1113 /* Tune/Gain osc-1/2 */
1114 bristolMidiSendMsg(global.controlfd, synth->sid, 0, 2, 8192);
1115 bristolMidiSendMsg(global.controlfd, synth->sid, 1, 2, 8192);
1116 bristolMidiSendMsg(global.controlfd, synth->sid, 0, 3, C_RANGE_MIN_1);
1117 bristolMidiSendMsg(global.controlfd, synth->sid, 1, 3, C_RANGE_MIN_1);
1118 /* Gain on filter contour */
1119 bristolMidiSendMsg(global.controlfd, synth->sid, 3, 4, C_RANGE_MIN_1);
1120 /* Select alt filter and pole remix */
1121 bristolMidiSendMsg(global.controlfd, synth->sid, 4, 4, 4);
1122 bristolMidiSendMsg(global.controlfd, synth->sid, 4, 7, 4096);
1123
1124 return(0);
1125 }
1126
1127 /*
1128 * This will be called to make any routine specific parameters available.
1129 */
1130 static int
obxConfigure(brightonWindow * win)1131 obxConfigure(brightonWindow *win)
1132 {
1133 guiSynth *synth = findSynth(global.synths, win);
1134 brightonEvent event;
1135
1136 if (synth == 0)
1137 {
1138 printf("problems going operational\n");
1139 return(-1);
1140 }
1141
1142 if (synth->flags & OPERATIONAL)
1143 return(0);
1144
1145 printf("going operational\n");
1146
1147 synth->flags |= OPERATIONAL;
1148 synth->keypanel = 1;
1149 synth->keypanel2 = -1;
1150 synth->transpose = 36;
1151
1152 synth->bank = 0;
1153 /* Don't load a memory, send a bank, location and load request. */
1154 event.intvalue = 1;
1155 brightonParamChange(synth->win, synth->panel,
1156 MEM_START + 1, &event);
1157 brightonParamChange(synth->win, synth->panel,
1158 MEM_START + 9, &event);
1159
1160 multiTune(synth, 0,0,0,0,0);
1161
1162 /* loadMemory(synth, "obx", 0, 0, synth->mem.active, FIRST_DEV, 0); */
1163 obxLoadMemory(synth, global.controlfd, synth->midichannel, 0, initmem, 0);
1164
1165 brightonPut(win,
1166 "bitmaps/blueprints/obxshade.xpm", 0, 0, win->width, win->height);
1167
1168 /*
1169 * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only
1170 * occurs on first paint, so we suppress the first paint, and then request
1171 * an expose here.
1172 */
1173 event.type = BRIGHTON_EXPOSE;
1174 event.intvalue = 1;
1175 brightonParamChange(synth->win, KEY_PANEL, -1, &event);
1176 configureGlobals(synth);
1177
1178 synth->loadMemory = (loadRoutine) obxKeyLoadMemory;
1179
1180 return(0);
1181 }
1182
1183