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  * Filter type selector DONE
24  *
25  * Synth Pan DONE
26  *
27  * Env touch sense - env to filter should not have touch? Maybe it should to
28  * add harmonics with touch hence an option. The option goes to the envelope
29  * and to the emulator since they have to both recognise when to use touch?
30  * DONE TEST
31  *
32  * Fixed Legato waveforms and waveform selection (alternate osc1/osc2). DONE
33  *
34  * Fixed Osc2 trill - Osc-1 trill is a function of joystick plus mod routing,
35  * Osc-2 trill is a funtion of this button? DONE
36  *
37  * Fixed glides DONE
38  *
39  * Fixed pedal DONE
40  *
41  * Corrected tuning DONE
42  *
43  * Added options information: DONE
44  *
45  *	P1 Master volume
46  *
47  *	P2  Organ pan
48  *	P3  Organ waveform distorts
49  *	P4  Organ spacialisation
50  *	P5  Organ mod level
51  *	J1  Organ key grooming
52  *	P6  Organ tuning
53  *
54  *	P7  Synth pan
55  *	P8  Synth tuning
56  *	P9  Synth osc1 harmonics
57  *	P10 Synth osc2 harmonics
58  *	J2  Synth velocity sensitivity
59  *	J3  Synth filter type
60  *	P11 Synth tracking
61  *
62  *	P12 String pan
63  *	P13 String harmonics
64  *	P14 String spacialisation
65  *	P15 String mod level
66  *	P16 String waveform - dropped?
67  *
68  * Continuous controllers and joystick DONE
69  *
70  * Consider the VCO LFO options. Could perhaps be improved however they are
71  * flexible and without more data on the original this will remain. DONE
72  *
73  * Fix LFO mono/multi for nosync/sync of lfo to key DONE TEST
74  *
75  * Fix envelope touch sense, emulation touch sense DONE
76  *
77  * Doublecheck options DONE
78  *
79  * Fix sync. This could be postponed but can try and look into whether the
80  * noise comes from the syncing waveform or the synced waveform.
81  *
82  * Added filter keyboard tracking. Reworked tuning needs testing. This could
83  * also be postponed however it is not far off.
84  */
85 
86 #include <fcntl.h>
87 
88 #include "brighton.h"
89 #include "brightonMini.h"
90 
91 static int initmem = 0;
92 
93 int stratusInit();
94 int stratusConfigure();
95 int stratusCallback(brightonWindow *, int, int, float);
96 /*static int keyCallback(void *, int, int, float); */
97 int stratusModCallback(brightonWindow *, int, int, float);
98 int stratusMidiCallback(brightonWindow *, int, int, float);
99 static void panelSwitch(guiSynth *, int, int, int, int, int);
100 static void stratusLoadMemory(guiSynth *, int, int, int, int, int);
101 
102 static int dc;
103 
104 extern guimain global;
105 static guimain manual;
106 
107 #include "brightonKeys.h"
108 #include "brightoninternals.h"
109 
110 #define DEVICE_COUNT 87
111 #define STRATUS_DEVS 47
112 #define ACTIVE_DEVS 70
113 #define MEM_START (ACTIVE_DEVS)
114 #define RADIOSET_1 MEM_START
115 #define RADIOSET_2 (MEM_START + 1)
116 #define RADIOSET_3 (MEM_START + 2)
117 #define DISPLAY_DEV (DEVICE_COUNT - 1)
118 
119 #define KEY_PANEL 1
120 #define OPTS_PANEL 3
121 #define OPTS_OFFSET 47
122 #define MODS_OFFSET 66
123 
124 /*
125  * This structure is for device definition. The structure is defined in
126  * include/brighton.h, further definitions in brighton/brightonDevtable.h and
127  * include/brightoninternals.h
128  *
129  *	typedef int (*brightonCallback)(int, float);
130  *	typedef struct BrightonLocations {
131  *		int device; 0=rotary, 1=scale, etc.
132  *		float relx, rely; relative position with regards to 1000 by 1000 window
133  *		float relw, relh; relative height.
134  *		int from, to;
135  *		brightonCallback callback; specific to this dev
136  *		char *image; bitmap. If zero take a device default.
137  *		int flags;
138  *	} brightonLocations;
139  *
140  * This example is for a stratusBristol type synth interface.
141  */
142 #define S1 35
143 #define S2 110
144 #define S2b 15
145 #define S2c 80
146 #define S3 70
147 #define S4 600
148 
149 #define BO 10
150 #define B2 6
151 
152 #define R1 190
153 #define R2 560
154 
155 #define R2a 260
156 #define R2b 380
157 #define R2c 500
158 #define R2d 620
159 
160 #define D1 51
161 #define D2 43
162 #define D3 30
163 
164 #define C1 26
165 #define C2 (C1 + D1)
166 #define C3 (C2 + D1)
167 #define C4 (C3 + D1)
168 #define C5 (C4 + D1)
169 #define C6 (C5 + D1)
170 #define C7 (C6 + D1)
171 #define C8 (C7 + D1)
172 #define C9 (C8 + D1)
173 #define C10 (C9 + D1)
174 #define C11 (C10 + D1)
175 #define C12 (C11 + D1)
176 #define C13 (C12 + D1 + 23)
177 #define C14 (C13 + D1)
178 #define C15 (C14 + D1)
179 #define C16 (C15 + D1)
180 #define C17 (C16 + D1 - 23)
181 #define C18 (C17 + D1)
182 #define C19 (C18 + D1)
183 #define C20 (C19 + D1)
184 
185 static brightonLocations stratusLocations[DEVICE_COUNT] = {
186 	/* Organ */
187 	{"Organ-2'", 1, C1-10, 110, 90, 40, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0,
188         BRIGHTON_VERTICAL|BRIGHTON_NOSHADOW|BRIGHTON_REVERSE},
189 	{"Organ-4'", 1, C1-10, 180, 90, 40, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0,
190         BRIGHTON_VERTICAL|BRIGHTON_NOSHADOW|BRIGHTON_REVERSE},
191 	{"Organ-8'", 1, C1-10, 250, 90, 40, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0,
192         BRIGHTON_VERTICAL|BRIGHTON_NOSHADOW|BRIGHTON_REVERSE},
193 	{"Organ-16'", 1, C1-10, 320, 90, 40, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm", 0,
194         BRIGHTON_VERTICAL|BRIGHTON_NOSHADOW|BRIGHTON_REVERSE},
195 
196 	/* Filter - 4 */
197 	{"VCF-Env", 0, C3, R1, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm",
198 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_NOTCH},
199 	{"VCF-Cutoff", 0, C4, R1, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm",
200 		"bitmaps/knobs/alpharotary.xpm", 0},
201 	{"VCF-Res", 0, C5, R1, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm",
202 		"bitmaps/knobs/alpharotary.xpm", 0},
203 	{"VCF-Pedal", 0, C6, R1, S1, S2, 0, 1.01, 0, "bitmaps/knobs/knob4.xpm",
204 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_STEPPED},
205 
206 	/* - 8 */
207 	{"Glide-Amount", 0, C7, R1, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm",
208 		"bitmaps/knobs/alpharotary.xpm", 0},
209 	{"Glide-Speed", 0, C8, R1, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm",
210 		"bitmaps/knobs/alpharotary.xpm", 0},
211 	{"Glide-Multi", 0, C9, R1, S1, S2, 0, 1.01, 0, "bitmaps/knobs/knob4.xpm",
212 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_STEPPED},
213 	{"Glide-Dir", 0, C10, R1, S1, S2, 0, 3, 0, "bitmaps/knobs/knob4.xpm",
214 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_STEPPED},
215 
216 	/* - 12 */
217 	{"Osc1-Tuning", 0, C11, R1, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm",
218 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_NOTCH},
219 	{"Osc1-Sync", 2, C11 + (D2*1) + 3, R1, S2b+4, S2-10, 0, 1, 0,
220 		"bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0},
221 	{"Osc1-Octave", 2, C11 + (D2*2), R1, S2b+4, S2-10, 0, 12, 0,
222 		"bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0},
223 
224 	/* - 15 */
225 	{"Osc1-Trill", 2, C11 + (D2*1) + 3, R2, S2b+4, S2-10, 0, 1, 0,
226 		"bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0},
227 	{"Osc2-Octave", 2, C11 + (D2*2), R2, S2b+4, S2-10, 0, 12, 0,
228 		"bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0},
229 	{"Osc2-Tuning", 0, C11 + (D2*0), R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm",
230 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_NOTCH},
231 
232 	/* - 18 */
233 	{"LFO-Routing", 0, C13+10, R1, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
234 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_STEPPED|BRIGHTON_NOTCH},
235 	{"LFO-Multi", 0, C14 + D1/2 + 3, R1, S1, S2, 0, 1.01, 0, "bitmaps/knobs/knob4.xpm",
236 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_STEPPED},
237 	{"LFO-Shape", 0, C16-5, R1, S1, S2, 0, 3, 0, "bitmaps/knobs/knob4.xpm",
238 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_STEPPED},
239 
240 	/* - 21 */
241 	{"Mix-Synth", 0, C1-5, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm",
242 		"bitmaps/knobs/alpharotary.xpm", 0},
243 	{"Mix-Organ", 0, C2-5, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm",
244 		"bitmaps/knobs/alpharotary.xpm", 0},
245 	{"Mix-X", 0, C3-5, 0, 0, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm",
246 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
247 
248 	/* - 24 String section */
249 	{"X1", 0, C4, 0, 0, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm",
250 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
251 	{"X2", 0, C5, 0, 0, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm",
252 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
253 	{"X3", 0, C6, 0, 0, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm",
254 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
255 	{"X4", 0, C7, 0, 0, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm",
256 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
257 
258 	/* - 28 */
259 	{"Osc-Waveform", 0, C7+10, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
260 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_STEPPED},
261 	{"Osc-WaveAlt", 0, C8 + D1/2 + 3, R2, S1, S2, 0, 1.01, 0, "bitmaps/knobs/knob4.xpm",
262 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_STEPPED},
263 	{"Osc-WaveLegato", 0, C10-5, R2, S1, S2, 0, 1.01, 0, "bitmaps/knobs/knob4.xpm",
264 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_STEPPED},
265 
266 	/* - 31 */
267 	{"LFO-Rate", 0, C13, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm",
268 		"bitmaps/knobs/alpharotary.xpm", 0},
269 	{"LFO-Attack", 0, C14, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm",
270 		"bitmaps/knobs/alpharotary.xpm", 0},
271 	{"LFO-Delay", 0, C15, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm",
272 		"bitmaps/knobs/alpharotary.xpm", 0},
273 	{"LFO-Depth", 0, C16, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm",
274 		"bitmaps/knobs/alpharotary.xpm", 0},
275 
276 	/* Dummies 12 - 39 */
277 	{"", 0, 0, 0, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
278 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
279 	{"", 0, 0, 0, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
280 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
281 	{"", 0, 0, 0, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
282 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
283 	{"", 0, 0, 0, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
284 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
285 	{"", 0, 0, 0, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
286 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
287 	{"", 0, 0, 0, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
288 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
289 	{"", 0, 0, 0, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
290 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
291 	{"", 0, 0, 0, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
292 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
293 	{"", 0, 0, 0, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
294 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
295 	{"", 0, 0, 0, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
296 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
297 	{"", 0, 0, 0, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
298 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
299 	{"", 0, 0, 0, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
300 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
301 
302 	/* These are shadows for the opts parameters - 47 */
303 	{"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
304 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
305 	{"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
306 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
307 	{"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
308 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
309 	{"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
310 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
311 	{"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
312 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
313 	{"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
314 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
315 	{"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
316 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
317 	{"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
318 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
319 	{"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
320 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
321 	{"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
322 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
323 	/* 57 */
324 	{"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
325 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
326 	{"", 2, 0, R2, S1, S2, 0, 1.01, 0, "bitmaps/knobs/knob4.xpm",
327 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
328 	{"", 2, 0, R2, S1, S2, 0, 4, 0, "bitmaps/knobs/knob4.xpm",
329 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
330 	{"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
331 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
332 	{"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
333 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
334 	{"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
335 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
336 	{"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
337 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
338 	{"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
339 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
340 	{"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
341 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
342 
343 	/* These are shadows for the envelope parameters from the mod panel - 66 */
344 	{"Attack", 0, C3, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm",
345 		"bitmaps/knobs/alpharotary.xpm", 0},
346 	{"Decay", 0, C4, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm",
347 		"bitmaps/knobs/alpharotary.xpm", 0},
348 	{"Sustain", 0, C5, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm",
349 		"bitmaps/knobs/alpharotary.xpm", 0},
350 	{"Release", 0, C6, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knobblue.xpm",
351 		"bitmaps/knobs/alpharotary.xpm", 0},
352 
353 /*
354 	{"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
355 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
356 	{"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
357 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
358 	{"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
359 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
360 	{"", 0, 0, R2, S1, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
361 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
362 */
363 
364 	/* Memory - 40 */
365 	{"", 2, C17+(D3*1), R2a, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
366 		"bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON},
367 	{"", 2, C17+(D3*2), R2a, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
368 		"bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON},
369 	{"", 2, C17+(D3*3), R2a, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
370 		"bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON},
371 	{"", 2, C17+(D3*4), R2a, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
372 		"bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON},
373 
374 	{"", 2, C17+(D3*1), R2b, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
375 		"bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON},
376 	{"", 2, C17+(D3*2), R2b, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
377 		"bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON},
378 	{"", 2, C17+(D3*3), R2b, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
379 		"bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON},
380 	{"", 2, C17+(D3*4), R2b, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
381 		"bitmaps/buttons/presson.xpm", BRIGHTON_RADIOBUTTON},
382 	/* Load and Save */
383 	{"", 2, C17+(D3*1), R2c, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
384 		"bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON},
385 	{"", 2, C17+(D3*1), R2d, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoffo.xpm",
386 		"bitmaps/buttons/pressono.xpm", BRIGHTON_CHECKBUTTON},
387 	/* Bank Sel */
388 	{"", 2, C17+(D3*2), R2c, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
389 		"bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON},
390 	/* Mem search buttons Down then Up */
391 	{"", 2, C17+(D3*3), R2d, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
392 		"bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON},
393 	{"", 2, C17+(D3*3), R2c, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
394 		"bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON},
395 	/* Search Free */
396 	{"", 2, C17+(D3*2), R2d, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
397 		"bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON},
398 
399 /* Midi, perhaps eventually file import/export buttons */
400 	{"", 2, C17+(D3*4), R2d, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
401 		"bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON},
402 	{"", 2, C17+(D3*4), R2c, S2b, S2c, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
403 		"bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON},
404 
405 	{"", 3, C17 + 30, R2a - 120, 106, 60, 0, 1, 0, 0,
406 		"bitmaps/images/alphadisplay3.xpm", 0}
407 };
408 
409 /*
410  * Need more tuning, there is a global for both layers, then one each for the
411  * three components (not synth)
412  */
413 static brightonLocations stratusOpts[19] = {
414 	/* First one is index 47 */
415 	{"", 0, C1, 100, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm",// Master vol
416 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_NOTCH},
417 	{"", 0, C1, 380, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm", // organ pan
418 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_NOTCH},
419 	{"", 0, C2 -4, 380, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm", // o wave
420 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_NOTCH},
421 	{"", 0, C3 + 10, 380, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm", // o space
422 		"bitmaps/knobs/alpharotary.xpm", 0},
423 	{"", 0, C4 - 10, 490, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm", // o mod
424 		"bitmaps/knobs/alpharotary.xpm", 0},
425 
426 	{"", 0, 312, 30, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm", // SynHarm
427 		"bitmaps/knobs/alpharotary.xpm", 0},
428 
429 	/* 53 */
430 	{"", 2, C1 - 15, 500, 20, 110, 0, 1, 0, // clicky
431 		"bitmaps/buttons/touchoff.xpm",
432 		"bitmaps/buttons/touch.xpm", BRIGHTON_NOSHADOW},
433 
434 	{"", 0, C1 - 18, 650, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm", // O tune
435 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_NOTCH},
436 
437 	{"", 0, C8 - 8, 380, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm", // syn pan
438 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_NOTCH},
439 	{"", 0, C8 - 8, 670, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm", // syn tune
440 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_NOTCH},
441 	{"", 0, 312, 620, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm", // not used
442 		"bitmaps/knobs/alpharotary.xpm", 0},
443 	/* 58 */
444 	{"", 2, C9 - 3, 380, 20, 110, 0, 1, 0,
445 		"bitmaps/buttons/touchoff.xpm",
446 		"bitmaps/buttons/touch.xpm", BRIGHTON_NOSHADOW}, // Env touch
447 	{"", 2, C10, 380, 20, 110, 0, 4, 0,
448 		"bitmaps/buttons/touchoff.xpm",
449 		"bitmaps/buttons/touch.xpm", BRIGHTON_NOSHADOW}, // filter type
450 	{"", 0, C11 - 22, 480, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm",
451 		"bitmaps/knobs/alpharotary.xpm", 0},
452 
453 	{"", 0, C15, R1, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm",
454 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
455 	{"", 0, C16, R1, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm",
456 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
457 	{"", 0, C17, R1, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm",
458 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
459 	{"", 0, C18, R1, 100, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm",
460 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
461 	{"", 0, C19, R1, S1, 100, 0, 1, 0, "bitmaps/knobs/smp.xpm",
462 		"bitmaps/knobs/alpharotary.xpm", BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
463 };
464 
465 #define STRATUS_MODCOUNT 7
466 static brightonLocations stratusMods[STRATUS_MODCOUNT] = {
467 	{"", 1, 440, 180, 80, 700, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm",
468 		0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
469 	{"", 1, 580, 180, 80, 700, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm",
470 		0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
471 	{"", 1, 720, 180, 80, 700, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm",
472 		0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
473 	{"", 1, 860, 180, 80, 700, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm",
474 		0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
475 
476 	/* View Opts button */
477 	{"", 2, 420, 800, 150, 170, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
478 		"bitmaps/buttons/presson.xpm", 0},
479 
480 	/* Joystick - we need to keep the dummy since it dispatches X/Y events */
481 	{"", 5, 200, 160, 600, 500, 0, 1, 0, "bitmaps/images/sphere.xpm",
482 		0, BRIGHTON_WIDE},
483 	{"", 0, 0, 0, 10, 10, 0, 1, 0, "bitmaps/knobs/sliderblack.xpm",
484 		0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
485 };
486 
487 /*
488  * This is a set of globals for the main window rendering. Again taken from
489  * include/brighton.h
490  */
491 brightonApp stratusApp = {
492 	"stratus",
493 	0, /* no blueprint on wood background. */
494 	"bitmaps/textures/metal6.xpm",
495 	BRIGHTON_STRETCH, /*flags */
496 	stratusInit,
497 	stratusConfigure, /* 3 callbacks, unused? */
498 	stratusMidiCallback,
499 	destroySynth,
500 	{5, 100, 1, 2, 5, 520, 0, 0},
501 	840, 385, 0, 0,
502 	7, /* Panel count */
503 	{
504 		{
505 			"Stratus",
506 			"bitmaps/blueprints/stratus.xpm",
507 			"bitmaps/textures/metal6.xpm",
508 			BRIGHTON_STRETCH|BRIGHTON_REVERSE, /* flags */
509 			0,
510 			0,
511 			stratusCallback,
512 			22, 100, 956, 550,
513 			DEVICE_COUNT,
514 			stratusLocations
515 		},
516 		{
517 			"Keyboard",
518 			0,
519 			"bitmaps/newkeys/kbg.xpm", /* flags */
520 			0x020|BRIGHTON_STRETCH,
521 			0,
522 			0,
523 			keyCallback,
524 			140, 690, 845, 290,
525 			KEY_COUNT,
526 			keys
527 		},
528 		{
529 			"Mods",
530 			"bitmaps/blueprints/stratusmods.xpm",
531 			"bitmaps/blueprints/stratusmods.xpm",
532 			BRIGHTON_STRETCH,
533 			0,
534 			0,
535 			stratusModCallback,
536 			30, 710, 100, 250,
537 			STRATUS_MODCOUNT,
538 			stratusMods
539 		},
540 		{
541 			"Options",
542 			"bitmaps/blueprints/stratusopts.xpm",
543 			"bitmaps/images/pcb.xpm",
544 			BRIGHTON_WITHDRAWN,
545 			0,
546 			0,
547 			stratusModCallback,
548 			32, 110, 940, 530,
549 			19,
550 			stratusOpts
551 		},
552 		{
553 			"Logo",
554 			"bitmaps/blueprints/stratuslogo.xpm",
555 			0,
556 			BRIGHTON_STRETCH, /*flags */
557 			0,
558 			0,
559 			0,
560 			22, 0, 956, 100,
561 			0,
562 			0
563 		},
564 		{
565 			"Edge",
566 			0,
567 			"bitmaps/textures/wood.xpm",
568 			BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */
569 			0,
570 			0,
571 			0,
572 			0, 0, 22, 1000,
573 			0,
574 			0
575 		},
576 		{
577 			"Edge",
578 			0,
579 			"bitmaps/textures/wood.xpm",
580 			BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /*flags */
581 			0,
582 			0,
583 			0,
584 			978, 0, 22, 1000,
585 			0,
586 			0
587 		},
588 	}
589 };
590 
591 int
stratusMidiCallback(brightonWindow * win,int controller,int value,float n)592 stratusMidiCallback(brightonWindow *win, int controller, int value, float n)
593 {
594 	guiSynth *synth = findSynth(global.synths, win);
595 
596 	printf("midi callback: %x, %i\n", controller, value);
597 
598 	switch(controller)
599 	{
600 		case MIDI_PROGRAM:
601 			printf("midi program: %x, %i\n", controller, value);
602 			synth->location = value;
603 			loadMemory(synth, synth->resources->name, 0, synth->bank + synth->location,
604 				synth->mem.active, 0, 0);
605 //			stratusLoadMemory(synth, global.controlfd, synth->midichannel,
606 //				0, 0, 0);
607 			break;
608 		case MIDI_BANK_SELECT:
609 			printf("midi banksel: %x, %i\n", controller, value);
610 			synth->bank = value;
611 			break;
612 	}
613 	return(0);
614 }
615 
616 static void
stratusLoadMemory(guiSynth * synth,int fd,int chan,int c,int o,int v)617 stratusLoadMemory(guiSynth *synth, int fd, int chan, int c, int o, int v)
618 {
619 	int i;
620 	brightonEvent event;
621 
622 	/*
623 	 * This is now a shim to map the opts and mods, we have to send the events
624 	 * twice since these controls are in the basic set and the shadow set since
625 	 * the different emulations have the envelope parameters in differents
626 	 * panels.
627 	 */
628 	event.type = BRISTOL_FLOAT;
629 
630 	event.value = synth->mem.param[MODS_OFFSET];
631 	brightonParamChange(synth->win, 0, MODS_OFFSET + 0, &event);
632 	brightonParamChange(synth->win, 2, 0, &event);
633 
634 	event.value = synth->mem.param[MODS_OFFSET + 1];
635 	brightonParamChange(synth->win, 0, MODS_OFFSET + 1, &event);
636 	brightonParamChange(synth->win, 2, 1, &event);
637 
638 	event.value = synth->mem.param[MODS_OFFSET + 2];
639 	brightonParamChange(synth->win, 0, MODS_OFFSET + 2, &event);
640 	brightonParamChange(synth->win, 2, 2, &event);
641 
642 	event.value = synth->mem.param[MODS_OFFSET + 3];
643 	brightonParamChange(synth->win, 0, MODS_OFFSET + 3, &event);
644 	brightonParamChange(synth->win, 2, 3, &event);
645 
646 	for (i = 0; i < 19; i++)
647 	{
648 		event.type = BRISTOL_FLOAT;
649 		event.value = synth->mem.param[OPTS_OFFSET + i];
650 
651 		brightonParamChange(synth->win, 3, i, &event);
652 	}
653 }
654 
655 int
stratusModCallback(brightonWindow * win,int panel,int dev,float value)656 stratusModCallback(brightonWindow *win, int panel, int dev, float value)
657 {
658 	guiSynth *synth = findSynth(global.synths, win);
659 	int sendvalue, index;
660 
661 	if (synth == NULL)
662 		return(0);
663 
664 /*
665 printf("stratusModCallback(%i, %i, %f) %x\n", panel, dev, value,
666 (size_t) synth);
667 */
668 
669 	/*
670 	 * If this is controller 0-3 it is the Envelope and we need to bury the
671 	 * values in our memory and dispatch the request.
672 	 * Then we have the panel switch and two more parameters which are combined
673 	 * callbacks for the Joystick X and Y.
674 	 */
675 	if (panel == 2) {
676 		switch (dev) {
677 			case 0:
678 			case 1:
679 			case 2:
680 			case 3:
681 				/* Envelope parameters, we need to send these */
682 				synth->mem.param[MODS_OFFSET + dev] = value;
683 				if (!global.libtest)
684 					bristolMidiSendMsg(global.controlfd, synth->sid,
685 						2, dev, (int) (value * C_RANGE_MIN_1));
686 				break;
687 			case 4:
688 				/* Panelswitch */
689 				panelSwitch(synth, 0, 0, 0, 0, value);
690 				break;
691 			case 5:
692 				/*
693 				 * Joystick Y motion, below 0.5 = VCA, above = VCF. We just
694 				 * send controller-1 and let the engine decipher it.
695 				 */
696 				if (!global.libtest)
697 					bristolMidiSendControlMsg(global.controlfd,
698 						synth->midichannel,
699 						1,
700 						((int) (value * C_RANGE_MIN_1)) >> 7);
701 				break;
702 			case 6:
703 				/* Joystick X motion - pitchbend */
704 				if (!global.libtest)
705 					bristolMidiSendMsg(global.controlfd, synth->midichannel,
706 						BRISTOL_EVENT_PITCH, 0, (int) (value * C_RANGE_MIN_1));
707 				break;
708 		}
709 		return(0);
710 	}
711 
712 	if (stratusApp.resources[panel].devlocn[dev].to == 1.0)
713 		sendvalue = value * C_RANGE_MIN_1;
714 	else
715 		sendvalue = value;
716 
717 	index = OPTS_OFFSET + dev;
718 
719 	if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0))
720 		return(0);
721 
722 	synth->mem.param[index] = value;
723 
724 	if ((!global.libtest) || (index >= ACTIVE_DEVS)) {
725 		if (synth->dispatch[index].other1 < 0) {
726 			synth->dispatch[index].routine(synth,
727 				global.controlfd,
728 				synth->sid,
729 				synth->dispatch[index].controller,
730 				synth->dispatch[index].operator,
731 				sendvalue);
732 			synth->dispatch[index].routine(synth,
733 				global.controlfd,
734 				synth->sid2,
735 				synth->dispatch[index].controller,
736 				synth->dispatch[index].operator,
737 				sendvalue);
738 		} else
739 			synth->dispatch[index].routine(synth,
740 				global.controlfd,
741 				synth->dispatch[index].other1, /* The SID is buried here */
742 				synth->dispatch[index].controller,
743 				synth->dispatch[index].operator,
744 				sendvalue);
745 	} else
746 		printf("dispatch2[%p,%i](%i, %i, %i, %i, %i)\n", synth, index,
747 			global.controlfd,
748 			synth->dispatch[index].other1, /* The SID is buried here */
749 			synth->dispatch[index].controller,
750 			synth->dispatch[index].operator,
751 			sendvalue);
752 
753 	return(0);
754 }
755 
756 static void
stratusMono(guiSynth * synth,int fd,int chan,int c,int o,int v)757 stratusMono(guiSynth *synth, int fd, int chan, int c, int o, int v)
758 {
759 	bristolMidiSendMsg(global.controlfd, synth->sid, c, o, 1 - v);
760 }
761 
762 static void
stratusMultiLFO(guiSynth * synth,int fd,int chan,int c,int o,int v)763 stratusMultiLFO(guiSynth *synth, int fd, int chan, int c, int o, int v)
764 {
765 	/*
766 	 * We don't need a shim for the MULTI option but I want one to add
767 	 * changes for LFO sync
768 	 */
769 	bristolMidiSendMsg(global.controlfd, synth->sid, 126, 16, v);
770 	bristolMidiSendMsg(global.controlfd, synth->sid, 5, 1, v);
771 }
772 
773 /* Mono Alternate osc A/B */
774 static void
stratusAlternate(guiSynth * synth,int fd,int chan,int c,int o,int v)775 stratusAlternate(guiSynth *synth, int fd, int chan, int c, int o, int v)
776 {
777 	bristolMidiSendMsg(global.controlfd, synth->sid, c, o, 1 - v);
778 }
779 
780 static void
trilogyWaveform(guiSynth * synth,int fd,int chan,int c,int o,int v)781 trilogyWaveform(guiSynth *synth, int fd, int chan, int c, int o, int v)
782 {
783 	/*
784 printf("trilogy wave %i/%i %i\n", c, o, v);
785 	 * 16' to 8'
786 	 */
787 	if (o == 0) {
788 		bristolMidiSendMsg(global.controlfd, synth->sid2, 2, 0,
789 			C_RANGE_MIN_1 - v);
790 		bristolMidiSendMsg(global.controlfd, synth->sid2, 2, 1, v);
791 	} else
792 		bristolMidiSendMsg(global.controlfd, synth->sid2, 2, 12, v);
793 }
794 
795 /*
796  */
797 static void
stratusWaveform(guiSynth * synth,int fd,int chan,int c,int o,int v)798 stratusWaveform(guiSynth *synth, int fd, int chan, int c, int o, int v)
799 {
800 	/*
801 	 * Mix Ramp to Square on both oscillators
802 	if (synth->mem.param[13] == 0)
803 	 */
804 	{
805 		bristolMidiSendMsg(global.controlfd, synth->sid, 0, 5, C_RANGE_MIN_1-v);
806 		bristolMidiSendMsg(global.controlfd, synth->sid, 0, 6, v);
807 	}
808 	bristolMidiSendMsg(global.controlfd, synth->sid, 1, 5, C_RANGE_MIN_1 - v);
809 	bristolMidiSendMsg(global.controlfd, synth->sid, 1, 6, v);
810 }
811 
812 static int
stratusMidiSendMsg(void * synth,int fd,int chan,int c,int o,int v)813 stratusMidiSendMsg(void *synth, int fd, int chan, int c, int o, int v)
814 {
815 	bristolMidiSendMsg(fd, chan, c, o, v);
816 	return(0);
817 }
818 
819 static void
stratusMemory(guiSynth * synth,int fd,int chan,int c,int o,int v)820 stratusMemory(guiSynth *synth, int fd, int chan, int c, int o, int v)
821 {
822 	brightonEvent event;
823 	int bank = synth->bank;
824 	int location = synth->location;
825 
826 	event.value = 1.0;
827 	event.type = BRISTOL_FLOAT;
828 
829 	if (synth->flags & MEM_LOADING)
830 		return;
831 	if ((synth->flags & OPERATIONAL) == 0)
832 		return;
833 
834 	if (synth->dispatch[MEM_START].other2)
835 	{
836 		synth->dispatch[MEM_START].other2 = 0;
837 		return;
838 	}
839 
840 	switch (c) {
841 		default:
842 		case 0:
843 			/*
844 			 * We want to make these into memory buttons. To do so we need to
845 			 * know what the last active button was, and deactivate its
846 			 * display, then send any message which represents the most
847 			 * recently configured value. Since this is a memory button we do
848 			 * not have much issue with the message, but we are concerned with
849 			 * the display.
850 			 */
851 			if (synth->dispatch[MEM_START].other1 != -1)
852 			{
853 				synth->dispatch[MEM_START].other2 = 1;
854 
855 				if (synth->dispatch[MEM_START].other1 != o)
856 					event.value = 0;
857 				else
858 					event.value = 1;
859 
860 				brightonParamChange(synth->win, synth->panel,
861 					synth->dispatch[MEM_START].other1 + MEM_START - 1, &event);
862 			}
863 			synth->dispatch[MEM_START].other1 = o;
864 
865 			if (synth->flags & BANK_SELECT) {
866 				if ((synth->bank * 10 + o) >= 100)
867 				{
868 					synth->location = o;
869 					synth->flags &= ~BANK_SELECT;
870 
871 					if (loadMemory(synth, synth->resources->name, 0,
872 						synth->bank * 10 + synth->location, synth->mem.active,
873 							0, BRISTOL_STAT) < 0)
874 						displayText(synth, "FREE",
875 							synth->bank * 10 + synth->location, DISPLAY_DEV);
876 					else
877 						displayText(synth, "PROG",
878 							synth->bank * 10 + synth->location, DISPLAY_DEV);
879 				} else {
880 					synth->bank = synth->bank * 10 + o;
881 					displayText(synth, "BANK",
882 						synth->bank * 10 + synth->location, DISPLAY_DEV);
883 				}
884 			} else {
885 				if (synth->bank < 1)
886 					synth->bank = 1;
887 				synth->location = o;
888 				if (loadMemory(synth, synth->resources->name, 0,
889 					synth->bank * 10 + synth->location, synth->mem.active,
890 						0, BRISTOL_STAT) < 0)
891 					displayText(synth, "FREE",
892 						synth->bank * 10 + synth->location, DISPLAY_DEV);
893 				else
894 					displayText(synth, "PROG",
895 						synth->bank * 10 + synth->location, DISPLAY_DEV);
896 			}
897 			break;
898 		case 1:
899 			if (synth->bank < 1)
900 				synth->bank = 1;
901 			if (synth->location == 0)
902 				synth->location = 1;
903 			if (loadMemory(synth, synth->resources->name, 0, synth->bank * 10 + synth->location,
904 				synth->mem.active, 0, BRISTOL_FORCE) < 0)
905 				displayText(synth, "FREE",
906 					synth->bank * 10 + synth->location, DISPLAY_DEV);
907 			else
908 				displayText(synth, "PROG",
909 					synth->bank * 10 + synth->location, DISPLAY_DEV);
910 
911 			if (brightonDoubleClick(dc))
912 				stratusLoadMemory(synth, global.controlfd, synth->midichannel,
913 					0, 0, 0);
914 			synth->flags &= ~BANK_SELECT;
915 			break;
916 		case 2:
917 			if (synth->bank < 1)
918 				synth->bank = 1;
919 			if (synth->location == 0)
920 				synth->location = 1;
921 			if (brightonDoubleClick(dc)) {
922 				saveMemory(synth, synth->resources->name, 0,
923 					synth->bank * 10 + synth->location, 0);
924 				displayText(synth, "PROG",
925 					synth->bank * 10 + synth->location, DISPLAY_DEV);
926 			}
927 			synth->flags &= ~BANK_SELECT;
928 			break;
929 		case 3:
930 			if (synth->flags & BANK_SELECT) {
931 				synth->flags &= ~BANK_SELECT;
932 				if (loadMemory(synth, synth->resources->name, 0,
933 					synth->bank * 10 + synth->location, synth->mem.active,
934 						0, BRISTOL_STAT) < 0)
935 					displayText(synth, "FREE",
936 						synth->bank * 10 + synth->location, DISPLAY_DEV);
937 				else
938 					displayText(synth, "PROG",
939 						synth->bank * 10 + synth->location, DISPLAY_DEV);
940 			} else {
941 				synth->bank = 0;
942 				displayText(synth, "BANK", synth->bank, DISPLAY_DEV);
943 				synth->flags |= BANK_SELECT;
944 			}
945 			break;
946 		case 4:
947 			if (--location < 1) {
948 				location = 8;
949 				if (--bank < 1)
950 					bank = 88;
951 			}
952 			while (loadMemory(synth, synth->resources->name, 0, bank * 10 + location,
953 				synth->mem.active, 0, BRISTOL_STAT) < 0)
954 			{
955 				if (--location < 1) {
956 					location = 8;
957 					if (--bank < 1)
958 						bank = 88;
959 				}
960 				if ((bank * 10 + location)
961 					== (synth->bank * 10 + synth->location))
962 					break;
963 			}
964 			displayText(synth, "PROG", bank * 10 + location, DISPLAY_DEV);
965 			synth->bank = bank;
966 			synth->location = location;
967 			loadMemory(synth, synth->resources->name, 0, bank * 10 + location,
968 				synth->mem.active, 0, BRISTOL_FORCE);
969 //			stratusLoadMemory(synth, global.controlfd, synth->midichannel,
970 //				0, 0, 0);
971 			brightonParamChange(synth->win, 0,
972 				MEM_START - 1 + synth->location, &event);
973 			break;
974 		case 5:
975 			if (++location > 8) {
976 				location = 1;
977 				if (++bank > 88)
978 					bank = 1;
979 			}
980 			while (loadMemory(synth, synth->resources->name, 0, bank * 10 + location,
981 				synth->mem.active, 0, BRISTOL_STAT) < 0)
982 			{
983 				if (++location > 8) {
984 					location = 1;
985 					if (++bank > 88)
986 						bank = 1;
987 				}
988 				if ((bank * 10 + location)
989 					== (synth->bank * 10 + synth->location))
990 					break;
991 			}
992 			displayText(synth, "PROG", bank * 10 + location, DISPLAY_DEV);
993 			synth->bank = bank;
994 			synth->location = location;
995 			loadMemory(synth, synth->resources->name, 0, bank * 10 + location,
996 				synth->mem.active, 0, BRISTOL_FORCE);
997 //			stratusLoadMemory(synth, global.controlfd, synth->midichannel,
998 //				0, 0, 0);
999 			brightonParamChange(synth->win, 0,
1000 				MEM_START - 1 + synth->location, &event);
1001 			break;
1002 		case 6:
1003 			/* Find the next free mem */
1004 			if (++location > 8) {
1005 				location = 1;
1006 				if (++bank > 88)
1007 					bank = 1;
1008 			}
1009 
1010 			while (loadMemory(synth, synth->resources->name, 0, bank * 10 + location,
1011 				synth->mem.active, 0, BRISTOL_STAT) >= 0)
1012 			{
1013 				if (++location > 8) {
1014 					location = 1;
1015 					if (++bank > 88)
1016 						bank = 1;
1017 				}
1018 				if ((bank * 10 + location)
1019 					== (synth->bank * 10 + synth->location))
1020 					break;
1021 			}
1022 
1023 			if (loadMemory(synth, synth->resources->name, 0, bank * 10 + location,
1024 				synth->mem.active, 0, BRISTOL_STAT) >= 0)
1025 				displayText(synth, "PROG",
1026 					bank * 10 + location, DISPLAY_DEV);
1027 			else
1028 				displayText(synth, "FREE",
1029 					bank * 10 + location, DISPLAY_DEV);
1030 
1031 			synth->bank = bank;
1032 			synth->location = location;
1033 			brightonParamChange(synth->win, 0,
1034 				MEM_START - 1 + synth->location, &event);
1035 			break;
1036 	}
1037 /*	printf("	stratusMemory(B: %i L %i: %i)\n", */
1038 /*		synth->bank, synth->location, o); */
1039 }
1040 
1041 static void
stratusFilter(guiSynth * synth,int fd,int chan,int c,int o,int v)1042 stratusFilter(guiSynth *synth, int fd, int chan, int c, int o, int v)
1043 {
1044 	/*
1045 	 * We need a shim since changing the filter type means we have to push
1046 	 * the parameters again.
1047 	 */
1048 	bristolMidiSendMsg(global.controlfd, synth->sid, 3, 4, v);
1049 	bristolMidiSendMsg(global.controlfd, synth->sid, 3, 0,
1050 		(int) (synth->mem.param[5] * C_RANGE_MIN_1));
1051 	bristolMidiSendMsg(global.controlfd, synth->sid, 3, 1,
1052 		(int) (synth->mem.param[6] * C_RANGE_MIN_1));
1053 }
1054 
1055 static void
stratusEnvelope(guiSynth * synth,int fd,int chan,int c,int o,int v)1056 stratusEnvelope(guiSynth *synth, int fd, int chan, int c, int o, int v)
1057 {
1058 	/*
1059 	 * Send touch to envelope and reverse to emulator to decide who controls
1060 	 * response.
1061 	 */
1062 	bristolMidiSendMsg(global.controlfd, synth->sid, 2, 5, v);
1063 	bristolMidiSendMsg(global.controlfd, synth->sid, 126, 27, v);
1064 }
1065 
1066 static void
trilogyStringHarmonics(guiSynth * synth,int fd,int chan,int c,int o,int v)1067 trilogyStringHarmonics(guiSynth *synth, int fd, int chan, int c, int o, int v)
1068 {
1069 	bristolMidiSendMsg(global.controlfd, synth->sid2, 2, 0, C_RANGE_MIN_1 - v);
1070 	bristolMidiSendMsg(global.controlfd, synth->sid2, 2, 2, v>>1);
1071 	bristolMidiSendMsg(global.controlfd, synth->sid2, 2, 3, v);
1072 }
1073 
1074 static void
stratusMod(guiSynth * synth,int fd,int chan,int c,int o,int v)1075 stratusMod(guiSynth *synth, int fd, int chan, int c, int o, int v)
1076 {
1077 	bristolMidiSendMsg(global.controlfd, synth->sid2, c, 5, v);
1078 	bristolMidiSendMsg(global.controlfd, synth->sid2, c, 6, v);
1079 }
1080 
1081 static void
stratusOscHarmonics(guiSynth * synth,int fd,int chan,int c,int o,int v)1082 stratusOscHarmonics(guiSynth *synth, int fd, int chan, int c, int o, int v)
1083 {
1084 	bristolMidiSendMsg(global.controlfd, synth->sid, c, 0, C_RANGE_MIN_1 - v);
1085 	bristolMidiSendMsg(global.controlfd, synth->sid, c, 2, v>>1);
1086 	bristolMidiSendMsg(global.controlfd, synth->sid, c, 3, v);
1087 }
1088 
1089 static void
stratusOrganEnv(guiSynth * synth,int fd,int chan,int c,int o,int v)1090 stratusOrganEnv(guiSynth *synth, int fd, int chan, int c, int o, int v)
1091 {
1092 	/* Clicky or not */
1093 	if (v == 0) {
1094 		bristolMidiSendMsg(global.controlfd, synth->sid2, 1, 0, 40);
1095 		bristolMidiSendMsg(global.controlfd, synth->sid2, 1, 1, 4096);
1096 		bristolMidiSendMsg(global.controlfd, synth->sid2, 1, 2, 16383);
1097 		bristolMidiSendMsg(global.controlfd, synth->sid2, 1, 3, 10);
1098 	} else {
1099 		bristolMidiSendMsg(global.controlfd, synth->sid2, 1, 0, 20);
1100 		bristolMidiSendMsg(global.controlfd, synth->sid2, 1, 1, 2000);
1101 		bristolMidiSendMsg(global.controlfd, synth->sid2, 1, 2, 2000);
1102 		bristolMidiSendMsg(global.controlfd, synth->sid2, 1, 3, 10);
1103 	}
1104 }
1105 
1106 static int
stratusMidi(guiSynth * synth,int fd,int chan,int c,int o,int v)1107 stratusMidi(guiSynth *synth, int fd, int chan, int c, int o, int v)
1108 {
1109 	int newchan;
1110 
1111 	if ((synth->flags & OPERATIONAL) == 0)
1112 		return(0);
1113 
1114 	if (c == 1) {
1115 		if ((newchan = synth->midichannel - 1) < 0)
1116 		{
1117 			synth->midichannel = 0;
1118 			displayText(synth, "CHAN", synth->midichannel + 1, DISPLAY_DEV);
1119 			return(0);
1120 		}
1121 	} else {
1122 		if ((newchan = synth->midichannel + 1) >= 16)
1123 		{
1124 			synth->midichannel = 15;
1125 			displayText(synth, "CHAN", synth->midichannel + 1, DISPLAY_DEV);
1126 			return(0);
1127 		}
1128 	}
1129 
1130 	if (global.libtest == 0)
1131 	{
1132 		bristolMidiSendMsg(global.controlfd, synth->sid,
1133 			127, 0, BRISTOL_MIDICHANNEL|newchan);
1134 	}
1135 
1136 	synth->midichannel = newchan;
1137 
1138 /*	printf("P: going to display: %x, %x\n", synth, synth->win); */
1139 	displayText(synth, "CHAN", synth->midichannel + 1, DISPLAY_DEV);
1140 
1141 	return(0);
1142 }
1143 
1144 /*
1145  * For the sake of ease of use, links have been placed here to be called
1146  * by any of the devices created. They would be better in some other file,
1147  * perhaps with this as a dispatch.
1148  *
1149  * Param refers to the device index in the locations table given below.
1150  */
1151 int
stratusCallback(brightonWindow * win,int panel,int index,float value)1152 stratusCallback(brightonWindow *win, int panel, int index, float value)
1153 {
1154 	guiSynth *synth = findSynth(global.synths, win);
1155 	int sendvalue;
1156 
1157 	if (synth == 0)
1158 		return(0);
1159 
1160 	if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0))
1161 		return(0);
1162 
1163 	if (stratusApp.resources[0].devlocn[index].to == 1.0)
1164 		sendvalue = value * C_RANGE_MIN_1;
1165 	else
1166 		sendvalue = value;
1167 
1168 	/* We need to keep a hole for the shadowed opts */
1169 	if ((index < ACTIVE_DEVS - 4) && (index >= STRATUS_DEVS))
1170 		return(0);
1171 
1172 	synth->mem.param[index] = value;
1173 
1174 	if ((!global.libtest) || (index >= ACTIVE_DEVS))
1175 	{
1176 		if (synth->dispatch[index].other1 < 0) {
1177 			synth->dispatch[index].routine(synth,
1178 				global.controlfd,
1179 				synth->sid,
1180 				synth->dispatch[index].controller,
1181 				synth->dispatch[index].operator,
1182 				sendvalue);
1183 			synth->dispatch[index].routine(synth,
1184 				global.controlfd,
1185 				synth->sid2,
1186 				synth->dispatch[index].controller,
1187 				synth->dispatch[index].operator,
1188 				sendvalue);
1189 		} else
1190 			synth->dispatch[index].routine(synth,
1191 				global.controlfd,
1192 				synth->dispatch[index].other1, /* The SID is buried here */
1193 				synth->dispatch[index].controller,
1194 				synth->dispatch[index].operator,
1195 				sendvalue);
1196 	} else
1197 		printf("dispatch[%p,%i](%i, %i, %i, %i, %i)\n", synth, index,
1198 			global.controlfd,
1199 			synth->dispatch[index].other1, /* The SID is buried here */
1200 			synth->dispatch[index].controller,
1201 			synth->dispatch[index].operator,
1202 			sendvalue);
1203 
1204 	return(0);
1205 }
1206 
1207 static int shade_id;
1208 
1209 void
panelSwitch(guiSynth * synth,int fd,int chan,int cont,int op,int value)1210 panelSwitch(guiSynth *synth, int fd, int chan, int cont, int op, int value)
1211 {
1212 	brightonEvent event;
1213 
1214 	/*
1215 	 * If the sendvalue is zero, then withdraw the opts window, draw the
1216 	 * slider window, and vice versa.
1217 	 */
1218 	if (value == 0)
1219 	{
1220 		event.type = BRIGHTON_EXPOSE;
1221 		event.intvalue = 0;
1222 		brightonParamChange(synth->win, 3, -1, &event);
1223 		event.intvalue = 1;
1224 		brightonParamChange(synth->win, 0, -1, &event);
1225 
1226 		if (strstr(synth->resources->name, "stratus") != 0)
1227 			shade_id = brightonPut(synth->win,
1228 				"bitmaps/blueprints/stratusshade.xpm",
1229 				0, 0, synth->win->width, synth->win->height);
1230 		else if (strstr(synth->resources->name, "trilogy") != 0)
1231 			shade_id = brightonPut(synth->win,
1232 				"bitmaps/blueprints/trilogyshade.xpm",
1233 				0, 0, synth->win->width, synth->win->height);
1234 	} else {
1235 		event.type = BRIGHTON_EXPOSE;
1236 		event.intvalue = 0;
1237 		brightonParamChange(synth->win, 0, -1, &event);
1238 		event.intvalue = 1;
1239 		brightonParamChange(synth->win, 3, -1, &event);
1240 
1241 		brightonRemove(synth->win, shade_id);
1242 	}
1243 }
1244 
1245 /*
1246  * We are going to start two synths here, the organ and string sections will
1247  * be one emulator with as many voices as the engine can handle since they are
1248  * going to be lightweight and were divider circuits anyway. The synth section
1249  * is then separate with a limited number of voices.
1250  */
1251 int
stratusInit(brightonWindow * win)1252 stratusInit(brightonWindow *win)
1253 {
1254 	guiSynth *synth = findSynth(global.synths, win);
1255 	dispatcher *dispatch;
1256 	int i;
1257 
1258 	if (synth == 0)
1259 	{
1260 		synth = findSynth(global.synths, 0);
1261 		if (synth == 0)
1262 		{
1263 			printf("cannot init\n");
1264 			return(0);
1265 		}
1266 	}
1267 
1268 	if ((initmem = synth->location) == 0)
1269 		initmem = 11;
1270 
1271 	synth->win = win;
1272 
1273 	printf("Initialise the strilogy link to bristol: %p\n", synth->win);
1274 
1275 	synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float));
1276 	synth->mem.count = DEVICE_COUNT;
1277 	synth->mem.active = ACTIVE_DEVS;
1278 
1279 	if (synth->voices == BRISTOL_VOICECOUNT)
1280 		synth->voices = 6;
1281 
1282 	synth->dispatch = (dispatcher *)
1283 		brightonmalloc(DEVICE_COUNT * sizeof(dispatcher));
1284 	dispatch = synth->dispatch;
1285 
1286 	synth->synthtype = BRISTOL_TRILOGY;
1287 	synth->second = brightonmalloc(sizeof(guiSynth));
1288 	bcopy(synth, ((guiSynth *) synth->second), sizeof(guiSynth));
1289 	((guiSynth *) synth->second)->mem.param =
1290 		(float *) brightonmalloc(DEVICE_COUNT * sizeof(float));
1291 	((guiSynth *) synth->second)->mem.count = DEVICE_COUNT;
1292 	((guiSynth *) synth->second)->mem.active = ACTIVE_DEVS;
1293 	((guiSynth *) synth->second)->dispatch = synth->dispatch;
1294 
1295 	/*
1296 	 * We really want to have three connection mechanisms. These should be
1297 	 *	1. Unix named sockets.
1298 	 *	2. UDP sockets.
1299 	 *	3. MIDI pipe.
1300 	 */
1301 	if (!global.libtest)
1302 	{
1303 		int voices = synth->voices;
1304 
1305 		printf("Initialise the strilogy synth circuits\n");
1306 		bcopy(&global, &manual, sizeof(guimain));
1307 		if ((synth->sid = initConnection(&global, synth)) < 0)
1308 			return(-1);
1309 
1310 		/*
1311 		 * We have to tweak the voicecount as we use the same synth definition
1312 		 * to request the second layer
1313 		 */
1314 		manual.flags |= BRISTOL_CONN_FORCE|BRIGHTON_NOENGINE;
1315 		manual.host = global.host;
1316 		manual.port = global.port;
1317 
1318 		printf("Initialise the strilogy organ divider circuits\n");
1319 		synth->synthtype = BRISTOL_TRILOGY_ODC;
1320 		synth->voices = BRISTOL_VOICECOUNT;
1321 		if ((synth->sid2 = initConnection(&manual, synth)) < 0)
1322 			return(-1);
1323 
1324 		global.manualfd = manual.controlfd;
1325 		global.manual = &manual;
1326 		manual.manual = &global;
1327 		/*
1328 		 * Having played with the synth type to get the correct emulator we now
1329 		 * have to put it back to the actual model so that the GUI will load
1330 		 * the correct profiles.
1331 		 */
1332 		if (strcmp("stratus", synth->resources->name) == 0)
1333 			synth->synthtype = BRISTOL_STRATUS;
1334 		else
1335 			synth->synthtype = BRISTOL_TRILOGY;
1336 		synth->voices = voices;
1337 	}
1338 
1339 	for (i = 0; i < DEVICE_COUNT; i++) {
1340 		synth->dispatch[i].routine = stratusMidiSendMsg;
1341 
1342 		dispatch[i].controller = 126;
1343 		dispatch[i].operator = 101;
1344 		dispatch[i].other1 = synth->sid;
1345 	}
1346 
1347 	dispatch[0].controller = 0;
1348 	dispatch[0].operator = 3;
1349 	dispatch[0].other1 = synth->sid2;
1350 	dispatch[1].controller = 0;
1351 	dispatch[1].operator = 2;
1352 	dispatch[1].other1 = synth->sid2;
1353 	dispatch[2].controller = 0;
1354 	dispatch[2].operator = 1;
1355 	dispatch[2].other1 = synth->sid2;
1356 	dispatch[3].controller = 0;
1357 	dispatch[3].operator = 0;
1358 	dispatch[3].other1 = synth->sid2;
1359 
1360 	/* Filter env, c, e */
1361 	dispatch[4].controller = 126;
1362 	dispatch[4].operator = 10;
1363 	dispatch[5].controller = 3;
1364 	dispatch[5].operator = 0;
1365 	dispatch[6].controller = 3;
1366 	dispatch[6].operator = 1;
1367 	dispatch[7].controller = 126; /* Pedal/Manual filter */
1368 	dispatch[7].operator = 26;
1369 
1370 	dispatch[8].controller = 126;
1371 	dispatch[8].operator = 22;
1372 	dispatch[9].controller = 126;
1373 	dispatch[9].operator = 23;
1374 	dispatch[10].controller = 126;
1375 	dispatch[10].operator = 24;
1376 	dispatch[11].controller = 126;
1377 	dispatch[11].operator = 25;
1378 
1379 	/* VCO 1 - tune, sync-2, octave */
1380 	dispatch[12].controller = 0;
1381 	dispatch[12].operator = 9;
1382 	dispatch[13].controller = 126;
1383 	dispatch[13].operator = 11; /* Sync */
1384 	dispatch[14].controller = 0;
1385 	dispatch[14].operator = 8;
1386 	/* VCO 2 - tune, sync-2, octave */
1387 	dispatch[15].controller = 126; /* This mixes LFO into osc-2 */
1388 	dispatch[15].operator = 12;
1389 	dispatch[16].controller = 1;
1390 	dispatch[16].operator = 8;
1391 	dispatch[17].controller = 1;
1392 	dispatch[17].operator = 9;
1393 
1394 	/* LFO Routing, multi, shape */
1395 	dispatch[18].controller = 126;
1396 	dispatch[18].operator = 15;
1397 	dispatch[19].controller = 126;
1398 	dispatch[19].operator = 16;
1399 	dispatch[19].routine = (synthRoutine) stratusMultiLFO;
1400 	dispatch[20].controller = 126;
1401 	dispatch[20].operator = 17;
1402 
1403 	/* Gains */
1404 	dispatch[21].controller = 126;
1405 	dispatch[21].operator = 9;
1406 	dispatch[22].controller = 126;
1407 	dispatch[22].operator = 5;
1408 	dispatch[22].other1 = synth->sid2;
1409 	dispatch[23].controller = 126;
1410 	dispatch[23].operator = 8;
1411 	dispatch[23].other1 = synth->sid2;
1412 
1413 	/* Trilogy string section */
1414 	dispatch[24].controller = 2;
1415 	dispatch[24].operator = 0;
1416 	dispatch[24].other1 = synth->sid2;
1417 	dispatch[24].routine = (synthRoutine) trilogyWaveform;
1418 	dispatch[25].controller = 2;
1419 	dispatch[25].operator = 1;
1420 	dispatch[25].other1 = synth->sid2;
1421 	dispatch[25].routine = (synthRoutine) trilogyWaveform;
1422 	/* Env */
1423 	dispatch[26].controller = 3;
1424 	dispatch[26].operator = 0;
1425 	dispatch[26].other1 = synth->sid2;
1426 	dispatch[27].controller = 3;
1427 	dispatch[27].operator = 3;
1428 	dispatch[27].other1 = synth->sid2;
1429 
1430 	/* Waveform */
1431 	dispatch[28].routine = (synthRoutine) stratusWaveform;
1432 	dispatch[29].controller = 126;
1433 	dispatch[29].operator = 13;
1434 	dispatch[29].routine = (synthRoutine) stratusAlternate;
1435 	dispatch[30].controller = 126;
1436 	dispatch[30].operator = 14;
1437 	dispatch[30].routine = (synthRoutine) stratusMono;
1438 
1439 	/*
1440 	 * LFO May need to be shimmed - if the LFO were not the same index in the
1441 	 * two different synths then this would not have worked.
1442 	 */
1443 	dispatch[31].controller = 5;
1444 	dispatch[31].operator = 0;
1445 	dispatch[31].other1 = -1;
1446 	dispatch[32].controller = 126;
1447 	dispatch[32].operator = 18;
1448 	dispatch[32].other1 = -1;
1449 	dispatch[33].controller = 126;
1450 	dispatch[33].operator = 19;
1451 	dispatch[33].other1 = -1;
1452 	dispatch[34].controller = 126;
1453 	dispatch[34].operator = 20;
1454 	dispatch[34].other1 = -1;
1455 
1456 	/* Organ options */
1457 	dispatch[47].controller = 126;
1458 	dispatch[47].operator = 1;
1459 	dispatch[47].other1 = -1;
1460 	dispatch[48].controller = 126; /* Organ panning */
1461 	dispatch[48].operator = 3;
1462 	dispatch[48].other1 = synth->sid2;
1463 	dispatch[49].controller = 0; /* Waveform */
1464 	dispatch[49].operator = 4;
1465 	dispatch[49].other1 = synth->sid2;
1466 	dispatch[50].controller = 126; /* Space */
1467 	dispatch[50].operator = 4;
1468 	dispatch[50].other1 = synth->sid2;
1469 	dispatch[51].controller = 0; /* Modulation */
1470 	dispatch[51].operator = 6;
1471 	dispatch[51].other1 = synth->sid2;
1472 	dispatch[51].routine = (synthRoutine) stratusMod;
1473 	/* Synth harmonics */
1474 	dispatch[52].controller = 0;
1475 	dispatch[52].routine = (synthRoutine) stratusOscHarmonics;
1476 	/* Organ env */
1477 	dispatch[53].routine = (synthRoutine) stratusOrganEnv;
1478 	dispatch[54].controller = 126; /* ODC Tuning */
1479 	dispatch[54].operator = 2;
1480 	dispatch[54].other1 = synth->sid2;
1481 	dispatch[55].controller = 126; /* Synth Pan */
1482 	dispatch[55].operator = 21;
1483 	dispatch[56].controller = 126; /* Synth Tuning? */
1484 	dispatch[56].operator = 2;
1485 	dispatch[57].controller = 1;
1486 	dispatch[57].routine = (synthRoutine) stratusOscHarmonics;
1487 	dispatch[58].controller = 2; /* Env touch */
1488 	dispatch[58].operator = 5;
1489 	dispatch[58].routine = (synthRoutine) stratusEnvelope;
1490 	dispatch[59].controller = 3; /* Filter Type */
1491 	dispatch[59].operator = 4;
1492 	dispatch[59].routine = (synthRoutine) stratusFilter;
1493 	dispatch[60].controller = 3; /* Filter Tracking */
1494 	dispatch[60].operator = 3;
1495 	/* String options */
1496 	dispatch[61].controller = 126; /* String panning */
1497 	dispatch[61].operator = 6;
1498 	dispatch[61].other1 = synth->sid2;
1499 	dispatch[62].routine = (synthRoutine) trilogyStringHarmonics;
1500 	dispatch[63].controller = 126; /* String spacialisation */
1501 	dispatch[63].operator = 7;
1502 	dispatch[63].other1 = synth->sid2;
1503 	dispatch[64].controller = 2; /* String mod */
1504 	dispatch[64].operator = 6;
1505 	dispatch[64].other1 = synth->sid2;
1506 	dispatch[64].routine = (synthRoutine) stratusMod;
1507 	dispatch[65].controller = 2; /* String Waveform */
1508 	dispatch[65].operator = 4;
1509 	dispatch[65].other1 = synth->sid2;
1510 
1511 	/* Synth env */
1512 	dispatch[66].controller = 2;
1513 	dispatch[66].operator = 0;
1514 	dispatch[67].controller = 2;
1515 	dispatch[67].operator = 1;
1516 	dispatch[68].controller = 2;
1517 	dispatch[68].operator = 2;
1518 	dispatch[69].controller = 2;
1519 	dispatch[69].operator = 3;
1520 
1521 	/* Memory and MIDI */
1522 	dispatch[MEM_START + 0].operator = 1;
1523 	dispatch[MEM_START + 1].operator = 2;
1524 	dispatch[MEM_START + 2].operator = 3;
1525 	dispatch[MEM_START + 3].operator = 4;
1526 	dispatch[MEM_START + 4].operator = 5;
1527 	dispatch[MEM_START + 5].operator = 6;
1528 	dispatch[MEM_START + 6].operator = 7;
1529 	dispatch[MEM_START + 7].operator = 8;
1530 
1531 	dispatch[MEM_START + 8].controller = 1;
1532 	dispatch[MEM_START + 9].controller = 2;
1533 	dispatch[MEM_START + 10].controller = 3;
1534 	dispatch[MEM_START + 11].controller = 4;
1535 	dispatch[MEM_START + 12].controller = 5;
1536 	dispatch[MEM_START + 13].controller = 6;
1537 
1538 	dispatch[MEM_START + 0].routine =
1539 		dispatch[MEM_START + 1].routine =
1540 		dispatch[MEM_START + 2].routine =
1541 		dispatch[MEM_START + 3].routine =
1542 		dispatch[MEM_START + 4].routine =
1543 		dispatch[MEM_START + 5].routine =
1544 		dispatch[MEM_START + 6].routine =
1545 		dispatch[MEM_START + 7].routine =
1546 		dispatch[MEM_START + 8].routine =
1547 		dispatch[MEM_START + 9].routine =
1548 		dispatch[MEM_START + 10].routine =
1549 		dispatch[MEM_START + 11].routine =
1550 		dispatch[MEM_START + 12].routine =
1551 		dispatch[MEM_START + 13].routine = (synthRoutine) stratusMemory;
1552 
1553 	dispatch[DEVICE_COUNT - 3].routine = dispatch[DEVICE_COUNT - 2].routine =
1554 		(synthRoutine) stratusMidi;
1555 	dispatch[DEVICE_COUNT - 3].controller = 1;
1556 	dispatch[DEVICE_COUNT - 2].controller = 2;
1557 
1558 	dispatch[MEM_START].other1 = -1;
1559 
1560 	/* Organ oscillator */
1561 	bristolMidiSendMsg(global.controlfd, synth->sid2, 0, 0, 16383);
1562 	bristolMidiSendMsg(global.controlfd, synth->sid2, 0, 1, 16383);
1563 	bristolMidiSendMsg(global.controlfd, synth->sid2, 0, 2, 16383);
1564 	bristolMidiSendMsg(global.controlfd, synth->sid2, 0, 3, 16383);
1565 	bristolMidiSendMsg(global.controlfd, synth->sid2, 0, 4, 0);
1566 	bristolMidiSendMsg(global.controlfd, synth->sid2, 0, 5, 0);
1567 	/* Pulse signal level and width */
1568 	bristolMidiSendMsg(global.controlfd, synth->sid2, 0, 7, 0);
1569 	bristolMidiSendMsg(global.controlfd, synth->sid2, 0, 8, 0);
1570 	bristolMidiSendMsg(global.controlfd, synth->sid2, 0, 9, 8192);
1571 	bristolMidiSendMsg(global.controlfd, synth->sid2, 0, 11, 16383);
1572 
1573 	/* ODC grooming envelope */
1574 	bristolMidiSendMsg(global.controlfd, synth->sid2, 1, 0, 0);
1575 	bristolMidiSendMsg(global.controlfd, synth->sid2, 1, 1, 100);
1576 	bristolMidiSendMsg(global.controlfd, synth->sid2, 1, 2, 6000);
1577 	bristolMidiSendMsg(global.controlfd, synth->sid2, 1, 3, 500);
1578 	bristolMidiSendMsg(global.controlfd, synth->sid2, 1, 4, 16383);
1579 	/* Velocity tracking envelope. Default is off */
1580 	bristolMidiSendMsg(global.controlfd, synth->sid2, 1, 5, 0);
1581 
1582 	/* String oscillator */
1583 	bristolMidiSendMsg(global.controlfd, synth->sid2, 2, 0, 16383);
1584 	bristolMidiSendMsg(global.controlfd, synth->sid2, 2, 1, 16383);
1585 	bristolMidiSendMsg(global.controlfd, synth->sid2, 2, 2, 16383);
1586 	bristolMidiSendMsg(global.controlfd, synth->sid2, 2, 3, 16383);
1587 	/* Load it up on a sawtooth although this is now a parameter */
1588 	bristolMidiSendMsg(global.controlfd, synth->sid2, 2, 4, 16383);
1589 	bristolMidiSendMsg(global.controlfd, synth->sid2, 2, 5, 0);
1590 	/* Pulse signal level and width */
1591 	bristolMidiSendMsg(global.controlfd, synth->sid2, 2, 7, 1);
1592 	bristolMidiSendMsg(global.controlfd, synth->sid2, 2, 8, 12);
1593 	bristolMidiSendMsg(global.controlfd, synth->sid2, 2, 9, 8192);
1594 	bristolMidiSendMsg(global.controlfd, synth->sid2, 2, 11, 16383);
1595 	/* String grooming ASR envelope */
1596 	bristolMidiSendMsg(global.controlfd, synth->sid2, 3, 1, 8192);
1597 	bristolMidiSendMsg(global.controlfd, synth->sid2, 3, 2, 16383);
1598 	bristolMidiSendMsg(global.controlfd, synth->sid2, 3, 4, 16383);
1599 	bristolMidiSendMsg(global.controlfd, synth->sid2, 3, 5, 1);
1600 
1601 	/* Filter mod, tracking and type */
1602 	bristolMidiSendMsg(global.controlfd, synth->sid, 3, 2, 8192);
1603 	bristolMidiSendMsg(global.controlfd, synth->sid, 3, 3, 16383);
1604 	bristolMidiSendMsg(global.controlfd, synth->sid, 3, 4, 4);
1605 
1606 	/* Synth envelope */
1607 	bristolMidiSendMsg(global.controlfd, synth->sid, 2, 4, 16383);
1608 
1609 	/*
1610 	 * Envelope is not touch sensitive, this is moved into the gain stage
1611 	 * since the same filter is used for the filter and amp
1612 	 */
1613 	bristolMidiSendMsg(global.controlfd, synth->sid, 2, 5, 0);
1614 
1615 	/* Osc harmonics - should add control */
1616 	bristolMidiSendMsg(global.controlfd, synth->sid, 0, 1, 8192);
1617 	bristolMidiSendMsg(global.controlfd, synth->sid, 1, 1, 8192);
1618 
1619 	return(0);
1620 }
1621 
1622 /*
1623  * This will be called to make any routine specific parameters available.
1624  */
1625 int
stratusConfigure(brightonWindow * win)1626 stratusConfigure(brightonWindow *win)
1627 {
1628 	guiSynth *synth = findSynth(global.synths, win);
1629 	brightonEvent event;
1630 
1631 	if (synth == 0)
1632 	{
1633 		printf("problems going operational\n");
1634 		return(-1);
1635 	}
1636 
1637 	if (synth->flags & OPERATIONAL)
1638 		return(0);
1639 
1640 	synth->flags |= OPERATIONAL;
1641 	synth->keypanel = 1;
1642 	synth->keypanel2 = -1;
1643 	synth->transpose = 24;
1644 
1645 	synth->bank = initmem / 10;
1646 	synth->location = initmem % 10;
1647 
1648 	loadMemory(synth, synth->resources->name, 0, initmem, synth->mem.active, 0,
1649 		BRISTOL_FORCE);
1650 	stratusLoadMemory(synth, global.controlfd, synth->midichannel, 0,
1651 		initmem, 0);
1652 
1653 	event.value = 1.0;
1654 	brightonParamChange(synth->win, synth->panel,
1655 		MEM_START + synth->location - 1, &event);
1656 
1657 	if (strstr(synth->resources->name, "stratus") != NULL)
1658 		shade_id = brightonPut(win, "bitmaps/blueprints/stratusshade.xpm",
1659 			0, 0, win->width, win->height);
1660 	else if (strstr(synth->resources->name, "trilogy") != NULL)
1661 		shade_id = brightonPut(win, "bitmaps/blueprints/trilogyshade.xpm",
1662 			0, 0, win->width, win->height);
1663 
1664 	/*
1665 	 * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only
1666 	 * occurs on first paint, so we suppress the first paint, and then request
1667 	 * an expose here.
1668 	 */
1669 	event.type = BRIGHTON_EXPOSE;
1670 	event.intvalue = 1;
1671 	brightonParamChange(synth->win, KEY_PANEL, -1, &event);
1672 //	brightonParamChange(synth->win, 0, -1, &event);
1673 	configureGlobals(synth);
1674 
1675 	dc = brightonGetDCTimer(win->dcTimeout);
1676 
1677 	return(0);
1678 }
1679 
1680