1 
2 /*
3  *  Diverse Bristol audio routines.
4  *  Copyright (c) by Nick Copeland <nickycopeland@hotmail.com> 1996,2012
5  *
6  *
7  *   This program is free software; you can redistribute it and/or modify
8  *   it under the terms of the GNU General Public License as published by
9  *   the Free Software Foundation; either version 3 of the License, or
10  *   (at your option) any later version.
11  *
12  *   This program is distributed in the hope that it will be useful,
13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *   GNU General Public License for more details.
16  *
17  *   You should have received a copy of the GNU General Public License
18  *   along with this program; if not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 /*
23  * Highkey/Lowkey will govern glide only.
24  * Integrate ADSR - GUI Done
25  * Add mod to GenX/Y - GUI Done
26  * Add PWM
27  * Add options for LFO multi/uni
28  * Add modwheel - GUI Done
29  * Add LFO for LFO gain?
30  * Add stereo reverb?
31  *
32  * Add global tuning.
33  *
34  * Octave is -/+2
35  */
36 
37 #include <fcntl.h>
38 
39 #include "brighton.h"
40 #include "brightonMini.h"
41 #include "brightoninternals.h"
42 
43 int initmem = 0;
44 
45 int sonic6Init();
46 int sonic6Configure();
47 int sonic6Callback(brightonWindow *, int, int, float);
48 static int midiCallback(brightonWindow *, int, int, float);
49 static int sonic6ModCallback(brightonWindow *, int, int, float);
50 
51 extern guimain global;
52 
53 extern int empty;
54 
55 #include "brightonKeys.h"
56 
57 #define KEY_PANEL 1
58 
59 #define FIRST_DEV 0
60 #define DEVICE_COUNT 85
61 #define ACTIVE_DEVS 60
62 #define MEM_START (ACTIVE_DEVS + 8)
63 
64 #define DISPLAY_DEV (DEVICE_COUNT - 1)
65 
66 #define S1 80
67 #define S2 60
68 #define S3 13
69 #define S4 60
70 #define S5 25
71 #define S6 30
72 #define S7 70
73 
74 #define B1 15
75 #define B2 110
76 #define B3 37
77 #define B4 42
78 
79 #define R14 200
80 #define R24 400
81 #define R34 600
82 #define R44 800
83 
84 #define R15 200
85 #define R25 350
86 #define R35 500
87 #define R45 650
88 #define R55 800
89 
90 #define C1 25
91 #define C2 90
92 #define C3 155
93 #define C4 220
94 #define C5 285
95 #define C6 350
96 #define C6I 395
97 
98 #define C7 615
99 #define C8 665
100 #define C9 742
101 #define C10 810
102 #define C11 875
103 #define C12 945
104 
105 /*
106  * This structure is for device definition. The structure is defined in
107  * include/brighton.h, further definitions in brighton/brightonDevtable.h and
108  * include/brightoninternals.h
109  *
110  *	typedef int (*brightonCallback)(int, float);
111  *	typedef struct BrightonLocations {
112  *		int device; 0=rotary, 1=scale, etc.
113  *		float relx, rely; relative position with regards to 1000 by 1000 window
114  *		float relw, relh; relative height.
115  *		int from, to;
116  *		brightonCallback callback; specific to this dev
117  *		char *image; bitmap. If zero take a device default.
118  *		int flags;
119  *	} brightonLocations;
120  *
121  * This example is for a sonic6Bristol type synth interface.
122  */
123 static brightonLocations locations[DEVICE_COUNT] = {
124 /* LFO Master - 0*/
125 	{"LFO-MasterF", 1, 114, 490, 13, 180, 0, 1, 0,
126 		"bitmaps/knobs/sliderArpBlack.xpm", 0, 0},
127 /* LFO 1 */
128 	{"LFO-X-Wave", 0, 40, 253, S1, S1, 0, 3, 0,
129 		"bitmaps/knobs/knob4.xpm", 0, BRIGHTON_STEPPED},
130 	{"LFO-X-Rate", 1, 90, 230, 13, 180, 0, 1, 0,
131 		"bitmaps/knobs/sliderArpBlack.xpm", 0, 0},
132 	{"LFO-Dest", 2, 40, 370, S3, S4, 0, 2, 0,
133 		"sonicrocker", 0, BRIGHTON_THREEWAY},
134 /* LFO 2  - 4*/
135 	{"LFO-Y-Rate", 1, 135, 230, 13, 180, 0, 1, 0,
136 		"bitmaps/knobs/sliderArpBlack.xpm", 0, 0},
137 	{"LFO-Wave", 0, 168, 253, S1, S1, 0, 3, 0,
138 		"bitmaps/knobs/knob4.xpm", 0, BRIGHTON_STEPPED},
139 	{"LFO-Dest", 2, 188, 370, S3, S4, 0, 2, 0,
140 		"sonicrocker", 0, BRIGHTON_THREEWAY},
141 /* LFO Mix */
142 	{"LFO-MIX", 0, 106, 88, S2, S2, 0, 1, 0,
143 		"bitmaps/knobs/knob4.xpm", 0, BRIGHTON_NOTCH},
144 
145 /* Osc 1 - 8 */
146 	{"OscA-Tuning", 0, 230, 260, S2, S2, 0, 1, 0,
147 		"bitmaps/knobs/knob4.xpm", 0, BRIGHTON_NOTCH},
148 	{"OscA-PW", 0, 230, 360, S2, S2, 0, 1, 0,
149 		"bitmaps/knobs/knob4.xpm", 0, 0},
150 	{"OscA-Transpose", 2, 278, 280, S5, S6, 0, 2, 0,
151 		"sonicrocker", 0, BRIGHTON_VERTICAL|BRIGHTON_THREEWAY},
152 	/* This can replace the previous for a 5 octave span */
153 //	{"OscA-F", 0, 278, 260, S2, S2, 0, 4, 0,
154 //		"bitmaps/knobs/knob4.xpm", 0, BRIGHTON_STEPPED},
155 	{"OscA-Waveform", 2, 278, 380, S5, S6, 0, 2, 0,
156 		"sonicrocker", 0, BRIGHTON_VERTICAL|BRIGHTON_THREEWAY},
157 
158 	{"dummy", 0, 0, 0, S2, S2, 0, 1, 0,
159 		"bitmaps/knobs/knob4.xpm", 0, BRIGHTON_WITHDRAWN},
160 	{"dummy", 0, 0, 0, S2, S2, 0, 1, 0,
161 		"bitmaps/knobs/knob4.xpm", 0, BRIGHTON_WITHDRAWN},
162 
163 	{"OscA-FM-XY", 0, 230, 518, S2, S2, 0, 1, 0,
164 		"bitmaps/knobs/knob4.xpm", 0, 0},
165 	{"OscA-FM-ADSR", 0, 285, 518, S2, S2, 0, 1, 0,
166 		"bitmaps/knobs/knob4.xpm", 0, 0},
167 	{"OscA-Mode", 2, 260, 640, S5, S6, 0, 2, 0,
168 		"sonicrocker", 0, BRIGHTON_VERTICAL|BRIGHTON_THREEWAY},
169 /* Osc 2 - 17 */
170 	{"OscB-Tuning", 0, 390, 260, S2, S2, 0, 1, 0,
171 		"bitmaps/knobs/knob4.xpm", 0, BRIGHTON_NOTCH},
172 	{"OscB-PW", 0, 390, 360, S2, S2, 0, 1, 0,
173 		"bitmaps/knobs/knob4.xpm", 0, 0},
174 	{"OscB-Transpose", 2, 337, 280, S5, S6, 0, 2, 0,
175 		"sonicrocker", 0, BRIGHTON_VERTICAL|BRIGHTON_THREEWAY},
176 	/* This can replace the previous for a 5 octave span */
177 //	{"OscA-F", 0, 337, 260, S2, S2, 0, 4, 0,
178 //		"bitmaps/knobs/knob4.xpm", 0, BRIGHTON_STEPPED},
179 	{"OscB-Waveform", 2, 337, 380, S5, S6, 0, 2, 0,
180 		"sonicrocker", 0, BRIGHTON_VERTICAL|BRIGHTON_THREEWAY},
181 
182 	{"dummy", 0, 0, 0, S2, S2, 0, 1, 0,
183 		"bitmaps/knobs/knob4.xpm", 0, BRIGHTON_WITHDRAWN},
184 	{"dummy", 0, 0, 0, S2, S2, 0, 1, 0,
185 		"bitmaps/knobs/knob4.xpm", 0, BRIGHTON_WITHDRAWN},
186 
187 	{"OscB-FM-XY", 0, 335, 518, S2, S2, 0, 1, 0,
188 		"bitmaps/knobs/knob4.xpm", 0, 0},
189 	{"OscB-FM-OscA", 0, 390, 518, S2, S2, 0, 1, 0,
190 		"bitmaps/knobs/knob4.xpm", 0, 0},
191 	{"OscB-PWM", 0, 362, 616, S2, S2, 0, 1, 0,
192 		"bitmaps/knobs/knob4.xpm", 0, 0},
193 /* Osc Mix - 26 */
194 	{"Osc-A/B-Mix", 0, 309, 88, S2, S2, 0, 1, 0,
195 		"bitmaps/knobs/knob4.xpm", 0, BRIGHTON_NOTCH},
196 
197 /* Ring Mod */
198 	{"RM-Src1", 2, 460, 274, S5, S6, 0, 1, 0,
199 		"bitmaps/buttons/sonicrocker1.xpm",
200 		"bitmaps/buttons/sonicrocker3.xpm", BRIGHTON_VERTICAL},
201 	{"RM-Src2", 2, 460, 380, S5, S6, 0, 1, 0,
202 		"bitmaps/buttons/sonicrocker1.xpm",
203 		"bitmaps/buttons/sonicrocker3.xpm", BRIGHTON_VERTICAL},
204 
205 /* Noise */
206 	{"WhitePink", 2, 469, 580, S3, S4 + 10, 0, 1, 0,
207 		"bitmaps/buttons/sonicrocker3.xpm",
208 		"bitmaps/buttons/sonicrocker1.xpm", 0},
209 
210 /* Mixer - 30 */
211 	{"Mix-OscA/B", 0, 548, 260, S2, S2, 0, 1, 0,
212 		"bitmaps/knobs/knob4.xpm", 0, 0},
213 	{"Mix-RM", 0, 548, 370, S2, S2, 0, 1, 0,
214 		"bitmaps/knobs/knob4.xpm", 0, 0},
215 	{"Mix-Ext", 0, 548, 480, S2, S2, 0, 1, 0,
216 		"bitmaps/knobs/knob4.xpm", 0, 0},
217 	{"Mix-Noise", 0, 548, 590, S2, S2, 0, 1, 0,
218 		"bitmaps/knobs/knob4.xpm", 0, 0},
219 
220 /* Bypass */
221 	{"Bypass", 2, 646, 225, S5, S6, 0, 1, 0,
222 		"bitmaps/buttons/sonicrocker1.xpm",
223 		"bitmaps/buttons/sonicrocker3.xpm", BRIGHTON_VERTICAL},
224 
225 /* Env - 35 */
226 	{"Attack", 0, 625, 88, S2, S2, 0, 1, 0,
227 		"bitmaps/knobs/knob4.xpm", 0, 0},
228 	{"Decay", 0, 677, 88, S2, S2, 0, 1, 0,
229 		"bitmaps/knobs/knob4.xpm", 0, 0},
230 	{"Sustain", 0, 729, 88, S2, S2, 0, 1, 0,
231 		"bitmaps/knobs/knob4.xpm", 0, 0},
232 	{"Release", 0, 781, 88, S2, S2, 0, 1, 0,
233 		"bitmaps/knobs/knob4.xpm", 0, 0},
234 /* Env Type */
235 	{"EnvType", 0, 647, 420, S2, S2, 0, 3, 0,
236 		"bitmaps/knobs/knob4.xpm", 0, BRIGHTON_STEPPED},
237 	{"Velocity", 2, 648, 495, S5, S6, 0, 1, 0,
238 		"bitmaps/buttons/sonicrocker1.xpm",
239 		"bitmaps/buttons/sonicrocker3.xpm", BRIGHTON_VERTICAL},
240 
241 /* Filter - 41 */
242 	{"VCF-Cutoff", 1, 740, 260, 13, 270, 0, 1, 0,
243 		"bitmaps/knobs/sliderArpBlack.xpm", 0, 0},
244 	{"VCF-Res", 1, 784, 260, 13, 270, 0, 1, 0,
245 		"bitmaps/knobs/sliderArpBlack.xpm", 0, 0},
246 
247 /* Direct output mixer */
248 	{"Direct-OscA", 0, 845, 88, S2, S2, 0, 1, 0,
249 		"bitmaps/knobs/knob4.xpm", 0, 0},
250 	{"Direct-OscB", 0, 890, 88, S2, S2, 0, 1, 0,
251 		"bitmaps/knobs/knob4.xpm", 0, 0},
252 	{"Direct-Ringmod", 0, 935, 88, S2, S2, 0, 1, 0,
253 		"bitmaps/knobs/knob4.xpm", 0, 0},
254 
255 /* Triggers */
256 	{"TriggerKBD", 2, 625, 612, S3, S4 + 10, 0, 1, 0,
257 		"bitmaps/buttons/sonicrocker1.xpm",
258 		"bitmaps/buttons/sonicrocker3.xpm", 0},
259 	{"TriggerLFO-X", 2, 655, 612, S3, S4 + 10, 0, 1, 0,
260 		"bitmaps/buttons/sonicrocker1.xpm",
261 		"bitmaps/buttons/sonicrocker3.xpm", 0},
262 	{"TriggerLFO-Y", 2, 685, 612, S3, S4 + 10, 0, 1, 0,
263 		"bitmaps/buttons/sonicrocker1.xpm",
264 		"bitmaps/buttons/sonicrocker3.xpm", 0},
265 
266 /* Pitch control - 49 */
267 	{"Osc1-FM-ADSR", 0, 728, 616, S2, S2, 0, 1, 0,
268 		"bitmaps/knobs/knob4.xpm", 0, 0},
269 	{"Osc1-FM-KBD", 2, 762, 612, S3, S4 + 10, 0, 1, 0,
270 		"bitmaps/buttons/sonicrocker1.xpm",
271 		"bitmaps/buttons/sonicrocker3.xpm", 0},
272 	{"Osc1-FM-X/Y", 0, 787, 616, S2, S2, 0, 1, 0,
273 		"bitmaps/knobs/knob4.xpm", 0, 0},
274 
275 /* Memories dummies - 52 */
276 	/* Multi LFO-X */
277 	{"LFO-X-Multi", 2, 150, 884, S3, S4 + 4, 0, 1, 0,
278 		"bitmaps/buttons/sonicrocker1.xpm",
279 		"bitmaps/buttons/sonicrocker3.xpm", 0},
280 	/* Multi LFO-X */
281 	{"LFO-Y-Multi", 2, 180, 884, S3, S4 + 4, 0, 1, 0,
282 		"bitmaps/buttons/sonicrocker1.xpm",
283 		"bitmaps/buttons/sonicrocker3.xpm", 0},
284 	{"is dummydummy", 0, 100, 880, S7, S7, 0, 1, 0,
285 		"bitmaps/knobs/knob4.xpm", 0, BRIGHTON_WITHDRAWN},
286 
287 	{"FX-1", 0, 807, 880, S7, S7, 0, 1, 0,
288 		"bitmaps/knobs/knob4.xpm", 0, 0},
289 	{"FX-2", 0, 842, 880, S7, S7, 0, 1, 0,
290 		"bitmaps/knobs/knob4.xpm", 0, 0},
291 	{"FX-3", 0, 877, 880, S7, S7, 0, 1, 0,
292 		"bitmaps/knobs/knob4.xpm", 0, 0},
293 	{"FX-4", 0, 912, 880, S7, S7, 0, 1, 0,
294 		"bitmaps/knobs/knob4.xpm", 0, 0},
295 	{"dummy", 0, 0, 0, S2, S2, 0, 1, 0,
296 		"bitmaps/knobs/knob4.xpm", 0, BRIGHTON_WITHDRAWN},
297 
298 /* Global controls (not in memories - 60 */
299 	{"Global", 0, 60, 880, S7, S7, 0, 1, 0,
300 		"bitmaps/knobs/knob4.xpm", 0, BRIGHTON_NOTCH},
301 	{"dummy", 0, 0, 0, S2, S2, 0, 1, 0,
302 		"bitmaps/knobs/knob4.xpm", 0, BRIGHTON_WITHDRAWN},
303 	{"dummy", 0, 0, 0, S2, S2, 0, 1, 0,
304 		"bitmaps/knobs/knob4.xpm", 0, BRIGHTON_WITHDRAWN},
305 	{"dummy", 0, 0, 0, S2, S2, 0, 1, 0,
306 		"bitmaps/knobs/knob4.xpm", 0, BRIGHTON_WITHDRAWN},
307 	{"dummy", 0, 0, 0, S2, S2, 0, 1, 0,
308 		"bitmaps/knobs/knob4.xpm", 0, BRIGHTON_WITHDRAWN},
309 	{"dummy", 0, 0, 0, S2, S2, 0, 1, 0,
310 		"bitmaps/knobs/knob4.xpm", 0, BRIGHTON_WITHDRAWN},
311 	{"dummy", 0, 0, 0, S2, S2, 0, 1, 0,
312 		"bitmaps/knobs/knob4.xpm", 0, BRIGHTON_WITHDRAWN},
313 	{"dummy", 0, 0, 0, S2, S2, 0, 1, 0,
314 		"bitmaps/knobs/knob4.xpm", 0, BRIGHTON_WITHDRAWN},
315 
316 /* REST IN HERE - memory, MIDI */
317 /* memories */
318 	{"", 2, 847, 300, 16, 50, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
319 		"bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
320 	{"", 2, 877, 300, 16, 50, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
321 		"bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
322 	{"", 2, 907, 300, 16, 50, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
323 		"bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
324 	{"", 2, 937, 300, 16, 50, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
325 		"bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
326 
327 	{"", 2, 847, 380, 16, 50, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
328 		"bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
329 	{"", 2, 877, 380, 16, 50, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
330 		"bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
331 	{"", 2, 907, 380, 16, 50, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
332 		"bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
333 	{"", 2, 937, 380, 16, 50, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
334 		"bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
335 
336 	/* Load Save, Bank */
337 	{"", 2, 847, 460, 16, 50, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
338 		"bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON},
339 	{"", 2, 877, 460, 16, 50, 0, 1, 0, "bitmaps/buttons/pressoffo.xpm",
340 		"bitmaps/buttons/pressono.xpm", BRIGHTON_CHECKBUTTON},
341 
342 	{"", 2, 847, 540, 16, 50, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
343 		"bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON},
344 	/* Mem search buttons */
345 	{"", 2, 907, 540, 16, 50, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
346 		"bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON},
347 	{"", 2, 907, 460, 16, 50, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
348 		"bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON},
349 	{"", 2, 877, 540, 16, 50, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
350 		"bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON},
351 
352 /*
353 	{"", 2, 907, 460, 16, 50, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
354 		"bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON},
355 	{"", 2, 847, 540, 16, 50, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
356 		"bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON},
357 	{"", 2, 877, 540, 16, 50, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
358 		"bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON},
359 	{"", 2, 907, 540, 16, 50, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
360 		"bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON},
361 */
362 /* Midi, perhaps eventually file import/export buttons */
363 	{"", 2, 937, 540, 16, 50, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
364 		"bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON},
365 	{"", 2, 937, 460, 16, 50, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
366 		"bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON},
367 
368 	/* display */
369 	{"", 3, 835, 226, 130, 40, 0, 1, 0, 0,
370 		"bitmaps/images/alphadisplay3.xpm", 0},
371 };
372 
373 /*
374  * These are the Sonic mods, glide, volume and now two wheels
375  */
376 #define SM_COUNT 4
377 static brightonLocations sonicmods[SM_COUNT] = {
378 	{"Glide", 1, 235, 30, 100, 580, 0, 1, 0,
379 		"bitmaps/knobs/sliderArpBlack.xpm", 0, 0},
380 	{"Volume", 1, 690, 30, 100, 580, 0, 1, 0,
381 		"bitmaps/knobs/sliderArpBlack.xpm", 0, 0},
382 	{"Bend", 1, 100, 715, 920, 55, 0, 1, 0, 0, 0,
383 		BRIGHTON_NOSHADOW|BRIGHTON_CENTER|BRIGHTON_VERTICAL|BRIGHTON_REVERSE},
384 	{"Mod", 1, 100, 850, 920, 55, 0, 1, 0, 0, 0,
385 		BRIGHTON_NOSHADOW|BRIGHTON_VERTICAL|BRIGHTON_REVERSE},
386 };
387 
388 /*
389  * This is a set of globals for the main window rendering. Again taken from
390  * include/brighton.h
391  */
392 brightonApp sonic6App = {
393 	"sonic6",
394 	0,
395 	"bitmaps/textures/leather.xpm",
396 	0,
397 	sonic6Init,
398 	sonic6Configure, /* 3 callbacks, unused? */
399 	midiCallback,
400 	destroySynth,
401 	{1, 100, 2, 2, 5, 520, 0, 0},
402 	900, 520, 0, 0,
403 	3,
404 	{
405 		{
406 			"Sonic6",
407 			"bitmaps/blueprints/sonic6.xpm",
408 			0, //"bitmaps/textures/metal6.xpm",
409 			BRIGHTON_STRETCH, /* flags */
410 			0,
411 			sonic6Configure,
412 			sonic6Callback,
413 			0, 0, 1000, 670,
414 			DEVICE_COUNT,
415 			locations
416 		},
417 		{
418 			"Keyboard",
419 			0,
420 			"bitmaps/keys/kbg.xpm",
421 			0x020|BRIGHTON_STRETCH,
422 			0,
423 			0,
424 			keyCallback,
425 			160, 700, 810, 280,
426 			KEY_COUNT_4OCTAVE,
427 			keys4octave
428 		},
429 		{
430 			"Mods",
431 			"bitmaps/blueprints/sonicmods.xpm",
432 			"bitmaps/textures/metal5.xpm",
433 			0,
434 			0,
435 			0,
436 			sonic6ModCallback,
437 			27, 685, 115, 280,
438 			SM_COUNT,
439 			sonicmods
440 		},
441 	}
442 };
443 
444 static int
sonic6ModCallback(brightonWindow * bwin,int c,int o,float value)445 sonic6ModCallback(brightonWindow *bwin, int c, int o, float value)
446 {
447 	guiSynth *synth = findSynth(global.synths, bwin);
448 
449 	switch (o) {
450 		case 0:
451 			/* Glide */
452 			bristolMidiSendMsg(global.controlfd, synth->sid,
453 				126, 0, (int) (value * C_RANGE_MIN_1));
454 			break;
455 		case 1:
456 			/* Volume */
457 			bristolMidiSendMsg(global.controlfd, synth->sid,
458 				126, 1, (int) (value * C_RANGE_MIN_1));
459 			break;
460 		case 2:
461 			/* Bend */
462 			bristolMidiSendMsg(global.controlfd, synth->midichannel,
463 				BRISTOL_EVENT_PITCH, 0, (int) (value * C_RANGE_MIN_1));
464 			break;
465 		case 3:
466 			/* Mod */
467 			bristolMidiControl(global.controlfd, synth->midichannel,
468 				0, 1, ((int) (value * (C_RANGE_MIN_1 - 1))) >> 7);
469 			break;
470 	}
471 
472 	return(0);
473 }
474 
475 static int
midiCallback(brightonWindow * win,int controller,int value,float n)476 midiCallback(brightonWindow *win, int controller, int value, float n)
477 {
478 	guiSynth *synth = findSynth(global.synths, win);
479 
480 	printf("midi callback: %x, %i\n", controller, value);
481 
482 	switch(controller)
483 	{
484 		case MIDI_PROGRAM:
485 			printf("midi program: %x, %i\n", controller, value);
486 			synth->location = value;
487 			loadMemory(synth, "sonic6", 0, synth->bank + synth->location,
488 				synth->mem.active, FIRST_DEV, 0);
489 			break;
490 		case MIDI_BANK_SELECT:
491 			printf("midi banksel: %x, %i\n", controller, value);
492 			synth->bank = value;
493 			break;
494 	}
495 	return(0);
496 }
497 
498 static int
sonic6MidiSendMsg(void * synth,int fd,int chan,int c,int o,int v)499 sonic6MidiSendMsg(void *synth, int fd, int chan, int c, int o, int v)
500 {
501 	bristolMidiSendMsg(fd, chan, c, o, v);
502 	return(0);
503 }
504 
505 /*
506  * For the sake of ease of use, links have been placed here to be called
507  * by any of the devices created. They would be better in some other file,
508  * perhaps with this as a dispatch.
509  *
510  * Param refers to the device index in the locations table given below.
511  */
512 int
sonic6Callback(brightonWindow * win,int panel,int index,float value)513 sonic6Callback(brightonWindow * win, int panel, int index, float value)
514 {
515 	guiSynth *synth = findSynth(global.synths, win);
516 	int sendvalue;
517 
518 /* printf("sonic6Callback(%i, %i, %f)\n", panel, index, value); */
519 
520 	if (synth == 0)
521 		return(0);
522 
523 	if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0))
524 		return(0);
525 	if (index >= DEVICE_COUNT)
526 		return(0);
527 
528 	if (sonic6App.resources[0].devlocn[index].to == 1.0)
529 		sendvalue = value * (CONTROLLER_RANGE - 1);
530 	else
531 		sendvalue = value;
532 
533 	synth->mem.param[index] = value;
534 
535 	if ((!global.libtest) || (index >= ACTIVE_DEVS))
536 		synth->dispatch[index].routine(synth,
537 			global.controlfd, synth->sid,
538 			synth->dispatch[index].controller,
539 			synth->dispatch[index].operator,
540 			sendvalue);
541 	else
542 		printf("dispatch[%p,%i](%i, %i, %i, %i, %i)\n", synth, index,
543 			global.controlfd, synth->sid,
544 			synth->dispatch[index].controller,
545 			synth->dispatch[index].operator,
546 			sendvalue);
547 	return(0);
548 }
549 
550 static int
sonic6Midi(guiSynth * synth,int fd,int chan,int c,int o,int value)551 sonic6Midi(guiSynth *synth, int fd, int chan, int c, int o, int value)
552 {
553 	int newchan;
554 
555 	if ((synth->flags & OPERATIONAL) == 0)
556 		return(0);
557 
558 	if (c == 1) {
559 		if ((newchan = synth->midichannel - 1) < 0)
560 			newchan = synth->midichannel = 0;
561 	} else {
562 		if ((newchan = synth->midichannel + 1) >= 16)
563 			newchan = synth->midichannel = 15;
564 	}
565 
566 	if (global.libtest == 0)
567 	{
568 		bristolMidiSendMsg(global.controlfd, synth->sid,
569 			127, 0, BRISTOL_MIDICHANNEL|newchan);
570 	}
571 
572 	synth->midichannel = newchan;
573 
574 	displayText(synth, "MIDI CH", synth->midichannel + 1, DISPLAY_DEV);
575 
576 	return(0);
577 
578 }
579 
580 static void
sonic6LFOFreq(guiSynth * synth,int fd,int chan,int o,int c,int v)581 sonic6LFOFreq(guiSynth *synth, int fd, int chan, int o, int c, int v)
582 {
583 	switch (o) {
584 		default:
585 			if (synth->mem.param[3] == 2)
586 				bristolMidiSendMsg(global.controlfd, synth->sid, 7, 0,
587 					(int) (synth->mem.param[0]
588 						* synth->mem.param[2] * C_RANGE_MIN_1));
589 			else
590 				bristolMidiSendMsg(global.controlfd, synth->sid, 7, 0,
591 					(int) (synth->mem.param[2] * C_RANGE_MIN_1));
592 
593 			if (synth->mem.param[6] == 2)
594 				bristolMidiSendMsg(global.controlfd, synth->sid, 8, 0,
595 					(int) (synth->mem.param[0]
596 						* synth->mem.param[4] * C_RANGE_MIN_1));
597 			else
598 				bristolMidiSendMsg(global.controlfd, synth->sid, 8, 0,
599 					(int) (synth->mem.param[4] * C_RANGE_MIN_1));
600 			break;
601 		case 7:
602 			if (synth->mem.param[3] == 2)
603 				bristolMidiSendMsg(global.controlfd, synth->sid, 7, 0,
604 					(int) (synth->mem.param[0]
605 						* synth->mem.param[2] * C_RANGE_MIN_1));
606 			else
607 				bristolMidiSendMsg(global.controlfd, synth->sid, 7, 0,
608 					(int) (synth->mem.param[2] * C_RANGE_MIN_1));
609 			break;
610 		case 8:
611 			if (synth->mem.param[3] == 2)
612 				bristolMidiSendMsg(global.controlfd, synth->sid, 8, 0,
613 					(int) (synth->mem.param[0]
614 						* synth->mem.param[4] * C_RANGE_MIN_1));
615 			else
616 				bristolMidiSendMsg(global.controlfd, synth->sid, 8, 0,
617 					(int) (synth->mem.param[4] * C_RANGE_MIN_1));
618 			break;
619 	}
620 }
621 
622 static void
sonic6Transpose(guiSynth * synth,int fd,int chan,int o,int c,int v)623 sonic6Transpose(guiSynth *synth, int fd, int chan, int o, int c, int v)
624 {
625 	bristolMidiSendMsg(global.controlfd, synth->sid, o, c, 3 - v);
626 }
627 
628 static void
sonic6Waveform(guiSynth * synth,int fd,int chan,int o,int c,int v)629 sonic6Waveform(guiSynth *synth, int fd, int chan, int o, int c, int v)
630 {
631 	switch (v) {
632 		case 2:
633 			bristolMidiSendMsg(global.controlfd, synth->sid, o, 4, 0);
634 			bristolMidiSendMsg(global.controlfd, synth->sid, o, 5, 1);
635 			bristolMidiSendMsg(global.controlfd, synth->sid, o, 6, 0);
636 			break;
637 		case 1:
638 			bristolMidiSendMsg(global.controlfd, synth->sid, o, 4, 1);
639 			bristolMidiSendMsg(global.controlfd, synth->sid, o, 5, 0);
640 			bristolMidiSendMsg(global.controlfd, synth->sid, o, 6, 0);
641 			break;
642 		case 0:
643 			bristolMidiSendMsg(global.controlfd, synth->sid, o, 4, 0);
644 			bristolMidiSendMsg(global.controlfd, synth->sid, o, 5, 0);
645 			bristolMidiSendMsg(global.controlfd, synth->sid, o, 6, 1);
646 			break;
647 	}
648 }
649 
650 static void
sonic6Envelope(guiSynth * synth,int fd,int chan,int o,int c,int v)651 sonic6Envelope(guiSynth *synth, int fd, int chan, int o, int c, int v)
652 {
653 	/*
654 	 * Shim for the different envelope types
655 	 * param[39] as AR(0), ASR(1), ADSD(2), ADSR(3).
656 	 *
657 	 * AR/AD and ASR are the two types supported by the original device.
658 	 * ADSD is a MiniMoog type envelope, really just three parameters
659 	 * The last one is a full ADSR.
660 	 */
661 	switch (c) {
662 		case 1:
663 			/* * Decay  */
664 			switch ((int) synth->mem.param[39]) {
665 				case 0:
666 					bristolMidiSendMsg(global.controlfd, synth->sid, 3, 1, v);
667 					break;
668 				case 1:
669 					break;
670 				case 2:
671 					bristolMidiSendMsg(global.controlfd, synth->sid, 3, 1, v);
672 					bristolMidiSendMsg(global.controlfd, synth->sid, 3, 3, v);
673 					break;
674 				default:
675 					bristolMidiSendMsg(global.controlfd, synth->sid, 3, 1, v);
676 					break;
677 			}
678 			break;
679 		case 2:
680 			/* Sustain */
681 			switch ((int) synth->mem.param[39]) {
682 				case 0:
683 				case 1:
684 					break;
685 				case 2:
686 				default:
687 					bristolMidiSendMsg(global.controlfd, synth->sid, 3, 2, v);
688 					break;
689 			}
690 			break;
691 		case 3:
692 			/* Release */
693 			switch ((int) synth->mem.param[39]) {
694 				case 0:
695 					/* Type 0 uses decay, not release */
696 					break;
697 				case 1:
698 					bristolMidiSendMsg(global.controlfd, synth->sid, 3, 3, v);
699 					break;
700 				case 2:
701 					break;
702 				default:
703 					bristolMidiSendMsg(global.controlfd, synth->sid, 3, 3, v);
704 					break;
705 			}
706 			break;
707 		default:
708 			/*
709 			 * If we change the envelope type we may need to reconfigure a set
710 			 * of basic parameters to force the desired function
711 			 */
712 			switch ((int) synth->mem.param[39]) {
713 				case 0:
714 					/* AR - zero sustain, configure release=decay */
715 					bristolMidiSendMsg(global.controlfd, synth->sid, 3, 2, 0);
716 					bristolMidiSendMsg(global.controlfd, synth->sid, 3, 1,
717 						(int) (synth->mem.param[36] * C_RANGE_MIN_1));
718 					bristolMidiSendMsg(global.controlfd, synth->sid, 3, 3,
719 						(int) (synth->mem.param[36] * C_RANGE_MIN_1));
720 					break;
721 				case 1:
722 					/* ASR - full sustain, configure decay=release */
723 					bristolMidiSendMsg(global.controlfd, synth->sid, 3, 2,
724 						C_RANGE_MIN_1);
725 					bristolMidiSendMsg(global.controlfd, synth->sid, 3, 1,
726 						(int) (synth->mem.param[38] * C_RANGE_MIN_1));
727 					bristolMidiSendMsg(global.controlfd, synth->sid, 3, 3,
728 						(int) (synth->mem.param[38] * C_RANGE_MIN_1));
729 					break;
730 				case 2:
731 					/* ADSD - configured sustain, configure release=decay */
732 					bristolMidiSendMsg(global.controlfd, synth->sid, 3, 2,
733 						(int) (synth->mem.param[37] * C_RANGE_MIN_1));
734 					bristolMidiSendMsg(global.controlfd, synth->sid, 3, 3,
735 						(int) (synth->mem.param[36] * C_RANGE_MIN_1));
736 					break;
737 				default:
738 					/* ADSD - configured sustain, configure release=decay */
739 					bristolMidiSendMsg(global.controlfd, synth->sid, 3, 1,
740 						(int) (synth->mem.param[36] * C_RANGE_MIN_1));
741 					bristolMidiSendMsg(global.controlfd, synth->sid, 3, 2,
742 						(int) (synth->mem.param[37] * C_RANGE_MIN_1));
743 					bristolMidiSendMsg(global.controlfd, synth->sid, 3, 3,
744 						(int) (synth->mem.param[38] * C_RANGE_MIN_1));
745 					break;
746 			}
747 			break;
748 	}
749 }
750 
751 static void
sonic6Filter(guiSynth * synth,int fd,int chan,int o,int c,int v)752 sonic6Filter(guiSynth *synth, int fd, int chan, int o, int c, int v)
753 {
754 	if (v == 0)
755 		bristolMidiSendMsg(global.controlfd, synth->sid, 4, 3, v);
756 	else
757 		bristolMidiSendMsg(global.controlfd, synth->sid, 4, 3, 8192);
758 }
759 
760 static void
sonic6Memory(guiSynth * synth,int fd,int chan,int c,int o,int v)761 sonic6Memory(guiSynth *synth, int fd, int chan, int c, int o, int v)
762 {
763 	brightonEvent event;
764 	int bank = synth->bank;
765 	int location = synth->location;
766 
767 	event.value = 1.0;
768 	event.type = BRISTOL_FLOAT;
769 
770 	if (synth->flags & MEM_LOADING)
771 		return;
772 	if ((synth->flags & OPERATIONAL) == 0)
773 		return;
774 
775 	if (synth->dispatch[MEM_START].other2)
776 	{
777 		synth->dispatch[MEM_START].other2 = 0;
778 		return;
779 	}
780 
781 	switch (c) {
782 		default:
783 		case 0:
784 			/*
785 			 * We want to make these into memory buttons. To do so we need to
786 			 * know what the last active button was, and deactivate its
787 			 * display, then send any message which represents the most
788 			 * recently configured value. Since this is a memory button we do
789 			 * not have much issue with the message, but we are concerned with
790 			 * the display.
791 			 */
792 			if (synth->dispatch[MEM_START].other1 != -1)
793 			{
794 				synth->dispatch[MEM_START].other2 = 1;
795 
796 				if (synth->dispatch[MEM_START].other1 != o)
797 					event.value = 0;
798 				else
799 					event.value = 1;
800 
801 				brightonParamChange(synth->win, synth->panel,
802 					synth->dispatch[MEM_START].other1 + MEM_START - 1, &event);
803 			}
804 			synth->dispatch[MEM_START].other1 = o;
805 
806 			if (synth->flags & BANK_SELECT) {
807 				if ((synth->bank * 10 + o) >= 100)
808 				{
809 					synth->location = o;
810 					synth->flags &= ~BANK_SELECT;
811 
812 					if (loadMemory(synth, "sonic6", 0,
813 						synth->bank * 10 + synth->location, synth->mem.active,
814 							0, BRISTOL_STAT) < 0)
815 						displayText(synth, "FREE MEM",
816 							synth->bank * 10 + synth->location, DISPLAY_DEV);
817 					else
818 						displayText(synth, "PROGRAM",
819 							synth->bank * 10 + synth->location, DISPLAY_DEV);
820 				} else {
821 					synth->bank = synth->bank * 10 + o;
822 					displayText(synth, "BANK",
823 						synth->bank * 10 + synth->location, DISPLAY_DEV);
824 				}
825 			} else {
826 				if (synth->bank < 1)
827 					synth->bank = 1;
828 				synth->location = o;
829 				if (loadMemory(synth, "sonic6", 0,
830 					synth->bank * 10 + synth->location, synth->mem.active,
831 						0, BRISTOL_STAT) < 0)
832 					displayText(synth, "FREE MEM",
833 						synth->bank * 10 + synth->location, DISPLAY_DEV);
834 				else
835 					displayText(synth, "PROGRAM",
836 						synth->bank * 10 + synth->location, DISPLAY_DEV);
837 			}
838 			break;
839 		case 1:
840 			if (synth->bank < 1)
841 				synth->bank = 1;
842 			if (synth->location == 0)
843 				synth->location = 1;
844 			if (loadMemory(synth, "sonic6", 0, synth->bank * 10 + synth->location,
845 				synth->mem.active, 0, BRISTOL_FORCE) < 0)
846 				displayText(synth, "FREE MEM",
847 					synth->bank * 10 + synth->location, DISPLAY_DEV);
848 			else
849 				displayText(synth, "PROGRAM",
850 					synth->bank * 10 + synth->location, DISPLAY_DEV);
851 			synth->flags &= ~BANK_SELECT;
852 			break;
853 		case 2:
854 			if (synth->bank < 1)
855 				synth->bank = 1;
856 			if (synth->location == 0)
857 				synth->location = 1;
858 			saveMemory(synth, "sonic6", 0, synth->bank * 10 + synth->location,
859 				0);
860 			displayText(synth, "PROGRAM", synth->bank * 10 + synth->location,
861 				DISPLAY_DEV);
862 			synth->flags &= ~BANK_SELECT;
863 			break;
864 		case 3:
865 			if (synth->flags & BANK_SELECT) {
866 				synth->flags &= ~BANK_SELECT;
867 				if (loadMemory(synth, "sonic6", 0,
868 					synth->bank * 10 + synth->location, synth->mem.active,
869 						0, BRISTOL_STAT) < 0)
870 					displayText(synth, "FREE MEM",
871 						synth->bank * 10 + synth->location, DISPLAY_DEV);
872 				else
873 					displayText(synth, "PROGRAM",
874 						synth->bank * 10 + synth->location, DISPLAY_DEV);
875 			} else {
876 				synth->bank = 0;
877 				displayText(synth, "BANK", synth->bank, DISPLAY_DEV);
878 				synth->flags |= BANK_SELECT;
879 			}
880 			break;
881 		case 4:
882 			if (--location < 1) {
883 				location = 8;
884 				if (--bank < 1)
885 					bank = 88;
886 			}
887 			while (loadMemory(synth, "sonic6", 0, bank * 10 + location,
888 				synth->mem.active, 0, BRISTOL_STAT) < 0)
889 			{
890 				if (--location < 1) {
891 					location = 8;
892 					if (--bank < 1)
893 						bank = 88;
894 				}
895 				if ((bank * 10 + location)
896 					== (synth->bank * 10 + synth->location))
897 					break;
898 			}
899 			displayText(synth, "PROGRAM", bank * 10 + location, DISPLAY_DEV);
900 			synth->bank = bank;
901 			synth->location = location;
902 			loadMemory(synth, "sonic6", 0, bank * 10 + location,
903 				synth->mem.active, 0, BRISTOL_FORCE);
904 			brightonParamChange(synth->win, 0,
905 				MEM_START - 1 + synth->location, &event);
906 			break;
907 		case 5:
908 			if (++location > 8) {
909 				location = 1;
910 				if (++bank > 88)
911 					bank = 1;
912 			}
913 			while (loadMemory(synth, "sonic6", 0, bank * 10 + location,
914 				synth->mem.active, 0, BRISTOL_STAT) < 0)
915 			{
916 				if (++location > 8) {
917 					location = 1;
918 					if (++bank > 88)
919 						bank = 1;
920 				}
921 				if ((bank * 10 + location)
922 					== (synth->bank * 10 + synth->location))
923 					break;
924 			}
925 			displayText(synth, "PROGRAM", bank * 10 + location, DISPLAY_DEV);
926 			synth->bank = bank;
927 			synth->location = location;
928 			loadMemory(synth, "sonic6", 0, bank * 10 + location,
929 				synth->mem.active, 0, BRISTOL_FORCE);
930 			brightonParamChange(synth->win, 0,
931 				MEM_START - 1 + synth->location, &event);
932 			break;
933 		case 6:
934 			/* Find the next free mem */
935 			if (++location > 8) {
936 				location = 1;
937 				if (++bank > 88)
938 					bank = 1;
939 			}
940 
941 			while (loadMemory(synth, "sonic6", 0, bank * 10 + location,
942 				synth->mem.active, 0, BRISTOL_STAT) >= 0)
943 			{
944 				if (++location > 8) {
945 					location = 1;
946 					if (++bank > 88)
947 						bank = 1;
948 				}
949 				if ((bank * 10 + location)
950 					== (synth->bank * 10 + synth->location))
951 					break;
952 			}
953 
954 			if (loadMemory(synth, "sonic6", 0, bank * 10 + location,
955 				synth->mem.active, 0, BRISTOL_STAT) >= 0)
956 				displayText(synth, "PROGRAM",
957 					bank * 10 + location, DISPLAY_DEV);
958 			else
959 				displayText(synth, "FREE MEM",
960 					bank * 10 + location, DISPLAY_DEV);
961 
962 			synth->bank = bank;
963 			synth->location = location;
964 			brightonParamChange(synth->win, 0,
965 				MEM_START - 1 + synth->location, &event);
966 			break;
967 	}
968 /*	printf("	pro1Memory(B: %i L %i: %i)\n", */
969 /*		synth->bank, synth->location, o); */
970 }
971 
972 /*
973  * Any location initialisation required to run the callbacks. For bristol, this
974  * will connect to the engine, and give it some base parameters.
975  * May need to generate some application specific menus.
976  * Will also then make specific requests to some of the devices to alter their
977  * rendering.
978  */
979 int
sonic6Init(brightonWindow * win)980 sonic6Init(brightonWindow *win)
981 {
982 	guiSynth *synth = findSynth(global.synths, win);
983 	dispatcher *dispatch;
984 	int i;
985 
986 	if (synth == 0)
987 	{
988 		synth = findSynth(global.synths, 0);
989 		if (synth == 0)
990 		{
991 			printf("cannot init\n");
992 			return(0);
993 		}
994 	}
995 
996 	if ((initmem = synth->location) == 0)
997 		initmem = 11;
998 
999 	synth->win = win;
1000 
1001 	printf("Initialise the sonic6 link to bristol: %p\n", synth->win);
1002 
1003 	synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float));
1004 	synth->mem.count = DEVICE_COUNT;
1005 	synth->mem.active = ACTIVE_DEVS;
1006 	synth->dispatch = (dispatcher *)
1007 		brightonmalloc(DEVICE_COUNT * sizeof(dispatcher));
1008 	dispatch = synth->dispatch;
1009 
1010 	/*
1011 	 * We really want to have three connection mechanisms. These should be
1012 	 *	1. Unix named sockets.
1013 	 *	2. UDP sockets.
1014 	 *	3. MIDI pipe.
1015 	 */
1016 	if (!global.libtest)
1017 		if ((synth->sid = initConnection(&global, synth)) < 0)
1018 			return(-1);
1019 
1020 	for (i = 0; i < DEVICE_COUNT; i++) {
1021 		synth->dispatch[i].controller = 126;
1022 		synth->dispatch[i].operator = 101;
1023 		synth->dispatch[i].routine = sonic6MidiSendMsg;
1024 	}
1025 
1026 	/* LFO */
1027 	synth->dispatch[0].controller = 0;
1028 	synth->dispatch[0].operator = 1;
1029 	synth->dispatch[0].routine = (synthRoutine) sonic6LFOFreq;
1030 	synth->dispatch[2].controller = 7;
1031 	synth->dispatch[2].operator = 0;
1032 	synth->dispatch[2].routine = (synthRoutine) sonic6LFOFreq;
1033 	synth->dispatch[4].controller = 8;
1034 	synth->dispatch[4].operator = 0;
1035 	synth->dispatch[4].routine = (synthRoutine) sonic6LFOFreq;
1036 
1037 	synth->dispatch[1].controller = 126;
1038 	synth->dispatch[1].operator = 15;
1039 	/* This should be shimmed to ensure the correct value is sent */
1040 	synth->dispatch[3].controller = 126;
1041 	synth->dispatch[3].operator = 16;
1042 
1043 	synth->dispatch[5].controller = 126;
1044 	synth->dispatch[5].operator = 17;
1045 	/* This should be shimmed to ensure the correct value is sent */
1046 	synth->dispatch[6].controller = 126;
1047 	synth->dispatch[6].operator = 18;
1048 
1049 	synth->dispatch[7].controller = 126;
1050 	synth->dispatch[7].operator = 14;
1051 
1052 	/* LFO Multi */
1053 	synth->dispatch[52].controller = 126;
1054 	synth->dispatch[52].operator = 19;
1055 	synth->dispatch[53].controller = 126;
1056 	synth->dispatch[53].operator = 20;
1057 
1058 	/* VCO A */
1059 	synth->dispatch[8].controller = 0;
1060 	synth->dispatch[8].operator = 2;
1061 	synth->dispatch[9].controller = 0;
1062 	synth->dispatch[9].operator = 0;
1063 	synth->dispatch[10].controller = 0;
1064 	synth->dispatch[10].operator = 1;
1065 	synth->dispatch[10].routine = (synthRoutine) sonic6Transpose;
1066 	synth->dispatch[11].controller = 0;
1067 	synth->dispatch[11].operator = 1;
1068 	synth->dispatch[11].routine = (synthRoutine) sonic6Waveform;
1069 	/* Two spares here */
1070 	synth->dispatch[14].controller = 126;
1071 	synth->dispatch[14].operator = 21;
1072 	synth->dispatch[15].controller = 126;
1073 	synth->dispatch[15].operator = 22;
1074 
1075 	/* Osc-A mode LFO/KBD/HIGH */
1076 	synth->dispatch[16].controller = 126;
1077 	synth->dispatch[16].operator = 32;
1078 
1079 	/* VCO B */
1080 	synth->dispatch[17].controller = 1;
1081 	synth->dispatch[17].operator = 2;
1082 	synth->dispatch[18].controller = 1;
1083 	synth->dispatch[18].operator = 0;
1084 	synth->dispatch[19].controller = 1;
1085 	synth->dispatch[19].operator = 1;
1086 	synth->dispatch[19].routine = (synthRoutine) sonic6Transpose;
1087 	synth->dispatch[20].controller = 1;
1088 	synth->dispatch[20].operator = 1;
1089 	synth->dispatch[20].routine = (synthRoutine) sonic6Waveform;
1090 	/* Two spares here */
1091 	synth->dispatch[23].controller = 126;
1092 	synth->dispatch[23].operator = 23;
1093 	synth->dispatch[24].controller = 126;
1094 	synth->dispatch[24].operator = 24;
1095 	synth->dispatch[25].controller = 126;
1096 	synth->dispatch[25].operator = 25;
1097 
1098 	/* Generate A/B */
1099 	synth->dispatch[26].controller = 126;
1100 	synth->dispatch[26].operator = 13;
1101 
1102 	/* RM */
1103 	synth->dispatch[27].controller = 126;
1104 	synth->dispatch[27].operator = 26;
1105 	synth->dispatch[28].controller = 126;
1106 	synth->dispatch[28].operator = 27;
1107 
1108 	/* Noise */
1109 	synth->dispatch[29].controller = 6;
1110 	synth->dispatch[29].operator = 1;
1111 
1112 	/* Mixer */
1113 	synth->dispatch[30].controller = 126;
1114 	synth->dispatch[30].operator = 28;
1115 	synth->dispatch[31].controller = 126;
1116 	synth->dispatch[31].operator = 29;
1117 	synth->dispatch[32].controller = 126;
1118 	synth->dispatch[32].operator = 30;
1119 	synth->dispatch[33].controller = 126;
1120 	synth->dispatch[33].operator = 31;
1121 
1122 	/* Bypass */
1123 	synth->dispatch[34].controller = 126;
1124 	synth->dispatch[34].operator = 35;
1125 
1126 	/* ADSR */
1127 	synth->dispatch[35].controller = 3;
1128 	synth->dispatch[35].operator = 0;
1129 	synth->dispatch[36].controller = 3;
1130 	synth->dispatch[36].operator = 1;
1131 	synth->dispatch[37].controller = 3;
1132 	synth->dispatch[37].operator = 2;
1133 	synth->dispatch[38].controller = 3;
1134 	synth->dispatch[38].operator = 3;
1135 	synth->dispatch[39].controller = 126;
1136 	synth->dispatch[39].operator = 101;
1137 	synth->dispatch[36].routine = synth->dispatch[37].routine
1138 		= synth->dispatch[38].routine = synth->dispatch[39].routine
1139 		= (synthRoutine) sonic6Envelope;
1140 
1141 	synth->dispatch[40].controller = 3;
1142 	synth->dispatch[40].operator = 5;
1143 
1144 	/* Filter */
1145 	synth->dispatch[41].controller = 4;
1146 	synth->dispatch[41].operator = 0;
1147 	synth->dispatch[42].controller = 4;
1148 	synth->dispatch[42].operator = 1;
1149 
1150 	/* Direct Outputs */
1151 	synth->dispatch[43].controller = 126;
1152 	synth->dispatch[43].operator = 10;
1153 	synth->dispatch[44].controller = 126;
1154 	synth->dispatch[44].operator = 11;
1155 	synth->dispatch[45].controller = 126;
1156 	synth->dispatch[45].operator = 12;
1157 
1158 	/* Triggers */
1159 	synth->dispatch[46].controller = 3;
1160 	synth->dispatch[46].operator = 6;
1161 	synth->dispatch[47].controller = 126;
1162 	synth->dispatch[47].operator = 36;
1163 	synth->dispatch[48].controller = 126;
1164 	synth->dispatch[48].operator = 37;
1165 
1166 	/* filter */
1167 	synth->dispatch[49].controller = 126;
1168 	synth->dispatch[49].operator = 33;
1169 	synth->dispatch[50].controller = 4;
1170 	synth->dispatch[50].operator = 3;
1171 	synth->dispatch[50].routine = (synthRoutine) sonic6Filter;
1172 	synth->dispatch[51].controller = 126;
1173 	synth->dispatch[51].operator = 34;
1174 
1175 	/* Reverb */
1176 	synth->dispatch[55].controller = 101;
1177 	synth->dispatch[55].operator = 0;
1178 	synth->dispatch[56].controller = 101;
1179 	synth->dispatch[56].operator = 1;
1180 	synth->dispatch[57].controller = 101;
1181 	synth->dispatch[57].operator = 2;
1182 	synth->dispatch[58].controller = 101;
1183 	synth->dispatch[58].operator = 3;
1184 
1185 	/* Global Tuning */
1186 	synth->dispatch[60].controller = 126;
1187 	synth->dispatch[60].operator = 2;
1188 
1189 	/* Memory and MIDI */
1190 	dispatch[MEM_START + 0].operator = 1;
1191 	dispatch[MEM_START + 1].operator = 2;
1192 	dispatch[MEM_START + 2].operator = 3;
1193 	dispatch[MEM_START + 3].operator = 4;
1194 	dispatch[MEM_START + 4].operator = 5;
1195 	dispatch[MEM_START + 5].operator = 6;
1196 	dispatch[MEM_START + 6].operator = 7;
1197 	dispatch[MEM_START + 7].operator = 8;
1198 
1199 	dispatch[MEM_START + 8].controller = 1;
1200 	dispatch[MEM_START + 9].controller = 2;
1201 	dispatch[MEM_START + 10].controller = 3;
1202 	dispatch[MEM_START + 11].controller = 4;
1203 	dispatch[MEM_START + 12].controller = 5;
1204 	dispatch[MEM_START + 13].controller = 6;
1205 
1206 	dispatch[MEM_START + 0].routine =
1207 		dispatch[MEM_START + 1].routine =
1208 		dispatch[MEM_START + 2].routine =
1209 		dispatch[MEM_START + 3].routine =
1210 		dispatch[MEM_START + 4].routine =
1211 		dispatch[MEM_START + 5].routine =
1212 		dispatch[MEM_START + 6].routine =
1213 		dispatch[MEM_START + 7].routine =
1214 		dispatch[MEM_START + 8].routine =
1215 		dispatch[MEM_START + 9].routine =
1216 		dispatch[MEM_START + 10].routine =
1217 		dispatch[MEM_START + 11].routine =
1218 		dispatch[MEM_START + 12].routine =
1219 		dispatch[MEM_START + 13].routine = (synthRoutine) sonic6Memory;
1220 
1221 	dispatch[DEVICE_COUNT - 3].routine = dispatch[DEVICE_COUNT - 2].routine =
1222 		(synthRoutine) sonic6Midi;
1223 	dispatch[DEVICE_COUNT - 3].controller = 1;
1224 	dispatch[DEVICE_COUNT - 2].controller = 2;
1225 
1226 	dispatch[MEM_START].other1 = -1;
1227 
1228 	/* VCO inits */
1229 	bristolMidiSendMsg(global.controlfd, synth->sid, 0, 0, 8192);
1230 	bristolMidiSendMsg(global.controlfd, synth->sid, 0, 1, 2);
1231 	bristolMidiSendMsg(global.controlfd, synth->sid, 0, 2, 8192);
1232 	bristolMidiSendMsg(global.controlfd, synth->sid, 0, 3, 16383);
1233 	bristolMidiSendMsg(global.controlfd, synth->sid, 0, 5, 16383);
1234 
1235 	/* VCO inits */
1236 	bristolMidiSendMsg(global.controlfd, synth->sid, 1, 0, 8192);
1237 	bristolMidiSendMsg(global.controlfd, synth->sid, 1, 1, 2);
1238 	bristolMidiSendMsg(global.controlfd, synth->sid, 1, 2, 8192);
1239 	bristolMidiSendMsg(global.controlfd, synth->sid, 1, 3, 16383);
1240 	bristolMidiSendMsg(global.controlfd, synth->sid, 1, 4, 16383);
1241 
1242 	/* LFO Sync to key_on */
1243 	bristolMidiSendMsg(global.controlfd, synth->sid, 7, 1, 16383);
1244 	bristolMidiSendMsg(global.controlfd, synth->sid, 8, 1, 16383);
1245 
1246 	/* ADSR gain */
1247 	bristolMidiSendMsg(global.controlfd, synth->sid, 3, 3, 16383);
1248 
1249 	/* Noise - gain and pink filter */
1250 	bristolMidiSendMsg(global.controlfd, synth->sid, 6, 0, 10024);
1251 	bristolMidiSendMsg(global.controlfd, synth->sid, 6, 2, 4096);
1252 
1253 	/* Ring Mod */
1254 	bristolMidiSendMsg(global.controlfd, synth->sid, 2, 0, 8192);
1255 	bristolMidiSendMsg(global.controlfd, synth->sid, 2, 1, 8192);
1256 	bristolMidiSendMsg(global.controlfd, synth->sid, 2, 2, 8192);
1257 
1258 	/* filter mod and key tracking stuff */
1259 	bristolMidiSendMsg(global.controlfd, synth->sid, 4, 2, 8192);
1260 	bristolMidiSendMsg(global.controlfd, synth->sid, 4, 3, 4096);
1261 	bristolMidiSendMsg(global.controlfd, synth->sid, 4, 4, 4);
1262 	bristolMidiSendMsg(global.controlfd, synth->sid, 4, 5, 16383);
1263 	bristolMidiSendMsg(global.controlfd, synth->sid, 4, 6, 0);
1264 
1265 	/* Tune */
1266 	bristolMidiSendMsg(global.controlfd, synth->sid, 126, 2, 8192);
1267 
1268 	return(0);
1269 }
1270 
1271 /*
1272  * This will be called to make any routine specific parameters available.
1273  */
1274 int
sonic6Configure(brightonWindow * win)1275 sonic6Configure(brightonWindow *win)
1276 {
1277 	guiSynth *synth = findSynth(global.synths, win);
1278 	brightonEvent event;
1279 
1280 	if (synth == 0)
1281 	{
1282 		printf("problems going operational\n");
1283 		return(-1);
1284 	}
1285 
1286 	if (synth->flags & OPERATIONAL)
1287 		return(0);
1288 
1289 	printf("going operational\n");
1290 
1291 	synth->flags |= OPERATIONAL;
1292 	synth->keypanel = 1;
1293 	synth->keypanel2 = -1;
1294 	synth->transpose = 36;
1295 
1296 	if (synth->location == 0)
1297 	{
1298 		synth->bank = 1;
1299 		synth->location = 1;
1300 	}
1301 
1302 	loadMemory(synth, "sonic6", 0, initmem, synth->mem.active, FIRST_DEV,
1303 		BRISTOL_FORCE);
1304 
1305 	event.type = BRIGHTON_FLOAT;
1306 	/* Tune */
1307 	event.value = 0.5;
1308 	brightonParamChange(synth->win, 0, 60, &event);
1309 	/* Volume */
1310 	event.value = 0.5;
1311 	brightonParamChange(synth->win, 2, 1, &event);
1312 	/* Glide */
1313 	event.value = 0.1;
1314 	brightonParamChange(synth->win, 2, 0, &event);
1315 	/* Modwheel */
1316 	event.value = 0.1;
1317 	brightonParamChange(synth->win, 2, 3, &event);
1318 
1319 	/*
1320 	 * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only
1321 	 * occurs on first paint, so we suppress the first paint, and then request
1322 	 * an expose here.
1323 	 */
1324 	event.type = BRIGHTON_EXPOSE;
1325 	event.intvalue = 1;
1326 	brightonParamChange(synth->win, KEY_PANEL, -1, &event);
1327 	configureGlobals(synth);
1328 
1329 	brightonPut(win,
1330 		"bitmaps/blueprints/sonic6shade.xpm", 0, 0, win->width, win->height);
1331 
1332 	return(0);
1333 }
1334 
1335