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