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