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 "bristol.h"
27 #include "bristolmidi.h"
28 #include "brightonMini.h"
29 #include "brightoninternals.h"
30 
31 static int initmem;
32 
33 extern void *brightonmalloc();
34 
35 static int splitPoint = -1, width = 0;
36 
37 static int obxaInit();
38 static int obxaConfigure();
39 static int obxaCallback(brightonWindow *, int, int, float);
40 static int obxaModCallback(brightonWindow *, int, int, float);
41 static int obxaKeyCallback(brightonWindow *, int, int, float);
42 static void obxaCopyLayer(guiSynth *);
43 static int obxaMidiCallback(brightonWindow *, int, int, float);
44 static void obxaSetMode(guiSynth *);
45 
46 static int seqLearn = 0, chordLearn = 0;
47 
48 extern guimain global;
49 /*
50  * These have to be integrated into the synth private structures, since we may
51  * have multiple invocations of any given synth.
52  */
53 static guimain manual;
54 
55 #include "brightonKeys.h"
56 
57 #define FIRST_DEV 0
58 #define DEVICE_COUNT 80
59 #define ACTIVE_DEVS 45
60 #define OBX_DEVS 50 /* Have to account for the manual options. */
61 #define MEM_START (OBX_DEVS)
62 #define MIDI_START (MEM_START + 18)
63 #define MOD_START (DEVICE_COUNT + ACTIVE_DEVS)
64 #define RADIOSET_1 MEM_START
65 #define RADIOSET_2 (MEM_START + 1)
66 #define RADIOSET_3 (MEM_START + 2)
67 /* Transpose radio set */
68 #define RADIOSET_4 (MOD_START + 10)
69 
70 #define FUNCTION 71
71 #define HOLD_KEY 48
72 #define SEQ_MODE 72
73 #define SEQ_SEL (72 + 3)
74 #define OCTAVE_MODE (72 + 4)
75 
76 #define LAYER_SWITCH 70
77 
78 #define KEY_PANEL 1
79 
80 /*
81  * This structure is for device definition. The structure is defined in
82  * include/brighton.h, further definitions in brighton/brightonDevtable.h and
83  * include/brightoninternals.h
84  *
85  *	typedef int (*brightonCallback)(int, float);
86  *	typedef struct BrightonLocations {
87  *		int device; 0=rotary, 1=scale, etc.
88  *		float relx, rely; relative position with regards to 1000 by 1000 window
89  *		float relw, relh; relative height.
90  *		int from, to;
91  *		brightonCallback callback; specific to this dev
92  *		char *image; bitmap. If zero take a device default.
93  *		int flags;
94  *	} brightonLocations;
95  *
96  * This example is for a obxaBristol type synth interface.
97  */
98 #define S1 110
99 #define S2 17
100 #define S3 70
101 
102 #define BO 10
103 #define B2 6
104 
105 #define R1 200
106 #define R2 440
107 #define R2a 315
108 #define R3 625
109 #define R3b 600
110 #define R3c 470
111 #define R4 805
112 
113 #define C1 30
114 #define C2 56
115 #define C3 100
116 
117 #define C4 175
118 
119 #define C5 242
120 #define C6 300
121 #define C7 354
122 
123 #define C8 415
124 #define C9 475
125 #define C10 535
126 
127 #define C11 590
128 #define C12 650
129 #define C13 710
130 
131 #define C11b 750
132 #define C12b 800
133 #define C13b 850
134 
135 #define C14 775
136 #define C15 825
137 #define C16 875
138 #define C17 925
139 
140 /* memories */
141 #define MD 18
142 #define C20 (C10 + MD + MD/2)
143 #define C21 (C20 + MD)
144 #define C22 (C21 + MD)
145 #define C23 (C22 + MD)
146 #define C24 (C23 + MD)
147 #define C25 (C24 + MD)
148 #define C26 (C25 + MD)
149 #define C27 (C26 + MD)
150 
151 #define C28 (C27 + MD + MD/2)
152 #define C29 (C28 + MD)
153 #define C30 (C29 + MD)
154 #define C31 (C30 + MD)
155 #define C32 (C31 + MD)
156 #define C33 (C32 + MD)
157 #define C34 (C33 + MD)
158 #define C35 (C34 + MD)
159 
160 #define C36 (C35 + MD + MD/2)
161 
162 #define C1a (29)
163 #define C2a (C1a + 29)
164 #define C3a (C2a + 29)
165 #define C4a (C3a + 29)
166 
167 static brightonLocations locations[DEVICE_COUNT] = {
168 /* 0 Control */
169 	{"Glide", 0, C4, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm",
170 		"bitmaps/knobs/alpharotary.xpm", 0},
171 	{"Unison", 2, C4 + B2, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
172 		"bitmaps/buttons/presson.xpm", 0},
173 	{"Osc2-Detune", 0, C4, R3b, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm",
174 		"bitmaps/knobs/alpharotary.xpm", 0},
175 /* 3 Modulation */
176 	{"LFO-Rate", 0, C5, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm",
177 		"bitmaps/knobs/alpharotary.xpm", 0},
178 	{"LFO-Sine", 2, C5 + B2, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
179 		"bitmaps/buttons/presson.xpm", 0},
180 	{"LFO-Square", 2, C5 + B2, R3, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
181 		"bitmaps/buttons/presson.xpm", 0},
182 	{"LFO-S/H", 2, C5 + B2, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
183 		"bitmaps/buttons/presson.xpm", 0},
184 
185 	{"Mod-FM-Gain", 0, C6, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm",
186 		"bitmaps/knobs/alpharotary.xpm", 0},
187 	{"Mod-FM-Osc1", 2, C6 + B2, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
188 		"bitmaps/buttons/presson.xpm", 0},
189 	{"Mod-FM-Osc2", 2, C6 + B2, R3, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
190 		"bitmaps/buttons/presson.xpm", 0},
191 	{"Mod-FM-Filt", 2, C6 + B2, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
192 		"bitmaps/buttons/presson.xpm", 0},
193 
194 	{"Mod-PWM-Gain", 0, C7, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm",
195 		"bitmaps/knobs/alpharotary.xpm", 0},
196 	{"Mod-PWM-Osc1", 2, C7 + B2, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
197 		"bitmaps/buttons/presson.xpm", 0},
198 	{"Mod-PWM-Osc2", 2, C7 + B2, R3, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
199 		"bitmaps/buttons/presson.xpm", 0},
200 /* 14 Oscillators */
201 	{"Osc1-Transpose", 0, C8, R1, S1, S1, 0, 5, 0, "bitmaps/knobs/knob5.xpm",
202 		"bitmaps/knobs/alpharotary.xpm", 0},
203 	{"Osc-PW-CLI!", 0, C9, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm",
204 		"bitmaps/knobs/alpharotary.xpm", 0},
205 	{"Osc2-Frequency", 0, C10, R1, S1, S1, 0, 47, 0, "bitmaps/knobs/knob5.xpm",
206 		"bitmaps/knobs/alpharotary.xpm", 0},
207 	{"Osc1-Saw", 2, C8 - 8, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
208 		"bitmaps/buttons/presson.xpm", 0},
209 	{"Osc1-Pulse", 2, C8 + 17, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
210 		"bitmaps/buttons/presson.xpm", 0},
211 	{"Osc1-Env", 2, C9 - 8, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
212 		"bitmaps/buttons/presson.xpm", 0},
213 	{"Osc1-2-Sync", 2, C9 + 17, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
214 		"bitmaps/buttons/presson.xpm", 0},
215 	{"Osc2-Saw", 2, C10 - 8, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
216 		"bitmaps/buttons/presson.xpm", 0},
217 	{"Osc2-Pulse", 2, C10 + 17, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
218 		"bitmaps/buttons/presson.xpm", 0},
219 /* 23 Filter */
220 	{"VCF-12/24", 2, C13 + 17, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
221 		"bitmaps/buttons/presson.xpm", 0},
222 	{"VCF-Cutoff", 0, C11, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm",
223 		"bitmaps/knobs/alpharotary.xpm", 0},
224 	{"VCF-Resonance", 0, C12, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm",
225 		"bitmaps/knobs/alpharotary.xpm", 0},
226 	{"VCF-Mod", 0, C13, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm",
227 		"bitmaps/knobs/alpharotary.xpm", 0},
228 	{"VCF-Mix-Osc1", 2, C11 - 8, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
229 		"bitmaps/buttons/presson.xpm", 0},
230 	{"VCF-KBD", 2, C11 + 17, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
231 		"bitmaps/buttons/presson.xpm", 0},
232 	{"VCF-Mix-O1-1", 2, C12 - 8, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
233 		"bitmaps/buttons/presson.xpm", 0},
234 	{"VCF-Mix-O1-2", 2, C12 + 17, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
235 		"bitmaps/buttons/presson.xpm", 0},
236 	{"VCF-Mix-Noise", 2, C13 - 8, R2, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
237 		"bitmaps/buttons/presson.xpm", 0},
238 /* 32 Envelopes */
239 	{"VCF-Attack", 0, C14, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm",
240 		"bitmaps/knobs/alpharotary.xpm", 0},
241 	{"VCF-Decay", 0, C15, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm",
242 		"bitmaps/knobs/alpharotary.xpm", 0},
243 	{"VCF-Sustain", 0, C16, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm",
244 		"bitmaps/knobs/alpharotary.xpm", 0},
245 	{"VCF-Release", 0, C17, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm",
246 		"bitmaps/knobs/alpharotary.xpm", 0},
247 
248 	{"VCA-Attack", 0, C14, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm",
249 		"bitmaps/knobs/alpharotary.xpm", 0},
250 	{"VCA-Decay", 0, C15, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm",
251 		"bitmaps/knobs/alpharotary.xpm", 0},
252 	{"VCA-Sustain", 0, C16, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm",
253 		"bitmaps/knobs/alpharotary.xpm", 0},
254 	{"VCA-Release", 0, C17, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm",
255 		"bitmaps/knobs/alpharotary.xpm", 0},
256 /* 40 Manual - vol, reset, balance */
257 	/* According to the original, these are not saved. Volume/balance will be. */
258 	{"MasterVolume", 0, C1, R1 - 100, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm",
259 		"bitmaps/knobs/alpharotary.xpm", 0},
260 	{"Reset", 2, C3 + BO, R2a, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
261 		"bitmaps/buttons/presson.xpm", 0},
262 	/* This is the Tremelo modifier */
263 	{"LFO-Mod-VCA", 2, C7 + B2, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
264 		"bitmaps/buttons/presson.xpm", 0},
265 	{"Balance", 0, C3, R1 - 100, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm",
266 		"bitmaps/knobs/alpharotary.xpm", 0},
267 	/* Master tune */
268 	{"Master-Tune", 0, C1, R3c, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm",
269 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_NOTCH},
270 /* 45 Poly, Split, Layer */
271 	{"Mode-Poly", 2, C8 - 8, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
272 		"bitmaps/buttons/presson.xpm", 0},
273 	{"Mode-Split", 2, C8 + 22, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
274 		"bitmaps/buttons/presson.xpm", 0},
275 	{"Mode-Layer", 2, C9 - 8, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
276 		"bitmaps/buttons/presson.xpm", 0},
277 /* 48 Hold/Auto - Up to now was 46 active devs */
278 	{"Hold", 2, C2 + BO * 3/2, R2a, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
279 		"bitmaps/buttons/presson.xpm", 0},
280 	/* AutoTune */
281 	{"", 2, C1, R2a, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
282 		"bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON},
283 /* 50 Programmer */
284 	{"", 2, C10, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
285 		"bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON},
286 
287 	{"", 2, C20, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
288 		"bitmaps/buttons/presson.xpm", 0},
289 	{"", 2, C21, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
290 		"bitmaps/buttons/presson.xpm", 0},
291 	{"", 2, C22, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
292 		"bitmaps/buttons/presson.xpm", 0},
293 	{"", 2, C23, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
294 		"bitmaps/buttons/presson.xpm", 0},
295 	{"", 2, C24, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
296 		"bitmaps/buttons/presson.xpm", 0},
297 	{"", 2, C25, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
298 		"bitmaps/buttons/presson.xpm", 0},
299 	{"", 2, C26, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
300 		"bitmaps/buttons/presson.xpm", 0},
301 	{"", 2, C27, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
302 		"bitmaps/buttons/presson.xpm", 0},
303 /* 59 */
304 	{"", 2, C28, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
305 		"bitmaps/buttons/presson.xpm", 0},
306 	{"", 2, C29, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
307 		"bitmaps/buttons/presson.xpm", 0},
308 	{"", 2, C30, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
309 		"bitmaps/buttons/presson.xpm", 0},
310 	{"", 2, C31, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
311 		"bitmaps/buttons/presson.xpm", 0},
312 	{"", 2, C32, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
313 		"bitmaps/buttons/presson.xpm", 0},
314 	{"", 2, C33, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
315 		"bitmaps/buttons/presson.xpm", 0},
316 	{"", 2, C34, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
317 		"bitmaps/buttons/presson.xpm", 0},
318 	{"", 2, C35, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
319 		"bitmaps/buttons/presson.xpm", 0},
320 
321 	{"", 2, C36, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
322 		"bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON},
323 
324 	{"", 2, C17 - 10, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
325 		"bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON},
326 	{"", 2, C17 + MD, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
327 		"bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON},
328 
329 	{"LayerSelect", 2, C9 + 20, R4, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
330 		"bitmaps/buttons/presson.xpm", 0},
331 
332 	/* Sequence and stuff - Fn, U, D, Hold - 71 */
333 	{"", 2, C1a, R4 - 110, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
334 		"bitmaps/buttons/presson.xpm", 0},
335 	{"", 2, C2a, R4 - 110, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
336 		"bitmaps/buttons/presson.xpm", 0},
337 	{"", 2, C3a, R4 - 110, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
338 		"bitmaps/buttons/presson.xpm", 0},
339 	{"", 2, C4a, R4 - 110, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
340 		"bitmaps/buttons/presson.xpm", 0},
341 
342 	/* SEQ and Octaves */
343 	{"", 2, C1a, R4 + 00, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
344 		"bitmaps/buttons/presson.xpm", 0},
345 	{"", 2, C2a, R4 + 00, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
346 		"bitmaps/buttons/presson.xpm", 0},
347 	{"", 2, C3a, R4 + 00, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
348 		"bitmaps/buttons/presson.xpm", 0},
349 	{"", 2, C4a, R4 + 00, S2, S3, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
350 		"bitmaps/buttons/presson.xpm", 0},
351 
352 	{"", 0, C3, R3c, S1, S1, 0, 1, 0, "bitmaps/knobs/knob5.xpm",
353 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_NOTCH},
354 };
355 
356 #define OB_MODCOUNT 14
357 static brightonLocations obxaMods[OB_MODCOUNT] = {
358 	{"", 0, 70, 100, 180, 180, 0, 1, 0, "bitmaps/knobs/knob5.xpm",
359 		"bitmaps/knobs/alpharotary.xpm", 0},
360 	{"", 2, 525, 100, 130, 140, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
361 		"bitmaps/buttons/presson.xpm", 0},
362 	{"", 2, 380, 100, 130, 140, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
363 		"bitmaps/buttons/presson.xpm", 0},
364 	{"", 0, 760, 100, 180, 180, 0, 1, 0, "bitmaps/knobs/knob5.xpm",
365 		"bitmaps/knobs/alpharotary.xpm", 0},
366 
367 	{"", 1, 385, 280, 100, 450, 0, 1, 0,
368 		"bitmaps/knobs/sliderblack.xpm", 0, BRIGHTON_CENTER},
369 	{"", 1, 520, 280, 100, 450, 0, 1, 0,
370 		"bitmaps/knobs/sliderblack.xpm", 0, 0},
371 
372 	{"", 2, 25, 750, 130, 140, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
373 		"bitmaps/buttons/presson.xpm", 0},
374 	{"", 2, 170, 750, 130, 140, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
375 		"bitmaps/buttons/presson.xpm", 0},
376 
377 	{"", 2, 380, 750, 130, 140, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
378 		"bitmaps/buttons/presson.xpm", 0},
379 	{"", 2, 525, 750, 130, 140, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
380 		"bitmaps/buttons/presson.xpm", 0},
381 
382 	{"", 2, 715, 750, 130, 140, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
383 		"bitmaps/buttons/presson.xpm", 0},
384 	{"", 2, 860, 750, 130, 140, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
385 		"bitmaps/buttons/presson.xpm", 0},
386 
387 	/* Multi LFO */
388 	{"", 2, 115, 465, 110, 130, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
389 		"bitmaps/buttons/pressong.xpm", 0},
390 	/* Layer copy functions */
391 	{"", 2, 800, 465, 110, 130, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
392 		"bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON},
393 };
394 
395 /*
396  * This is a set of globals for the main window rendering. Again taken from
397  * include/brighton.h
398  */
399 brightonApp obxaApp = {
400 	"obxa",
401 	0, /* no blueprint on wood background. */
402 	"bitmaps/textures/metal6.xpm",
403 	BRIGHTON_STRETCH, /*flags */
404 	obxaInit,
405 	obxaConfigure, /* 3 callbacks, unused? */
406 	obxaMidiCallback,
407 	destroySynth,
408 	{10, 100, 2, 2, 5, 520, 55, 0},
409 	770, 350, 0, 0,
410 	6, /* panel count */
411 	{
412 		{
413 			"OBXaPanel",
414 			"bitmaps/blueprints/obxa.xpm",
415 			"bitmaps/textures/metal4.xpm",
416 			BRIGHTON_STRETCH, /* flags */
417 			0,
418 			0,
419 			obxaCallback,
420 			15, 130, 970, 520,
421 			DEVICE_COUNT,
422 			locations
423 		},
424 		{
425 			"Keyboard",
426 			0,
427 			"bitmaps/newkeys/kbg.xpm", /* flags */
428 			0x020|BRIGHTON_STRETCH,
429 			0,
430 			0,
431 			obxaKeyCallback,
432 			155, 690, 854, 290,
433 			KEY_COUNT,
434 			keys
435 		},
436 		{
437 			"OBXaMods",
438 			"bitmaps/blueprints/obxamod.xpm",
439 			"bitmaps/textures/metal5.xpm", /* flags */
440 			0,
441 			0,
442 			0,
443 			obxaModCallback,
444 			17, 690, 136, 290,
445 			OB_MODCOUNT,
446 			obxaMods
447 		},
448 		{
449 			"Logo",
450 			"bitmaps/blueprints/obxalogo.xpm",
451 			0,
452 			BRIGHTON_STRETCH, /*flags */
453 			0,
454 			0,
455 			0,
456 			15, 0, 970, 130,
457 			0,
458 			0
459 		},
460 
461 		{
462 			"Wood",
463 			0,
464 			"bitmaps/textures/wood4.xpm",
465 			0, /* flags */
466 			0,
467 			0,
468 			0,
469 			0, 0, 15, 1000,
470 			0,
471 			0
472 		},
473 		{
474 			"Wood",
475 			0,
476 			"bitmaps/textures/wood4.xpm",
477 			0, /*flags */
478 			0,
479 			0,
480 			0,
481 			985, 0, 15, 1000,
482 			0,
483 			0
484 		},
485 	}
486 };
487 
488 static void
obxaPanelSwitch(guiSynth * synth,int dummy,int chan,int c,int o,int v)489 obxaPanelSwitch(guiSynth *synth, int dummy, int chan, int c, int o, int v)
490 {
491 	brightonEvent event;
492 	int i;
493 
494 /*printf("obxaPanelSwitch(%x, %i, %i, %i, %i, %1.0f)\n", */
495 /*synth, fd, chan, c, o, global.synths->mem.param[LAYER_SWITCH]); */
496 
497 	/*
498 	 * Prevent param changes when we are switching panels.
499 	 */
500 	synth->flags |= SUPPRESS;
501 
502 	/*
503 	 * Go through all the active devices, and force the GUI to represent
504 	 * the new value.
505 	 */
506 	if (synth->mem.param[LAYER_SWITCH] == 0)
507 	{
508 		/*
509 		 * Go through all the params, and request an update to the GUI
510 		 */
511 		for (i = 0; i < ACTIVE_DEVS; i++)
512 		{
513 			event.type = BRIGHTON_FLOAT;
514 			event.value = synth->mem.param[i] + 1;
515 			brightonParamChange(synth->win, 0, i, &event);
516 			event.value = synth->mem.param[i];
517 			brightonParamChange(synth->win, 0, i, &event);
518 		}
519 	} else {
520 		for (i = 0; i < ACTIVE_DEVS; i++)
521 		{
522 			event.type = BRIGHTON_FLOAT;
523 			/*
524 			event.value = ((guiSynth *) synth->second)->mem.param[i] + 1;
525 			brightonParamChange(synth->win, 0, i, &event);
526 			event.value = ((guiSynth *) synth->second)->mem.param[i];
527 			brightonParamChange(synth->win, 0, i, &event);
528 			 */
529 			event.value = synth->mem.param[DEVICE_COUNT + i] + 1;
530 			brightonParamChange(synth->win, 0, i, &event);
531 			event.value = synth->mem.param[DEVICE_COUNT + i];
532 			brightonParamChange(synth->win, 0, i, &event);
533 		}
534 	}
535 
536 	synth->flags &= ~SUPPRESS;
537 }
538 
539 /*
540  * We need our own load and save routines as these are non standard memories.
541  * Am going to use the normal 'loadMemory' to set most of the parameters for
542  * the second layer, then explicit read/write the second layer.
543  */
544 static void
obxaLoadMemory(guiSynth * synth,char * name,char * d,int loc,int o,int x,int y)545 obxaLoadMemory(guiSynth *synth, char *name, char *d,
546 int loc, int o, int x, int y)
547 {
548 	char path[256];
549 	int fd, i, pSel;
550 	brightonEvent event;
551 	float pw[4];
552 
553 	/*
554 	 * Memory loading should be a few phases. Firstly see which layer is visible
555 	 * and if it is not the first then display the first panel and load the mem.
556 	 * After that display the upper panel and load the next set of memories.
557 	 * Finally return to the original panel.
558 	 */
559 	if ((pSel = synth->mem.param[LAYER_SWITCH]) != 0)
560 	{
561 		synth->mem.param[LAYER_SWITCH] = 0;
562 		/*
563 		 * We should consider actually sending the button change action
564 		 */
565 		obxaPanelSwitch(synth, global.controlfd, synth->midichannel, 0, 0, 0);
566 	}
567 
568 	/*
569 	 * We cannot really use this due to the added complexity of the dual PW
570 	 * controller as it removes any relationship between the value of the dial
571 	 * and what it controls. We can do it with 'NOCALLS' though.
572 	 */
573 	loadMemory(synth, name, d, loc, o, x, BRISTOL_NOCALLS);
574 
575 	/*
576 	 * Save our PW
577 	 */
578 	pw[0] = synth->mem.param[15];
579 
580 	event.type = BRIGHTON_FLOAT;
581 	for (i = 0; i < synth->mem.active; i++)
582 	{
583 		event.value = synth->mem.param[i];
584 
585 		brightonParamChange(synth->win, 0, i, &event);
586 	}
587 
588 	/*
589 	 * Now we need to consider the second layer.
590 	 */
591 	if ((name != 0) && (name[0] == '/'))
592 	{
593 		sprintf(synth->mem.algo, "%s", name);
594 		sprintf(path, "%s", name);
595 	} else {
596 		sprintf(path, "%s/memory/%s/%s%i.mem",
597 			getBristolCache("midicontrollermap"), name, name, loc);
598 		sprintf(synth->mem.algo, "%s", name);
599 		if (name == NULL)
600 			sprintf(synth->mem.name, "no name");
601 		else
602 			sprintf(synth->mem.name, "%s", name);
603 	}
604 
605 	if ((fd = open(path, O_RDONLY, 0770)) < 0)
606 	{
607 		sprintf(path, "%s/memory/%s/%s%i.mem",
608 			global.home, name, name, loc);
609 
610 		if ((fd = open(path, O_RDONLY, 0770)) < 0)
611 		{
612 			synth->flags &= ~MEM_LOADING;
613 			return;
614 		}
615 	}
616 
617 	lseek(fd, DEVICE_COUNT * sizeof(float), SEEK_SET);
618 
619 	if (read(fd, &synth->mem.param[DEVICE_COUNT],
620 		DEVICE_COUNT * sizeof(float)) < 0)
621 		printf("read failed for 2nd layer\n");
622 
623 	close(fd);
624 
625 	pw[1] = synth->mem.param[MOD_START + OB_MODCOUNT + 3];
626 	pw[2] = synth->mem.param[DEVICE_COUNT + 15];
627 	pw[3] = synth->mem.param[MOD_START + OB_MODCOUNT + 4];
628 	/*
629 	 * The parameters for the second layer are now set, but we need to set up
630 	 * the upper layer.
631 	 */
632 printf("loading second layer: %s\n", path);
633 
634 	synth->mem.param[LAYER_SWITCH] = 1.0f;
635 	obxaPanelSwitch(synth, global.controlfd, synth->midichannel, 0, 0, 0);
636 
637 	/*
638 	 * We now have to call the GUI to configure all these values. The GUI
639 	 * will then call us back with the parameters to send to the synth.
640 	 */
641 	event.type = BRIGHTON_FLOAT;
642 	for (i = 0; i < synth->mem.active; i++)
643 	{
644 		event.value = synth->mem.param[DEVICE_COUNT + i];
645 
646 		brightonParamChange(synth->win, 0, i, &event);
647 	}
648 
649 	synth->flags &= ~MEM_LOADING;
650 
651 	synth->mem.param[LAYER_SWITCH] = pSel;
652 
653 	obxaPanelSwitch(synth, global.controlfd, synth->midichannel, 0, 0, 0);
654 
655 	/*
656 	 * At this point we have to have a good look at the poly/split/layer
657 	 * selection, and force it to the correct value.
658 	 * The fix is to send an event to set the button state.....
659 	 */
660 	event.value = 1.0;
661 	if (synth->mem.param[MOD_START + OB_MODCOUNT + 0])
662 		brightonParamChange(synth->win, synth->panel, 45, &event);
663 	else if (synth->mem.param[MOD_START + OB_MODCOUNT + 1]) {
664 		brightonParamChange(synth->win, synth->panel, 46, &event);
665 		splitPoint = synth->mem.param[MOD_START + OB_MODCOUNT + 5];
666 	} else if (synth->mem.param[MOD_START + OB_MODCOUNT + 2])
667 		brightonParamChange(synth->win, synth->panel, 47, &event);
668 
669 	/*
670 printf("Load %f %f %f %f\n", pw[0], pw[1], pw[2], pw[3]);
671 	 * We now need to force the PW of the two oscillators, both layers.
672 	 */
673 	bristolMidiSendMsg(global.controlfd, synth->sid, 0, 0,
674 		(int) (pw[0]));
675 	bristolMidiSendMsg(global.controlfd, synth->sid, 1, 0,
676 		(int) (pw[1]));
677 	bristolMidiSendMsg(global.controlfd, synth->sid2, 0, 0,
678 		(int) (pw[2]));
679 	bristolMidiSendMsg(global.controlfd, synth->sid2, 1, 0,
680 		(int) (pw[3]));
681 
682 	synth->flags |= MEM_LOADING;
683 	/*
684 	 * Finally we need to look at the mods. There are two we do not want to
685 	 * look at, the two wheels - 4 and 5, the rest need to be set.
686 	 */
687 	for (i = 0; i < OB_MODCOUNT; i++)
688 	{
689 		if ((i == 4) || (i == 5))
690 			continue;
691 
692 		event.value = synth->mem.param[MOD_START + i];
693 		brightonParamChange(synth->win, 2, i, &event);
694 	}
695 	synth->flags &= ~MEM_LOADING;
696 
697 	/*
698 	 * Finally load and push the sequence information for this memory.
699 	 */
700 	loadSequence(&synth->seq1, "obxa", synth->bank*10 + synth->location, 0);
701 	fillSequencer(synth, (arpeggiatorMemory *) synth->seq1.param, 0);
702 }
703 
704 static int
obxaMidiCallback(brightonWindow * win,int controller,int value,float n)705 obxaMidiCallback(brightonWindow *win, int controller, int value, float n)
706 {
707 	guiSynth *synth = findSynth(global.synths, win);
708 
709 	printf("midi callback: %x, %i\n", controller, value);
710 
711 	switch(controller)
712 	{
713 		case MIDI_PROGRAM:
714 			printf("midi program: %x, %i\n", controller, value);
715 			synth->location = value;
716 			obxaLoadMemory(synth, "obxa", 0, synth->bank * 10 + synth->location,
717 				synth->mem.active, FIRST_DEV, 0);
718 			break;
719 		case MIDI_BANK_SELECT:
720 			printf("midi banksel: %x, %i\n", controller, value);
721 			synth->bank = value;
722 			break;
723 	}
724 	return(0);
725 }
726 
727 static int
obxaKeyCallback(brightonWindow * win,int panel,int index,float value)728 obxaKeyCallback(brightonWindow *win, int panel, int index, float value)
729 {
730 	guiSynth *synth = findSynth(global.synths, win);
731 
732 /*
733 printf("obxaKeycallback(%x, %i, %i, %f): %i %i - %i\n", (size_t) synth, panel,
734 index, value, synth->transpose, global.controlfd, index + synth->transpose);
735 */
736 
737 	if ((seqLearn == 1) && (value != 0))
738 		seqInsert((arpeggiatorMemory *) synth->seq1.param,
739 			(int) index, synth->transpose);
740 
741 	if ((chordLearn == 1) && (value != 0))
742 		chordInsert((arpeggiatorMemory *) synth->seq1.param,
743 			(int) index, synth->transpose);
744 
745 	if (splitPoint == -2)
746 	{
747 printf("setting split point: %i\n", index);
748 		splitPoint = index;
749 		obxaSetMode(synth);
750 		synth->mem.param[MOD_START + OB_MODCOUNT + 5] = index;
751 		return(0);
752 	}
753 
754 	/* Don't send MIDI messages if we are testing */
755 	if (global.libtest)
756 		return(0);
757 
758 	/*
759 	 * Want to send a note event, on or off, for this index + transpose.
760 	 * Look at the Mode options. If we are layer then send two events, one for
761 	 * each channel. If split then check the key we have selected, and if
762 	 * poly send to each voice in turn.
763 	 *
764 	 * Take the tranpose out of here.
765 	 */
766 	if (value)
767 		bristolMidiSendMsg(global.controlfd, synth->midichannel,
768 			BRISTOL_EVENT_KEYON, 0, index + synth->transpose);
769 	else
770 		bristolMidiSendMsg(global.controlfd, synth->midichannel,
771 			BRISTOL_EVENT_KEYOFF, 0, index + synth->transpose);
772 
773 	return(0);
774 }
775 
776 /*
777 static void
778 obxadestroy(brightonWindow *win)
779 {
780 	guiSynth *synth = findSynth(global.synths, win);
781 
782 	bristolMidiSendMsg(manual.controlfd, synth->sid2, 127, 0,
783 		BRISTOL_EXIT_ALGO);
784 	bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0,
785 		BRISTOL_EXIT_ALGO);
786 }
787 */
788 
789 static void
obxaSeqRate(guiSynth * synth,int fd,int chan,int c,int o,int v)790 obxaSeqRate(guiSynth *synth, int fd, int chan, int c, int o, int v)
791 {
792 	bristolMidiSendMsg(global.controlfd, synth->sid,
793 		BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RATE, v);
794 	bristolMidiSendMsg(global.controlfd, synth->sid,
795 		BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_RATE, v);
796 }
797 
798 static int
obxaModCallback(brightonWindow * cid,int panel,int index,float value)799 obxaModCallback(brightonWindow *cid, int panel, int index, float value)
800 {
801 	guiSynth *synth = findSynth(global.synths, cid);
802 	int sendvalue;
803 
804 	/* printf("obxaModCallback(%x, %i, %i, %f)\n",
805 		(size_t)synth, panel, index, value); */
806 
807 	/*
808 	 * These may eventually be saved with the memories. Location is above the
809 	 * second voice memories.
810 	 */
811 	synth->mem.param[MOD_START + index] = value;
812 
813 	/*
814 	 * If this is controller 0 it is the frequency control, otherwise a
815 	 * generic controller 1.
816 	 */
817 	switch (index) {
818 		case 0: /* Rate pot - Second LFO */
819 			sendvalue = value * C_RANGE_MIN_1;
820 			/*
821 			 * This is a monolithic LFO, applies to both layers via preops
822 			 */
823 			bristolMidiSendMsg(global.controlfd, synth->sid, 8, 0, sendvalue);
824 			bristolMidiSendMsg(global.controlfd, synth->sid2, 8, 0, sendvalue);
825 			break;
826 		case 1: /* Lower - Apply mods to given layer */
827 			if (value != 0) {
828 				if (synth->mem.param[MOD_START + 6] != 0.0)
829 					bristolMidiSendMsg(global.controlfd, synth->sid2,
830 						126, 25, 1);
831 				else
832 					bristolMidiSendMsg(global.controlfd, synth->sid2,
833 						126, 25, 0);
834 
835 				if (synth->mem.param[MOD_START + 7] != 0.0)
836 					bristolMidiSendMsg(global.controlfd, synth->sid2,
837 						126, 27, 1);
838 				else
839 					bristolMidiSendMsg(global.controlfd, synth->sid2,
840 						126, 27, 0);
841 
842 				if (synth->mem.param[MOD_START + 8] != 0.0)
843 					bristolMidiSendMsg(global.controlfd, synth->sid2,
844 						126, 29, 1);
845 				else
846 					bristolMidiSendMsg(global.controlfd, synth->sid2,
847 						126, 29, 0);
848 			} else {
849 				bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 25, 0);
850 				bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 27, 0);
851 				bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 29, 0);
852 			}
853 			break;
854 		case 2: /* Upper - Apply mods to given layer */
855 			if (value != 0.0) {
856 				if (synth->mem.param[MOD_START + 6] != 0.0)
857 					bristolMidiSendMsg(global.controlfd, synth->sid,
858 						126, 25, 1);
859 				else
860 					bristolMidiSendMsg(global.controlfd, synth->sid,
861 						126, 25, 0);
862 
863 				if (synth->mem.param[MOD_START + 7] != 0.0)
864 					bristolMidiSendMsg(global.controlfd, synth->sid,
865 						126, 27, 1);
866 				else
867 					bristolMidiSendMsg(global.controlfd, synth->sid,
868 						126, 27, 0);
869 
870 				if (synth->mem.param[MOD_START + 8] != 0.0)
871 					bristolMidiSendMsg(global.controlfd, synth->sid,
872 						126, 29, 1);
873 				else
874 					bristolMidiSendMsg(global.controlfd, synth->sid,
875 						126, 29, 0);
876 			} else {
877 				bristolMidiSendMsg(global.controlfd, synth->sid, 126, 25, 0);
878 				bristolMidiSendMsg(global.controlfd, synth->sid, 126, 27, 0);
879 				bristolMidiSendMsg(global.controlfd, synth->sid, 126, 29, 0);
880 			}
881 			break;
882 		case 3: /* Depth pot - Of LFO, affected by mod wheel */
883 			if (synth->mem.param[MOD_START + 9] == 0)
884 				sendvalue = value * C_RANGE_MIN_1;
885 			else
886 				sendvalue = C_RANGE_MIN_1 / 2 +
887 					(int) (((value - 0.5) / 3) * C_RANGE_MIN_1);
888 
889 			/*
890 			 * This is a monolithic LFO, applies to both layers via preops
891 			 */
892 			bristolMidiSendMsg(global.controlfd, synth->sid,
893 					126, 26, sendvalue);
894 			bristolMidiSendMsg(global.controlfd, synth->sid2,
895 					126, 26, sendvalue);
896 			break;
897 		case 4: /* Freq wheel */
898 			if (synth->mem.param[MOD_START + 9] == 0)
899 				sendvalue = value * C_RANGE_MIN_1;
900 			else
901 				sendvalue = C_RANGE_MIN_1 / 2 +
902 					(int) (((value - 0.5) / 3) * C_RANGE_MIN_1);
903 			/* Check on Layer switch and Osc settings */
904 			if (synth->mem.param[MOD_START + 1] != 0)
905 				bristolMidiSendMsg(global.controlfd, synth->midichannel,
906 					BRISTOL_EVENT_PITCH, 0, sendvalue);
907 			if (synth->mem.param[MOD_START + 2] != 0)
908 				bristolMidiSendMsg(global.controlfd, synth->midichannel + 1,
909 					BRISTOL_EVENT_PITCH, 0, sendvalue);
910 			break;
911 		case 5: /* Mod wheel */
912 			if (synth->mem.param[MOD_START + 9] == 0)
913 				sendvalue = value * C_RANGE_MIN_1;
914 			else
915 				sendvalue = value * C_RANGE_MIN_1 / 4;
916 
917 			/* Check on Layer switches */
918 			bristolMidiControl(global.controlfd, synth->midichannel,
919 				0, 1, ((int) (value * C_RANGE_MIN_1)) >> 7);
920 			bristolMidiControl(global.controlfd, synth->midichannel + 1,
921 				0, 1, ((int) (value * C_RANGE_MIN_1)) >> 7);
922 			break;
923 		case 6: /* Mod O1 - Apply Mod to Osc 1 */
924 			if (value != 0) {
925 				if (synth->mem.param[MOD_START + 1] != 0.0)
926 					bristolMidiSendMsg(global.controlfd, synth->sid2,
927 						126, 25, 1);
928 				else
929 					bristolMidiSendMsg(global.controlfd, synth->sid2,
930 						126, 25, 0);
931 			} else {
932 				bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 25, 0);
933 			}
934 
935 			if (value != 0) {
936 				if (synth->mem.param[MOD_START + 2] != 0.0)
937 					bristolMidiSendMsg(global.controlfd, synth->sid,
938 						126, 25, 1);
939 				else
940 					bristolMidiSendMsg(global.controlfd, synth->sid,
941 						126, 25, 0);
942 			} else {
943 				bristolMidiSendMsg(global.controlfd, synth->sid, 126, 25, 0);
944 			}
945 			break;
946 		case 7: /* Mod O2 - Apply Mod to Osc 2 */
947 			if (value != 0) {
948 				if (synth->mem.param[MOD_START + 1] != 0.0)
949 					bristolMidiSendMsg(global.controlfd, synth->sid2,
950 						126, 27, 1);
951 				else
952 					bristolMidiSendMsg(global.controlfd, synth->sid2,
953 						126, 27, 0);
954 			} else {
955 					bristolMidiSendMsg(global.controlfd, synth->sid2,
956 						126, 27, 0);
957 			}
958 
959 			if (value != 0) {
960 				if (synth->mem.param[MOD_START + 2] != 0.0)
961 					bristolMidiSendMsg(global.controlfd, synth->sid,
962 						126, 27, 1);
963 				else
964 					bristolMidiSendMsg(global.controlfd, synth->sid,
965 						126, 27, 0);
966 			} else {
967 					bristolMidiSendMsg(global.controlfd, synth->sid,
968 						126, 27, 0);
969 			}
970 			break;
971 		case 8: /* MOD to PWM */
972 			if (value != 0) {
973 				if (synth->mem.param[MOD_START + 1] != 0.0)
974 					bristolMidiSendMsg(global.controlfd, synth->sid2,
975 						126, 29, 1);
976 				else
977 					bristolMidiSendMsg(global.controlfd, synth->sid2,
978 						126, 29, 0);
979 			} else {
980 					bristolMidiSendMsg(global.controlfd, synth->sid2,
981 						126, 29, 0);
982 			}
983 
984 			if (value != 0) {
985 				if (synth->mem.param[MOD_START + 2] != 0.0)
986 					bristolMidiSendMsg(global.controlfd, synth->sid,
987 						126, 29, 1);
988 				else
989 					bristolMidiSendMsg(global.controlfd, synth->sid,
990 						126, 29, 0);
991 			} else {
992 					bristolMidiSendMsg(global.controlfd, synth->sid,
993 						126, 29, 0);
994 			}
995 			break;
996 		case 9: /* Ammount - Wide Narrow mods */
997 			/* Nothing to do - just a flag that affects swing of wheels. */
998 			/* That is not wise, it should really go to the engine */
999 			break;
1000 		case 10: /* Transpose down - Radio buttons */
1001 			/*
1002 			 * These are 3 way radio buttons, which is a bit of a bummer. We
1003 			 * should consider making it layer sensitive however there is
1004 			 * already sufficient transpose in the oscillators.
1005 			 */
1006 			if (value == 0) {
1007 				if (synth->mem.param[MOD_START + 11] == 0)
1008 					/*
1009 					 * Default transpose
1010 					synth->transpose = 36;
1011 					 */
1012 					bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0,
1013 						BRISTOL_TRANSPOSE);
1014 					bristolMidiSendMsg(global.controlfd, synth->sid2, 127, 0,
1015 						BRISTOL_TRANSPOSE);
1016 			} else {
1017 				if (synth->mem.param[MOD_START + 11] != 0)
1018 				{
1019 					brightonEvent event;
1020 
1021 					event.type = BRIGHTON_FLOAT;
1022 					event.value = 0;
1023 					brightonParamChange(synth->win, 2, 11, &event);
1024 				}
1025 				bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0,
1026 					BRISTOL_TRANSPOSE - 12);
1027 				bristolMidiSendMsg(global.controlfd, synth->sid2, 127, 0,
1028 					BRISTOL_TRANSPOSE - 12);
1029 			}
1030 			break;
1031 		case 11: /* Transpose up - Radio buttons */
1032 			if (value == 0) {
1033 				if (synth->mem.param[MOD_START + 10] == 0)
1034 					/* Default transpose */
1035 					bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0,
1036 						BRISTOL_TRANSPOSE);
1037 					bristolMidiSendMsg(global.controlfd, synth->sid2, 127, 0,
1038 						BRISTOL_TRANSPOSE);
1039 			} else {
1040 				if (synth->mem.param[MOD_START + 10] != 0)
1041 				{
1042 					brightonEvent event;
1043 
1044 					event.type = BRIGHTON_FLOAT;
1045 					event.value = 0;
1046 					brightonParamChange(synth->win, 2, 10, &event);
1047 				}
1048 				bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0,
1049 					BRISTOL_TRANSPOSE + 12);
1050 				bristolMidiSendMsg(global.controlfd, synth->sid2, 127, 0,
1051 					BRISTOL_TRANSPOSE + 12);
1052 			}
1053 			break;
1054 		case 12: /* MULTI MOD LFO - gives MOD LFO per voice rather than global. */
1055 			if (synth->mem.param[MOD_START + 12] != 0)
1056 			{
1057 				bristolMidiSendMsg(global.controlfd, synth->sid, 126, 22, 1);
1058 				bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 22, 1);
1059 				/*
1060 				 * Configure for sync to NOTE_ON, improves variance.
1061 				 */
1062 				bristolMidiSendMsg(global.controlfd, synth->sid, 8, 1, 1);
1063 				bristolMidiSendMsg(global.controlfd, synth->sid2, 8, 1, 1);
1064 			} else {
1065 				bristolMidiSendMsg(global.controlfd, synth->sid, 126, 22, 0);
1066 				bristolMidiSendMsg(global.controlfd, synth->sid2, 126, 22, 0);
1067 				/*
1068 				 * Configure for sync to never
1069 				 */
1070 				bristolMidiSendMsg(global.controlfd, synth->sid, 8, 1, 0);
1071 				bristolMidiSendMsg(global.controlfd, synth->sid2, 8, 1, 0);
1072 			}
1073 			break;
1074 		case 13: /* Copy lower layer parameters to upper layer */
1075 			if ((synth->flags & MEM_LOADING) == 0)
1076 				obxaCopyLayer(synth);
1077 			break;
1078 	}
1079 	return(0);
1080 }
1081 
1082 static void
obxaSetMode(guiSynth * synth)1083 obxaSetMode(guiSynth *synth)
1084 {
1085 	int selection = synth->mem.param[45];
1086 
1087 	if (selection == 0)
1088 	{
1089 		if (synth->mem.param[46] == 0)
1090 			selection = 3;
1091 		else
1092 			selection = 2;
1093 	}
1094 
1095 	switch (selection) {
1096 		case 1:
1097 			/* Poly */
1098 			printf("configure poly\n");
1099 			bristolMidiSendMsg(global.controlfd, synth->sid, 126, 30, 1);
1100 			bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0,
1101 				BRISTOL_HIGHKEY|127);
1102 			bristolMidiSendMsg(global.controlfd, synth->sid2, 127, 0,
1103 				BRISTOL_LOWKEY|127);
1104 			break;
1105 		case 2:
1106 			/* Split */
1107 			printf("configure split %i\n", splitPoint);
1108 			bristolMidiSendMsg(global.controlfd, synth->sid, 126, 30, 0);
1109 			if (splitPoint > 0) {
1110 				bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0,
1111 					BRISTOL_HIGHKEY|splitPoint);
1112 				bristolMidiSendMsg(global.controlfd, synth->sid2, 127, 0,
1113 					BRISTOL_LOWKEY|(splitPoint + 1));
1114 			}
1115 			break;
1116 		case 3:
1117 			/* Layer */
1118 			printf("configure layer\n");
1119 			bristolMidiSendMsg(global.controlfd, synth->sid, 126, 30, 0);
1120 			bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0,
1121 				BRISTOL_HIGHKEY|127);
1122 			bristolMidiSendMsg(global.controlfd, synth->sid2, 127, 0,
1123 				BRISTOL_LOWKEY|0);
1124 			break;
1125 	}
1126 }
1127 
1128 static void
obxaMode(guiSynth * synth,int c,int o,int value)1129 obxaMode(guiSynth *synth, int c, int o, int value)
1130 {
1131 	brightonEvent event;
1132 
1133 	if (synth->flags & MEM_LOADING)
1134 		return;
1135 
1136 	synth->mem.param[c] = value;
1137 
1138 	/*
1139 	 * Poly, split and layer radio buttons.
1140 	 */
1141 	if (synth->dispatch[RADIOSET_3].other2)
1142 	{
1143 		synth->dispatch[RADIOSET_3].other2 = 0;
1144 		return;
1145 	}
1146 
1147 	//printf("obxaMode(%i, %i, %i)\n", c, o, value);
1148 
1149 	if (synth->dispatch[RADIOSET_3].other1 != -1)
1150 	{
1151 		event.type = BRIGHTON_FLOAT;
1152 
1153 		synth->dispatch[RADIOSET_3].other2 = 1;
1154 
1155 		if (synth->dispatch[RADIOSET_3].other1 != c)
1156 			event.value = 0;
1157 		else
1158 			event.value = 1;
1159 
1160 		brightonParamChange(synth->win, synth->panel,
1161 			synth->dispatch[RADIOSET_3].other1, &event);
1162 	}
1163 	synth->dispatch[RADIOSET_3].other1 = c;
1164 
1165 	/* Bury this here as it has to go somewhere */
1166 	if (synth->win->width != width)
1167 		brightonPut(synth->win, "bitmaps/blueprints/obxashade.xpm",
1168 			0, 0, width = synth->win->width, synth->win->height);
1169 
1170 	if (global.libtest)
1171 		return;
1172 
1173 	/*
1174 	 * If Poly then set upper split to 127-127, lower to 0-127, raise voices
1175 	 * on lower layer.
1176 	 * Dual set both splits to 0-127, lower voices on lower layer.
1177 	 * Layer then set upper and lower splits, lower voices on lower layer.
1178 	 */
1179 	if (value == 0)
1180 		return;
1181 
1182 	obxaSetMode(synth);
1183 
1184 	return;
1185 }
1186 
1187 static int pwSelect = 0;
1188 /*
1189  * We need to see if for any given oscillator none of the wave buttons are
1190  * selected. If this is the case then select triangle. Else disable tri and
1191  * configure the selected values.
1192  */
1193 static void
obxaWaveform(guiSynth * synth,int fd,int chan,int c,int o,int v)1194 obxaWaveform(guiSynth *synth, int fd, int chan, int c, int o, int v)
1195 {
1196 	/*
1197 	 * See if this is the PW parameter.
1198 	 */
1199 	if (c == 15)
1200 	{
1201 		if (synth->flags & MEM_LOADING)
1202 			return;
1203 		if (pwSelect == 0) {
1204 			if (synth->mem.param[LAYER_SWITCH] == 0)
1205 				synth->mem.param[15] = v;
1206 			else
1207 				synth->mem.param[DEVICE_COUNT + 15] = v;
1208 			bristolMidiSendMsg(fd, chan, 0, 0, v);
1209 		} else {
1210 			synth->mem.param[MOD_START + OB_MODCOUNT + 3
1211 				+ (int) synth->mem.param[LAYER_SWITCH]] = v;
1212 			bristolMidiSendMsg(fd, chan, 1, 0, v);
1213 		}
1214 		return;
1215 	}
1216 
1217 	/*
1218 	 * See if we need to set PW selector
1219 	 */
1220 	if (o == 6)
1221 	{
1222 		/*
1223 		 * If the sqr is being selected, then PW will modify this oscillator,
1224 		 * and if going off then it will cotrol the other
1225 		 */
1226 		if (v != 0)
1227 			pwSelect = c;
1228 		else
1229 			pwSelect = 1 - c;
1230 	}
1231 
1232 	/*
1233 	 * If the value is '1' we can just set the desired wave and disable tri.
1234 	 */
1235 	if (v != 0)
1236 	{
1237 		bristolMidiSendMsg(fd, chan, c, o, v);
1238 		bristolMidiSendMsg(fd, chan, c, 5, 0);
1239 	} else {
1240 		int layer = 0;
1241 
1242 		if (synth->mem.param[LAYER_SWITCH] != 0)
1243 			layer = DEVICE_COUNT;
1244 		bristolMidiSendMsg(fd, chan, c, o, v);
1245 		if (c == 0)
1246 		{
1247 			if ((synth->mem.param[layer + 17] == 0) &&
1248 				(synth->mem.param[layer + 18] == 0))
1249 				bristolMidiSendMsg(fd, chan, c, 5, 1);
1250 		} else {
1251 			if ((synth->mem.param[layer + 21] == 0) &&
1252 				(synth->mem.param[layer + 22] == 0))
1253 				bristolMidiSendMsg(fd, chan, c, 5, 1);
1254 		}
1255 	}
1256 }
1257 
1258 static int dreset = 0;
1259 static int d1 = 0;
1260 static int d2 = 0;
1261 
1262 /*
1263  * If controller #41 has value zero then we configure the release rates, else
1264  * we use the shortest release rate.
1265  */
1266 static void
obxaDecay(void * synth,int fd,int chan,int c,int o,int v)1267 obxaDecay(void *synth, int fd, int chan, int c, int o, int v)
1268 {
1269 	if (c == 41)
1270 	{
1271 		if (v == 0)
1272 		{
1273 			/*
1274 			 * Set values to their current settings
1275 			 */
1276 			dreset = 0;
1277 			bristolMidiSendMsg(fd, chan, 3, 3, d1);
1278 			bristolMidiSendMsg(fd, chan, 5, 3, d2);
1279 		} else {
1280 			/*
1281 			 * Set values to minimum release time
1282 			 */
1283 			dreset = 1;
1284 			bristolMidiSendMsg(fd, chan, 3, 3, 20);
1285 			bristolMidiSendMsg(fd, chan, 5, 3, 20);
1286 		}
1287 	} else {
1288 		if (dreset == 0)
1289 			bristolMidiSendMsg(fd, chan, c, o, v);
1290 
1291 		if (c == 3)
1292 			d1 = v;
1293 		else
1294 			d2 = v;
1295 	}
1296 }
1297 
1298 static int
obxaMidiSendMsg(void * synth,int fd,int chan,int c,int o,int v)1299 obxaMidiSendMsg(void *synth, int fd, int chan, int c, int o, int v)
1300 {
1301 	bristolMidiSendMsg(fd, chan, c, o, v);
1302 	return(0);
1303 }
1304 
1305 static void
multiTune(guiSynth * synth,int fd,int chan,int c,int o,int v)1306 multiTune(guiSynth *synth, int fd, int chan, int c, int o, int v)
1307 {
1308 	brightonEvent event;
1309 	int layer = global.synths->mem.param[LAYER_SWITCH];
1310 
1311 /*	if (synth->flags & MEM_LOADING) */
1312 /*		return; */
1313 
1314 	/*
1315 	 * Configures all the tune settings to zero (ie, 0.5).
1316 	 */
1317 
1318 	event.type = BRIGHTON_FLOAT;
1319 	event.value = 0.5;
1320 
1321 	global.synths->mem.param[LAYER_SWITCH] = 0;
1322 	brightonParamChange(synth->win, synth->panel, FIRST_DEV + 2,
1323 		&event);
1324 	brightonParamChange(synth->win, synth->panel, FIRST_DEV + 44,
1325 		&event);
1326 
1327 	global.synths->mem.param[LAYER_SWITCH] = 1;
1328 	brightonParamChange(synth->win, synth->panel, FIRST_DEV + 2,
1329 		&event);
1330 	brightonParamChange(synth->win, synth->panel, FIRST_DEV + 44,
1331 		&event);
1332 
1333 	global.synths->mem.param[LAYER_SWITCH] = layer;
1334 
1335 	global.synths->mem.param[2] = 0.5;
1336 	global.synths->mem.param[44] = 0.5;
1337 	global.synths->mem.param[DEVICE_COUNT + 2] = 0.5;
1338 	global.synths->mem.param[DEVICE_COUNT + 44] = 0.5;
1339 }
1340 
1341 /*
1342  * This should take the current layer and copy to the other.
1343  */
1344 static void
obxaCopyLayer(guiSynth * synth)1345 obxaCopyLayer(guiSynth *synth)
1346 {
1347 	int i, pSel;
1348 	brightonEvent event;
1349 	float pw[2];
1350 
1351 printf("Copy Layer\n");
1352 
1353 	pw[0] = synth->mem.param[15];
1354 	pw[1] = synth->mem.param[MOD_START + OB_MODCOUNT + 3];
1355 
1356 	bcopy(synth->mem.param, &synth->mem.param[DEVICE_COUNT],
1357 		ACTIVE_DEVS * sizeof(float));
1358 
1359 	/*
1360 	 * Memory loading should be a few phases. Firstly see which layer is visible
1361 	 * and if it is not the first then display the first panel and load the mem.
1362 	 * After that display the upper panel and load the next set of memories.
1363 	 * Finally return to the original panel.
1364 	 */
1365 	if ((pSel = synth->mem.param[LAYER_SWITCH]) == 0)
1366 	{
1367 		synth->mem.param[LAYER_SWITCH] = 1;
1368 		/*
1369 		 * We should consider actually sending the button change action
1370 		 */
1371 		obxaPanelSwitch(synth, global.controlfd, synth->midichannel, 0, 0, 0);
1372 	}
1373 
1374 	/*
1375 	 * We now have to call the GUI to configure all these values. The GUI
1376 	 * will then call us back with the parameters to send to the synth.
1377 	 */
1378 	event.type = BRIGHTON_FLOAT;
1379 	for (i = 0; i < synth->mem.active - 2; i++)
1380 	{
1381 		event.value = synth->mem.param[DEVICE_COUNT + i];
1382 
1383 		brightonParamChange(synth->win, 0, i, &event);
1384 	}
1385 
1386 	synth->mem.param[DEVICE_COUNT + 15] = pw[0];
1387 	synth->mem.param[MOD_START + OB_MODCOUNT + 4] = pw[1];
1388 
1389 	bristolMidiSendMsg(global.controlfd, synth->sid2, 0, 0,
1390 		(int) pw[0] * C_RANGE_MIN_1);
1391 	bristolMidiSendMsg(global.controlfd, synth->sid2, 1, 0,
1392 		(int) pw[1] * C_RANGE_MIN_1);
1393 
1394 	/*
1395 	 * Memory loading should be a few phases. Firstly see which layer is visible
1396 	 * and if it is not the first then display the first panel and load the mem.
1397 	 * After that display the upper panel and load the next set of memories.
1398 	 * Finally return to the original panel.
1399 	 */
1400 	if ((synth->mem.param[LAYER_SWITCH] = pSel) == 0)
1401 		/*
1402 		 * We should consider actually sending the button change action
1403 		 */
1404 		obxaPanelSwitch(synth, global.controlfd, synth->midichannel, 0, 0, 0);
1405 }
1406 
1407 static void
obxaSaveMemory(guiSynth * synth,char * name,char * d,int loc,int o)1408 obxaSaveMemory(guiSynth *synth, char *name, char *d, int loc, int o)
1409 {
1410 	char path[256];
1411 	int fd;
1412 
1413 	/*
1414 printf("%f %f %f %f\n",
1415 synth->mem.param[15],
1416 synth->mem.param[MOD_START + OB_MODCOUNT + 3],
1417 synth->mem.param[DEVICE_COUNT + 15],
1418 synth->mem.param[MOD_START + OB_MODCOUNT + 4]);
1419 	 * We need to save the Poly/Split/Layer, but don't really want them to be
1420 	 * part of the other general routines, so 'force' it here. Not nice but
1421 	 * will do for now.
1422 	 */
1423 	saveMemory(synth, name, d, loc, o);
1424 
1425 	/*
1426 	 * Just save a single sequencer, not one per memory. Can that, save lots
1427 	 */
1428 	saveSequence(synth, "obxa", loc, 0);
1429 
1430 	/*
1431 	 * Now we need to consider the second layer.
1432 	 */
1433 	if ((name != 0) && (name[0] == '/'))
1434 	{
1435 		sprintf(synth->mem.algo, "%s", name);
1436 		sprintf(path, "%s", name);
1437 	} else {
1438 		sprintf(path, "%s/memory/%s/%s%i.mem",
1439 			getBristolCache("midicontrollermap"), name, name, loc);
1440 		sprintf(synth->mem.algo, "%s", name);
1441 		if (name == NULL)
1442 			sprintf(synth->mem.name, "no name");
1443 		else
1444 			sprintf(synth->mem.name, "%s", name);
1445 		//printf("saving second layer\n");
1446 	}
1447 
1448 	if ((fd = open(path, O_WRONLY, 0770)) < 0)
1449 	{
1450 		sprintf(path, "%s/memory/%s/%s%i.mem",
1451 			global.home, name, name, loc);
1452 		if ((fd = open(path, O_WRONLY, 0770)) < 0)
1453 		{
1454 			return;
1455 		}
1456 	}
1457 
1458 	lseek(fd, DEVICE_COUNT * sizeof(float), SEEK_SET);
1459 
1460 	if (write(fd, &synth->mem.param[DEVICE_COUNT],
1461 			DEVICE_COUNT * sizeof(float)) < 0)
1462 		printf("write failed 2\n");
1463 
1464 	close(fd);
1465 }
1466 
1467 static void
obxaSequence(guiSynth * synth,int fd,int chan,int c,int o,int v)1468 obxaSequence(guiSynth *synth, int fd, int chan, int c, int o, int v)
1469 {
1470 	brightonEvent event;
1471 
1472 	printf("obxaSequence\n");
1473 
1474 	if (synth->seq1.param == NULL) {
1475 		loadSequence(&synth->seq1, "obxa", synth->bank*10 + synth->location, 0);
1476 		fillSequencer(synth, (arpeggiatorMemory *) synth->seq1.param, 0);
1477 	}
1478 
1479 	if (synth->mem.param[FUNCTION] != 0)
1480 	{
1481 		if  (v != 0) {
1482 			if ((synth->flags & OPERATIONAL) == 0)
1483 				return;
1484 			if (synth->flags & MEM_LOADING)
1485 				return;
1486 
1487 			printf("Sequence learn mode requested %x\n",  synth->flags);
1488 
1489 			seqLearn = 1;
1490 
1491 			synth->seq1.param[BRISTOL_AM_SMAX] = 0;
1492 
1493 			/*
1494 			 * Stop the arpeggiator and send a learn request
1495 			 */
1496 			bristolMidiSendMsg(global.controlfd, synth->sid,
1497 				BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_ENABLE, 0);
1498 			bristolMidiSendMsg(global.controlfd, synth->sid,
1499 				BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RESEQ, 1);
1500 		} else {
1501 			/*
1502 			 * Stop the learning process
1503 			 */
1504 			seqLearn = 0;
1505 			bristolMidiSendMsg(global.controlfd, synth->sid,
1506 				BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RESEQ, 0);
1507 			event.value = 0;
1508 			brightonParamChange(synth->win, synth->panel, FUNCTION, &event);
1509 		}
1510 
1511 		return;
1512 	}
1513 
1514 	if (seqLearn == 1) {
1515 		/*
1516 		 * This is a button press during the learning sequence, in which case
1517 		 * it needs to be terminated.
1518 		 */
1519 		seqLearn = 0;
1520 
1521 		bristolMidiSendMsg(global.controlfd, synth->sid,
1522 			BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RESEQ, 0);
1523 	}
1524 
1525 	/*
1526 	 * If value is going to zero then stop the sequencer.
1527 	 */
1528 	if (v == 0)
1529 	{
1530 		bristolMidiSendMsg(global.controlfd, synth->sid,
1531 			BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_ENABLE, 0);
1532 		bristolMidiSendMsg(global.controlfd, synth->sid,
1533 			BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_ENABLE, 0);
1534 
1535 		return;
1536 	}
1537 
1538 	/*
1539 	 * Otherwise start it.
1540 	 */
1541 	bristolMidiSendMsg(global.controlfd, synth->sid,
1542 		BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_ENABLE, 1);
1543 }
1544 
1545 static void
obxaFunction(guiSynth * synth,int fd,int chan,int c,int o,int v)1546 obxaFunction(guiSynth *synth, int fd, int chan, int c, int o, int v)
1547 {
1548 	brightonEvent event;
1549 
1550 	/*
1551 	 * This is not really an active button so does not really require a
1552 	 * callback - the memory location is polled by other callbacks.
1553 	 */
1554 	printf("obxaFunction\n");
1555 
1556 	if (v == 0) {
1557 		if (synth->mem.param[HOLD_KEY] != 0) {
1558 			event.type = BRIGHTON_FLOAT;
1559 			event.value = 0;
1560 			brightonParamChange(synth->win, synth->panel, HOLD_KEY, &event);
1561 		}
1562 
1563 		if (synth->mem.param[SEQ_MODE] != 0) {
1564 			event.type = BRIGHTON_FLOAT;
1565 			event.value = 0;
1566 			brightonParamChange(synth->win, synth->panel, SEQ_MODE, &event);
1567 		}
1568 
1569 		if (synth->mem.param[SEQ_MODE + 1] != 0) {
1570 			event.type = BRIGHTON_FLOAT;
1571 			event.value = 0;
1572 			brightonParamChange(synth->win, synth->panel, SEQ_MODE+1, &event);
1573 		}
1574 
1575 		if (synth->mem.param[SEQ_MODE + 2] != 0) {
1576 			event.type = BRIGHTON_FLOAT;
1577 			event.value = 0;
1578 			brightonParamChange(synth->win, synth->panel, SEQ_MODE+2, &event);
1579 		}
1580 	}
1581 }
1582 
1583 static void
obxaArpOctave(guiSynth * synth,int fd,int chan,int c,int o,int v)1584 obxaArpOctave(guiSynth *synth, int fd, int chan, int c, int o, int v)
1585 {
1586 	brightonEvent event;
1587 
1588 printf("obxaArpOctave: %i %i %i\n", c, o, v);
1589 	/*
1590 	 * Force exclusion
1591 	 */
1592 	if (synth->dispatch[OCTAVE_MODE].other2)
1593 	{
1594 		synth->dispatch[OCTAVE_MODE].other2 = 0;
1595 		return;
1596 	}
1597 
1598 	event.type = BRIGHTON_FLOAT;
1599 
1600 	if (v != 0)
1601 	{
1602 		if (synth->dispatch[OCTAVE_MODE].other1 != -1)
1603 		{
1604 			synth->dispatch[OCTAVE_MODE].other2 = 1;
1605 
1606 			if (synth->dispatch[OCTAVE_MODE].other1 != c)
1607 				event.value = 0;
1608 			else
1609 				event.value = 1;
1610 
1611 			brightonParamChange(synth->win, synth->panel,
1612 				synth->dispatch[OCTAVE_MODE].other1, &event);
1613 		}
1614 		synth->dispatch[OCTAVE_MODE].other1 = c;
1615 
1616 		bristolMidiSendMsg(global.controlfd, synth->sid,
1617 			BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RANGE, o);
1618 		bristolMidiSendMsg(global.controlfd, synth->sid,
1619 			BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_RANGE, o);
1620 
1621 		return;
1622 	} else {
1623 		if ((synth->mem.param[OCTAVE_MODE] == 0)
1624 			&& (synth->mem.param[OCTAVE_MODE + 1] == 0)
1625 			&& (synth->mem.param[OCTAVE_MODE + 2] == 0))
1626 		{
1627 			event.value = 1;
1628 
1629 			brightonParamChange(synth->win, synth->panel, c, &event);
1630 
1631 			bristolMidiSendMsg(global.controlfd, synth->sid,
1632 				BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RANGE, o);
1633 			bristolMidiSendMsg(global.controlfd, synth->sid,
1634 				BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_RANGE, o);
1635 		}
1636 	}
1637 
1638 }
1639 
1640 static void
obxaFilter(guiSynth * synth,int fd,int chan,int c,int o,int v)1641 obxaFilter(guiSynth *synth, int fd, int chan, int c, int o, int v)
1642 {
1643 	/*
1644 	 * Don't change the filter type, alter the feedforward from the other
1645 	 * poles
1646 	 */
1647 	if (v != 0)
1648 		v = 16383;
1649 
1650 	bristolMidiSendMsg(fd, chan, 4, 4, 4);
1651 	bristolMidiSendMsg(fd, chan, 4, 7, v);
1652 //	bristolMidiSendMsg(fd, chan, 4, 1, synth->mem.param[25] * C_RANGE_MIN_1);
1653 }
1654 
1655 static void
obxaArpeggiate(guiSynth * synth,int fd,int chan,int c,int o,int v)1656 obxaArpeggiate(guiSynth *synth, int fd, int chan, int c, int o, int v)
1657 {
1658 	brightonEvent event;
1659 
1660 printf("obxaArpeggiate: %i %i\n", c, v);
1661 	/*
1662 	 * Force exclusion
1663 	 */
1664 	if (synth->dispatch[SEQ_MODE].other2)
1665 	{
1666 		synth->dispatch[SEQ_MODE].other2 = 0;
1667 		return;
1668 	}
1669 
1670 	if (synth->seq1.param == NULL) {
1671 		loadSequence(&synth->seq1, "obxa", synth->bank*10 + synth->location, 0);
1672 		fillSequencer(synth, (arpeggiatorMemory *) synth->seq1.param, 0);
1673 	}
1674 
1675 	printf("obxaArpeggiate(%i, %i)\n", c, v);
1676 
1677 	event.type = BRIGHTON_FLOAT;
1678 
1679 	if (v != 0)
1680 	{
1681 		if (synth->dispatch[SEQ_MODE].other1 != -1)
1682 		{
1683 			synth->dispatch[SEQ_MODE].other2 = 1;
1684 
1685 			if (synth->dispatch[SEQ_MODE].other1 != c)
1686 				event.value = 0;
1687 			else
1688 				event.value = 1;
1689 
1690 			brightonParamChange(synth->win, synth->panel,
1691 				synth->dispatch[SEQ_MODE].other1, &event);
1692 		}
1693 		synth->dispatch[SEQ_MODE].other1 = c;
1694 
1695 		bristolMidiSendMsg(global.controlfd, synth->sid,
1696 			BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_DIR, o);
1697 		bristolMidiSendMsg(global.controlfd, synth->sid,
1698 			BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_DIR, o);
1699 		/* And enable it */
1700 		if (synth->mem.param[SEQ_SEL] == 0)
1701 			bristolMidiSendMsg(global.controlfd, synth->sid,
1702 				BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_ENABLE, 1);
1703 		else
1704 			bristolMidiSendMsg(global.controlfd, synth->sid,
1705 				BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_ENABLE, 1);
1706 
1707 		return;
1708 	}
1709 
1710 	/*
1711 	 * If we are going off then disable the arpeggiator, otherwise set the
1712 	 * mode and start it.
1713 	 */
1714 	if (v == 0) {
1715 		/*
1716 		 * OK, the value is zero. If this is the same controller going off
1717 		 * then disable the arpeggiator, otherwise do nothing.
1718 		 */
1719 		if (synth->dispatch[SEQ_MODE].other1 == c) {
1720 			bristolMidiSendMsg(global.controlfd, synth->sid,
1721 				BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_ENABLE, 0);
1722 			bristolMidiSendMsg(global.controlfd, synth->sid,
1723 				BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_ENABLE, 0);
1724 		}
1725 		return;
1726 	}
1727 }
1728 
1729 static void
obxaChord(guiSynth * synth,int fd,int chan,int c,int o,int v)1730 obxaChord(guiSynth *synth, int fd, int chan, int c, int o, int v)
1731 {
1732 	brightonEvent event;
1733 
1734 	printf("Chord request: %i\n", v);
1735 
1736 	if (synth->seq1.param == NULL) {
1737 		loadSequence(&synth->seq1, "obxa", synth->bank*10 + synth->location, 0);
1738 		fillSequencer(synth, (arpeggiatorMemory *) synth->seq1.param, 0);
1739 	}
1740 
1741 	event.type = BRIGHTON_FLOAT;
1742 
1743 	if (synth->mem.param[FUNCTION] != 0)
1744 	{
1745 		if  (v != 0)
1746 		{
1747 			if ((synth->flags & OPERATIONAL) == 0)
1748 				return;
1749 			if (synth->flags & MEM_LOADING)
1750 				return;
1751 
1752 			chordLearn = 1;
1753 
1754 			printf("Chord learn requested %x\n",  synth->flags);
1755 
1756 			synth->seq1.param[BRISTOL_AM_CCOUNT] = 0;
1757 
1758 			/*
1759 			 * This is to start a re-seq of the chord.
1760 			 */
1761 			bristolMidiSendMsg(global.controlfd, synth->sid,
1762 				BRISTOL_ARPEGGIATOR, BRISTOL_CHORD_ENABLE, 0);
1763 			bristolMidiSendMsg(global.controlfd, synth->sid,
1764 				BRISTOL_ARPEGGIATOR, BRISTOL_CHORD_RESEQ, 1);
1765 		} else {
1766 			chordLearn = 0;
1767 			bristolMidiSendMsg(global.controlfd, synth->sid,
1768 				BRISTOL_ARPEGGIATOR, BRISTOL_CHORD_RESEQ, 0);
1769 			bristolMidiSendMsg(global.controlfd, synth->sid2,
1770 				BRISTOL_ARPEGGIATOR, BRISTOL_CHORD_RESEQ, 0);
1771 			event.value = 0;
1772 			brightonParamChange(synth->win, synth->panel, FUNCTION, &event);
1773 		}
1774 
1775 		return;
1776 	}
1777 
1778 	if (chordLearn == 1) {
1779 		/*
1780 		 * This is a button press during the learning sequence, in which case
1781 		 * it needs to be terminated.
1782 		 */
1783 		chordLearn = 0;
1784 		bristolMidiSendMsg(global.controlfd, synth->sid,
1785 			BRISTOL_ARPEGGIATOR, BRISTOL_CHORD_RESEQ, 0);
1786 	}
1787 
1788 	bristolMidiSendMsg(global.controlfd, synth->sid,
1789 		BRISTOL_ARPEGGIATOR, BRISTOL_CHORD_ENABLE, v);
1790 }
1791 
1792 static void
obxaMemory(guiSynth * synth,int fd,int chan,int c,int o,int v)1793 obxaMemory(guiSynth *synth, int fd, int chan, int c, int o, int v)
1794 {
1795 	brightonEvent event;
1796 
1797 	if ((synth->flags & OPERATIONAL) == 0)
1798 		return;
1799 
1800 	switch (c) {
1801 		case 16:
1802 			/* Load */
1803 			obxaLoadMemory(synth, "obxa", 0, synth->bank * 10 + synth->location,
1804 				synth->mem.active, FIRST_DEV, 0);
1805 			break;
1806 		case 17:
1807 			/* Save */
1808 			obxaSaveMemory(synth, "obxa", 0,
1809 				synth->bank * 10 + synth->location, 0);
1810 			break;
1811 		case 0:
1812 		case 1:
1813 		case 2:
1814 		case 3:
1815 		case 4:
1816 		case 5:
1817 		case 6:
1818 		case 7:
1819 			if (synth->dispatch[RADIOSET_1].other2)
1820 			{
1821 				synth->dispatch[RADIOSET_1].other2 = 0;
1822 				return;
1823 			}
1824 			if (synth->dispatch[RADIOSET_1].other1 != -1)
1825 			{
1826 				synth->dispatch[RADIOSET_1].other2 = 1;
1827 
1828 				if (synth->dispatch[RADIOSET_1].other1 != o)
1829 					event.value = 0;
1830 				else
1831 					event.value = 1;
1832 
1833 				brightonParamChange(synth->win, synth->panel,
1834 					synth->dispatch[RADIOSET_1].other1, &event);
1835 			}
1836 			synth->dispatch[RADIOSET_1].other1 = o;
1837 			synth->bank = c + 1;
1838 			break;
1839 		case 8:
1840 		case 9:
1841 		case 10:
1842 		case 11:
1843 		case 12:
1844 		case 13:
1845 		case 14:
1846 		case 15:
1847 			if (synth->dispatch[RADIOSET_2].other2)
1848 			{
1849 				synth->dispatch[RADIOSET_2].other2 = 0;
1850 				return;
1851 			}
1852 			if (synth->dispatch[RADIOSET_2].other1 != -1)
1853 			{
1854 				synth->dispatch[RADIOSET_2].other2 = 1;
1855 
1856 				if (synth->dispatch[RADIOSET_2].other1 != o)
1857 					event.value = 0;
1858 				else
1859 					event.value = 1;
1860 
1861 				brightonParamChange(synth->win, synth->panel,
1862 					synth->dispatch[RADIOSET_2].other1, &event);
1863 			}
1864 			synth->dispatch[RADIOSET_2].other1 = o;
1865 			/*
1866 			 * Having the minus seven looks odd, but the controllers count from
1867 			 * zero but I want the actual memories to be from 1 to 64, this
1868 			 * reflects the panel blueprint c - 8 + 1 = c - 7;
1869 			 */
1870 			synth->location = c - 7;
1871 			break;
1872 	}
1873 
1874 /*	printf("	obxaMemory(B: %i L %i: %i)\n", */
1875 /*		synth->bank, synth->location, o); */
1876 }
1877 
1878 static void
obxaMidi(guiSynth * synth,int fd,int chan,int c,int o,int v)1879 obxaMidi(guiSynth *synth, int fd, int chan, int c, int o, int v)
1880 {
1881 	int newchan;
1882 
1883 	if ((synth->flags & OPERATIONAL) == 0)
1884 		return;
1885 
1886 	/*
1887 	 * For this synth we are going to try and put everything on a single
1888 	 * midi channel - split poly is all voices, split will tell the engine
1889 	 * which ranges apply to which voices on this synth, layer will apply
1890 	 * two notes on the channel, and unison all of them. Unison should really
1891 	 * be an engine feature to setup every voice for a given baudio structure.
1892 	 *
1893 	 * This works badly for the Prophet10 though, so may go for two midi
1894 	 * channels and decide how to intepret them.
1895 	 */
1896 	if (c == 2) {
1897 		if ((newchan = synth->midichannel - 1) < 0)
1898 		{
1899 			synth->midichannel = 0;
1900 			return;
1901 		}
1902 	} else {
1903 		if ((newchan = synth->midichannel + 1) > 15)
1904 		{
1905 			synth->midichannel = 15;
1906 			return;
1907 		}
1908 	}
1909 
1910 	printf("midichannel %i %i\n", c, newchan);
1911 
1912 	if (global.libtest == 0)
1913 	{
1914 		bristolMidiSendMsg(global.controlfd, synth->sid2,
1915 			127, 0, BRISTOL_MIDICHANNEL|newchan);
1916 		bristolMidiSendMsg(global.controlfd, synth->sid,
1917 			127, 0, BRISTOL_MIDICHANNEL|newchan);
1918 	}
1919 
1920 	synth->midichannel = newchan;
1921 }
1922 
1923 /*
1924  * For the sake of ease of use, links have been placed here to be called
1925  * by any of the devices created. They would be better in some other file,
1926  * perhaps with this as a dispatch.
1927  *
1928  * Param refers to the device index in the locations table given below.
1929  */
1930 static int
obxaCallback(brightonWindow * win,int panel,int index,float value)1931 obxaCallback(brightonWindow * win, int panel, int index, float value)
1932 {
1933 	guiSynth *synth = findSynth(global.synths, win);
1934 	int sendvalue, sid = 0;
1935 
1936 //printf("obxaCallback(%i, %i, %f): %x, %1.0f\n", panel, index, value, synth,
1937 //global.synths->mem.param[LAYER_SWITCH]);
1938 
1939 	if (synth->flags & SUPPRESS)
1940 		return(0);
1941 
1942 	if (synth == 0)
1943 		return(0);
1944 
1945 	if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0))
1946 		return(0);
1947 
1948 	if (obxaApp.resources[0].devlocn[index].to == 1.0)
1949 		sendvalue = value * C_RANGE_MIN_1;
1950 	else
1951 		sendvalue = value;
1952 
1953 	if (index == LAYER_SWITCH)
1954 	{
1955 		synth->mem.param[LAYER_SWITCH] = value;
1956 
1957 		obxaPanelSwitch(synth,
1958 			global.controlfd,
1959 			sid,
1960 			synth->dispatch[index].controller,
1961 			synth->dispatch[index].operator,
1962 			sendvalue);
1963 
1964 		return(0);
1965 	}
1966 
1967 	if (synth->mem.param[LAYER_SWITCH] == 0)
1968 	{
1969 		/*
1970 		 * This is actually broken for certain cases with the dual function of
1971 		 * the pulsewidth button.
1972 		 */
1973 		if (index != 15)
1974 			synth->mem.param[index] = value;
1975 		sid = synth->sid;
1976 	} else {
1977 		((guiSynth *) synth->second)->mem.param[index] = value;
1978 		if (index != 15)
1979 			synth->mem.param[DEVICE_COUNT + index] = value;
1980 		sid = synth->sid2;
1981 	}
1982 
1983 	/* Mode switches */
1984 	if ((index == 45) || (index == 46) || (index == 47))
1985 	{
1986 		if (index == 46)
1987 		{
1988 			if (value != 0)
1989 				splitPoint = -2;
1990 			else
1991 				splitPoint = -1;
1992 		}
1993 
1994 		obxaMode(synth, synth->dispatch[index].controller,
1995 			synth->dispatch[index].operator, value);
1996 
1997 		/* Looks odd, but need to hide the parameters in spare space. */
1998 		synth->mem.param[MOD_START + OB_MODCOUNT + index - 45] = value;
1999 		return(0);
2000 	}
2001 
2002 	if ((!global.libtest) || (index >= ACTIVE_DEVS))
2003 		synth->dispatch[index].routine(synth,
2004 			global.controlfd,
2005 			sid,
2006 			synth->dispatch[index].controller,
2007 			synth->dispatch[index].operator,
2008 			sendvalue);
2009 
2010 #ifdef DEBUG
2011 	else
2012 		printf("dispatch[%x,%i](%i, %i, %i, %i, %i)\n", synth, index,
2013 			global.controlfd,
2014 			synth->sid,
2015 			synth->dispatch[index].controller,
2016 			synth->dispatch[index].operator,
2017 			sendvalue);
2018 #endif
2019 
2020 	return(0);
2021 }
2022 
2023 /*
2024  * Any location initialisation required to run the callbacks. For bristol, this
2025  * will connect to the engine, and give it some base parameters.
2026  * May need to generate some application specific menus.
2027  * Will also then make specific requests to some of the devices to alter their
2028  * rendering.
2029  */
2030 static int
obxaInit(brightonWindow * win)2031 obxaInit(brightonWindow *win)
2032 {
2033 	guiSynth *synth = findSynth(global.synths, win);
2034 	dispatcher *dispatch;
2035 	int i;
2036 
2037 	if (synth == 0)
2038 	{
2039 		synth = findSynth(global.synths, 0);
2040 
2041 		if (synth == 0)
2042 		{
2043 			printf("cannot init\n");
2044 			return(0);
2045 		}
2046 	}
2047 
2048 	if ((initmem = synth->location) == 0)
2049 		initmem = 11;
2050 
2051 	synth->win = win;
2052 
2053 	printf("Initialise the %s link to bristol: %p %p\n",
2054 		synth->resources->name, synth, synth->win);
2055 
2056 	synth->mem.param = (float *)
2057 		brightonmalloc(DEVICE_COUNT * 2 * sizeof(float));
2058 	synth->mem.count = DEVICE_COUNT;
2059 	synth->mem.active = ACTIVE_DEVS;
2060 	synth->dispatch = (dispatcher *)
2061 		brightonmalloc(DEVICE_COUNT * sizeof(dispatcher));
2062 	dispatch = synth->dispatch;
2063 
2064 	synth->second = brightonmalloc(sizeof(guiSynth));
2065 	bcopy(synth, ((guiSynth *) synth->second), sizeof(guiSynth));
2066 	((guiSynth *) synth->second)->mem.param =
2067 		(float *) brightonmalloc(DEVICE_COUNT * sizeof(float));
2068 	((guiSynth *) synth->second)->mem.count = DEVICE_COUNT;
2069 	((guiSynth *) synth->second)->mem.active = ACTIVE_DEVS;
2070 	((guiSynth *) synth->second)->dispatch = synth->dispatch;
2071 
2072 	/*
2073 	 * We really want to have three connection mechanisms. These should be
2074 	 *	1. Unix named sockets.
2075 	 *	2. UDP sockets.
2076 	 *	3. MIDI pipe.
2077 	 */
2078 	if (!global.libtest)
2079 	{
2080 		int v;
2081 
2082 		if (synth->voices == BRISTOL_VOICECOUNT) {
2083 			synth->voices = 10;
2084 			((guiSynth *) synth->second)->voices = 5;
2085 		} else
2086 			((guiSynth *) synth->second)->voices = synth->voices >> 1;
2087 
2088 		v = synth->voices;
2089 
2090 		synth->synthtype = BRISTOL_OBX;
2091 		bcopy(&global, &manual, sizeof(guimain));
2092 		if ((synth->sid = initConnection(&global, synth)) < 0)
2093 			return(-1);
2094 
2095 		manual.flags |= BRISTOL_CONN_FORCE|BRIGHTON_NOENGINE;
2096 		manual.port = global.port;
2097 		manual.host = global.host;
2098 		synth->voices = ((guiSynth *) synth->second)->voices;
2099 		/*
2100 		 * Just 5 voices on each layer. This should be a parameter since they
2101 		 * had 3, 4 and 5 voices per layer originally.
2102 		 */
2103 		if ((synth->sid2 = initConnection(&manual, synth)) < 0)
2104 			return(-1);
2105 
2106 		global.manualfd = manual.controlfd;
2107 		global.manual = &manual;
2108 		manual.manual = &global;
2109 
2110 		synth->voices = v;
2111 	} else {
2112 		synth->sid = 5;
2113 		synth->sid2 = 10;
2114 	}
2115 
2116 	for (i = 0; i < DEVICE_COUNT; i++)
2117 		synth->dispatch[i].routine = obxaMidiSendMsg;
2118 
2119 	/* Glide and Unison, done */
2120 	dispatch[FIRST_DEV].controller = 126;
2121 	dispatch[FIRST_DEV].operator = 0;
2122 	dispatch[FIRST_DEV + 1].controller = 126;
2123 	dispatch[FIRST_DEV + 1].operator = 1;
2124 	dispatch[FIRST_DEV + 2].controller = 1;
2125 	dispatch[FIRST_DEV + 2].operator = 10;
2126 
2127 	/* LFO - operator 2 parameters - Done */
2128 	dispatch[FIRST_DEV + 3].controller = 2;
2129 	dispatch[FIRST_DEV + 3].operator = 0;
2130 	dispatch[FIRST_DEV + 4].controller = 126;
2131 	dispatch[FIRST_DEV + 4].operator = 19;
2132 	dispatch[FIRST_DEV + 5].controller = 126;
2133 	dispatch[FIRST_DEV + 5].operator = 20;
2134 	/* S/H - this should be a routing switch. */
2135 	dispatch[FIRST_DEV + 6].controller = 126;
2136 	dispatch[FIRST_DEV + 6].operator = 21;
2137 
2138 	/* Depth Osc/Osc/Filt - routing control/switches */
2139 	dispatch[FIRST_DEV + 7].controller = 126;
2140 	dispatch[FIRST_DEV + 7].operator = 4;
2141 	dispatch[FIRST_DEV + 8].controller = 126;
2142 	dispatch[FIRST_DEV + 8].operator = 5;
2143 	dispatch[FIRST_DEV + 9].controller = 126;
2144 	dispatch[FIRST_DEV + 9].operator = 6;
2145 	dispatch[FIRST_DEV + 10].controller = 126;
2146 	dispatch[FIRST_DEV + 10].operator = 7;
2147 
2148 	/* PWM Osc/Osc - routing control/switches */
2149 	dispatch[FIRST_DEV + 11].controller = 126;
2150 	dispatch[FIRST_DEV + 11].operator = 8;
2151 	dispatch[FIRST_DEV + 12].controller = 126;
2152 	dispatch[FIRST_DEV + 12].operator = 9;
2153 	dispatch[FIRST_DEV + 13].controller = 126;
2154 	dispatch[FIRST_DEV + 13].operator = 10;
2155 
2156 	/* Osc - Some routing switches. */
2157 	dispatch[FIRST_DEV + 14].controller = 0;
2158 	dispatch[FIRST_DEV + 14].operator = 1;
2159 	/* PWM - needs to adjust both oscillators, so need a dispatcher. */
2160 	dispatch[FIRST_DEV + 15].controller = 15;
2161 	dispatch[FIRST_DEV + 15].operator = 1;
2162 	dispatch[FIRST_DEV + 16].controller = 1;
2163 	dispatch[FIRST_DEV + 16].operator = 9;
2164 	/* Saw/Square. May need dispatch for tri when both off */
2165 	dispatch[FIRST_DEV + 17].controller = 0;
2166 	dispatch[FIRST_DEV + 17].operator = 4;
2167 	dispatch[FIRST_DEV + 18].controller = 0;
2168 	dispatch[FIRST_DEV + 18].operator = 6;
2169 	/* Crossmod and sync - routing switches */
2170 	dispatch[FIRST_DEV + 19].controller = 126;
2171 	dispatch[FIRST_DEV + 19].operator = 23;
2172 	dispatch[FIRST_DEV + 20].controller = 1;
2173 	dispatch[FIRST_DEV + 20].operator = 7;
2174 	/* Saw/Square. May need dispatch for tri when both off */
2175 	dispatch[FIRST_DEV + 21].controller = 1;
2176 	dispatch[FIRST_DEV + 21].operator = 4;
2177 	dispatch[FIRST_DEV + 22].controller = 1;
2178 	dispatch[FIRST_DEV + 22].operator = 6;
2179 	/* Osc waveforms need a dispatcher to enable tri with both buttons off. */
2180 	dispatch[FIRST_DEV + 15].routine =
2181 		dispatch[FIRST_DEV + 17].routine =
2182 		dispatch[FIRST_DEV + 18].routine =
2183 		dispatch[FIRST_DEV + 21].routine =
2184 		dispatch[FIRST_DEV + 22].routine =
2185 			(synthRoutine) obxaWaveform;
2186 
2187 	/* Filter - some routing switches */
2188 	dispatch[FIRST_DEV + 23].controller = 4;
2189 	dispatch[FIRST_DEV + 23].operator = 4;
2190 	dispatch[FIRST_DEV + 23].routine = (synthRoutine) obxaFilter;
2191 	dispatch[FIRST_DEV + 24].controller = 4;
2192 	dispatch[FIRST_DEV + 24].operator = 0;
2193 	dispatch[FIRST_DEV + 25].controller = 4;
2194 	dispatch[FIRST_DEV + 25].operator = 1;
2195 	dispatch[FIRST_DEV + 26].controller = 4;
2196 	dispatch[FIRST_DEV + 26].operator = 2;
2197 	/* Routing switches. Need to check on KBD tracking though */
2198 	dispatch[FIRST_DEV + 27].controller = 126;
2199 	dispatch[FIRST_DEV + 27].operator = 12;
2200 	dispatch[FIRST_DEV + 28].controller = 4;
2201 	dispatch[FIRST_DEV + 28].operator = 3;
2202 	dispatch[FIRST_DEV + 29].controller = 126;
2203 	dispatch[FIRST_DEV + 29].operator = 14;
2204 	dispatch[FIRST_DEV + 30].controller = 126;
2205 	dispatch[FIRST_DEV + 30].operator = 15;
2206 	dispatch[FIRST_DEV + 31].controller = 126;
2207 	dispatch[FIRST_DEV + 31].operator = 17;
2208 
2209 	/* Envelopes */
2210 	dispatch[FIRST_DEV + 32].controller = 3;
2211 	dispatch[FIRST_DEV + 32].operator = 0;
2212 	dispatch[FIRST_DEV + 33].controller = 3;
2213 	dispatch[FIRST_DEV + 33].operator = 1;
2214 	dispatch[FIRST_DEV + 34].controller = 3;
2215 	dispatch[FIRST_DEV + 34].operator = 2;
2216 	dispatch[FIRST_DEV + 35].controller = 3;
2217 	dispatch[FIRST_DEV + 35].operator = 3;
2218 	dispatch[FIRST_DEV + 36].controller = 5;
2219 	dispatch[FIRST_DEV + 36].operator = 0;
2220 	dispatch[FIRST_DEV + 37].controller = 5;
2221 	dispatch[FIRST_DEV + 37].operator = 1;
2222 	dispatch[FIRST_DEV + 38].controller = 5;
2223 	dispatch[FIRST_DEV + 38].operator = 2;
2224 	dispatch[FIRST_DEV + 39].controller = 5;
2225 	dispatch[FIRST_DEV + 39].operator = 3;
2226 	/* We need a separate dispatcher for the decay, since the reset button */
2227 	/* will affect the value. */
2228 	dispatch[FIRST_DEV + 35].routine = dispatch[FIRST_DEV + 39].routine =
2229 			(synthRoutine) obxaDecay;
2230 
2231 	/* Master volume - gain of envelope? */
2232 	dispatch[FIRST_DEV + 40].controller = 5;
2233 	dispatch[FIRST_DEV + 40].operator = 4;
2234 	/* Reset or 'release' DONE */
2235 	dispatch[FIRST_DEV + 41].controller = 41;
2236 	dispatch[FIRST_DEV + 41].operator = 0;
2237 	dispatch[FIRST_DEV + 41].routine = (synthRoutine) obxaDecay;
2238 	/* Mod to tremelo */
2239 	dispatch[FIRST_DEV + 42].controller = 126;
2240 	dispatch[FIRST_DEV + 42].operator = 18;
2241 	/* Balance. Should work as a dispatcher along with master volume? */
2242 	dispatch[FIRST_DEV + 43].controller = 126;
2243 	dispatch[FIRST_DEV + 43].operator = 28;
2244 	/* Master tune */
2245 	dispatch[FIRST_DEV + 44].controller = 126;
2246 	dispatch[FIRST_DEV + 44].operator = 2;
2247 
2248 	/* Mode management */
2249 	dispatch[FIRST_DEV + 45].controller = 45;
2250 	dispatch[FIRST_DEV + 45].operator = 0;
2251 	dispatch[FIRST_DEV + 46].controller = 46;
2252 	dispatch[FIRST_DEV + 46].operator = 1;
2253 	dispatch[FIRST_DEV + 47].controller = 47;
2254 	dispatch[FIRST_DEV + 47].operator = 2;
2255 	dispatch[FIRST_DEV + 45].routine =
2256 		dispatch[FIRST_DEV + 46].routine =
2257 		dispatch[FIRST_DEV + 47].routine = (synthRoutine) obxaMode;
2258 
2259 	/* Hold - DONE (stole from Juno.....). Remapped to chording */
2260 	dispatch[FIRST_DEV + 48].routine = (synthRoutine) obxaChord;
2261 	/* Master tune - Done. */
2262 	/*dispatch[FIRST_DEV + 48].controller = 126; */
2263 	/*dispatch[FIRST_DEV + 48].operator = 2; */
2264 	/* Autotune */
2265 	dispatch[FIRST_DEV + 49].routine = (synthRoutine) multiTune;
2266 
2267 	dispatch[FIRST_DEV + 79].routine = (synthRoutine) obxaSeqRate;
2268 
2269 /* Memories. */
2270 	dispatch[MEM_START + 0].controller = 16;
2271 	dispatch[MEM_START + 1].controller = 0;
2272 	dispatch[MEM_START + 2].controller = 1;
2273 	dispatch[MEM_START + 3].controller = 2;
2274 	dispatch[MEM_START + 4].controller = 3;
2275 	dispatch[MEM_START + 5].controller = 4;
2276 	dispatch[MEM_START + 6].controller = 5;
2277 	dispatch[MEM_START + 7].controller = 6;
2278 	dispatch[MEM_START + 8].controller = 7;
2279 	dispatch[MEM_START + 9].controller = 8;
2280 	dispatch[MEM_START + 10].controller = 9;
2281 	dispatch[MEM_START + 11].controller = 10;
2282 	dispatch[MEM_START + 12].controller = 11;
2283 	dispatch[MEM_START + 13].controller = 12;
2284 	dispatch[MEM_START + 14].controller = 13;
2285 	dispatch[MEM_START + 15].controller = 14;
2286 	dispatch[MEM_START + 16].controller = 15;
2287 	dispatch[MEM_START + 17].controller = 17;
2288 
2289 	dispatch[MEM_START + 0].operator = MEM_START + 0;
2290 	dispatch[MEM_START + 1].operator = MEM_START + 1;
2291 	dispatch[MEM_START + 2].operator = MEM_START + 2;
2292 	dispatch[MEM_START + 3].operator = MEM_START + 3;
2293 	dispatch[MEM_START + 4].operator = MEM_START + 4;
2294 	dispatch[MEM_START + 5].operator = MEM_START + 5;
2295 	dispatch[MEM_START + 6].operator = MEM_START + 6;
2296 	dispatch[MEM_START + 7].operator = MEM_START + 7;
2297 	dispatch[MEM_START + 8].operator = MEM_START + 8;
2298 	dispatch[MEM_START + 9].operator = MEM_START + 9;
2299 	dispatch[MEM_START + 10].operator = MEM_START + 10;
2300 	dispatch[MEM_START + 11].operator = MEM_START + 11;
2301 	dispatch[MEM_START + 12].operator = MEM_START + 12;
2302 	dispatch[MEM_START + 13].operator = MEM_START + 13;
2303 	dispatch[MEM_START + 14].operator = MEM_START + 14;
2304 	dispatch[MEM_START + 15].operator = MEM_START + 15;
2305 	dispatch[MEM_START + 16].operator = MEM_START + 16;
2306 	dispatch[MEM_START + 17].operator = MEM_START + 17;
2307 
2308 	dispatch[MEM_START + 0].routine =
2309 		dispatch[MEM_START + 1].routine =
2310 		dispatch[MEM_START + 2].routine =
2311 		dispatch[MEM_START + 3].routine =
2312 		dispatch[MEM_START + 4].routine =
2313 		dispatch[MEM_START + 5].routine =
2314 		dispatch[MEM_START + 6].routine =
2315 		dispatch[MEM_START + 7].routine =
2316 		dispatch[MEM_START + 8].routine =
2317 		dispatch[MEM_START + 9].routine =
2318 		dispatch[MEM_START + 10].routine =
2319 		dispatch[MEM_START + 11].routine =
2320 		dispatch[MEM_START + 12].routine =
2321 		dispatch[MEM_START + 13].routine =
2322 		dispatch[MEM_START + 14].routine =
2323 		dispatch[MEM_START + 15].routine =
2324 		dispatch[MEM_START + 16].routine =
2325 		dispatch[MEM_START + 17].routine =
2326 			(synthRoutine) obxaMemory;
2327 
2328 	dispatch[FIRST_DEV + 68].routine = dispatch[FIRST_DEV + 69].routine =
2329 		(synthRoutine) obxaMidi;
2330 	dispatch[FIRST_DEV + 68].controller = 1;
2331 	dispatch[FIRST_DEV + 69].controller = 2;
2332 
2333 	dispatch[FIRST_DEV + 71].routine = (synthRoutine) obxaFunction;
2334 	dispatch[FIRST_DEV + 72].controller = 72;
2335 	dispatch[FIRST_DEV + 72].operator = 0;
2336 	dispatch[FIRST_DEV + 72].routine = (synthRoutine) obxaArpeggiate;
2337 	dispatch[FIRST_DEV + 73].controller = 73;
2338 	dispatch[FIRST_DEV + 73].operator = 1;
2339 	dispatch[FIRST_DEV + 73].routine = (synthRoutine) obxaArpeggiate;
2340 	dispatch[FIRST_DEV + 74].controller = 74;
2341 	dispatch[FIRST_DEV + 74].operator = 2;
2342 	dispatch[FIRST_DEV + 74].routine = (synthRoutine) obxaArpeggiate;
2343 
2344 	dispatch[FIRST_DEV + 75].routine = (synthRoutine) obxaSequence;
2345 	dispatch[FIRST_DEV + 76].controller = 76;
2346 	dispatch[FIRST_DEV + 76].operator = 0;
2347 	dispatch[FIRST_DEV + 76].routine = (synthRoutine) obxaArpOctave;
2348 	dispatch[FIRST_DEV + 77].controller = 77;
2349 	dispatch[FIRST_DEV + 77].operator = 1;
2350 	dispatch[FIRST_DEV + 77].routine = (synthRoutine) obxaArpOctave;
2351 	dispatch[FIRST_DEV + 78].controller = 78;
2352 	dispatch[FIRST_DEV + 78].operator = 2;
2353 	dispatch[FIRST_DEV + 78].routine = (synthRoutine) obxaArpOctave;
2354 
2355 	dispatch[RADIOSET_1].other1 = -1;
2356 	dispatch[RADIOSET_2].other1 = -1;
2357 	dispatch[RADIOSET_3].other1 = -1;
2358 	dispatch[SEQ_MODE].other1 = -1;
2359 	dispatch[OCTAVE_MODE].other1 = -1;
2360 
2361 	dispatch[FIRST_DEV + 70].routine = (synthRoutine) obxaPanelSwitch;
2362 
2363 	dispatch[RADIOSET_1].other1 = -1;
2364 
2365 	/* Tune/Gain osc-1/2 main layer */
2366 	bristolMidiSendMsg(global.controlfd, synth->sid, 0, 2, 8192);
2367 	bristolMidiSendMsg(global.controlfd, synth->sid, 1, 2, 8192);
2368 	bristolMidiSendMsg(global.controlfd, synth->sid, 0, 3, C_RANGE_MIN_1);
2369 	bristolMidiSendMsg(global.controlfd, synth->sid, 1, 3, C_RANGE_MIN_1);
2370 	/* Gain on filter contour */
2371 	bristolMidiSendMsg(global.controlfd, synth->sid, 3, 4, C_RANGE_MIN_1);
2372 	/* Select alt filter */
2373 	bristolMidiSendMsg(global.controlfd, synth->sid, 4, 4, 0);
2374 
2375 	/* Tune/Gain osc-1/2 second layer */
2376 	bristolMidiSendMsg(global.controlfd, synth->sid2, 0, 2, 8192);
2377 	bristolMidiSendMsg(global.controlfd, synth->sid2, 1, 2, 8192);
2378 	bristolMidiSendMsg(global.controlfd, synth->sid2, 0, 3, C_RANGE_MIN_1);
2379 	bristolMidiSendMsg(global.controlfd, synth->sid2, 1, 3, C_RANGE_MIN_1);
2380 	/* Gain on filter contour */
2381 	bristolMidiSendMsg(global.controlfd, synth->sid2, 3, 4, C_RANGE_MIN_1);
2382 	/* Select alt filter and pole remixing */
2383 	bristolMidiSendMsg(global.controlfd, synth->sid2, 4, 4, 4);
2384 	bristolMidiSendMsg(global.controlfd, synth->sid2, 4, 7, 4096);
2385 
2386 	/* This cause the voices to see REKEY events for arpeg and seq steps */
2387 	bristolMidiSendMsg(global.controlfd, synth->sid,
2388 		BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_TRIGGER, 1);
2389 	bristolMidiSendMsg(global.controlfd, synth->sid,
2390 		BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_RANGE, 2);
2391 	bristolMidiSendMsg(global.controlfd, synth->sid,
2392 		BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_TRIGGER, 1);
2393 	bristolMidiSendMsg(global.controlfd, synth->sid,
2394 		BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RANGE, 2);
2395 
2396 	return(0);
2397 }
2398 
2399 /*
2400  * This will be called to make any routine specific parameters available.
2401  */
2402 static int
obxaConfigure(brightonWindow * win)2403 obxaConfigure(brightonWindow *win)
2404 {
2405 	guiSynth *synth = findSynth(global.synths, win);
2406 	brightonEvent event;
2407 
2408 	if (synth == 0)
2409 	{
2410 		printf("problems going operational\n");
2411 		return(-1);
2412 	}
2413 
2414 	if (synth->flags & OPERATIONAL)
2415 		return(0);
2416 
2417 	printf("going operational: %p, %p\n", synth, win);
2418 
2419 	synth->flags |= OPERATIONAL;
2420 	synth->keypanel = 1;
2421 	synth->keypanel2 = -1;
2422 	synth->transpose = 36;
2423 
2424 	/* Don't load a memory, send a bank, location and load request. */
2425 	event.intvalue = 1;
2426 	brightonParamChange(synth->win, synth->panel,
2427 		MEM_START + 1, &event);
2428 	brightonParamChange(synth->win, synth->panel,
2429 		MEM_START + 9, &event);
2430 
2431 	multiTune(synth, 0,0,0,0,0);
2432 
2433 	synth->mem.param[LAYER_SWITCH] = 0;
2434 
2435 	synth->bank = 1;
2436 
2437 	/*
2438 	 * For the OBXa, most of the following has to be moved into the memory
2439 	 * load routines. It is a new paradigm - one panel, two synths.
2440 	 */
2441 	obxaLoadMemory(synth, "obxa", 0, initmem,
2442 		synth->mem.active, FIRST_DEV, 0);
2443 
2444 	synth->mem.param[LAYER_SWITCH] = 0;
2445 
2446 	/*
2447 	 * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only
2448 	 * occurs on first paint, so we suppress the first paint, and then request
2449 	 * an expose here.
2450 	 */
2451 	event.type = BRIGHTON_EXPOSE;
2452 	event.intvalue = 1;
2453 	brightonParamChange(synth->win, KEY_PANEL, -1, &event);
2454 
2455 	/* Set arpeggiator to 2 octaves and a middle rate */
2456 	event.type = BRIGHTON_FLOAT;
2457 	event.value = 1.0;
2458 	brightonParamChange(synth->win, 0, OCTAVE_MODE + 1, &event);
2459 	event.value = 0.4;
2460 	brightonParamChange(synth->win, 0, 79, &event);
2461 
2462 	synth->loadMemory = (loadRoutine) obxaLoadMemory;
2463 	synth->saveMemory = (saveRoutine) obxaSaveMemory;
2464 
2465 	configureGlobals(synth);
2466 	return(0);
2467 }
2468 
2469