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 #include <fcntl.h>
23 
24 #include "brighton.h"
25 #include "brightonMini.h"
26 #include "brightoninternals.h"
27 
28 static int sidInit();
29 static int sidConfigure();
30 static int sidCallback(brightonWindow *, int, int, float);
31 static int sidModCallback(brightonWindow *, int, int, float);
32 static int midiCallback(brightonWindow *, int, int, float);
33 static int sidKeyCallback(brightonWindow *, int, int, float);
34 
35 extern guimain global;
36 
37 #include "brightonKeys.h"
38 
39 #define SYNTH_NAME synth->resources->name
40 
41 #define DEVICE_COUNT 135
42 #define ACTIVE_DEVS 118
43 #define MEM_START ACTIVE_DEVS
44 
45 #define ENTRY_POT 18
46 
47 
48 #define KEY_PANEL 1
49 #define MODS_PANEL 2
50 #define DISPLAY_DEV (DEVICE_COUNT - 1)
51 
52 static int dc, mbh = 0;
53 
54 /*
55  * This structure is for device definition. The structure is defined in
56  * include/brighton.h, further definitions in brighton/brightonDevtable.h and
57  * include/brightoninternals.h
58  *
59  *	typedef int (*brightonCallback)(int, float);
60  *	typedef struct BrightonLocations {
61  *		int device; 0=rotary, 1=scale, etc.
62  *		float relx, rely; relative position with regards to 1000 by 1000 window
63  *		float relw, relh; relative height.
64  *		int from, to;
65  *		brightonCallback callback; specific to this dev
66  *		char *image; bitmap. If zero take a device default.
67  *		int flags;
68  *	} brightonLocations;
69  *
70  * This example is for a sidBristol type synth interface.
71  */
72 
73 /*
74  * The GUI should give three voices with all the OSC, ENV, RM, SYNC options
75  * and then separately the test, multi and detune.
76  *
77  * Tri/Ramp/Square/Noise
78  * PW/Tune/transpose(/Glide?)
79  * RM/SYNC/Mute/Routing
80  * Att/Dec/Sust/Rel
81  *
82  * osc3 -> PWM osc 1/2
83  *
84  * Filter:
85  * freq, res, pole
86  * HP/BP/LP inc 24dB
87  *
88  * should add in option * of osc3 and env3 to filter cutoff.
89  * Multi
90  *
91  * Must have S/N, leakage, global tuning. DC bias? Reset?.
92  *
93  * Voice options to include:
94  *
95  * 	mono (with detune then between voices in emulator)
96  * 	three voice poly-1: all play same sound
97  * 	three voice poly-2: all have their own sound
98  * 	two voice poly, voice 3 arpeggio - argeggiate all other held notes
99  *
100  * Arpeggiator to have rate, retrig and wavescanning, rates down to X samples.
101  *
102  * We should consider using two SID, the second one could be used just for
103  * an extra Env and Osc(LF) to modulate the first one, later look at more
104  * voices or other layer options?
105  *
106  * The second SID will have voices 1 + 2 in TEST state, no output will be taken
107  * just clocked, no filter selections made to all reduce overhead - we only
108  * want env3 and osc3 outputs from the registers anyway.
109  *
110  * MODS:
111  *
112  * Env will have adsr plus routing
113  * LFO will have waveform, rate (0.1-10Hz) and routing
114  *
115  * Destinations can be
116  * 	vibrato, PW -> v1/v2/v3.
117  *	wah
118  *
119  * Notes:
120  *
121  * 	Lost multi, vol - replaced them. FIXED
122  * 	Lost detune in multi FIXED CHECK
123  *
124  *	S/N ratio is far too high (value levels needs reducing) FIXED
125  *	Filter res is not working FIXED
126  *	Mixed 12/24 filters not working FIXED
127  *	Mods are mixed up re lfo/env to what parameters FIXED
128  *	Mods are overloaded FIXED
129  *	Mods default to noise FIXED
130  *	Noise MOD does not work - no signal output from SID-2. FIXED
131  *	Tune/Transpose are not proactive Fixed
132  *	Glide not implemented. FIXED
133  *	Pitch bend implemented. FIXED, but leaves notes shifted when disabled.
134  *	RM damaged FIXED
135  *	Memories using S&H do not get LFO Mod loaded correctly. FIXED
136  *
137  *	Key assign modes finished. FIXED
138  *		Need to clear out keys when changing modes in engine. FIXED
139  *	Arpeggio finished, needs more testing, esp trig FIXED
140  *
141  * Implemented two new arpeggiation modes, Arpeg-1 and Arpeg-2. Both will split
142  * the keyboard at note 52 then Arpeg-1 will apply on the top half, the bottom
143  * half can play duophonic baselines. Arpeg-2 will apply to the bottom half
144  * and the upper half can play duophonic leads.
145  *
146  * Review volume levels direct/filter and Multi.
147  *
148  * Linux audio drivers are broken, stutter with window changes.
149  *
150  * May need more Poly modes:
151  *	lowest key, highest key, arpeggiate rest.
152  *
153  * Future release
154  *
155  *	need Mod env retrig option - legato?
156  *	need Aud env retrig option - legato?
157  *	access to analogue parameters from GUI
158  *	filter tracking keyboard - whick key?
159  *	velocity to mod, filter, pw
160  *	arpeg direction
161  */
162 
163 /* SID-1 */
164 #define V1R1 50
165 #define V1R2 120
166 #define V1R3 240
167 #define V1R4 430
168 
169 #define VD1 36
170 #define VD2 22
171 #define VD3 2
172 
173 #define VBW1 28
174 #define VBW2 10
175 #define VBW3 45
176 
177 #define VBH1 45
178 #define VBH2 110
179 #define VBH3 370
180 #define VBH4 290
181 
182 #define V1C1 25
183 #define V1C2 (V1C1 + VD1)
184 #define V1C3 (V1C2 + VD1)
185 #define V1C4 (V1C3 + VD1)
186 #define V1C1b (V1C1 + VD3)
187 #define V1C2b (V1C2 + VD3)
188 #define V1C3b (V1C3 + VD3)
189 #define V1C4b (V1C4 + VD3)
190 #define V1C5 (V1C4 + VD1 + 15)
191 #define V1C6 (V1C5 + VD2)
192 #define V1C7 (V1C6 + VD2)
193 #define V1C8 (V1C7 + VD2)
194 
195 #define V2C1 (V1C8 + VD2 + VD1)
196 #define V2C2 (V2C1 + VD1)
197 #define V2C3 (V2C2 + VD1)
198 #define V2C4 (V2C3 + VD1)
199 #define V2C1b (V2C1 + VD3)
200 #define V2C2b (V2C2 + VD3)
201 #define V2C3b (V2C3 + VD3)
202 #define V2C4b (V2C4 + VD3)
203 #define V2C5 (V2C4 + VD1 + 15)
204 #define V2C6 (V2C5 + VD2)
205 #define V2C7 (V2C6 + VD2)
206 #define V2C8 (V2C7 + VD2)
207 
208 #define V3C1 (V2C8 + VD2 + VD1)
209 #define V3C2 (V3C1 + VD1)
210 #define V3C3 (V3C2 + VD1)
211 #define V3C4 (V3C3 + VD1)
212 #define V3C1b (V3C1 + VD3)
213 #define V3C2b (V3C2 + VD3)
214 #define V3C3b (V3C3 + VD3)
215 #define V3C4b (V3C4 + VD3)
216 #define V3C5 (V3C4 + VD1 + 15)
217 #define V3C6 (V3C5 + VD2)
218 #define V3C7 (V3C6 + VD2)
219 #define V3C8 (V3C7 + VD2)
220 
221 #define FC1 (V3C8 + VD2 + VD1)
222 #define FC2 (FC1 + VD1)
223 #define FC3 (FC2 + VD1)
224 #define FC1b (FC1 + VD3)
225 #define FC2b (FC2 + VD3)
226 #define FC3b (FC3 + VD3)
227 
228 /* SID-2 Mods */
229 #define S2R0 650
230 #define S2R1 (S2R0 + 30) //630
231 #define S2R2 (S2R1 + 45) //675
232 #define S2R3 (S2R2 + 75) //750
233 #define S2R4 (S2R3 + 75) //825
234 
235 #define S2C0 20
236 #define S2C1 (S2C0 + VD1 + VD1 + 5)
237 #define S2C1b (S2C1 + VD1/2)
238 #define S2C2 (S2C1 + VD1)
239 #define S2C2b (S2C1 + VD1 + VD1/2)
240 #define S2C3 (S2C2 + VD1)
241 #define S2C3b (S2C3 + VD1/2)
242 #define S2C4 (S2C3 + VD1)
243 #define S2C5 (S2C4 + VD1 + VD2)
244 #define S2C6 (S2C5 + VD1)
245 
246 #define S2C7 (S2C6 + VD1 + VD1)
247 #define S2C8 (S2C7 + VD1)
248 #define S2C8b (S2C8 + VD1 + VD2)
249 #define S2C9 (S2C8b + VD2)
250 #define S2C10 (S2C9 + VD2)
251 #define S2C11 (S2C10 + VD2)
252 #define S2C12 (S2C11 + VD2)
253 
254 #define S2C13 (S2C12 + VD1 + 10)
255 #define S2C14 (S2C13 + VD1/2)
256 #define S2C15 (S2C13 + VD1)
257 
258 #define S2C16 (S2C15 + VD1 + VD2)
259 #define S2C17 (S2C16 + VD1)
260 #define S2C18 (S2C17 + VD1)
261 #define S2C19 (S2C18 + VD1)
262 #define S2C20 (S2C19 + VD1)
263 #define S2C21 (S2C20 + VD1)
264 #define S2C22 (S2C21 + VD1)
265 #define S2C23 (S2C22 + VD1)
266 
267 static
268 brightonLocations modwheel[5] = {
269 	{"", BRIGHTON_MODWHEEL, 0, 0, 380, 1000, 0, 1, 0,
270 		"bitmaps/knobs/modwheel.xpm", 0,
271 		BRIGHTON_HSCALE|BRIGHTON_NOSHADOW|BRIGHTON_NOTCH},
272 	{"", 2, 500, 50, 500, 130, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
273 		"bitmaps/buttons/sidbon.xpm", 0},
274 	{"", 2, 500, 306, 500, 130, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
275 		"bitmaps/buttons/sidbon.xpm", 0},
276 	{"", 2, 500, 562, 500, 130, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
277 		"bitmaps/buttons/sidbon.xpm", 0},
278 	{"", 2, 500, 820, 500, 130, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
279 		"bitmaps/buttons/sidbongreen.xpm", 0},
280 };
281 
282 static
283 brightonLocations locations[DEVICE_COUNT] = {
284 	/*
285 	 * Three voices with same parameterisation, roughly
286 	 * Tri/Ramp/Square/Noise Buttons
287 	 * RM/SYNC/Mute/Routing(Multi global) Buttons
288 	 * PW/Tune/transpose(/Glide?) - Pots
289 	 * Att/Dec/Sust/Rel - Sliders
290 	 */
291 	{"V1-Noise", 2, V1C1, V1R2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
292 		"bitmaps/buttons/sidbon.xpm", 0},
293 	{"V1-Tri", 2, V1C2, V1R2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
294 		"bitmaps/buttons/sidbon.xpm", 0},
295 	{"V1-Ramp", 2, V1C3, V1R2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
296 		"bitmaps/buttons/sidbon.xpm", 0},
297 	{"V1-Square", 2, V1C4, V1R2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
298 		"bitmaps/buttons/sidbon.xpm", 0},
299 	{"V1-PW", 0, V1C1b, V1R3, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobred.xpm", 0, 0},
300 	{"V1-Tune", 0, V1C2b, V1R3, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobred.xpm", 0,
301 		BRIGHTON_NOTCH},
302 	{"V1-Transpose", 0, V1C3b, V1R3, VBW3, VBH2, 0, 24,0, "bitmaps/knobs/knobred.xpm", 0, 0},
303 	{"V1-Glide", 0, V1C4b, V1R3, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobred.xpm", 0, 0},
304 	{"V1-RM", 2, V1C1, V1R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
305 		"bitmaps/buttons/sidbon.xpm", 0},
306 	{"V1-3-1-Sync", 2, V1C2, V1R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
307 		"bitmaps/buttons/sidbon.xpm", 0},
308 	{"V1-Mute", 2, V1C3, V1R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
309 		"bitmaps/buttons/sidbon.xpm", 0},
310 	{"V1-Filt", 2, V1C4, V1R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
311 		"bitmaps/buttons/sidbon.xpm", 0},
312 	{"V1-Attack", 1, V1C5, V1R2, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm",
313 		0, 0},
314 	{"V1-Decay", 1, V1C6, V1R2, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm",
315 		0, 0},
316 	{"V1-Sustain", 1, V1C7, V1R2, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm",
317 		0, 0},
318 	{"V1-Release", 1, V1C8, V1R2, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm",
319 		0, 0},
320 	/* Dummies */
321 	{"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm",
322 		0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN},
323 	{"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm",
324 		0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN},
325 	{"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm",
326 		0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN},
327 	{"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm",
328 		0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN},
329 
330 	/* Voice 2 - 20 */
331 	{"V2-Noise", 2, V2C1, V1R2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
332 		"bitmaps/buttons/sidbon.xpm", 0},
333 	{"V2-Tri", 2, V2C2, V1R2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
334 		"bitmaps/buttons/sidbon.xpm", 0},
335 	{"V2-Ramp", 2, V2C3, V1R2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
336 		"bitmaps/buttons/sidbon.xpm", 0},
337 	{"V2-Square", 2, V2C4, V1R2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
338 		"bitmaps/buttons/sidbon.xpm", 0},
339 	{"V2-PW", 0, V2C1b, V1R3, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobred.xpm", 0,0},
340 	{"V2-Tune", 0, V2C2b, V1R3, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobred.xpm", 0,
341 		BRIGHTON_NOTCH},
342 	{"V2-Transpose", 0, V2C3b, V1R3, VBW3, VBH2, 0, 24, 0, "bitmaps/knobs/knobred.xpm",0,0},
343 	{"V2-Glide", 0, V2C4b, V1R3, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobred.xpm", 0,0},
344 	{"V2-RM-1-2", 2, V2C1, V1R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
345 		"bitmaps/buttons/sidbon.xpm", 0},
346 	{"V2-Sync", 2, V2C2, V1R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
347 		"bitmaps/buttons/sidbon.xpm", 0},
348 	{"V2-Mute", 2, V2C3, V1R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
349 		"bitmaps/buttons/sidbon.xpm", 0},
350 	{"V2-Filt", 2, V2C4, V1R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
351 		"bitmaps/buttons/sidbon.xpm", 0},
352 	{"V2-Attack", 1, V2C5, V1R2, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm",
353 		0, 0},
354 	{"V2-Decay", 1, V2C6, V1R2, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm",
355 		0, 0},
356 	{"V2-Sustain", 1, V2C7, V1R2, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm",
357 		0, 0},
358 	{"V2-Release", 1, V2C8, V1R2, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm",
359 		0, 0},
360 	/* Dummies */
361 	{"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm",
362 		0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN},
363 	{"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm",
364 		0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN},
365 	{"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm",
366 		0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN},
367 	{"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm",
368 		0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN},
369 
370 	/* Voice 3 - 40 */
371 	{"V3-Noise", 2, V3C1, V1R2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
372 		"bitmaps/buttons/sidbon.xpm", 0},
373 	{"V3-Tri", 2, V3C2, V1R2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
374 		"bitmaps/buttons/sidbon.xpm", 0},
375 	{"V3-Ramp", 2, V3C3, V1R2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
376 		"bitmaps/buttons/sidbon.xpm", 0},
377 	{"V3-Square", 2, V3C4, V1R2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
378 		"bitmaps/buttons/sidbon.xpm", 0},
379 	{"V3-PW", 0, V3C1b, V1R3, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobred.xpm", 0, 0},
380 	{"V3-Tune", 0, V3C2b, V1R3, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobred.xpm", 0,
381 		BRIGHTON_NOTCH},
382 	{"V3-Transpose", 0, V3C3b, V1R3, VBW3, VBH2, 0, 24, 0, "bitmaps/knobs/knobred.xpm", 0,0},
383 	{"V3-Glide", 0, V3C4b, V1R3, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobred.xpm", 0, 0},
384 	{"V3-RM-2-3", 2, V3C1, V1R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
385 		"bitmaps/buttons/sidbon.xpm", 0},
386 	{"V3-Sync", 2, V3C2, V1R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
387 		"bitmaps/buttons/sidbon.xpm", 0},
388 	{"V3-Mute", 2, V3C3, V1R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
389 		"bitmaps/buttons/sidbon.xpm", 0},
390 	{"V3-Filt", 2, V3C4, V1R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
391 		"bitmaps/buttons/sidbon.xpm", 0},
392 	{"V3-Attack", 1, V3C5, V1R2, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm",
393 		0, 0},
394 	{"V3-Decay", 1, V3C6, V1R2, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm",
395 		0, 0},
396 	{"V3-Sustain", 1, V3C7, V1R2, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm",
397 		0, 0},
398 	{"V3-Release", 1, V3C8, V1R2, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm",
399 		0, 0},
400 	/* Dummies */
401 	{"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm",
402 		0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN},
403 	{"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm",
404 		0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN},
405 	{"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm",
406 		0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN},
407 	{"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm",
408 		0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN},
409 
410 	/* Filter - 60 */
411 	{"VCF-HP", 2, FC1, V1R2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
412 		"bitmaps/buttons/sidbon.xpm", 0},
413 	{"VCF-BP", 2, FC2, V1R2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
414 		"bitmaps/buttons/sidbon.xpm", 0},
415 	{"VCF-LP", 2, FC3, V1R2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
416 		"bitmaps/buttons/sidbon.xpm", 0},
417 	{"VCF-Cutoff", 0, FC1b, V1R3, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobred.xpm", 0, 0},
418 	{"VCF-Resonance", 0, FC2b, V1R3, VBW3, VBH2, 0, 15,0, "bitmaps/knobs/knobred.xpm", 0, 0},
419 	{"VCF-Mix", 0, FC3b, V1R3, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobred.xpm", 0, 0},
420 	{"VCF-LPF24", 2, FC3, V1R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
421 		"bitmaps/buttons/sidbon.xpm", 0},
422 
423 	/* VCF Multi and MasterVol */
424 	{"VCF-Multi", 2, FC1, V1R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
425 		"bitmaps/buttons/sidbon.xpm", 0},
426 	{"MasterVolume", 0,  S2C23+8, S2R0 - 50, VBW3, VBH2, 0, 15, 0,
427 		"bitmaps/knobs/knobyellow.xpm", 0, 0},
428 
429 	/*
430 	 * MODS: 69 (was 70)
431 	 *
432 	 * Env will have adsr plus routing
433 	 * LFO will have waveform, rate (0.1-10Hz) and routing
434 	 *
435 	 * Destinations can be
436 	 * 	vibrato, PW -> v1/v2/v3.
437 	 *	wah
438 	 */
439 	/* Key Mode */
440 	{"Mode Mono", 2, S2C0-3, S2R0, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
441 		"bitmaps/buttons/sidbon.xpm", 0},
442 	{"Mode Poly1", 2, S2C0-3, S2R0+60, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
443 		"bitmaps/buttons/sidbon.xpm", 0},
444 	{"Mode Poly2", 2, S2C0-3, S2R0+120, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
445 		"bitmaps/buttons/sidbon.xpm", 0},
446 	{"Mode Arpeg1", 2, S2C0-3, S2R0+180, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
447 		"bitmaps/buttons/sidbon.xpm", 0},
448 	{"Mode Arpeg2", 2, S2C0-3, S2R0+240, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
449 		"bitmaps/buttons/sidbon.xpm", 0},
450 
451 	/* Mods - 76 */
452 	{"LFO-Rate", 0, S2C1b+2, S2R1, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobgreen.xpm",
453 		0, 0},
454 	{"LFO-Depth", 0, S2C3b+2, S2R1, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobgreen.xpm",
455 		0, 0},
456 	{"???1", 2, S2C1, S2R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
457 		"bitmaps/buttons/sidbon.xpm", 0},
458 	{"???2", 2, S2C2, S2R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
459 		"bitmaps/buttons/sidbon.xpm", 0},
460 	{"???3", 2, S2C3, S2R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
461 		"bitmaps/buttons/sidbon.xpm", 0},
462 	{"???4", 2, S2C4, S2R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
463 		"bitmaps/buttons/sidbon.xpm", 0},
464 
465 	/* 80 */
466 	{"LFO-PW-V1", 2, S2C5, S2R0, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
467 		"bitmaps/buttons/sidbon.xpm", 0},
468 	{"LFO-PW-V2", 2, S2C5, S2R2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
469 		"bitmaps/buttons/sidbon.xpm", 0},
470 	{"LFO-PW-V3", 2, S2C5, S2R3, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
471 		"bitmaps/buttons/sidbon.xpm", 0},
472 	{"LFO-FM-V1", 2, S2C6, S2R0, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
473 		"bitmaps/buttons/sidbon.xpm", 0},
474 	{"LFO-FM-V2", 2, S2C6, S2R2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
475 		"bitmaps/buttons/sidbon.xpm", 0},
476 	{"LFO-FM-V3", 2, S2C6, S2R3, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
477 		"bitmaps/buttons/sidbon.xpm", 0},
478 	{"LFO-FM-Filt", 2, S2C6, S2R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
479 		"bitmaps/buttons/sidbon.xpm", 0},
480 	/* Mod Touch control */
481 	{"LFO-F-Touch", 2, S2C1b, S2R0 - 70, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
482 		"bitmaps/buttons/sidbon.xpm", 0},
483 	{"LFO-G-Touch", 2, S2C3b, S2R0 - 70, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
484 		"bitmaps/buttons/sidbon.xpm", 0},
485 	{"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm",
486 		0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN},
487 	{"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm",
488 		0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN},
489 	{"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm",
490 		0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN},
491 	{"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm",
492 		0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN},
493 	{"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm",
494 		0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN},
495 	{"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm",
496 		0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN},
497 
498 	/* Env mods 95 */
499 	{"ModEnv-FM-V1", 2, S2C7, S2R0, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
500 		"bitmaps/buttons/sidbon.xpm", 0},
501 	{"ModEnv-FM-V2", 2, S2C7, S2R2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
502 		"bitmaps/buttons/sidbon.xpm", 0},
503 	{"ModEnv-FM-V3", 2, S2C7, S2R3, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
504 		"bitmaps/buttons/sidbon.xpm", 0},
505 	{"ModEnv-FM-Filt", 2, S2C7, S2R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
506 		"bitmaps/buttons/sidbon.xpm", 0},
507 	{"ModEnv-PW-V1", 2, S2C8, S2R0, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
508 		"bitmaps/buttons/sidbon.xpm", 0},
509 	{"ModEnv-PW-V2", 2, S2C8, S2R2, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
510 		"bitmaps/buttons/sidbon.xpm", 0},
511 	{"ModEnv-PW-V3", 2, S2C8, S2R3, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
512 		"bitmaps/buttons/sidbon.xpm", 0},
513 
514 	/* 102 - Mod Env */
515 	{"ModEnv-Attack", 1, S2C8b, S2R0, VBW2, VBH4, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm",
516 		0, 0},
517 	{"ModEnv-Sustain", 1, S2C9, S2R0, VBW2, VBH4, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm",
518 		0, 0},
519 	{"ModEnv-Decay", 1, S2C10, S2R0, VBW2, VBH4, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm",
520 		0, 0},
521 	{"ModEnv-Release", 1, S2C11, S2R0, VBW2, VBH4, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm",
522 		0, 0},
523 	{"ModEnv-Gain", 1, S2C12, S2R0, VBW2, VBH4, 0, 1, 0, "bitmaps/buttons/polywhiteV.xpm",
524 		0, 0},
525 	{"ModEnv-Touch", 2, S2C11+13, S2R0-70, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
526 		"bitmaps/buttons/sidbon.xpm", 0},
527 	{"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm",
528 		0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN},
529 
530 	/*
531 	 * This will shadow the version of the memory. Existing memories will have
532 	 * a zero in here (0.40) ones saved by this release (0.40.2) will have a
533 	 * 1 in there, this allows the GUI to adjust the keymode parameter.
534 	 */
535 	{"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm",
536 		0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN},
537 
538 	/* 110 - These shadow the mod panel */
539 	{"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm",
540 		0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN},
541 	{"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm",
542 		0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN},
543 	{"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm",
544 		0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN},
545 	{"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm",
546 		0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN},
547 	{"", 1, 0, 0, VBW2, VBH3, 0, 15, 0, "bitmaps/buttons/polywhiteV.xpm",
548 		0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN},
549 
550 	{"Arpeg-Rate", 0, S2C14, S2R1, VBW3, VBH2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm",0,0},
551 	{"Arpeg-Trig", 2, S2C13, S2R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
552 		"bitmaps/buttons/sidbon.xpm", 0},
553 	{"Arpeg-Scan", 2, S2C15, S2R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
554 		"bitmaps/buttons/sidbon.xpm", 0},
555 
556 	/* Memories 118 - first 8 digits */
557 	{"", 2, S2C17, S2R3, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
558 		"bitmaps/buttons/sidbongreen.xpm", 0},
559 	{"", 2, S2C18, S2R3, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
560 		"bitmaps/buttons/sidbongreen.xpm", 0},
561 	{"", 2, S2C19, S2R3, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
562 		"bitmaps/buttons/sidbongreen.xpm", 0},
563 	{"", 2, S2C20, S2R3, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
564 		"bitmaps/buttons/sidbongreen.xpm", 0},
565 
566 	{"", 2, S2C17, S2R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
567 		"bitmaps/buttons/sidbongreen.xpm", 0},
568 	{"", 2, S2C18, S2R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
569 		"bitmaps/buttons/sidbongreen.xpm", 0},
570 	{"", 2, S2C19, S2R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
571 		"bitmaps/buttons/sidbongreen.xpm", 0},
572 	{"", 2, S2C20, S2R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
573 		"bitmaps/buttons/sidbongreen.xpm", 0},
574 
575 	/* Then load/save */
576 	{"", 2, S2C16, S2R3, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
577 		"bitmaps/buttons/sidbon.xpm", BRIGHTON_CHECKBUTTON},
578 	{"", 2, S2C16, S2R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
579 		"bitmaps/buttons/sidbon.xpm", BRIGHTON_CHECKBUTTON},
580 
581 	/* Then Bank, down, up, find */
582 	{"", 2, S2C21, S2R3, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
583 		"bitmaps/buttons/sidbon.xpm", BRIGHTON_CHECKBUTTON},
584 	{"", 2, S2C22, S2R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
585 		"bitmaps/buttons/sidbon.xpm", BRIGHTON_CHECKBUTTON},
586 	{"", 2, S2C22, S2R3, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
587 		"bitmaps/buttons/sidbon.xpm", BRIGHTON_CHECKBUTTON},
588 	{"", 2, S2C21, S2R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
589 		"bitmaps/buttons/sidbon.xpm", BRIGHTON_CHECKBUTTON},
590 
591 	{"", 2, S2C23 + 6, S2R3, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
592 		"bitmaps/buttons/sidbon.xpm", BRIGHTON_CHECKBUTTON},
593 	{"", 2, S2C23 + 6, S2R4, VBW1, VBH1, 0, 1, 0, "bitmaps/buttons/sidb.xpm",
594 		"bitmaps/buttons/sidbon.xpm", BRIGHTON_CHECKBUTTON},
595 
596 	/* Done */
597 
598 	{"", 3, S2C17, S2R1, 175, 60, 0, 1, 0, 0,
599 		"bitmaps/images/alphadisplay3.xpm", 0}
600 
601 };
602 
603 /*
604  * This is a set of globals for the main window rendering. Again taken from
605  * include/brighton.h
606  * Hm, the bit-1 was black, and the bit 99 was in various builds including a
607  * white one, but also a black one and a black one with wood panels. I would
608  * like the black one with wood panels, so that will have to be the bit-1, the
609  * bit-99 will be white with thin metal panels.
610  */
611 brightonApp sidApp = {
612 	"sidney",
613 	0, /* no blueprint on wood background. */
614 	"bitmaps/textures/metal1.xpm",
615 	//"bitmaps/textures/p8b.xpm",
616 	BRIGHTON_STRETCH,
617 	sidInit,
618 	sidConfigure, /* 3 callbacks, unused? */
619 	midiCallback,
620 	destroySynth,
621 	{1, 100, 2, 2, 5, 520, 0, 0},
622 	1000, 330, 0, 0,
623 	3, /* panels */
624 	{
625 		{
626 			"Sid800",
627 			"bitmaps/blueprints/sid.xpm",
628 			"bitmaps/textures/metal1.xpm",
629 			BRIGHTON_STRETCH, /* flags */
630 			0,
631 			0,
632 			sidCallback,
633 			25, 29, 950, 620,
634 			DEVICE_COUNT,
635 			locations
636 		},
637 		{
638 			"Keyboard",
639 			0,
640 //			"bitmaps/keys/kbg.xpm",
641 			"bitmaps/newkeys/nkbg.xpm",
642 			0x020|BRIGHTON_STRETCH,
643 			0,
644 			0,
645 			sidKeyCallback,
646 			90, 680, 893, 318,
647 			KEY_COUNT_5OCTAVE,
648 			keysprofile2
649 		},
650 		{
651 			"mods",
652 			"bitmaps/buttons/blue.xpm",
653 			"bitmaps/textures/metal1.xpm",
654 			0,
655 			0,
656 			0,
657 			sidModCallback,
658 			32, 695, 50, 220,
659 			5,
660 			modwheel
661 		},
662 	}
663 };
664 
665 /*
666  * We really want to just use one midi channel and let the midi library decide
667  * that we have multiple synths on the channel with their own split points.
668  * The lower layer should define the midi channel, split point and transpose
669  * of upper layer.
670  */
671 static int
sidKeyCallback(brightonWindow * win,int panel,int index,float value)672 sidKeyCallback(brightonWindow *win, int panel, int index, float value)
673 {
674 	guiSynth *synth = findSynth(global.synths, win);
675 
676 	if (global.libtest)
677 		return(0);
678 
679 	/*
680 	 * So we have a single key event and two MIDI channels. Just send the
681 	 * event on both channels, no need to be difficult about it since if this
682 	 * was a split configuration the library filters out the events.
683 	 */
684 	if (value) {
685 		bristolMidiSendMsg(global.controlfd, synth->midichannel,
686 			BRISTOL_EVENT_KEYON, 0, index + synth->transpose);
687 	} else {
688 		bristolMidiSendMsg(global.controlfd, synth->midichannel,
689 			BRISTOL_EVENT_KEYOFF, 0, index + synth->transpose);
690 	}
691 
692 	return(0);
693 }
694 
695 /*
696  * At this point we have loaded a memory so we need to send those actual new
697  * parameters to the engine. This is an issue for MIDI program load, perhaps
698  * we should consider dual load above memory 74 as per the original?
699  *
700  * The path of least resistance here is to scan through the the memory table
701  * incrementing the input selector and delivering the memory value to the
702  * data entry pot.....
703  */
704 static void
loadMemoryShim(guiSynth * synth)705 loadMemoryShim(guiSynth *synth)
706 {
707 	brightonEvent event;
708 
709 	/* We need to force some exclusion on LFO mods and Mode */
710 	synth->dispatch[76].other1 =
711 		synth->mem.param[76] != 0? 0:
712 			synth->mem.param[77] != 0? 1:
713 				synth->mem.param[78] != 0? 2:
714 						synth->mem.param[79] != 0? 3: 0;
715 
716 	/* Key mode changed between releases, this recovers them */
717 	if (synth->mem.param[109] == 0) {
718 		int on;
719 
720 		synth->dispatch[69].other1 =
721 			synth->mem.param[70] != 0? 0:
722 				synth->mem.param[71] != 0? 1:
723 					synth->mem.param[72] != 0? 2:
724 						synth->mem.param[73] != 0? 3: 0;
725 		on = 69 + synth->dispatch[69].other1;
726 		event.type = BRISTOL_FLOAT;
727 		event.value = 0;
728 		brightonParamChange(synth->win, 0,
729 			70 + synth->dispatch[69].other1, &event);
730 		event.value = 1;
731 		brightonParamChange(synth->win, 0, on, &event);
732 	} else
733 		synth->dispatch[69].other1 =
734 			synth->mem.param[69] != 0? 0:
735 				synth->mem.param[70] != 0? 1:
736 					synth->mem.param[71] != 0? 2:
737 						synth->mem.param[72] != 0? 3:
738 							synth->mem.param[73] != 0? 4: 0;
739 
740 	bristolMidiSendMsg(global.controlfd, synth->sid, 126, 5,
741 		synth->dispatch[69].other1);
742 
743 	/* Set up the trigger options */
744 
745 	/* Then we can look at the mod panel options */
746 	event.type = BRISTOL_FLOAT;
747 	event.value = synth->mem.param[111];
748 	brightonParamChange(synth->win, MODS_PANEL, 1, &event);
749 	event.value = synth->mem.param[112];
750 	brightonParamChange(synth->win, MODS_PANEL, 2, &event);
751 	event.value = synth->mem.param[113];
752 	brightonParamChange(synth->win, MODS_PANEL, 3, &event);
753 	event.value = synth->mem.param[114];
754 	brightonParamChange(synth->win, MODS_PANEL, 4, &event);
755 
756 	/* And we should enforce mod waveform */
757 	bristolMidiSendMsg(global.controlfd, synth->sid, 126, 66,
758 		synth->mem.param[76] == 0?0:1);
759 	bristolMidiSendMsg(global.controlfd, synth->sid, 126, 67,
760 		synth->mem.param[77] == 0?0:1);
761 	bristolMidiSendMsg(global.controlfd, synth->sid, 126, 68,
762 		synth->mem.param[78] == 0?0:1);
763 	bristolMidiSendMsg(global.controlfd, synth->sid, 126, 69,
764 		synth->mem.param[79] == 0?0:1);
765 	if (synth->mem.param[76] != 0)
766 		bristolMidiSendMsg(global.controlfd, synth->sid, 126, 66, 1);
767 
768 	/* See if we have to force memory variables */
769 	if (synth->mem.param[70] != 0)
770 	{
771 		int i;
772 
773 		for (i = 0; i < 20; i++)
774 		{
775 			event.value = synth->mem.param[i];
776 			brightonParamChange(synth->win, 0, i, &event);
777 			brightonParamChange(synth->win, 0, i + 20, &event);
778 			brightonParamChange(synth->win, 0, i + 40, &event);
779 		}
780 	}
781 }
782 
783 static void
loadMemoryMidiShim(guiSynth * synth,int from)784 loadMemoryMidiShim(guiSynth *synth, int from)
785 {
786 	loadMemory(synth, SYNTH_NAME, 0, synth->bank * 10 + from,
787 		synth->mem.active, 0, BRISTOL_FORCE);
788 	loadMemoryShim(synth);
789 }
790 
791 int
loadMemoryKeyShim(guiSynth * synth,char * algo,char * name,int location,int active,int skip,int flags)792 loadMemoryKeyShim(guiSynth *synth, char *algo, char *name, int location,
793 int active, int skip, int flags)
794 {
795 	loadMemory(synth, SYNTH_NAME, 0, location,
796 		synth->mem.active, 0, BRISTOL_FORCE);
797 	loadMemoryShim(synth);
798 	return(0);
799 }
800 
801 static int
midiCallback(brightonWindow * win,int controller,int value,float n)802 midiCallback(brightonWindow *win, int controller, int value, float n)
803 {
804 	guiSynth *synth = findSynth(global.synths, win);
805 
806 	switch(controller)
807 	{
808 		case MIDI_PROGRAM:
809 			if (synth->mem.param[87] == 0)
810 				return(0);
811 			/*
812 			 * We should accept 0..74 as lower layer and above that as dual
813 			 * loading requests.
814 			 */
815 			printf("midi program: %x, %i\n", controller, value);
816 			synth->location = value;
817 			loadMemoryMidiShim(synth, synth->location);
818 			break;
819 		case MIDI_BANK_SELECT:
820 			printf("midi banksel: %x, %i\n", controller, value);
821 			synth->bank = value;
822 			break;
823 	}
824 	return(0);
825 }
826 
827 static int
sidMidiNull(void * synth,int fd,int chan,int c,int o,int v)828 sidMidiNull(void *synth, int fd, int chan, int c, int o, int v)
829 {
830 	if (global.libtest)
831 		printf("This is a null callback on %i id %i\n", c, o);
832 
833 	return(0);
834 }
835 
836 static int vexclude = 0;
837 
838 /*
839  * Typically this should just do what sidMidiShim does, send the parameter to
840  * the target however in mode Poly-1 all voices need to have the same set of
841  * parameters. This really means the GUI needs to replicate the parameter
842  * changes all voice params. There are many ways to do this, the coolest is
843  * actually to redistribute the requests, ganging the controls.
844  */
845 static void
sidVoiceShim(guiSynth * synth,int fd,int chan,int c,int o,int v)846 sidVoiceShim(guiSynth *synth, int fd, int chan, int c, int o, int v)
847 {
848 	brightonEvent event;
849 	int off1 = 20, off2 = 40;
850 
851 	if (synth->mem.param[70] != 0)
852 	{
853 		if (vexclude)
854 			return;
855 
856 		event.value = synth->mem.param[o - 10];
857 
858 		vexclude = 1;
859 
860 		/* Find out what parameters we need to use */
861 		if (o >= 50)
862 		{
863 			off1 = -40;
864 			off2 = -20;
865 		} else if (o >= 30) {
866 			off1 = -20;
867 			off2 = 20;
868 		}
869 
870 		/* Update the displays */
871 		brightonParamChange(synth->win, synth->panel, o - 10 + off1, &event);
872 		brightonParamChange(synth->win, synth->panel, o - 10 + off2, &event);
873 
874 		vexclude = 0;
875 
876 		/* Send the messages for the other voices */
877 		bristolMidiSendMsg(fd, synth->sid, c, o + off1, v);
878 		bristolMidiSendMsg(fd, synth->sid, c, o + off2, v);
879 	}
880 	bristolMidiSendMsg(fd, synth->sid, c, o, v);
881 }
882 
883 static void
sidMidiShim(guiSynth * synth,int fd,int chan,int c,int o,int v)884 sidMidiShim(guiSynth *synth, int fd, int chan, int c, int o, int v)
885 {
886 	bristolMidiSendMsg(fd, synth->sid, c, o, v);
887 }
888 
889 static void
sidLFOWave(guiSynth * synth,int fd,int chan,int c,int o,int v)890 sidLFOWave(guiSynth *synth, int fd, int chan, int c, int o, int v)
891 {
892 	brightonEvent event;
893 
894 	event.value = 1.0;
895 	event.type = BRISTOL_FLOAT;
896 
897 	if (synth->flags & MEM_LOADING)
898 		return;
899 	if ((synth->flags & OPERATIONAL) == 0)
900 		return;
901 
902 	if (synth->dispatch[76].other2)
903 	{
904 		synth->dispatch[76].other2 = 0;
905 		return;
906 	}
907 
908 	/*
909 	 * We want to make these into memory buttons. To do so we need to
910 	 * know what the last active button was, and deactivate its
911 	 * display, then send any message which represents the most
912 	 * recently configured value. Since this is a memory button we do
913 	 * not have much issue with the message, but we are concerned with
914 	 * the display.
915 	 */
916 	if (synth->dispatch[76].other1 != -1)
917 	{
918 		synth->dispatch[76].other2 = 1;
919 
920 		if (synth->dispatch[76].other1 != o)
921 			event.value = 0;
922 		else
923 			event.value = 1;
924 
925 		brightonParamChange(synth->win, synth->panel,
926 			synth->dispatch[76].other1 + 76, &event);
927 		bristolMidiSendMsg(fd, synth->sid, 126,
928 			66 + synth->dispatch[76].other1, 0);
929 	}
930 	synth->dispatch[76].other1 = o;
931 
932 	bristolMidiSendMsg(fd, synth->sid, 126, 66 + o, 1);
933 }
934 
935 static int mode = -1;
936 
937 static void
sidMode(guiSynth * synth,int fd,int chan,int c,int o,int v)938 sidMode(guiSynth *synth, int fd, int chan, int c, int o, int v)
939 {
940 	brightonEvent event;
941 	int i, sv;
942 
943 	event.value = 1.0;
944 	event.type = BRISTOL_FLOAT;
945 
946 	if (synth->flags & MEM_LOADING)
947 		return;
948 	if ((synth->flags & OPERATIONAL) == 0)
949 		return;
950 
951 	if (synth->dispatch[69].other2)
952 	{
953 		synth->dispatch[69].other2 = 0;
954 		return;
955 	}
956 
957 	/*
958 	 * We want to make these into memory buttons. To do so we need to
959 	 * know what the last active button was, and deactivate its
960 	 * display, then send any message which represents the most
961 	 * recently configured value. Since this is a memory button we do
962 	 * not have much issue with the message, but we are concerned with
963 	 * the display.
964 	 */
965 	if (synth->dispatch[69].other1 != -1)
966 	{
967 		synth->dispatch[69].other2 = 1;
968 
969 		if (synth->dispatch[69].other1 != o)
970 			event.value = 0;
971 		else
972 			event.value = 1;
973 
974 		brightonParamChange(synth->win, synth->panel,
975 			synth->dispatch[69].other1 + 69, &event);
976 	}
977 	synth->dispatch[69].other1 = o;
978 
979 	bristolMidiSendMsg(fd, synth->sid, 126, 5, o);
980 
981 	/*
982 	 * This code would sync all the voice parameters as we enter Poly-1 however
983 	 * that is always desirable. We should either sync the engine parameters
984 	 * to voice-3 entering Poly-1 and reset them to GUI parameters on exit,
985 	 * or do nothing.
986 	 */
987 	if (synth->mem.param[70] != 0)
988 	{
989 		/*
990 		 * Sync voices in engine
991 		 */
992 		if (mode != 1)
993 			for (i = 0; i < 20; i++)
994 			{
995 				if (sidApp.resources[0].devlocn[i].to == 1)
996 					sv = synth->mem.param[i+40] * C_RANGE_MIN_1;
997 				else
998 					sv = synth->mem.param[i+40];
999 
1000 				bristolMidiSendMsg(fd, synth->sid, 126, i + 10, sv);
1001 				bristolMidiSendMsg(fd, synth->sid, 126, i + 30, sv);
1002 			}
1003 	} else {
1004 		if (mode == 1)
1005 			for (i = 0; i < 60; i++)
1006 			{
1007 				event.value = synth->mem.param[i];
1008 				brightonParamChange(synth->win, synth->panel, i, &event);
1009 			}
1010 	}
1011 
1012 	mode = o;
1013 }
1014 
1015 static void
sidMemory(guiSynth * synth,int fd,int chan,int c,int o,int v)1016 sidMemory(guiSynth *synth, int fd, int chan, int c, int o, int v)
1017 {
1018 	brightonEvent event;
1019 	int bank = synth->bank;
1020 	int location = synth->location;
1021 
1022 	event.value = 1.0;
1023 	event.type = BRISTOL_FLOAT;
1024 
1025 	if (synth->flags & MEM_LOADING)
1026 		return;
1027 	if ((synth->flags & OPERATIONAL) == 0)
1028 		return;
1029 
1030 	if (synth->dispatch[MEM_START].other2)
1031 	{
1032 		synth->dispatch[MEM_START].other2 = 0;
1033 		return;
1034 	}
1035 
1036 	switch (c) {
1037 		default:
1038 		case 0:
1039 			/*
1040 			 * We want to make these into memory buttons. To do so we need to
1041 			 * know what the last active button was, and deactivate its
1042 			 * display, then send any message which represents the most
1043 			 * recently configured value. Since this is a memory button we do
1044 			 * not have much issue with the message, but we are concerned with
1045 			 * the display.
1046 			 */
1047 			if (synth->dispatch[MEM_START].other1 != -1)
1048 			{
1049 				synth->dispatch[MEM_START].other2 = 1;
1050 
1051 				if (synth->dispatch[MEM_START].other1 != o)
1052 					event.value = 0;
1053 				else
1054 					event.value = 1;
1055 
1056 				brightonParamChange(synth->win, synth->panel,
1057 					synth->dispatch[MEM_START].other1 + MEM_START - 1, &event);
1058 			}
1059 			synth->dispatch[MEM_START].other1 = o;
1060 
1061 			if (synth->flags & BANK_SELECT) {
1062 				if ((synth->bank * 10 + o) >= 100)
1063 				{
1064 					synth->location = o;
1065 					synth->flags &= ~BANK_SELECT;
1066 
1067 					if (loadMemory(synth, SYNTH_NAME, 0,
1068 						synth->bank * 10 + synth->location, synth->mem.active,
1069 							0, BRISTOL_STAT) < 0)
1070 						displayText(synth, "FREE MEM",
1071 							synth->bank * 10 + synth->location, DISPLAY_DEV);
1072 					else
1073 						displayText(synth, "PROGRAM",
1074 							synth->bank * 10 + synth->location, DISPLAY_DEV);
1075 				} else {
1076 					synth->bank = synth->bank * 10 + o;
1077 					displayText(synth, "BANK",
1078 						synth->bank * 10 + synth->location, DISPLAY_DEV);
1079 				}
1080 			} else {
1081 				if (synth->bank < 1)
1082 					synth->bank = 1;
1083 				synth->location = o;
1084 				if (loadMemory(synth, SYNTH_NAME, 0,
1085 					synth->bank * 10 + synth->location, synth->mem.active,
1086 						0, BRISTOL_STAT) < 0)
1087 					displayText(synth, "FREE MEM",
1088 						synth->bank * 10 + synth->location, DISPLAY_DEV);
1089 				else
1090 					displayText(synth, "PROGRAM",
1091 						synth->bank * 10 + synth->location, DISPLAY_DEV);
1092 			}
1093 			break;
1094 		case 1:
1095 			if (synth->bank < 1)
1096 				synth->bank = 1;
1097 			if (synth->location == 0)
1098 				synth->location = 1;
1099 			if (loadMemory(synth, SYNTH_NAME, 0,
1100 				synth->bank * 10 + synth->location,
1101 				synth->mem.active, 0, BRISTOL_FORCE) < 0)
1102 				displayText(synth, "FREE MEM",
1103 					synth->bank * 10 + synth->location, DISPLAY_DEV);
1104 			else {
1105 				loadMemoryShim(synth);
1106 				displayText(synth, "PROGRAM",
1107 					synth->bank * 10 + synth->location, DISPLAY_DEV);
1108 			}
1109 			synth->flags &= ~BANK_SELECT;
1110 
1111 			/*
1112 			 * Doubleclick on load will toggle debugging
1113 			if (brightonDoubleClick(dc) != 0)
1114 				bristolMidiSendMsg(fd, synth->sid, 126, 4, 1);
1115 			 */
1116 
1117 			break;
1118 		case 2:
1119 			if (synth->bank < 1)
1120 				synth->bank = 1;
1121 			if (synth->location == 0)
1122 				synth->location = 1;
1123 			if (brightonDoubleClick(dc) != 0)
1124 			{
1125 				synth->mem.param[109] = 1.0;
1126 				saveMemory(synth, SYNTH_NAME, 0,
1127 					synth->bank * 10 + synth->location, 0);
1128 				displayText(synth, "PROGRAM",
1129 					synth->bank * 10 + synth->location, DISPLAY_DEV);
1130 				synth->flags &= ~BANK_SELECT;
1131 			}
1132 			break;
1133 		case 3:
1134 			if (synth->flags & BANK_SELECT) {
1135 				synth->flags &= ~BANK_SELECT;
1136 				if (loadMemory(synth, SYNTH_NAME, 0,
1137 					synth->bank * 10 + synth->location, synth->mem.active,
1138 						0, BRISTOL_STAT) < 0)
1139 					displayText(synth, "FREE MEM",
1140 						synth->bank * 10 + synth->location, DISPLAY_DEV);
1141 				else
1142 					displayText(synth, "PROGRAM",
1143 						synth->bank * 10 + synth->location, DISPLAY_DEV);
1144 			} else {
1145 				synth->bank = 0;
1146 				displayText(synth, "BANK", synth->bank, DISPLAY_DEV);
1147 				synth->flags |= BANK_SELECT;
1148 			}
1149 			break;
1150 		case 4:
1151 			if (--location < 1) {
1152 				location = 8;
1153 				if (--bank < 1)
1154 					bank = 88;
1155 			}
1156 			while (loadMemory(synth, SYNTH_NAME, 0, bank * 10 + location,
1157 				synth->mem.active, 0, BRISTOL_STAT) < 0)
1158 			{
1159 				if (--location < 1) {
1160 					location = 8;
1161 					if (--bank < 1)
1162 						bank = 88;
1163 				}
1164 				if ((bank * 10 + location)
1165 					== (synth->bank * 10 + synth->location))
1166 					break;
1167 			}
1168 			displayText(synth, "PROGRAM", bank * 10 + location, DISPLAY_DEV);
1169 			synth->bank = bank;
1170 			synth->location = location;
1171 			loadMemory(synth, SYNTH_NAME, 0, bank * 10 + location,
1172 				synth->mem.active, 0, BRISTOL_FORCE);
1173 			loadMemoryShim(synth);
1174 			brightonParamChange(synth->win, 0,
1175 				MEM_START - 1 + synth->location, &event);
1176 			break;
1177 		case 5:
1178 			if (++location > 8) {
1179 				location = 1;
1180 				if (++bank > 88)
1181 					bank = 1;
1182 			}
1183 			while (loadMemory(synth, SYNTH_NAME, 0, bank * 10 + location,
1184 				synth->mem.active, 0, BRISTOL_STAT) < 0)
1185 			{
1186 				if (++location > 8) {
1187 					location = 1;
1188 					if (++bank > 88)
1189 						bank = 1;
1190 				}
1191 				if ((bank * 10 + location)
1192 					== (synth->bank * 10 + synth->location))
1193 					break;
1194 			}
1195 			displayText(synth, "PROGRAM", bank * 10 + location, DISPLAY_DEV);
1196 			synth->bank = bank;
1197 			synth->location = location;
1198 			loadMemory(synth, SYNTH_NAME, 0, bank * 10 + location,
1199 				synth->mem.active, 0, BRISTOL_FORCE);
1200 			loadMemoryShim(synth);
1201 			brightonParamChange(synth->win, 0,
1202 				MEM_START - 1 + synth->location, &event);
1203 			break;
1204 		case 6:
1205 			/* Find the next free mem */
1206 			if (++location > 8) {
1207 				location = 1;
1208 				if (++bank > 88)
1209 					bank = 1;
1210 			}
1211 
1212 			while (loadMemory(synth, SYNTH_NAME, 0, bank * 10 + location,
1213 				synth->mem.active, 0, BRISTOL_STAT) >= 0)
1214 			{
1215 				if (++location > 8) {
1216 					location = 1;
1217 					if (++bank > 88)
1218 						bank = 1;
1219 				}
1220 				if ((bank * 10 + location)
1221 					== (synth->bank * 10 + synth->location))
1222 					break;
1223 			}
1224 
1225 			if (loadMemory(synth, SYNTH_NAME, 0, bank * 10 + location,
1226 				synth->mem.active, 0, BRISTOL_STAT) >= 0)
1227 				displayText(synth, "PROGRAM",
1228 					bank * 10 + location, DISPLAY_DEV);
1229 			else
1230 				displayText(synth, "FREE MEM",
1231 					bank * 10 + location, DISPLAY_DEV);
1232 
1233 			synth->bank = bank;
1234 			synth->location = location;
1235 			brightonParamChange(synth->win, 0,
1236 				MEM_START - 1 + synth->location, &event);
1237 			break;
1238 	}
1239 }
1240 
1241 static int
sidModCallback(brightonWindow * win,int panel,int index,float value)1242 sidModCallback(brightonWindow *win, int panel, int index, float value)
1243 {
1244 	guiSynth *synth = findSynth(global.synths, win);
1245 	brightonEvent event;
1246 
1247 	event.type = BRISTOL_FLOAT;
1248 	synth->mem.param[110 + index] = value;
1249 
1250 	switch (index) {
1251 		case 0:
1252 			/* Wheel - we don't send pitch, just mod */
1253 			bristolMidiControl(global.controlfd, synth->midichannel,
1254 				0, 1, ((int) (value * (C_RANGE_MIN_1 - 1))) >> 7);
1255 			break;
1256 		case 1:
1257 			/* Pitch select - these should actually just flag the engine */
1258 			bristolMidiSendMsg(global.controlfd, synth->sid, 126, 100,
1259 				value == 0?0:1);
1260 			break;
1261 		case 2:
1262 			/* LFO Select - these should actually just flag the engine */
1263 			bristolMidiSendMsg(global.controlfd, synth->sid, 126, 98,
1264 				value == 0?0:1);
1265 			if ((synth->mem.param[110 + index] = value) == 0)
1266 				return(0);
1267 
1268 			bristolMidiControl(global.controlfd, synth->midichannel, 0, 1,
1269 				((int) (synth->mem.param[110] * (C_RANGE_MIN_1 - 1))) >> 7);
1270 			break;
1271 		case 3:
1272 			/* ENV Select - these should actually just flag the engine */
1273 			bristolMidiSendMsg(global.controlfd, synth->sid, 126, 99,
1274 				value == 0?0:1);
1275 			if ((synth->mem.param[110 + index] = value) == 0)
1276 				return(0);
1277 
1278 			bristolMidiControl(global.controlfd, synth->midichannel, 0, 1,
1279 				((int) (synth->mem.param[110] * (C_RANGE_MIN_1 - 1))) >> 7);
1280 			break;
1281 		case 4:
1282 			/* Center spring */
1283 			if (value == 0)
1284 				win->app->resources[panel].devlocn[0].flags &= ~BRIGHTON_CENTER;
1285 			else {
1286 				win->app->resources[panel].devlocn[0].flags |= BRIGHTON_CENTER;
1287 				/* And centre the control */
1288 				event.value = 0.5;
1289 				brightonParamChange(synth->win, panel, 0, &event);
1290 			}
1291 			break;
1292 	};
1293 
1294 	return(0);
1295 }
1296 
1297 /*
1298  * For the sake of ease of use, links have been placed here to be called
1299  * by any of the devices created. They would be better in some other file,
1300  * perhaps with this as a dispatch.
1301  *
1302  * Param refers to the device index in the locations table given below.
1303  */
1304 static int
sidCallback(brightonWindow * win,int panel,int index,float value)1305 sidCallback(brightonWindow *win, int panel, int index, float value)
1306 {
1307 	guiSynth *synth = findSynth(global.synths, win);
1308 	int sendvalue;
1309 
1310 	if (global.libtest)
1311 		printf("sidCallback(%i, %i, %f)\n", panel, index, value);
1312 
1313 	if (synth == 0)
1314 		return(0);
1315 
1316 	if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0))
1317 		return(0);
1318 
1319 	if ((index >= 111) && (index <= 114))
1320 		return(sidModCallback(win, MODS_PANEL, index - 110, value));
1321 
1322 	if (sidApp.resources[0].devlocn[index].to == 1)
1323 		sendvalue = value * C_RANGE_MIN_1;
1324 	else
1325 		sendvalue = value;
1326 
1327 	synth->mem.param[index] = value;
1328 
1329 //	if (index < 100)
1330 		synth->dispatch[index].routine(synth,
1331 			global.controlfd, synth->sid,
1332 			synth->dispatch[index].controller,
1333 			synth->dispatch[index].operator,
1334 			sendvalue);
1335 
1336 	return(0);
1337 }
1338 
1339 static void
sidMidiChannel(guiSynth * synth,int fd,int chan,int c,int o,int v)1340 sidMidiChannel(guiSynth *synth, int fd, int chan, int c, int o, int v)
1341 {
1342 	if ((c == 0) && (++synth->midichannel > 15))
1343 		synth->midichannel = 15;
1344 	else if ((c == 1) && (--synth->midichannel < 0))
1345 		synth->midichannel = 0;
1346 
1347 	displayText(synth, "MIDI CHAN", synth->midichannel + 1, DISPLAY_DEV);
1348 
1349 	if (global.libtest)
1350 		return;
1351 
1352 	bristolMidiSendMsg(global.controlfd, synth->sid,
1353 		127, 0, BRISTOL_MIDICHANNEL|synth->midichannel);
1354 }
1355 
1356 /*
1357  * Any location initialisation required to run the callbacks. For bristol, this
1358  * will connect to the engine, and give it some base parameters.
1359  * May need to generate some application specific menus.
1360  * Will also then make specific requests to some of the devices to alter their
1361  * rendering.
1362  */
1363 static int
sidInit(brightonWindow * win)1364 sidInit(brightonWindow *win)
1365 {
1366 	guiSynth *synth = findSynth(global.synths, win);
1367 	dispatcher *dispatch;
1368 	int i;
1369 
1370 	if (synth == 0)
1371 	{
1372 		synth = findSynth(global.synths, 0);
1373 		if (synth == 0)
1374 		{
1375 			printf("cannot init\n");
1376 			return(0);
1377 		}
1378 	}
1379 
1380 	synth->win = win;
1381 
1382 	printf("Initialise the sid link to bristol: %p\n", synth->win);
1383 
1384 	synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float));
1385 	synth->mem.count = DEVICE_COUNT;
1386 	synth->mem.active = ACTIVE_DEVS;
1387 	synth->dispatch = (dispatcher *)
1388 		brightonmalloc(DEVICE_COUNT * sizeof(dispatcher));
1389 	dispatch = synth->dispatch;
1390 
1391 	/*
1392 	 * We really want to have three connection mechanisms. These should be
1393 	 *	1. Unix named sockets.
1394 	 *	2. UDP sockets (actually implements TCP unfortunately).
1395 	 *	3. MIDI pipe.
1396 	 */
1397 	if (!global.libtest)
1398 	{
1399 		if ((synth->sid = initConnection(&global, synth)) < 0)
1400 			return(-1);
1401 	}
1402 
1403 	for (i = 0; i < DEVICE_COUNT; i++)
1404 	{
1405 		synth->dispatch[i].routine = (synthRoutine) sidMidiNull;
1406 		synth->dispatch[i].controller = i;
1407 		synth->dispatch[i].operator = i;
1408 	}
1409 
1410 	/* Voice 1 */
1411 	dispatch[0].controller = 126;
1412 	dispatch[0].operator = 10;
1413 	dispatch[0].routine = (synthRoutine) sidVoiceShim;
1414 	dispatch[1].controller = 126;
1415 	dispatch[1].operator = 11;
1416 	dispatch[1].routine = (synthRoutine) sidVoiceShim;
1417 	dispatch[2].controller = 126;
1418 	dispatch[2].operator = 12;
1419 	dispatch[2].routine = (synthRoutine) sidVoiceShim;
1420 	dispatch[3].controller = 126;
1421 	dispatch[3].operator = 13;
1422 	dispatch[3].routine = (synthRoutine) sidVoiceShim;
1423 	/* PW, tune, transpose, glide */
1424 	dispatch[4].controller = 126;
1425 	dispatch[4].operator = 14;
1426 	dispatch[4].routine = (synthRoutine) sidVoiceShim;
1427 	dispatch[5].controller = 126;
1428 	dispatch[5].operator = 15;
1429 	dispatch[5].routine = (synthRoutine) sidVoiceShim;
1430 	dispatch[6].controller = 126;
1431 	dispatch[6].operator = 16;
1432 	dispatch[6].routine = (synthRoutine) sidVoiceShim;
1433 	dispatch[7].controller = 126;
1434 	dispatch[7].operator = 17;
1435 	dispatch[7].routine = (synthRoutine) sidVoiceShim;
1436 	/* RM/sync/mute/route */
1437 	dispatch[8].controller = 126;
1438 	dispatch[8].operator = 18;
1439 	dispatch[8].routine = (synthRoutine) sidVoiceShim;
1440 	dispatch[9].controller = 126;
1441 	dispatch[9].operator = 19;
1442 	dispatch[9].routine = (synthRoutine) sidVoiceShim;
1443 	dispatch[10].controller = 126;
1444 	dispatch[10].operator = 20;
1445 	dispatch[10].routine = (synthRoutine) sidVoiceShim;
1446 	dispatch[11].controller = 126;
1447 	dispatch[11].operator = 21;
1448 	dispatch[11].routine = (synthRoutine) sidVoiceShim;
1449 	/* Env */
1450 	dispatch[12].controller = 126;
1451 	dispatch[12].operator = 22;
1452 	dispatch[12].routine = (synthRoutine) sidVoiceShim;
1453 	dispatch[13].controller = 126;
1454 	dispatch[13].operator = 23;
1455 	dispatch[13].routine = (synthRoutine) sidVoiceShim;
1456 	dispatch[14].controller = 126;
1457 	dispatch[14].operator = 24;
1458 	dispatch[14].routine = (synthRoutine) sidVoiceShim;
1459 	dispatch[15].controller = 126;
1460 	dispatch[15].operator = 25;
1461 	dispatch[15].routine = (synthRoutine) sidVoiceShim;
1462 
1463 	/* Voice 2 */
1464 	dispatch[20].controller = 126;
1465 	dispatch[20].operator = 30;
1466 	dispatch[20].routine = (synthRoutine) sidVoiceShim;
1467 	dispatch[21].controller = 126;
1468 	dispatch[21].operator = 31;
1469 	dispatch[21].routine = (synthRoutine) sidVoiceShim;
1470 	dispatch[22].controller = 126;
1471 	dispatch[22].operator = 32;
1472 	dispatch[22].routine = (synthRoutine) sidVoiceShim;
1473 	dispatch[23].controller = 126;
1474 	dispatch[23].operator = 33;
1475 	dispatch[23].routine = (synthRoutine) sidVoiceShim;
1476 	/* PW, tune, transpose, glide */
1477 	dispatch[24].controller = 126;
1478 	dispatch[24].operator = 34;
1479 	dispatch[24].routine = (synthRoutine) sidVoiceShim;
1480 	dispatch[25].controller = 126;
1481 	dispatch[25].operator = 35;
1482 	dispatch[25].routine = (synthRoutine) sidVoiceShim;
1483 	dispatch[26].controller = 126;
1484 	dispatch[26].operator = 36;
1485 	dispatch[26].routine = (synthRoutine) sidVoiceShim;
1486 	dispatch[27].controller = 126;
1487 	dispatch[27].operator = 37;
1488 	dispatch[27].routine = (synthRoutine) sidVoiceShim;
1489 	/* RM/sync/mute/route */
1490 	dispatch[28].controller = 126;
1491 	dispatch[28].operator = 38;
1492 	dispatch[28].routine = (synthRoutine) sidVoiceShim;
1493 	dispatch[29].controller = 126;
1494 	dispatch[29].operator = 39;
1495 	dispatch[29].routine = (synthRoutine) sidVoiceShim;
1496 	dispatch[30].controller = 126;
1497 	dispatch[30].operator = 40;
1498 	dispatch[30].routine = (synthRoutine) sidVoiceShim;
1499 	dispatch[31].controller = 126;
1500 	dispatch[31].operator = 41;
1501 	dispatch[31].routine = (synthRoutine) sidVoiceShim;
1502 	/* Env */
1503 	dispatch[32].controller = 126;
1504 	dispatch[32].operator = 42;
1505 	dispatch[32].routine = (synthRoutine) sidVoiceShim;
1506 	dispatch[33].controller = 126;
1507 	dispatch[33].operator = 43;
1508 	dispatch[33].routine = (synthRoutine) sidVoiceShim;
1509 	dispatch[34].controller = 126;
1510 	dispatch[34].operator = 44;
1511 	dispatch[34].routine = (synthRoutine) sidVoiceShim;
1512 	dispatch[35].controller = 126;
1513 	dispatch[35].operator = 45;
1514 	dispatch[35].routine = (synthRoutine) sidVoiceShim;
1515 
1516 	/* Voice 3 */
1517 	dispatch[40].controller = 126;
1518 	dispatch[40].operator = 50;
1519 	dispatch[40].routine = (synthRoutine) sidVoiceShim;
1520 	dispatch[41].controller = 126;
1521 	dispatch[41].operator = 51;
1522 	dispatch[41].routine = (synthRoutine) sidVoiceShim;
1523 	dispatch[42].controller = 126;
1524 	dispatch[42].operator = 52;
1525 	dispatch[42].routine = (synthRoutine) sidVoiceShim;
1526 	dispatch[43].controller = 126;
1527 	dispatch[43].operator = 53;
1528 	dispatch[43].routine = (synthRoutine) sidVoiceShim;
1529 	/* PW, tune, transpose, glide */
1530 	dispatch[44].controller = 126;
1531 	dispatch[44].operator = 54;
1532 	dispatch[44].routine = (synthRoutine) sidVoiceShim;
1533 	dispatch[45].controller = 126;
1534 	dispatch[45].operator = 55;
1535 	dispatch[45].routine = (synthRoutine) sidVoiceShim;
1536 	dispatch[46].controller = 126;
1537 	dispatch[46].operator = 56;
1538 	dispatch[46].routine = (synthRoutine) sidVoiceShim;
1539 	dispatch[47].controller = 126;
1540 	dispatch[47].operator = 57;
1541 	dispatch[47].routine = (synthRoutine) sidVoiceShim;
1542 	/* RM/sync/mute/route */
1543 	dispatch[48].controller = 126;
1544 	dispatch[48].operator = 58;
1545 	dispatch[48].routine = (synthRoutine) sidVoiceShim;
1546 	dispatch[49].controller = 126;
1547 	dispatch[49].operator = 59;
1548 	dispatch[49].routine = (synthRoutine) sidVoiceShim;
1549 	dispatch[50].controller = 126;
1550 	dispatch[50].operator = 60;
1551 	dispatch[50].routine = (synthRoutine) sidVoiceShim;
1552 	dispatch[51].controller = 126;
1553 	dispatch[51].operator = 61;
1554 	dispatch[51].routine = (synthRoutine) sidVoiceShim;
1555 	/* Env */
1556 	dispatch[52].controller = 126;
1557 	dispatch[52].operator = 62;
1558 	dispatch[52].routine = (synthRoutine) sidVoiceShim;
1559 	dispatch[53].controller = 126;
1560 	dispatch[53].operator = 63;
1561 	dispatch[53].routine = (synthRoutine) sidVoiceShim;
1562 	dispatch[54].controller = 126;
1563 	dispatch[54].operator = 64;
1564 	dispatch[54].routine = (synthRoutine) sidVoiceShim;
1565 	dispatch[55].controller = 126;
1566 	dispatch[55].operator = 65;
1567 	dispatch[55].routine = (synthRoutine) sidVoiceShim;
1568 
1569 	/* Filter */
1570 	dispatch[60].controller = 126;
1571 	dispatch[60].operator = 70;
1572 	dispatch[60].routine = (synthRoutine) sidMidiShim;
1573 	dispatch[61].controller = 126;
1574 	dispatch[61].operator = 71;
1575 	dispatch[61].routine = (synthRoutine) sidMidiShim;
1576 	dispatch[62].controller = 126;
1577 	dispatch[62].operator = 72;
1578 	dispatch[62].routine = (synthRoutine) sidMidiShim;
1579 	/* Cutoff/res/OBmix */
1580 	dispatch[63].controller = 126;
1581 	dispatch[63].operator = 73;
1582 	dispatch[63].routine = (synthRoutine) sidMidiShim;
1583 	dispatch[64].controller = 126;
1584 	dispatch[64].operator = 74;
1585 	dispatch[64].routine = (synthRoutine) sidMidiShim;
1586 	dispatch[65].controller = 126;
1587 	dispatch[65].operator = 75;
1588 	dispatch[65].routine = (synthRoutine) sidMidiShim;
1589 	dispatch[66].controller = 126;
1590 	dispatch[66].operator = 76;
1591 	dispatch[66].routine = (synthRoutine) sidMidiShim;
1592 
1593 	/* Multi and master vol */
1594 	dispatch[67].controller = 126;
1595 	dispatch[67].operator = 2;
1596 	dispatch[67].routine = (synthRoutine) sidMidiShim;
1597 	dispatch[68].controller = 126;
1598 	dispatch[68].operator = 3;
1599 	dispatch[68].routine = (synthRoutine) sidMidiShim;
1600 
1601 	dispatch[69].operator = 0;
1602 	dispatch[70].operator = 1;
1603 	dispatch[71].operator = 2;
1604 	dispatch[72].operator = 3;
1605 	dispatch[73].operator = 4;
1606 	dispatch[69].routine = dispatch[70].routine = dispatch[71].routine
1607 		= dispatch[72].routine = dispatch[73].routine = (synthRoutine) sidMode;
1608 
1609 	/* Mod freq, gain and waveform */
1610 	dispatch[74].controller = 126;
1611 	dispatch[74].operator = 77;
1612 	dispatch[74].routine = (synthRoutine) sidMidiShim;
1613 	dispatch[75].controller = 126;
1614 	dispatch[75].operator = 78;
1615 	dispatch[75].routine = (synthRoutine) sidMidiShim;
1616 	dispatch[76].operator = 0;
1617 	dispatch[77].operator = 1;
1618 	dispatch[78].operator = 2;
1619 	dispatch[79].operator = 3;
1620 	dispatch[76].routine = dispatch[77].routine = dispatch[78].routine =
1621 		dispatch[79].routine = (synthRoutine) sidLFOWave;
1622 
1623 	/* Then we have the routing buttons, TBD */
1624 	dispatch[80].controller = 126;
1625 	dispatch[80].operator = 79;
1626 	dispatch[80].routine = (synthRoutine) sidMidiShim;
1627 	dispatch[81].controller = 126;
1628 	dispatch[81].operator = 80;
1629 	dispatch[81].routine = (synthRoutine) sidMidiShim;
1630 	dispatch[82].controller = 126;
1631 	dispatch[82].operator = 81;
1632 	dispatch[82].routine = (synthRoutine) sidMidiShim;
1633 	dispatch[83].controller = 126;
1634 	dispatch[83].operator = 82;
1635 	dispatch[83].routine = (synthRoutine) sidMidiShim;
1636 	dispatch[84].controller = 126;
1637 	dispatch[84].operator = 83;
1638 	dispatch[84].routine = (synthRoutine) sidMidiShim;
1639 	dispatch[85].controller = 126;
1640 	dispatch[85].operator = 84;
1641 	dispatch[85].routine = (synthRoutine) sidMidiShim;
1642 	dispatch[86].controller = 126;
1643 	dispatch[86].operator = 85;
1644 	dispatch[86].routine = (synthRoutine) sidMidiShim;
1645 	dispatch[87].controller = 126;
1646 	dispatch[87].operator = 101;
1647 	dispatch[87].routine = (synthRoutine) sidMidiShim;
1648 	dispatch[88].controller = 126;
1649 	dispatch[88].operator = 102;
1650 	dispatch[88].routine = (synthRoutine) sidMidiShim;
1651 
1652 	dispatch[95].controller = 126;
1653 	dispatch[95].operator = 89;
1654 	dispatch[95].routine = (synthRoutine) sidMidiShim;
1655 	dispatch[96].controller = 126;
1656 	dispatch[96].operator = 90;
1657 	dispatch[96].routine = (synthRoutine) sidMidiShim;
1658 	dispatch[97].controller = 126;
1659 	dispatch[97].operator = 91;
1660 	dispatch[97].routine = (synthRoutine) sidMidiShim;
1661 	dispatch[98].controller = 126;
1662 	dispatch[98].operator = 92;
1663 	dispatch[98].routine = (synthRoutine) sidMidiShim;
1664 	dispatch[99].controller = 126;
1665 	dispatch[99].operator = 86;
1666 	dispatch[99].routine = (synthRoutine) sidMidiShim;
1667 	dispatch[100].controller = 126;
1668 	dispatch[100].operator = 87;
1669 	dispatch[100].routine = (synthRoutine) sidMidiShim;
1670 	dispatch[101].controller = 126;
1671 	dispatch[101].operator = 88;
1672 	dispatch[101].routine = (synthRoutine) sidMidiShim;
1673 
1674 	/* Env mod */
1675 	dispatch[102].controller = 126;
1676 	dispatch[102].operator = 93;
1677 	dispatch[102].routine = (synthRoutine) sidMidiShim;
1678 	dispatch[103].controller = 126;
1679 	dispatch[103].operator = 94;
1680 	dispatch[103].routine = (synthRoutine) sidMidiShim;
1681 	dispatch[104].controller = 126;
1682 	dispatch[104].operator = 95;
1683 	dispatch[104].routine = (synthRoutine) sidMidiShim;
1684 	dispatch[105].controller = 126;
1685 	dispatch[105].operator = 96;
1686 	dispatch[105].routine = (synthRoutine) sidMidiShim;
1687 	dispatch[106].controller = 126;
1688 	dispatch[106].operator = 97;
1689 	dispatch[106].routine = (synthRoutine) sidMidiShim;
1690 	dispatch[107].controller = 126;
1691 	dispatch[107].operator = 103;
1692 	dispatch[107].routine = (synthRoutine) sidMidiShim;
1693 
1694 	/* Arpeggiator */
1695 	dispatch[115].controller = 126;
1696 	dispatch[115].operator = 6;
1697 	dispatch[115].routine = (synthRoutine) sidMidiShim;
1698 	dispatch[116].controller = 126;
1699 	dispatch[116].operator = 7;
1700 	dispatch[116].routine = (synthRoutine) sidMidiShim;
1701 	dispatch[117].controller = 126;
1702 	dispatch[117].operator = 8;
1703 	dispatch[117].routine = (synthRoutine) sidMidiShim;
1704 
1705 	/* Memory and MIDI */
1706 	dispatch[MEM_START + 0].operator = 1;
1707 	dispatch[MEM_START + 1].operator = 2;
1708 	dispatch[MEM_START + 2].operator = 3;
1709 	dispatch[MEM_START + 3].operator = 4;
1710 	dispatch[MEM_START + 4].operator = 5;
1711 	dispatch[MEM_START + 5].operator = 6;
1712 	dispatch[MEM_START + 6].operator = 7;
1713 	dispatch[MEM_START + 7].operator = 8;
1714 
1715 	dispatch[MEM_START + 8].controller = 1;
1716 	dispatch[MEM_START + 9].controller = 2;
1717 	dispatch[MEM_START + 10].controller = 3;
1718 	dispatch[MEM_START + 11].controller = 4;
1719 	dispatch[MEM_START + 12].controller = 5;
1720 	dispatch[MEM_START + 13].controller = 6;
1721 
1722 	dispatch[MEM_START + 0].routine =
1723 		dispatch[MEM_START + 1].routine =
1724 		dispatch[MEM_START + 2].routine =
1725 		dispatch[MEM_START + 3].routine =
1726 		dispatch[MEM_START + 4].routine =
1727 		dispatch[MEM_START + 5].routine =
1728 		dispatch[MEM_START + 6].routine =
1729 		dispatch[MEM_START + 7].routine =
1730 		dispatch[MEM_START + 8].routine =
1731 		dispatch[MEM_START + 9].routine =
1732 		dispatch[MEM_START + 10].routine =
1733 		dispatch[MEM_START + 11].routine =
1734 		dispatch[MEM_START + 12].routine =
1735 		dispatch[MEM_START + 13].routine = (synthRoutine) sidMemory;
1736 
1737 	dispatch[132].controller = 0;
1738 	dispatch[133].controller = 1;
1739 	dispatch[132].routine = dispatch[133].routine
1740 		= (synthRoutine) sidMidiChannel;
1741 
1742 	/* Osc-1 settings */
1743 
1744 	/* Env settings */
1745 
1746 	/* Filter */
1747 
1748 	dispatch[MEM_START].other1 = 1;
1749 	dispatch[69].other1 = 0;
1750 	dispatch[76].other1 = 0;
1751 
1752 	return(0);
1753 }
1754 
1755 /*
1756  * This will be called to make any routine specific parameters available.
1757  */
1758 static int
sidConfigure(brightonWindow * win)1759 sidConfigure(brightonWindow *win)
1760 {
1761 	guiSynth *synth = findSynth(global.synths, win);
1762 	brightonEvent event;
1763 
1764 	if (synth == 0)
1765 	{
1766 		printf("problems going operational\n");
1767 		return(-1);
1768 	}
1769 
1770 	if (synth->location == 0) {
1771 		synth->bank = 1;
1772 		synth->location = 1;
1773 	} else if (synth->location > 0) {
1774 		mbh = (synth->location / 100) * 100;
1775 		if ((synth->bank = synth->location / 10) > 10)
1776 			synth->bank = synth->bank % 10;
1777 		if (((synth->location = synth->location % 10) == 0)
1778 			|| (synth->location > 8))
1779 			synth->location = 1;
1780 	}
1781 
1782 	if (synth->flags & OPERATIONAL)
1783 		return(0);
1784 
1785 	printf("going operational\n");
1786 
1787 	synth->flags |= OPERATIONAL;
1788 	synth->keypanel = 1;
1789 	synth->keypanel2 = -1;
1790 	synth->transpose = 24;
1791 
1792 	brightonPut(win,
1793 		"bitmaps/blueprints/sidshade.xpm", 0, 0, win->width, win->height);
1794 
1795 	/*
1796 	 * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only
1797 	 * occurs on first paint, so we suppress the first paint, and then request
1798 	 * an expose here.
1799 	 */
1800 	event.type = BRIGHTON_EXPOSE;
1801 	event.intvalue = 1;
1802 	brightonParamChange(synth->win, KEY_PANEL, -1, &event);
1803 	event.type = BRISTOL_FLOAT;
1804 	event.value = 1;
1805 	brightonParamChange(synth->win, MODS_PANEL, 1, &event);
1806 	brightonParamChange(synth->win, MODS_PANEL, 2, &event);
1807 	brightonParamChange(synth->win, MODS_PANEL, 4, &event);
1808 	configureGlobals(synth);
1809 
1810 	/* First memory location */
1811 	event.value = 1.0;
1812 	brightonParamChange(synth->win, 0, MEM_START + synth->location-1, &event);
1813 	brightonParamChange(synth->win, 0, 69, &event);
1814 	brightonParamChange(synth->win, 0, 76, &event);
1815 
1816 	loadMemory(synth, SYNTH_NAME, 0, synth->bank * 10 + synth->location,
1817 		synth->mem.active, 0, BRISTOL_FORCE);
1818 	loadMemoryShim(synth);
1819 
1820 	event.value = 0.505;
1821 	brightonParamChange(synth->win, MODS_PANEL, 0, &event);
1822 
1823 	synth->dispatch[MEM_START].other1 = synth->location;
1824 
1825 	dc = brightonGetDCTimer(1000000);
1826 
1827 	synth->loadMemory = (loadRoutine) loadMemoryKeyShim;
1828 
1829 	return(0);
1830 }
1831 
1832