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  * The 'Bass' Maker, 4 stage 16 step sequencer.
24  *
25  * Crashes after BM is stopped. Issues with voice->baudio was NULL.
26  * Apparent loss of pitch bend.
27  * Mod controller mapping does not appear to work.
28  *
29  *	Global transpose. Test.
30  *	Mem search DONE
31  *	Midi channel DONE
32  *	Need to make sure transpose and channel selections are in the memories and
33  *	recovered. Tested ctype, cc, transpose
34  *
35  *	Controller options
36  *	Controller to note (13 steps) + channel
37  *	Controller to tune
38  *	Controller to pitchwheel
39  *	Controller to mod wheel
40  *	Controller to other continuous controller
41  *	Controller to operator parameter
42  *
43  *	Copy page
44  *	Fill values
45  *
46  *	Midi send and recieve clock. ffs.
47  */
48 
49 #include <fcntl.h>
50 
51 #include "brighton.h"
52 #include "bristolmidi.h"
53 #include "brightonMini.h"
54 #include "brightoninternals.h"
55 #include "brightonledstates.h"
56 
57 static int bmInit();
58 static int bmConfigure();
59 static int bmCallback(brightonWindow *, int, int, float);
60 
61 extern guimain global;
62 
63 #include "brightonKeys.h"
64 
65 static int dc;
66 
67 #define BM_TRANSPOSE 24
68 
69 #define KEY_PANEL 1
70 
71 #define PAGE_COUNT 4 /* This would require rebuilding the control panel */
72 #define OP_COUNT 8
73 #define PAGE_STEP 16
74 #define STEP_COUNT (PAGE_STEP * PAGE_COUNT)
75 
76 #define TOTAL_DEVS (PAGE_STEP * OP_COUNT)
77 #define CONTROL_COUNT 60 /* controls less memomry selectors/entry */
78 #define CONTROL_ACTIVE 20
79 #define COFF (TOTAL_DEVS * PAGE_COUNT)
80 #define ACTIVE_DEVS (COFF + CONTROL_ACTIVE)
81 #define DEVICE_COUNT (COFF + CONTROL_COUNT)
82 #define DISPLAY_DEV (CONTROL_COUNT - 1)
83 
84 #define BM_C_CONTROL	0 /* or greater */
85 #define BM_C_NOTE		-1
86 #define BM_C_TUNE		-2
87 #define BM_C_GLIDE		-3 /* ffs */
88 #define BM_C_MOD		-4 /* ffs */
89 #define BM_C_OPERATOR	-5 /* ffs */
90 
91 /*
92  * This structure is for device definition. The structure is defined in
93  * include/brighton.h, further definitions in brighton/brightonDevtable.h and
94  * include/brightoninternals.h
95  *
96  *	typedef int (*brightonCallback)(int, float);
97  *	typedef struct BrightonLocations {
98  *		int device; 0=rotary, 1=scale, etc.
99  *		float relx, rely; relative position with regards to 1000 by 1000 window
100  *		float relw, relh; relative height.
101  *		int from, to;
102  *		brightonCallback callback; specific to this dev
103  *		char *image; bitmap. If zero take a device default.
104  *		int flags;
105  *	} brightonLocations;
106  *
107  * This example is for a bmBristol type synth interface.
108  */
109 
110 typedef struct BmNote {
111 	float note;
112 	float transp;
113 	float velocity;
114 	float cont;
115 	float led;
116 	float button;
117 	float pad1;
118 	float pad2;
119 } bmNote;
120 
121 typedef struct BmPage {
122 	bmNote step[PAGE_STEP];
123 } bmPage;
124 
125 /* A/B/C/D active: 0 4 4 */
126 /* A/B/C/D select: 4 4 8 */
127 /* Speed, Duty, 4xdirection: 8 6 14 */
128 /* 6 pad: 14 6 20 */
129 /* ABCD led * 2: 20 8 28  */
130 /* Dir led * 4: 28 4 32 */
131 /* Memory 12: 32 12 44 */
132 /* Display 4: 44 4 48 */
133 /* 12 pad: 48 12 60 */
134 
135 typedef struct BmControl {
136 	float speed;
137 	float duty;
138 	float up;
139 	float down;
140 	float updown;
141 	float rand;
142 	float active[PAGE_COUNT];
143 	float select[PAGE_COUNT];
144 	float transpose;
145 	float ctype;
146 	float cc;
147 	float cop;
148 	float pad1[2];
149 	/* 20 Following parameters are NOT in the memories */
150 	float activeled[PAGE_COUNT];
151 	float selectled[PAGE_COUNT];
152 	float dirled[PAGE_COUNT];
153 	float mem[12];
154 	float start;
155 	float stop;
156 	float pad2[10];
157 	float display[PAGE_COUNT];
158 } bmControl;
159 
160 typedef struct BmMem {
161 	bmPage page[PAGE_COUNT];
162 	bmControl control;
163 	/* These are transient parameters used during operation */
164 	int lastnote;
165 	int lastpage;
166 	int laststep;
167 	int clearstep;
168 	int lastcnote;
169 	int cMemPage;
170 	int cMemEntry;
171 	int pageSelect;
172 } bmMem;
173 
174 struct {
175 	synthRoutine control[OP_COUNT];
176 } call;
177 
178 #define DR1 194
179 #define R1 60
180 #define R2 (R1 + DR1 + 10)
181 #define R3 (R2 + DR1 - 10)
182 #define R4 (R3 + DR1)
183 #define R5 (R4 + DR1)
184 #define R6 (R5 + DR1/3 - 15)
185 
186 #define DC1 60
187 #define C1 30
188 #define C2 (C1 + DC1)
189 #define C3 (C2 + DC1)
190 #define C4 (C3 + DC1)
191 #define C5 (C4 + DC1)
192 #define C6 (C5 + DC1)
193 #define C7 (C6 + DC1)
194 #define C8 (C7 + DC1)
195 #define C9 (C8 + DC1)
196 #define C10 (C9 + DC1)
197 #define C11 (C10 + DC1)
198 #define C12 (C11 + DC1)
199 #define C13 (C12 + DC1)
200 #define C14 (C13 + DC1)
201 #define C15 (C14 + DC1)
202 #define C16 (C15 + DC1)
203 
204 #define W1 35
205 #define H1 100
206 #define W2 20
207 #define H2 60
208 #define W3 12
209 #define H3 27
210 #define H4 75
211 #define O1 (W1 / 3)
212 #define O2 ((W1 - W2) / 2 + 4)
213 #define O3 ((W1 - W3) / 2 + 3)
214 
215 static brightonLocations locations[TOTAL_DEVS] = {
216 
217 	{"", 0, C1, R1, W1, H1, 0, 12, 0, "bitmaps/knobs/knob4.xpm", 0, 0},
218 	{"", 2, C1 + O3, R2, 10, H4, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY},
219 	{"", 0, C1, R3, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0},
220 	{"", 0, C1, R4, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0,
221 		BRIGHTON_NOTCH},
222 	{"", 12, C1 + O3, R5, W3, H3, 0, 4, 0, 0, 0, 0},
223 	{"", 2, C1 + O2, R6, W2, H2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm",
224 		"bitmaps/buttons/touchnlW.xpm", BRIGHTON_CHECKBUTTON},
225 	{"", 0, C1 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
226 	{"", 0, C1 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
227 
228 	{"", 0, C2, R1, W1, H1, 0, 12, 0, "bitmaps/knobs/knob4.xpm", 0, 0},
229 	{"", 2, C2 + O3, R2, 10, H4, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY},
230 	{"", 0, C2, R3, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0},
231 	{"", 0, C2, R4, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0,
232 		BRIGHTON_NOTCH},
233 	{"", 12, C2 + O3, R5, W3, H3, 0, 4, 0, 0, 0, 0},
234 	{"", 2, C2 + O2, R6, W2, H2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm",
235 		"bitmaps/buttons/touchnlW.xpm", BRIGHTON_CHECKBUTTON},
236 	{"", 0, C2 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
237 	{"", 0, C2 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
238 
239 	{"", 0, C3, R1, W1, H1, 0, 12, 0, "bitmaps/knobs/knob4.xpm", 0, 0},
240 	{"", 2, C3 + O3, R2, 10, H4, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY},
241 	{"", 0, C3, R3, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0},
242 	{"", 0, C3, R4, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0,
243 		BRIGHTON_NOTCH},
244 	{"", 12, C3 + O3, R5, W3, H3, 0, 4, 0, 0, 0, 0},
245 	{"", 2, C3 + O2, R6, W2, H2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm",
246 		"bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON},
247 	{"", 0, C3 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
248 	{"", 0, C3 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
249 
250 	{"", 0, C4, R1, W1, H1, 0, 12, 0, "bitmaps/knobs/knob4.xpm", 0, 0},
251 	{"", 2, C4 + O3, R2, 10, H4, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY},
252 	{"", 0, C4, R3, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0},
253 	{"", 0, C4, R4, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0,
254 		BRIGHTON_NOTCH},
255 	{"", 12, C4 + O3, R5, W3, H3, 0, 4, 0, 0, 0, 0},
256 	{"", 2, C4 + O2, R6, W2, H2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm",
257 		"bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON},
258 	{"", 0, C4 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
259 	{"", 0, C4 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
260 
261 	{"", 0, C5, R1, W1, H1, 0, 12, 0, "bitmaps/knobs/knob4.xpm", 0, 0},
262 	{"", 2, C5 + O3, R2, 10, H4, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY},
263 	{"", 0, C5, R3, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0},
264 	{"", 0, C5, R4, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0,
265 		BRIGHTON_NOTCH},
266 	{"", 12, C5 + O3, R5, W3, H3, 0, 4, 0, 0, 0, 0},
267 	{"", 2, C5 + O2, R6, W2, H2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm",
268 		"bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON},
269 	{"", 0, C5 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
270 	{"", 0, C5 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
271 
272 	{"", 0, C6, R1, W1, H1, 0, 12, 0, "bitmaps/knobs/knob4.xpm", 0,
273 		0},
274 	{"", 2, C6 + O3, R2, 10, H4, 0, 2, 0, 0,
275 		0, BRIGHTON_THREEWAY},
276 	{"", 0, C6, R3, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0,
277 		0},
278 	{"", 0, C6, R4, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0,
279 		BRIGHTON_NOTCH},
280 	{"", 12, C6 + O3, R5, W3, H3, 0, 4, 0, 0, 0, 0},
281 	{"", 2, C6 + O2, R6, W2, H2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm",
282 		"bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON},
283 	{"", 0, C6 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
284 	{"", 0, C6 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
285 
286 	{"", 0, C7, R1, W1, H1, 0, 12, 0, "bitmaps/knobs/knob4.xpm", 0,
287 		0},
288 	{"", 2, C7 + O3, R2, 10, H4, 0, 2, 0, 0,
289 		0, BRIGHTON_THREEWAY},
290 	{"", 0, C7, R3, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0,
291 		0},
292 	{"", 0, C7, R4, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0,
293 		BRIGHTON_NOTCH},
294 	{"", 12, C7 + O3, R5, W3, H3, 0, 4, 0, 0, 0, 0},
295 	{"", 2, C7 + O2, R6, W2, H2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm",
296 		"bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON},
297 	{"", 0, C7 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
298 	{"", 0, C7 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
299 
300 	{"", 0, C8, R1, W1, H1, 0, 12, 0, "bitmaps/knobs/knob4.xpm", 0,
301 		0},
302 	{"", 2, C8 + O3, R2, 10, H4, 0, 2, 0, 0,
303 		0, BRIGHTON_THREEWAY},
304 	{"", 0, C8, R3, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0,
305 		0},
306 	{"", 0, C8, R4, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0,
307 		BRIGHTON_NOTCH},
308 	{"", 12, C8 + O3, R5, W3, H3, 0, 4, 0, 0, 0, 0},
309 	{"", 2, C8 + O2, R6, W2, H2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm",
310 		"bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON},
311 	{"", 0, C8 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
312 	{"", 0, C8 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
313 
314 	{"", 0, C9, R1, W1, H1, 0, 12, 0, "bitmaps/knobs/knob4.xpm", 0,
315 		0},
316 	{"", 2, C9 + O3, R2, 10, H4, 0, 2, 0, 0,
317 		0, BRIGHTON_THREEWAY},
318 	{"", 0, C9, R3, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0,
319 		0},
320 	{"", 0, C9, R4, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0,
321 		BRIGHTON_NOTCH},
322 	{"", 12, C9 + O3, R5, W3, H3, 0, 4, 0, 0, 0, 0},
323 	{"", 2, C9 + O2, R6, W2, H2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm",
324 		"bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON},
325 	{"", 0, C9 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
326 	{"", 0, C9 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
327 
328 	{"", 0, C10, R1, W1, H1, 0, 12, 0, "bitmaps/knobs/knob4.xpm", 0,
329 		0},
330 	{"", 2, C10 + O3, R2, 10, H4, 0, 2, 0, 0,
331 		0, BRIGHTON_THREEWAY},
332 	{"", 0, C10, R3, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0,
333 		0},
334 	{"", 0, C10, R4, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0,
335 		BRIGHTON_NOTCH},
336 	{"", 12, C10 + O3, R5, W3, H3, 0, 4, 0, 0, 0, 0},
337 	{"", 2, C10 + O2, R6, W2, H2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm",
338 		"bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON},
339 	{"", 0, C10 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
340 	{"", 0, C10 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
341 
342 	{"", 0, C11, R1, W1, H1, 0, 12, 0, "bitmaps/knobs/knob4.xpm", 0,
343 		0},
344 	{"", 2, C11 + O3, R2, 10, H4, 0, 2, 0, 0,
345 		0, BRIGHTON_THREEWAY},
346 	{"", 0, C11, R3, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0,
347 		0},
348 	{"", 0, C11, R4, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0,
349 		BRIGHTON_NOTCH},
350 	{"", 12, C11 + O3, R5, W3, H3, 0, 4, 0, 0, 0, 0},
351 	{"", 2, C11 + O2, R6, W2, H2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm",
352 		"bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON},
353 	{"", 0, C11 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
354 	{"", 0, C11 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
355 
356 	{"", 0, C12, R1, W1, H1, 0, 12, 0, "bitmaps/knobs/knob4.xpm", 0,
357 		0},
358 	{"", 2, C12 + O3, R2, 10, H4, 0, 2, 0, 0,
359 		0, BRIGHTON_THREEWAY},
360 	{"", 0, C12, R3, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0,
361 		0},
362 	{"", 0, C12, R4, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0,
363 		BRIGHTON_NOTCH},
364 	{"", 12, C12 + O3, R5, W3, H3, 0, 4, 0, 0, 0, 0},
365 	{"", 2, C12 + O2, R6, W2, H2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm",
366 		"bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON},
367 	{"", 0, C12 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
368 	{"", 0, C12 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
369 
370 	{"", 0, C13, R1, W1, H1, 0, 12, 0, "bitmaps/knobs/knob4.xpm", 0,
371 		0},
372 	{"", 2, C13 + O3, R2, 10, H4, 0, 2, 0, 0,
373 		0, BRIGHTON_THREEWAY},
374 	{"", 0, C13, R3, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0,
375 		0},
376 	{"", 0, C13, R4, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0,
377 		BRIGHTON_NOTCH},
378 	{"", 12, C13 + O3, R5, W3, H3, 0, 4, 0, 0, 0, 0},
379 	{"", 2, C13 + O2, R6, W2, H2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm",
380 		"bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON},
381 	{"", 0, C13 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
382 	{"", 0, C13 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
383 
384 	{"", 0, C14, R1, W1, H1, 0, 12, 0, "bitmaps/knobs/knob4.xpm", 0,
385 		0},
386 	{"", 2, C14 + O3, R2, 10, H4, 0, 2, 0, 0,
387 		0, BRIGHTON_THREEWAY},
388 	{"", 0, C14, R3, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0,
389 		0},
390 	{"", 0, C14, R4, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0,
391 		BRIGHTON_NOTCH},
392 	{"", 12, C14 + O3, R5, W3, H3, 0, 4, 0, 0, 0, 0},
393 	{"", 2, C14 + O2, R6, W2, H2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm",
394 		"bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON},
395 	{"", 0, C14 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
396 	{"", 0, C14 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
397 
398 	{"", 0, C15, R1, W1, H1, 0, 12, 0, "bitmaps/knobs/knob4.xpm", 0,
399 		0},
400 	{"", 2, C15 + O3, R2, 10, H4, 0, 2, 0, 0,
401 		0, BRIGHTON_THREEWAY},
402 	{"", 0, C15, R3, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0,
403 		0},
404 	{"", 0, C15, R4, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0,
405 		BRIGHTON_NOTCH},
406 	{"", 12, C15 + O3, R5, W3, H3, 0, 4, 0, 0, 0, 0},
407 	{"", 2, C15 + O2, R6, W2, H2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm",
408 		"bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON},
409 	{"", 0, C15 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
410 	{"", 0, C15 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
411 
412 	{"", 0, C16, R1, W1, H1, 0, 12, 0, "bitmaps/knobs/knob4.xpm", 0,
413 		0},
414 	{"", 2, C16 + O3, R2, 10, H4, 0, 2, 0, 0,
415 		0, BRIGHTON_THREEWAY},
416 	{"", 0, C16, R3, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0,
417 		0},
418 	{"", 0, C16, R4, W1, H1, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0,
419 		BRIGHTON_NOTCH},
420 	{"", 12, C16 + O3, R5, W3, H3, 0, 4, 0, 0, 0, 0},
421 	{"", 2, C16 + O2, R6, W2, H2, 0, 1, 0, "bitmaps/buttons/touchnlw.xpm",
422 		"bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON},
423 	{"", 0, C16 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
424 	{"", 0, C16 + O2, R6, W2, H2, 0, 1, 0, 0, 0, BRIGHTON_WITHDRAWN|BRIGHTON_NOSHADOW},
425 
426 };
427 
428 /*
429  *	start/pause + flash, stop=return to start.			2 + led
430  *	4 screen selectors + 4 active selectors a/b/c/d		8 + 8 led
431  *
432  *	speed, up, down, u/d, rand, trig, duty cycle.
433  *		rotary * 2 + 5.
434  *
435  *	memories		12
436  *
437  *	controller mapping - tuning, mod, etc.
438  *	display + option + up/down
439  *
440  *	8+7(+5pad+)8+3+12+4(+12pad)=60
441  */
442 #define CR1 300
443 #define CR2 500
444 #define CW1 30
445 #define CH1 200
446 
447 static brightonLocations bm_controls[CONTROL_COUNT] = {
448 	/* Speed, Duty, 4xdirection: 0 6 6 */
449 	{"", 0, 20, 255, 50, 500, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0},
450 	{"", 0, 100, 255, 50, 500, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0},
451 	{"", 2, 230, CR1, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_u.xpm",
452 		"bitmaps/digits/kbd_u.xpm", BRIGHTON_NOSHADOW},
453 	{"", 2, 230, CR2, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_down.xpm",
454 		"bitmaps/digits/kbd_down.xpm",	0},
455 	{"", 2, 260, CR1, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_ud.xpm",
456 		"bitmaps/digits/kbd_ud.xpm",	0},
457 	{"", 2, 260, CR2, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_r.xpm",
458 		"bitmaps/digits/kbd_r.xpm",	0},
459 	/* A/B/C/D active: 6 4 10 */
460 	{"", 2, 340, CR1, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_a.xpm",
461 		"bitmaps/digits/kbd_a.xpm",	BRIGHTON_NOSHADOW},
462 	{"", 2, 370, CR1, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_b.xpm",
463 		"bitmaps/digits/kbd_b.xpm",	BRIGHTON_NOSHADOW},
464 	{"", 2, 400, CR1, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_c.xpm",
465 		"bitmaps/digits/kbd_c.xpm",	BRIGHTON_NOSHADOW},
466 	{"", 2, 430, CR1, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_d.xpm",
467 		"bitmaps/digits/kbd_d.xpm",	0},
468 	/* A/B/C/D select: 10 4 14 */
469 	{"", 2, 340, CR2, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_a.xpm",
470 		"bitmaps/buttons/touchnlW.xpm", BRIGHTON_CHECKBUTTON|0},
471 	{"", 2, 370, CR2, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_b.xpm",
472 		"bitmaps/buttons/touchnlW.xpm", BRIGHTON_CHECKBUTTON|0},
473 	{"", 2, 400, CR2, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_c.xpm",
474 		"bitmaps/buttons/touchnlW.xpm", BRIGHTON_CHECKBUTTON|0},
475 	{"", 2, 430, CR2, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_d.xpm",
476 		"bitmaps/buttons/touchnlW.xpm", BRIGHTON_CHECKBUTTON|0},
477 	/* 6 pad: 14 6 20 */
478 	{"", 0, 9, 9, 9, 9, 0, 1, 0, 0, 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN},
479 	{"", 0, 9, 9, 9, 9, 0, 1, 0, 0, 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN},
480 	{"", 0, 9, 9, 9, 9, 0, 1, 0, 0, 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN},
481 	{"", 0, 9, 9, 9, 9, 0, 1, 0, 0, 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN},
482 	{"", 0, 9, 9, 9, 9, 0, 1, 0, 0, 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN},
483 	{"", 0, 9, 9, 9, 9, 0, 1, 0, 0, 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN},
484 	/* ABCD led * 2: 20 8 28  */
485 	{"", 12, 350, 200, 11, 85, 0, 4, 0, 0, 0, 0},
486 	{"", 12, 380, 200, 11, 85, 0, 4, 0, 0, 0, 0},
487 	{"", 12, 410, 200, 11, 85, 0, 4, 0, 0, 0, 0},
488 	{"", 12, 440, 200, 11, 85, 0, 4, 0, 0, 0, 0},
489 	{"", 12, 350, 730, 11, 85, 0, 4, 0, 0, 0, 0},
490 	{"", 12, 380, 730, 11, 85, 0, 4, 0, 0, 0, 0},
491 	{"", 12, 410, 730, 11, 85, 0, 4, 0, 0, 0, 0},
492 	{"", 12, 440, 730, 11, 85, 0, 4, 0, 0, 0, 0},
493 	/* Dir led * 4: 28 4 32 */
494 	{"", 12, 240, 200, 11, 85, 0, 4, 0, 0, 0, 0},
495 	{"", 12, 240, 730, 11, 85, 0, 4, 0, 0, 0, 0},
496 	{"", 12, 270, 200, 11, 85, 0, 4, 0, 0, 0, 0},
497 	{"", 12, 270, 730, 11, 85, 0, 4, 0, 0, 0, 0},
498 	/* Memory 12: 32 12 44 */
499 	{"", 2, 530, CR1, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_0.xpm",
500 		"bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW},
501 	{"", 2, 560, CR1, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_1.xpm",
502 		"bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW},
503 	{"", 2, 590, CR1, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_2.xpm",
504 		"bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW},
505 	{"", 2, 620, CR1, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_3.xpm",
506 		"bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW},
507 	{"", 2, 650, CR1, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_4.xpm",
508 		"bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON|0},
509 
510 	{"", 2, 530, CR2, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_5.xpm",
511 		"bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON|0},
512 	{"", 2, 560, CR2, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_6.xpm",
513 		"bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON|0},
514 	{"", 2, 590, CR2, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_7.xpm",
515 		"bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON|0},
516 	{"", 2, 620, CR2, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_8.xpm",
517 		"bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON|0},
518 	{"", 2, 650, CR2, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_9.xpm",
519 		"bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON|0},
520 
521 	{"", 2, 680, CR1, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_ld.xpm",
522 		"bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON|0},
523 	{"", 2, 680, CR2, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_s.xpm",
524 		"bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON|0},
525 	/* Start/Stop + LED */
526 	{"", 2, 175, CR1, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_st.xpm",
527 		"bitmaps/digits/kbd_st.xpm", 0},
528 	{"", 2, 175, CR2, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_stop.xpm",
529 		"bitmaps/digits/kbd_stop.xpm", 0},
530 	{"", 12, 185, 200, 11, 80, 0, 4, 0, 0, 0, 0},
531 	{"", 12, 185, 730, 11, 80, 0, 4, 0, 0, 0, 0},
532 	/* 8 pad: 52 8 60 */
533 	{"", 0, 9, 9, 9, 9, 0, 1, 0, 0, 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN},
534 	{"", 0, 9, 9, 9, 9, 0, 1, 0, 0, 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN},
535 	{"", 0, 9, 9, 9, 9, 0, 1, 0, 0, 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN},
536 	{"", 0, 9, 9, 9, 9, 0, 1, 0, 0, 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN},
537 	{"", 0, 9, 9, 9, 9, 0, 1, 0, 0, 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN},
538 	{"", 0, 9, 9, 9, 9, 0, 1, 0, 0, 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN},
539 	{"", 0, 9, 9, 9, 9, 0, 1, 0, 0, 0, BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN},
540 	/* Display 5: 55 5 60 */
541 	{"", 2, 740, CR1, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_ua.xpm",
542 		"bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON|0},
543 	{"", 2, 740, CR2, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_da.xpm",
544 		"bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON},
545 	{"", 2, 950, CR1, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_fn.xpm",
546 		"bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON|0},
547 	{"", 2, 950, CR2, CW1, CH1, 0, 1, 0, "bitmaps/digits/kbd_ret.xpm",
548 		"bitmaps/buttons/touchnlW.xpm",BRIGHTON_CHECKBUTTON},
549 	{"", 3, 775, 415, 170, 123, 0, 1, 0, 0,
550 		"bitmaps/images/alphadisplay3.xpm", 0}
551 };
552 
553 static int
bmMidiCallback(brightonWindow * win,int controller,int value,float n)554 bmMidiCallback(brightonWindow *win, int controller, int value, float n)
555 {
556 	guiSynth *synth = findSynth(global.synths, win);
557 
558 	printf("midi callback: %x, %i\n", controller, value);
559 
560 	switch(controller)
561 	{
562 		case MIDI_PROGRAM:
563 			printf("midi program: %x, %i\n", controller, value);
564 			synth->bank = value - (value % 8);
565 			synth->location = value % 8;
566 			loadMemory(synth, "bassmaker", 0, synth->bank * 10 + synth->location,
567 				synth->mem.active, 0, 0);
568 			break;
569 		/*
570 		 * This needs a case statement for midi clock which can then be used
571 		 * to drive the fast timers.
572 		 */
573 	}
574 	return(0);
575 }
576 
577 /*
578  * This is a set of globals for the main window rendering. Again taken from
579  * include/brighton.h
580  */
581 brightonApp bmApp = {
582 	"bassmaker",
583 	0,
584 	"bitmaps/textures/metal2.xpm",
585 	BRIGHTON_STRETCH|BRIGHTON_REVERSE, /* default is tesselate */
586 	bmInit,
587 	bmConfigure, /* 3 callbacks, unused? */
588 	bmMidiCallback,
589 	destroySynth,
590 	{1, 100, 2, 2, 5, 520, 0, 0},
591 	820, 410, 0, 0,
592 	8,
593 	{
594 		{
595 			"BM-20",
596 			"bitmaps/blueprints/bm.xpm",
597 			"bitmaps/textures/metal2.xpm",
598 			BRIGHTON_STRETCH|BRIGHTON_REVERSE, /* flags */
599 			0,
600 			bmConfigure,
601 			bmCallback,
602 			11, 243, 976, 690,
603 			TOTAL_DEVS,
604 			locations
605 		},
606 		{
607 			"BM-20",
608 			"bitmaps/blueprints/bm.xpm",
609 			"bitmaps/textures/metal2.xpm",
610 			BRIGHTON_STRETCH|BRIGHTON_REVERSE|BRIGHTON_WITHDRAWN, /* flags */
611 			0,
612 			bmConfigure,
613 			bmCallback,
614 			11, 243, 976, 690,
615 			TOTAL_DEVS,
616 			locations
617 		},
618 		{
619 			"BM-20",
620 			"bitmaps/blueprints/bm.xpm",
621 			"bitmaps/textures/metal2.xpm",
622 			BRIGHTON_STRETCH|BRIGHTON_REVERSE|BRIGHTON_WITHDRAWN, /* flags */
623 			0,
624 			bmConfigure,
625 			bmCallback,
626 			11, 243, 976, 690,
627 			TOTAL_DEVS,
628 			locations
629 		},
630 		{
631 			"BM-20",
632 			"bitmaps/blueprints/bm.xpm",
633 			"bitmaps/textures/metal2.xpm",
634 			BRIGHTON_STRETCH|BRIGHTON_REVERSE|BRIGHTON_WITHDRAWN, /* flags */
635 			0,
636 			bmConfigure,
637 			bmCallback,
638 			11, 243, 976, 690,
639 			TOTAL_DEVS,
640 			locations
641 		},
642 		{
643 			"Mods",
644 			"bitmaps/blueprints/bmmods.xpm",
645 			//"bitmaps/textures/metal7.xpm", /* flags */
646 			"bitmaps/textures/metal2.xpm",
647 			BRIGHTON_VERTICAL|BRIGHTON_REVERSE|BRIGHTON_STRETCH,
648 			0,
649 			0,
650 			bmCallback,
651 			12, 0, 977, 240,
652 			CONTROL_COUNT,
653 			bm_controls
654 		},
655 		{
656 			"Wood",
657 			0,
658 			"bitmaps/textures/wood6.xpm",
659 			BRIGHTON_VERTICAL, /* flags */
660 			0,
661 			0,
662 			0,
663 			14, 930, 974, 60,
664 			0,
665 			0
666 		},
667 		{
668 			"SP1",
669 			0,
670 			"bitmaps/images/rhodes.xpm",
671 			BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */
672 			0,
673 			0,
674 			0,
675 			0, 0, 12, 1000,
676 			0,
677 			0
678 		},
679 		{
680 			"SP2",
681 			0,
682 			"bitmaps/images/rhodes.xpm",
683 			BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */
684 			0,
685 			0,
686 			0,
687 			988, 0, 12, 1000,
688 			0,
689 			0
690 		},
691 	}
692 };
693 
694 int
bmMidiSendMsg(void * synth,int fd,int chan,int c,int o,int v)695 bmMidiSendMsg(void *synth, int fd, int chan, int c, int o, int v)
696 {
697 //	bristolMidiSendMsg(fd, chan, c, o, v);
698 	return(0);
699 }
700 
701 static void
bmMemShim(guiSynth * synth)702 bmMemShim(guiSynth *synth)
703 {
704 	int i;
705 	bmMem *bm = (bmMem *) synth->mem.param;
706 	brightonEvent event;
707 
708 	event.type = BRIGHTON_FLOAT;
709 
710 	/*
711 	 * We need to review the button state and from that set the per note LED to
712 	 * the desired color
713 	 */
714 	for (i = 0; i < STEP_COUNT; i++)
715 	{
716 		event.value = bm->page[i / PAGE_STEP].step[i % PAGE_STEP].button;
717 //printf("Shim %i: %i %i = %f\n", i, i / PAGE_STEP, (i % PAGE_STEP) * OP_COUNT + 4, event.value);
718 		brightonParamChange(synth->win, i / PAGE_STEP,
719 			(i % PAGE_STEP) * OP_COUNT + 4, &event);
720 	}
721 
722 	synth->transpose = bm->control.transpose - 12;
723 }
724 
725 #define BM_DIR_UP 0
726 #define BM_DIR_DOWN 1
727 #define BM_DIR_UPDOWN 2
728 #define BM_DIR_RAND 3
729 
730 #define BM_INC_A	0x01
731 #define BM_INC_B	0x02
732 #define BM_INC_C	0x04
733 #define BM_INC_D	0x08
734 
735 static void
bmStuffPage(guiSynth * synth,int page,int dir)736 bmStuffPage(guiSynth *synth, int page, int dir)
737 {
738 	if (dir == BM_DIR_UP)
739 	{
740 		brightonFastTimer(synth->win, page, 4, BRIGHTON_FT_REQ, 0);
741 		brightonFastTimer(synth->win, page, 12, BRIGHTON_FT_REQ, 0);
742 		brightonFastTimer(synth->win, page, 20, BRIGHTON_FT_REQ, 0);
743 		brightonFastTimer(synth->win, page, 28, BRIGHTON_FT_REQ, 0);
744 		brightonFastTimer(synth->win, page, 36, BRIGHTON_FT_REQ, 0);
745 		brightonFastTimer(synth->win, page, 44, BRIGHTON_FT_REQ, 0);
746 		brightonFastTimer(synth->win, page, 52, BRIGHTON_FT_REQ, 0);
747 		brightonFastTimer(synth->win, page, 60, BRIGHTON_FT_REQ, 0);
748 
749 		brightonFastTimer(synth->win, page, 68, BRIGHTON_FT_REQ, 0);
750 		brightonFastTimer(synth->win, page, 76, BRIGHTON_FT_REQ, 0);
751 		brightonFastTimer(synth->win, page, 84, BRIGHTON_FT_REQ, 0);
752 		brightonFastTimer(synth->win, page, 92, BRIGHTON_FT_REQ, 0);
753 		brightonFastTimer(synth->win, page, 100, BRIGHTON_FT_REQ, 0);
754 		brightonFastTimer(synth->win, page, 108, BRIGHTON_FT_REQ, 0);
755 		brightonFastTimer(synth->win, page, 116, BRIGHTON_FT_REQ, 0);
756 		brightonFastTimer(synth->win, page, 124, BRIGHTON_FT_REQ, 0);
757 	} else if (dir == BM_DIR_DOWN) {
758 		brightonFastTimer(synth->win, page, 124, BRIGHTON_FT_REQ, 0);
759 		brightonFastTimer(synth->win, page, 116, BRIGHTON_FT_REQ, 0);
760 		brightonFastTimer(synth->win, page, 108, BRIGHTON_FT_REQ, 0);
761 		brightonFastTimer(synth->win, page, 100, BRIGHTON_FT_REQ, 0);
762 		brightonFastTimer(synth->win, page, 92, BRIGHTON_FT_REQ, 0);
763 		brightonFastTimer(synth->win, page, 84, BRIGHTON_FT_REQ, 0);
764 		brightonFastTimer(synth->win, page, 76, BRIGHTON_FT_REQ, 0);
765 		brightonFastTimer(synth->win, page, 68, BRIGHTON_FT_REQ, 0);
766 
767 		brightonFastTimer(synth->win, page, 60, BRIGHTON_FT_REQ, 0);
768 		brightonFastTimer(synth->win, page, 52, BRIGHTON_FT_REQ, 0);
769 		brightonFastTimer(synth->win, page, 44, BRIGHTON_FT_REQ, 0);
770 		brightonFastTimer(synth->win, page, 36, BRIGHTON_FT_REQ, 0);
771 		brightonFastTimer(synth->win, page, 28, BRIGHTON_FT_REQ, 0);
772 		brightonFastTimer(synth->win, page, 20, BRIGHTON_FT_REQ, 0);
773 		brightonFastTimer(synth->win, page, 12, BRIGHTON_FT_REQ, 0);
774 		brightonFastTimer(synth->win, page, 4, BRIGHTON_FT_REQ, 0);
775 	} else if (dir == BM_DIR_RAND) {
776 		brightonFastTimer(synth->win, page,
777 			(rand() & 0x0f) * 8 + 4, BRIGHTON_FT_REQ, 0);
778 		brightonFastTimer(synth->win, page,
779 			(rand() & 0x0f) * 8 + 4, BRIGHTON_FT_REQ, 0);
780 		brightonFastTimer(synth->win, page,
781 			(rand() & 0x0f) * 8 + 4, BRIGHTON_FT_REQ, 0);
782 		brightonFastTimer(synth->win, page,
783 			(rand() & 0x0f) * 8 + 4, BRIGHTON_FT_REQ, 0);
784 		brightonFastTimer(synth->win, page,
785 			(rand() & 0x0f) * 8 + 4, BRIGHTON_FT_REQ, 0);
786 		brightonFastTimer(synth->win, page,
787 			(rand() & 0x0f) * 8 + 4, BRIGHTON_FT_REQ, 0);
788 		brightonFastTimer(synth->win, page,
789 			(rand() & 0x0f) * 8 + 4, BRIGHTON_FT_REQ, 0);
790 		brightonFastTimer(synth->win, page,
791 			(rand() & 0x0f) * 8 + 4, BRIGHTON_FT_REQ, 0);
792 		brightonFastTimer(synth->win, page,
793 			(rand() & 0x0f) * 8 + 4, BRIGHTON_FT_REQ, 0);
794 		brightonFastTimer(synth->win, page,
795 			(rand() & 0x0f) * 8 + 4, BRIGHTON_FT_REQ, 0);
796 		brightonFastTimer(synth->win, page,
797 			(rand() & 0x0f) * 8 + 4, BRIGHTON_FT_REQ, 0);
798 		brightonFastTimer(synth->win, page,
799 			(rand() & 0x0f) * 8 + 4, BRIGHTON_FT_REQ, 0);
800 		brightonFastTimer(synth->win, page,
801 			(rand() & 0x0f) * 8 + 4, BRIGHTON_FT_REQ, 0);
802 		brightonFastTimer(synth->win, page,
803 			(rand() & 0x0f) * 8 + 4, BRIGHTON_FT_REQ, 0);
804 		brightonFastTimer(synth->win, page,
805 			(rand() & 0x0f) * 8 + 4, BRIGHTON_FT_REQ, 0);
806 		brightonFastTimer(synth->win, page,
807 			(rand() & 0x0f) * 8 + 4, BRIGHTON_FT_REQ, 0);
808 	}
809 }
810 
811 static void
bmStuffCallbacks(guiSynth * synth)812 bmStuffCallbacks(guiSynth *synth)
813 {
814 	bmMem *bm = (bmMem *) synth->mem.param;
815 
816 	int seq, inc = 0;
817 
818 	if (synth->flags & MEM_LOADING)
819 		return;
820 
821 	/*
822 	 * The next two changes would disable the sequence if we change it, that
823 	 * is arguably correct?
824 	event.value = BRIGHTON_LED_OFF;
825 	brightonParamChange(synth->win, 4, 46, &event);
826 	event.value = BRIGHTON_LED_RED;
827 	brightonParamChange(synth->win, 4, 47, &event);
828 	 */
829 
830 	/*
831 	 * We have to consider which pages we are going to include, the page and
832 	 * note ordering (U, D, UD, R) and perhaps eventually a time code 3/4, 4/4?
833 	brightonFastTimer(synth->win, 0, 4, BRIGHTON_FT_REQ, 0);
834 	 */
835 
836 	if (bm->control.up != 0) {
837 		printf("Sequence Up: include page");
838 		seq = BM_DIR_UP;
839 	}
840 	if (bm->control.down != 0) {
841 		printf("Sequence down: include page");
842 		seq = BM_DIR_DOWN;
843 	}
844 	if (bm->control.updown != 0) {
845 		printf("Sequence updown: include page");
846 		seq = BM_DIR_UPDOWN;
847 	}
848 	if (bm->control.rand != 0) {
849 		printf("Sequence rand: include page");
850 		seq = BM_DIR_RAND;
851 	}
852 
853 	if (bm->control.active[0] != 0) {
854 		printf(" A");
855 		inc |= BM_INC_A;
856 	}
857 	if (bm->control.active[1] != 0) {
858 		printf(" B");
859 		inc |= BM_INC_B;
860 	}
861 	if (bm->control.active[2] != 0) {
862 		printf(" C");
863 		inc |= BM_INC_C;
864 	}
865 	if (bm->control.active[3] != 0) {
866 		printf(" D");
867 		inc |= BM_INC_D;
868 	}
869 
870 	brightonFastTimer(0, 0, 0, BRIGHTON_FT_CANCEL, 0);
871 
872 	if (bm->control.up != 0) {
873 		/* Stuff the straight sequence */
874 		if (bm->control.active[0] != 0)
875 			bmStuffPage(synth, 0, BM_DIR_UP);
876 		if (bm->control.active[1] != 0)
877 			bmStuffPage(synth, 1, BM_DIR_UP);
878 		if (bm->control.active[2] != 0)
879 			bmStuffPage(synth, 2, BM_DIR_UP);
880 		if (bm->control.active[3] != 0)
881 			bmStuffPage(synth, 3, BM_DIR_UP);
882 	} else if (bm->control.down != 0) {
883 		if (bm->control.active[0] != 0)
884 			bmStuffPage(synth, 0, BM_DIR_DOWN);
885 		if (bm->control.active[1] != 0)
886 			bmStuffPage(synth, 1, BM_DIR_DOWN);
887 		if (bm->control.active[2] != 0)
888 			bmStuffPage(synth, 2, BM_DIR_DOWN);
889 		if (bm->control.active[3] != 0)
890 			bmStuffPage(synth, 3, BM_DIR_DOWN);
891 	} else if (bm->control.updown != 0) {
892 		if (bm->control.active[0] != 0)
893 			bmStuffPage(synth, 0, BM_DIR_UP);
894 		if (bm->control.active[1] != 0)
895 			bmStuffPage(synth, 1, BM_DIR_UP);
896 		if (bm->control.active[2] != 0)
897 			bmStuffPage(synth, 2, BM_DIR_UP);
898 		if (bm->control.active[3] != 0)
899 			bmStuffPage(synth, 3, BM_DIR_UP);
900 		if (bm->control.active[3] != 0)
901 			bmStuffPage(synth, 3, BM_DIR_DOWN);
902 		if (bm->control.active[2] != 0)
903 			bmStuffPage(synth, 2, BM_DIR_DOWN);
904 		if (bm->control.active[1] != 0)
905 			bmStuffPage(synth, 1, BM_DIR_DOWN);
906 		if (bm->control.active[0] != 0)
907 			bmStuffPage(synth, 0, BM_DIR_DOWN);
908 	} else if (bm->control.rand != 0) {
909 		/*
910 		 * Choose a random page, then request a random order of the notes.
911 		 */
912 		bmStuffPage(synth, rand() & 0x03, BM_DIR_RAND);
913 		bmStuffPage(synth, rand() & 0x03, BM_DIR_RAND);
914 		bmStuffPage(synth, rand() & 0x03, BM_DIR_RAND);
915 		bmStuffPage(synth, rand() & 0x03, BM_DIR_RAND);
916 	}
917 
918 	printf("\n");
919 
920 	if (bm->control.start != 0)
921 		brightonFastTimer(0, 0, 0, BRIGHTON_FT_START, 0);
922 }
923 
924 static int rmi = 0;
925 
926 static int
bmMemory(guiSynth * synth,int fd,int chan,int c,int o,int v)927 bmMemory(guiSynth *synth, int fd, int chan, int c, int o, int v)
928 {
929 	printf("bmMemory(%i %i %i %i %i)\n", fd, chan, c, o, v);
930 
931 	if (synth->flags & MEM_LOADING)
932 		return(0);
933 	if ((synth->flags & OPERATIONAL) == 0)
934 		return(0);
935 
936 	/*
937 	 * We have 12 buttons, 0..9, load, save.
938 	 */
939 	switch (c) {
940 		case 0:
941 		case 1:
942 		case 2:
943 		case 3:
944 		case 4:
945 		case 5:
946 		case 6:
947 		case 7:
948 		case 8:
949 		case 9:
950 			if (rmi) {
951 				rmi = 0;
952 				synth->location = c;
953 			} else if ((synth->location = synth->location * 10 + c) >= 1000)
954 				synth->location = c;
955 			displayPanelText(synth, "MEM", synth->location, 4, DISPLAY_DEV);
956 			break;
957 		case 10:
958 			/*
959 			 * We have to send a notes off before reloading a sequence otherwise
960 			 * we might leave notes dangling.
961 			 */
962 			bristolMidiSendMsg(fd, synth->sid, 127, 0, BRISTOL_ALL_NOTES_OFF);
963 			if (loadMemory(synth, "bassmaker", 0, synth->location,
964 				synth->mem.active, 0, BRISTOL_FORCE) < 0)
965 				displayPanelText(synth, "FREE", synth->location, 4,DISPLAY_DEV);
966 			else
967 				displayPanelText(synth, "LOAD", synth->location, 4,DISPLAY_DEV);
968 			bmStuffCallbacks(synth);
969 			bmMemShim(synth);
970 			rmi = 1;
971 			break;
972 		case 11:
973 			if (brightonDoubleClick(dc)) {
974 				displayPanelText(synth, "SAVE", synth->location, 4,DISPLAY_DEV);
975 				saveMemory(synth, "bassmaker", 0, synth->location, 0);
976 				rmi = 1;
977 			}
978 			break;
979 	}
980 
981 	return(0);
982 }
983 
984 /*
985  * For the sake of ease of use, links have been placed here to be called
986  * by any of the devices created. They would be better in some other file,
987  * perhaps with this as a dispatch.
988  *
989  * Param refers to the device index in the locations table given below.
990  */
991 static int
bmCallback(brightonWindow * win,int panel,int index,float value)992 bmCallback(brightonWindow * win, int panel, int index, float value)
993 {
994 	guiSynth *synth = findSynth(global.synths, win);
995 	int sendvalue;
996 
997 //printf("bmCallback(%i, %i, %f) %x\n", panel, index, value, synth);
998 
999 	if (synth == 0)
1000 		return(0);
1001 
1002 	switch (panel) {
1003 		case 1:
1004 			index += TOTAL_DEVS;
1005 			break;
1006 		case 2:
1007 			index += TOTAL_DEVS * 2;
1008 			break;
1009 		case 3:
1010 			index += TOTAL_DEVS * 3;
1011 			break;
1012 		case 4:
1013 			index += TOTAL_DEVS * 4;
1014 			break;
1015 	}
1016 
1017 	if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0))
1018 		return(0);
1019 
1020 	if (bmApp.resources[panel].devlocn[index].to == 1.0)
1021 		sendvalue = value * (CONTROLLER_RANGE - 1);
1022 	else
1023 		sendvalue = value;
1024 
1025 	synth->mem.param[index] = value;
1026 
1027 /*	if ((!global.libtest) || (index >= ACTIVE_DEVS)) */
1028 //	if ((!global.libtest) || (index >= 40))
1029 		synth->dispatch[index].routine(synth,
1030 			global.controlfd, synth->sid,
1031 			synth->dispatch[index].controller,
1032 			synth->dispatch[index].operator,
1033 			sendvalue);
1034 /*
1035 //	else
1036 		printf("dispatch[%p,%i](%i, %i, %i, %i, %i)\n", synth, index,
1037 			global.controlfd, synth->sid,
1038 			synth->dispatch[index].controller,
1039 			synth->dispatch[index].operator,
1040 			sendvalue);
1041 //
1042 */
1043 	return(0);
1044 }
1045 
1046 static void
bmPanelSwitch(guiSynth * synth,int fd,int chan,int c,int o,int v)1047 bmPanelSwitch(guiSynth *synth, int fd, int chan, int c, int o, int v)
1048 {
1049 	brightonEvent event;
1050 	bmMem *bm = (bmMem *) synth->mem.param;
1051 
1052 	event.type = BRIGHTON_FLOAT;
1053 	event.value = BRIGHTON_LED_OFF;
1054 	brightonParamChange(synth->win, 4, 24, &event);
1055 	brightonParamChange(synth->win, 4, 25, &event);
1056 	brightonParamChange(synth->win, 4, 26, &event);
1057 	brightonParamChange(synth->win, 4, 27, &event);
1058 
1059 	event.type = BRIGHTON_EXPOSE;
1060 	event.intvalue = 0;
1061 	brightonParamChange(synth->win, 0, -1, &event);
1062 //	event.type = BRIGHTON_EXPOSE;
1063 //	event.intvalue = 0;
1064 	brightonParamChange(synth->win, 1, -1, &event);
1065 //	event.type = BRIGHTON_EXPOSE;
1066 //	event.intvalue = 0;
1067 	brightonParamChange(synth->win, 2, -1, &event);
1068 //	event.type = BRIGHTON_EXPOSE;
1069 //	event.intvalue = 0;
1070 	brightonParamChange(synth->win, 3, -1, &event);
1071 
1072 	event.type = BRIGHTON_FLOAT;
1073 	event.value = BRIGHTON_LED_YELLOW_FLASHING;
1074 	brightonParamChange(synth->win, 4, 24+c, &event);
1075 
1076 	event.type = BRIGHTON_EXPOSE;
1077 	event.intvalue = 1;
1078 	brightonParamChange(synth->win, c, -1, &event);
1079 
1080 	switch (c) {
1081 		case 0:
1082 			displayPanelText(synth, "panel A", c + 1, 4, DISPLAY_DEV);
1083 			bm->pageSelect = 0;
1084 			break;
1085 		case 1:
1086 			displayPanelText(synth, "panel B", c + 1, 4, DISPLAY_DEV);
1087 			bm->pageSelect = 1;
1088 			break;
1089 		case 2:
1090 			displayPanelText(synth, "panel C", c + 1, 4, DISPLAY_DEV);
1091 			bm->pageSelect = 2;
1092 			break;
1093 		case 3:
1094 			displayPanelText(synth, "panel D", c + 1, 4, DISPLAY_DEV);
1095 			bm->pageSelect = 3;
1096 			break;
1097 	}
1098 }
1099 
1100 static void
bmSendControl(guiSynth * synth,bmMem * bm,int c,int o)1101 bmSendControl(guiSynth *synth, bmMem *bm, int c, int o)
1102 {
1103 	/*
1104 	 * Control can have various possibilities ranging from a basic controller
1105 	 * change to note events and targetted device events.
1106 	 */
1107 	switch ((int) bm->control.ctype) {
1108 		case BM_C_CONTROL:
1109 			/*
1110 			 * Because of the way control.cc is implemented, this is actually
1111 			 * the second MIDI channel: this gives access to the first 15 CC
1112 			 */
1113 			bristolMidiSendMsg(global.controlfd, synth->midichannel, 0,
1114 				bm->control.cc, (int)
1115 					(bm->page[c].step[o].cont * C_RANGE_MIN_1));
1116 			break;
1117 		case BM_C_NOTE:
1118 		{
1119 			int note, chan, velocity;
1120 
1121 			/*
1122 			 * Convert the setting into 12 steps, take cc to be midi channel
1123 			 * Channel is the 'cc' setting here.
1124 			 */
1125 			if ((chan = bm->control.cc) > 15)
1126 				chan = 15;
1127 			note = (int) (bm->page[c].step[o].cont * 12);
1128 			velocity = (int) (bm->page[c].step[o].velocity * 127);
1129 
1130 			note += synth->transpose
1131 				+ bm->page[c].step[o].transp * 12;
1132 
1133 			bristolMidiSendKeyMsg(global.controlfd, chan,
1134 				BRISTOL_EVENT_KEYOFF, bm->lastcnote, velocity);
1135 			bristolMidiSendKeyMsg(global.controlfd, chan,
1136 				BRISTOL_EVENT_KEYON, note, velocity);
1137 
1138 			bm->lastcnote = note;
1139 
1140 			break;
1141 		}
1142 		case BM_C_GLIDE:
1143 			/*
1144 			 * This is 126/0 for most emulators and that may need to be
1145 			 * enforced later.
1146 			 */
1147 			bristolMidiSendMsg(global.controlfd, synth->sid, 126, 0,
1148 				(int) (bm->page[c].step[o].cont * C_RANGE_MIN_1));
1149 			break;
1150 		case BM_C_TUNE:
1151 			/*
1152 			 * This is 126/1 for most emulators and that may need to be
1153 			 * enforced later.
1154 			 */
1155 			bristolMidiSendMsg(global.controlfd, synth->sid, 126, 1,
1156 				(int) (bm->page[c].step[o].cont * C_RANGE_MIN_1));
1157 			break;
1158 		case BM_C_MOD:
1159 			/*
1160 			 * This is CC #1 for most emulators and that may need to be
1161 			 * enforced later.
1162 			 */
1163 			bristolMidiSendMsg(global.controlfd, synth->midichannel, 0,
1164 				1, (int) (bm->page[c].step[o].cont * C_RANGE_MIN_1));
1165 			break;
1166 		case BM_C_OPERATOR:
1167 			/*
1168 			 * cop = operator, 126 will be typical use.
1169 			 * cc = controller of operator
1170 			 */
1171 			break;
1172 	}
1173 }
1174 
1175 static void
bmCallNote(guiSynth * synth,int fd,int chan,int c,int o,int v)1176 bmCallNote(guiSynth *synth, int fd, int chan, int c, int o, int v)
1177 {
1178 	bmMem *bm = (bmMem *) synth->mem.param;
1179 	int note = bm->page[c].step[o].note + synth->transpose
1180 		+ bm->page[c].step[o].transp * 12;
1181 	int velocity = (int) (bm->page[c].step[o].velocity * 127);
1182 //printf("bmCallNote(%i, %i, %i)\n", c, o, v);
1183 	/*
1184 	 * If we are stopped then send the note, otherwise do nothing
1185 	 */
1186 	if (bm->control.stop != 0) {
1187 		bristolMidiSendKeyMsg(global.controlfd, synth->midichannel,
1188 			BRISTOL_EVENT_KEYOFF, bm->lastnote, velocity);
1189 		bmSendControl(synth, bm, c, o);
1190 		bristolMidiSendKeyMsg(global.controlfd, synth->midichannel,
1191 			BRISTOL_EVENT_KEYON, note, velocity);
1192 	}
1193 	bm->lastnote = note;
1194 	bm->lastpage = c;
1195 	bm->laststep = o;
1196 }
1197 
1198 static void
bmCallTranspose(guiSynth * synth,int fd,int chan,int c,int o,int v)1199 bmCallTranspose(guiSynth *synth, int fd, int chan, int c, int o, int v)
1200 {
1201 	bmMem *bm = (bmMem *) synth->mem.param;
1202 	int note = bm->page[c].step[o].note + synth->transpose
1203 		+ bm->page[c].step[o].transp * 12;
1204 	int velocity = (int) (bm->page[c].step[o].velocity * 127);
1205 	/*
1206 	 * If we are stopped then send the note, otherwise do nothing
1207 	 */
1208 	if (bm->control.stop != 0) {
1209 		bristolMidiSendKeyMsg(global.controlfd, synth->midichannel,
1210 			BRISTOL_EVENT_KEYOFF, bm->lastnote, velocity);
1211 		bmSendControl(synth, bm, c, o);
1212 		bristolMidiSendKeyMsg(global.controlfd, synth->midichannel,
1213 			BRISTOL_EVENT_KEYON, note, velocity);
1214 	}
1215 	bm->lastnote = note;
1216 	bm->lastpage = c;
1217 	bm->laststep = o;
1218 //printf("bmCallTranspose(%i, %i, %i)\n", c, o, v);
1219 }
1220 
1221 static void
bmCallVolume(guiSynth * synth,int fd,int chan,int c,int o,int v)1222 bmCallVolume(guiSynth *synth, int fd, int chan, int c, int o, int v)
1223 {
1224 	bmMem *bm = (bmMem *) synth->mem.param;
1225 	int note = bm->page[c].step[o].note + synth->transpose
1226 		+ bm->page[c].step[o].transp * 12;
1227 	int velocity = (int) (bm->page[c].step[o].velocity * 127);
1228 	/*
1229 	 * If we are stopped then send the note, otherwise do nothing
1230 	 */
1231 	if (bm->control.stop != 0) {
1232 		bristolMidiSendKeyMsg(global.controlfd, synth->midichannel,
1233 			BRISTOL_EVENT_KEYOFF, bm->lastnote, velocity);
1234 		bmSendControl(synth, bm, c, o);
1235 		bristolMidiSendKeyMsg(global.controlfd, synth->midichannel,
1236 			BRISTOL_EVENT_KEYON, note, velocity);
1237 	}
1238 	bm->lastnote = note;
1239 	bm->lastpage = c;
1240 	bm->laststep = o;
1241 //printf("bmCallVolume(%i, %i, %i)\n", c, o, v);
1242 }
1243 
1244 static void
bmCallController(guiSynth * synth,int fd,int chan,int c,int o,int v)1245 bmCallController(guiSynth *synth, int fd, int chan, int c, int o, int v)
1246 {
1247 	/*
1248 	 * If we are stopped then send the controller, otherwise do nothing
1249 	 */
1250 //printf("bmCallController(%i, %i, %i)\n", c, o, v);
1251 }
1252 
1253 static void
bmCallLed(guiSynth * synth,int fd,int chan,int c,int o,int v)1254 bmCallLed(guiSynth *synth, int fd, int chan, int c, int o, int v)
1255 {
1256 	bmMem *bm = (bmMem *) synth->mem.param;
1257 	int note;
1258 	int velocity;
1259 
1260 	/*
1261 	 * If we are playing then send the note on/off + control. Depending on the
1262 	 * configured LED state we may skip the note, skip the note off event, etc.
1263 	 */
1264 //synth->mem.param[c * TOTAL_DEVS + o * OP_COUNT + 5]);
1265 
1266 	note = bm->page[c].step[o].note + synth->transpose
1267 		+ bm->page[c].step[o].transp * 12;
1268 	velocity = (int) (bm->page[c].step[o].velocity * 127);
1269 
1270 //printf("bmCallLed(%i, %i, %i) note %i, v %i \n", c, o, v, note, velocity);
1271 
1272 	switch ((int) bm->page[c].step[o].button) {
1273 		case 0:
1274 		default:
1275 			/* Send note on/off according to value */
1276 			if (v)
1277 			{
1278 				bmSendControl(synth, bm, c, o);
1279 				bristolMidiSendKeyMsg(global.controlfd, synth->midichannel,
1280 					BRISTOL_EVENT_KEYON, note, velocity);
1281 			} else
1282 				bristolMidiSendKeyMsg(global.controlfd, synth->midichannel,
1283 					BRISTOL_EVENT_KEYOFF, note, velocity);
1284 			break;
1285 		case 1:
1286 			/* Dont' send note off */
1287 			if (v)
1288 				{
1289 					bmSendControl(synth, bm, c, o);
1290 					bristolMidiSendKeyMsg(global.controlfd, synth->midichannel,
1291 						BRISTOL_EVENT_KEYON, note, velocity);
1292 				}
1293 			break;
1294 		case 2:
1295 			/* Dont' send note on, only off */
1296 			bristolMidiSendKeyMsg(global.controlfd, synth->midichannel,
1297 				BRISTOL_EVENT_KEYOFF, note, velocity);
1298 			return;
1299 		case 3:
1300 			/*
1301 			 * all notes off? Nothing?
1302 			bristolMidiSendMsg(fd, synth->sid, 127, 0, BRISTOL_ALL_NOTES_OFF);
1303 			 */
1304 			return;
1305 	}
1306 	bm->lastnote = note;
1307 	bm->lastpage = c;
1308 	bm->laststep = o;
1309 }
1310 
1311 static void
bmCallButton(guiSynth * synth,int fd,int chan,int c,int o,int v)1312 bmCallButton(guiSynth *synth, int fd, int chan, int c, int o, int v)
1313 {
1314 	brightonEvent event;
1315 
1316 	printf("bmCallButton(%i, %i, %i)\n", c, o, c * TOTAL_DEVS + 0);
1317 
1318 	event.type = BRIGHTON_FLOAT;
1319 
1320 	if (++synth->mem.param[c * TOTAL_DEVS + o * OP_COUNT + 4] > 3)
1321 		synth->mem.param[c * TOTAL_DEVS + o * OP_COUNT + 4] = 0;
1322 
1323 	event.value = synth->mem.param[c * TOTAL_DEVS + o * OP_COUNT + 4];
1324 
1325 	brightonParamChange(synth->win, c, o * OP_COUNT + 4, &event);
1326 
1327 	synth->mem.param[c * TOTAL_DEVS + o * OP_COUNT + 5]
1328 		= synth->mem.param[c * TOTAL_DEVS + o * OP_COUNT + 4];
1329 }
1330 
1331 static void
bmCallPad1(guiSynth * synth,int fd,int chan,int c,int o,int v)1332 bmCallPad1(guiSynth *synth, int fd, int chan, int c, int o, int v)
1333 {
1334 }
1335 
1336 static void
bmCallPad2(guiSynth * synth,int fd,int chan,int c,int o,int v)1337 bmCallPad2(guiSynth *synth, int fd, int chan, int c, int o, int v)
1338 {
1339 }
1340 
1341 static void
bmSpeed(guiSynth * synth,int fd,int chan,int c,int o,int v)1342 bmSpeed(guiSynth *synth, int fd, int chan, int c, int o, int v)
1343 {
1344 	/*
1345 	 * We need to stuff both speed and duty cycle
1346 	printf("speed %f, duty %f\n",
1347 		10 + synth->mem.param[COFF + 0] * synth->mem.param[COFF + 0] * 990,
1348 		(10 + synth->mem.param[COFF + 0] * synth->mem.param[COFF + 0] * 990) *
1349 			synth->mem.param[COFF + 1]);
1350 	 */
1351 
1352 	/*
1353 	 * Speed should go from 10 to 1000ms? Can change that later.
1354 	 */
1355 	brightonFastTimer(0, 0, 0, BRIGHTON_FT_TICKTIME,
1356 		10 + synth->mem.param[COFF + 0] * synth->mem.param[COFF + 0] * 990);
1357 	brightonFastTimer(0, 0, 0, BRIGHTON_FT_DUTYCYCLE,
1358 		(10 + synth->mem.param[COFF + 0] * synth->mem.param[COFF + 0] * 990)
1359 			* synth->mem.param[COFF + 1]);
1360 }
1361 
1362 static int ssEx = 0;
1363 
1364 static void
bmDirection(guiSynth * synth,int fd,int chan,int c,int o,int v)1365 bmDirection(guiSynth *synth, int fd, int chan, int c, int o, int v)
1366 {
1367 	brightonEvent event;
1368 
1369 	if (v ==0)
1370 		return;
1371 
1372 	/*
1373 	 * Clear all the LED, light this one, stuff the callback table
1374 	 */
1375 	event.type = BRIGHTON_FLOAT;
1376 	event.value = BRIGHTON_LED_OFF;
1377 	brightonParamChange(synth->win, 4, 28, &event);
1378 	brightonParamChange(synth->win, 4, 29, &event);
1379 	brightonParamChange(synth->win, 4, 30, &event);
1380 	brightonParamChange(synth->win, 4, 31, &event);
1381 
1382 	switch (c) {
1383 		case 0:
1384 			synth->mem.param[COFF + 3] = synth->mem.param[COFF + 4]
1385 				= synth->mem.param[COFF + 5] = 0;
1386 			break;
1387 		case 1:
1388 			synth->mem.param[COFF + 2] = synth->mem.param[COFF + 4]
1389 				= synth->mem.param[COFF + 5] = 0;
1390 			break;
1391 		case 2:
1392 			synth->mem.param[COFF + 2] = synth->mem.param[COFF + 3]
1393 				= synth->mem.param[COFF + 5] = 0;
1394 			break;
1395 		case 3:
1396 			synth->mem.param[COFF + 2] = synth->mem.param[COFF + 3]
1397 				= synth->mem.param[COFF + 4] = 0;
1398 			break;
1399 	}
1400 
1401 	event.value = BRIGHTON_LED_GREEN;
1402 	brightonParamChange(synth->win, 4, 28 + c, &event);
1403 
1404 	bmStuffCallbacks(synth);
1405 }
1406 
1407 /*
1408  *	Controller options
1409  *		Controller to mod wheel
1410  *		Controller to tune
1411  *		Controller to pitchwheel
1412  *		Controller to note (13 steps) + channel
1413  *		Controller to other continuous controller
1414  *		Controller to operator parameter (later)
1415  *	Copy page
1416  *	Save
1417  *	Load
1418  */
1419 
1420 static void
bmCopyPage(guiSynth * synth,int fd,int chan,bmMem * bm,int from,int to)1421 bmCopyPage(guiSynth *synth, int fd, int chan, bmMem *bm, int from, int to)
1422 {
1423 	int i;
1424 	brightonEvent event;
1425 
1426 	if (from == to)
1427 		return;
1428 
1429 	event.type = BRIGHTON_FLOAT;
1430 	for (i = 0; i < PAGE_STEP; i++)
1431 	{
1432 		event.value = bm->page[from].step[i].note;
1433 		brightonParamChange(synth->win, to, i * OP_COUNT + 0, &event);
1434 		event.value = bm->page[from].step[i].transp;
1435 		brightonParamChange(synth->win, to, i * OP_COUNT + 1, &event);
1436 		event.value = bm->page[from].step[i].velocity;
1437 		brightonParamChange(synth->win, to, i * OP_COUNT + 2, &event);
1438 		event.value = bm->page[from].step[i].cont;
1439 		brightonParamChange(synth->win, to, i * OP_COUNT + 3, &event);
1440 		event.value = bm->page[from].step[i].led;
1441 		brightonParamChange(synth->win, to, i * OP_COUNT + 4, &event);
1442 	}
1443 }
1444 
1445 static char * copyMenu[5] = {
1446 	"copy to A",
1447 	"copy to B",
1448 	"copy to C",
1449 	"copy to D",
1450 	0
1451 };
1452 
1453 static char * ctlMenu[6] = {
1454 	"CTL CC",
1455 	"CTL NOTE",
1456 	"CTL TUNE",
1457 	"CTL Glide",
1458 	"CTL MOD",
1459 	0
1460 };
1461 
1462 static char *transpMenu[26] = {
1463 	"-12 Semitones",
1464 	"-11 Semitones",
1465 	"-10 Semitones",
1466 	"-9 Semitones",
1467 	"-8 Semitones",
1468 	"-7 Semitones",
1469 	"-6 Semitones",
1470 	"-5 Semitones",
1471 	"-4 Semitones",
1472 	"-3 Semitones",
1473 	"-2 Semitones",
1474 	"-1 Semitone",
1475 	"0 Semitones",
1476 	"+1 Semitone",
1477 	"+2 Semitones",
1478 	"+3 Semitones",
1479 	"+4 Semitones",
1480 	"+5 Semitones",
1481 	"+6 Semitones",
1482 	"+7 Semitones",
1483 	"+8 Semitones",
1484 	"+9 Semitones",
1485 	"+10 Semitones",
1486 	"+11 Semitones",
1487 	"+12 Semitones",
1488 	0
1489 };
1490 
1491 static char *midiChan[17] = {
1492 	"MIDI CH 1", /* Bass channel selection. These should be submenu */
1493 	"MIDI CH 2",
1494 	"MIDI CH 3",
1495 	"MIDI CH 4",
1496 	"MIDI CH 5",
1497 	"MIDI CH 6",
1498 	"MIDI CH 7",
1499 	"MIDI CH 8",
1500 	"MIDI CH 9",
1501 	"MIDI CH 10",
1502 	"MIDI CH 11",
1503 	"MIDI CH 12",
1504 	"MIDI CH 13",
1505 	"MIDI CH 14",
1506 	"MIDI CH 15",
1507 	"MIDI CH 16",
1508 	0
1509 };
1510 
1511 static char *clearMenu[6] = {
1512 	"Clear Note",
1513 	"Clear Tranpose",
1514 	"Clear Volume",
1515 	"Clear Cont",
1516 	"Clear Trigger",
1517 	0
1518 };
1519 
1520 static char *memMenu[4] = {
1521 	"Find Up",
1522 	"Mem Down",
1523 	"Mem Up",
1524 	0
1525 };
1526 
1527 typedef struct bMenuList {
1528 	char *title;
1529 	int count;
1530 	char **content;
1531 } bMenuList;
1532 
1533 #define B_M_C 7
1534 
1535 typedef struct BMenu {
1536 	bMenuList item[B_M_C];
1537 	int count;
1538 	int current;
1539 	int sub;
1540 } bMenu;
1541 
1542 bMenu mainMenu = {
1543 	{
1544 		{"Memory", 3, memMenu},
1545 		{"Copy", 4, copyMenu},
1546 		{"Controllers", 5, ctlMenu},
1547 		{"First MIDI", 16, midiChan},
1548 		{"Second MIDI", 16, midiChan},
1549 		{"Clear", 5, clearMenu},
1550 		{"Transpose", 25, transpMenu},
1551 	},
1552 	B_M_C, 0, -1
1553 };
1554 
1555 static void
bmMultiMenuMove(guiSynth * synth,int fd,int chan,int c,int o,int v)1556 bmMultiMenuMove(guiSynth *synth, int fd, int chan, int c, int o, int v)
1557 {
1558 	/*
1559 	 * We could be in the main menu or a submenu, need to check the submenu
1560 	 * setting then move through the text strings.
1561 	 */
1562 	if (mainMenu.sub == -1) {
1563 		/*
1564 		 * Main menu
1565 		 */
1566 		if (v == 0)
1567 		{
1568 			if (--mainMenu.current < 0)
1569 				mainMenu.current = mainMenu.count - 1;
1570 
1571 			displayPanel(synth, mainMenu.item[mainMenu.current].title,
1572 				synth->location, 4, DISPLAY_DEV);
1573 		} else {
1574 			if (++mainMenu.current >= mainMenu.count)
1575 				mainMenu.current = 0;
1576 
1577 			displayPanel(synth, mainMenu.item[mainMenu.current].title,
1578 				synth->location, 4, DISPLAY_DEV);
1579 		}
1580 	} else {
1581 		/*
1582 		 * Sub menu
1583 		 */
1584 		if (v == 0)
1585 		{
1586 			if (--mainMenu.sub < 0)
1587 				mainMenu.sub = mainMenu.item[mainMenu.current].count - 1;
1588 
1589 			displayPanel(synth,
1590 				mainMenu.item[mainMenu.current].content[mainMenu.sub],
1591 				synth->location, 4, DISPLAY_DEV);
1592 		} else {
1593 			if (++mainMenu.sub >= mainMenu.item[mainMenu.current].count)
1594 				mainMenu.sub = 0;
1595 
1596 			displayPanel(synth,
1597 				mainMenu.item[mainMenu.current].content[mainMenu.sub],
1598 				synth->location, 4, DISPLAY_DEV);
1599 		}
1600 	}
1601 }
1602 
1603 static void
bmMenuFunction(guiSynth * synth,int fd,int chan,int c,int o,int v)1604 bmMenuFunction(guiSynth *synth, int fd, int chan, int c, int o, int v)
1605 {
1606 	/*
1607 	 * For now just return to start of main menu
1608 	 */
1609 	mainMenu.sub = -1;
1610 
1611 	displayPanel(synth, mainMenu.item[mainMenu.current].title,
1612 		synth->location, 4, DISPLAY_DEV);
1613 }
1614 
1615 static void
bmMultiMenuEnter(guiSynth * synth,int fd,int chan,int c,int o,int v)1616 bmMultiMenuEnter(guiSynth *synth, int fd, int chan, int c, int o, int v)
1617 {
1618 	bmMem *bm = (bmMem *) synth->mem.param;
1619 
1620 	/*
1621 	 * Execute the desired function and save to a memory dummy location if
1622 	 * necessary (controller functions).
1623 	 */
1624 	if (mainMenu.sub < 0)
1625 	{
1626 		/*
1627 		 * We should preload a value here which is the current selected value
1628 		 */
1629 		switch (mainMenu.current)
1630 		{
1631 			case 3:
1632 				mainMenu.sub = synth->midichannel;
1633 				break;
1634 			case 4:
1635 				mainMenu.sub = bm->control.cc;
1636 				break;
1637 			case 6:
1638 				mainMenu.sub = synth->transpose + 12;
1639 				break;
1640 			default:
1641 				mainMenu.sub = 0;
1642 				break;
1643 		}
1644 
1645 		displayPanel(synth,
1646 			mainMenu.item[mainMenu.current].content[mainMenu.sub],
1647 			synth->location, 4, DISPLAY_DEV);
1648 		return;
1649 	}
1650 
1651 	switch (mainMenu.current) {
1652 		case 0:
1653 			/* Memory */
1654 			switch (mainMenu.sub) {
1655 				case 2:
1656 				{
1657 					/* Mem Up */
1658 					int location = synth->location;
1659 
1660 					while (loadMemory(synth, "bassmaker", 0, ++location,
1661 						synth->mem.active, 0, BRISTOL_STAT) < 0)
1662 					{
1663 						if (location == synth->location)
1664 							break;
1665 						if (location == 1023)
1666 							location = -1;
1667 					}
1668 					synth->location = location;
1669 					displayPanelText(synth, "Mem", synth->location,
1670 						4, DISPLAY_DEV);
1671 					break;
1672 				}
1673 				case 1:
1674 				{
1675 					/* Mem Down */
1676 					int location;
1677 
1678 					if ((location = synth->location) == 0)
1679 						location = 1024;
1680 
1681 					while (loadMemory(synth, "bassmaker", 0, --location,
1682 						synth->mem.active, 0, BRISTOL_STAT) < 0)
1683 					{
1684 						if (location == synth->location)
1685 							break;
1686 						if (location == 0)
1687 							location = 1024;
1688 					}
1689 					synth->location = location;
1690 					displayPanelText(synth, "Mem", synth->location,
1691 						4, DISPLAY_DEV);
1692 					break;
1693 				}
1694 				case 0:
1695 				{
1696 					/* Mem Find Up */
1697 					int location = synth->location;
1698 
1699 					while (loadMemory(synth, "bassmaker", 0, ++location,
1700 						synth->mem.active, 0, BRISTOL_STAT) >= 0)
1701 					{
1702 						if (location == synth->location)
1703 							break;
1704 						if (location == 1023)
1705 							location = 0;
1706 					}
1707 					synth->location = location;
1708 					displayPanelText(synth, "Free", synth->location,
1709 						4, DISPLAY_DEV);
1710 					break;
1711 				}
1712 			}
1713 			break;
1714 		case 1:
1715 			/* Copy */
1716 			switch (mainMenu.sub) {
1717 				case 0:
1718 					/* Copy page */
1719 					bmCopyPage(synth, fd, chan, bm, bm->pageSelect, 0);
1720 					break;
1721 				case 1:
1722 					/* Copy page */
1723 					bmCopyPage(synth, fd, chan, bm, bm->pageSelect, 1);
1724 					break;
1725 				case 2:
1726 					/* Copy page */
1727 					bmCopyPage(synth, fd, chan, bm, bm->pageSelect, 2);
1728 					break;
1729 				case 3:
1730 					/* Copy page */
1731 					bmCopyPage(synth, fd, chan, bm, bm->pageSelect, 3);
1732 					break;
1733 			}
1734 			break;
1735 		case 2:
1736 			/*
1737 			 * Controllers
1738 			 */
1739 			switch (mainMenu.sub) {
1740 				case 0:
1741 					/* CC */
1742 					bm->control.ctype = 11;
1743 					break;
1744 				case 1:
1745 					bm->control.ctype = -1;
1746 					break;
1747 				case 2:
1748 					/* Set control function Pitch */
1749 					bm->control.ctype = -2;
1750 					break;
1751 				case 3:
1752 					bm->control.ctype = -2;
1753 					break;
1754 				case 4:
1755 					bm->control.ctype = -4;
1756 					break;
1757 			}
1758 
1759 			break;
1760 		case 3:
1761 			/* Fist MIDI */
1762 			synth->midichannel = mainMenu.sub;
1763 			break;
1764 		case 4:
1765 			/* Second MIDI */
1766 			bm->control.cc = mainMenu.sub;
1767 			break;
1768 		case 5:
1769 			/* Clear Menu ops */
1770 			{
1771 				int i, page, offset;
1772 				brightonEvent event;
1773 
1774 				event.type = BRIGHTON_FLOAT;
1775 
1776 				page = bm->pageSelect;
1777 				offset = mainMenu.sub;
1778 
1779 				switch (offset)
1780 				{
1781 					case 0:
1782 					default:
1783 						event.value = 0;
1784 						break;
1785 					case 1:
1786 						event.value = 1.0;
1787 						break;
1788 					case 2:
1789 						event.value = 0.8;
1790 						break;
1791 					case 3:
1792 						event.value = 0.5;
1793 						break;
1794 				}
1795 
1796 				for (i = 0; i < PAGE_STEP; i++)
1797 				{
1798 					brightonParamChange(synth->win, page,
1799 						i * OP_COUNT + offset, &event);
1800 				}
1801 			}
1802 			break;
1803 		case 6:
1804 			/* Transpose */
1805 			bm->control.transpose = BM_TRANSPOSE + mainMenu.sub - 12;
1806 			synth->transpose = BM_TRANSPOSE + mainMenu.sub - 12;
1807 			break;
1808 	}
1809 }
1810 
1811 static void
bmMenu(guiSynth * synth,int fd,int chan,int c,int o,int v)1812 bmMenu(guiSynth *synth, int fd, int chan, int c, int o, int v)
1813 {
1814 	printf("bmMenu(%i, %i, %i)\n", c, o, v);
1815 
1816 	switch(c) {
1817 		case 0:
1818 			/* Up menu */
1819 			bmMultiMenuMove(synth, fd, chan, c, o, 1);
1820 			break;
1821 		case 1:
1822 			/* Down menu */
1823 			bmMultiMenuMove(synth, fd, chan, c, o, 0);
1824 			break;
1825 		case 2:
1826 			/* Function */
1827 			bmMenuFunction(synth, fd, chan, c, o, v);
1828 			break;
1829 		case 3:
1830 			/* Enter */
1831 			bmMultiMenuEnter(synth, fd, chan, c, o, v);
1832 			break;
1833 	}
1834 }
1835 
1836 static void
bmPageSelect(guiSynth * synth,int fd,int chan,int c,int o,int v)1837 bmPageSelect(guiSynth *synth, int fd, int chan, int c, int o, int v)
1838 {
1839 	brightonEvent event;
1840 
1841 	event.type = BRIGHTON_FLOAT;
1842 	if (v == 0)
1843 		event.value = BRIGHTON_LED_OFF;
1844 	else
1845 		event.value = BRIGHTON_LED_GREEN;
1846 	brightonParamChange(synth->win, 4, 20 + c, &event);
1847 
1848 	bmStuffCallbacks(synth);
1849 }
1850 
1851 static void
bmStartStop(guiSynth * synth,int fd,int chan,int c,int o,int v)1852 bmStartStop(guiSynth *synth, int fd, int chan, int c, int o, int v)
1853 {
1854 	brightonEvent event;
1855 	bmMem *bm = (bmMem *) synth->mem.param;
1856 
1857 	if (ssEx) {
1858 		ssEx = 0;
1859 		return;
1860 	}
1861 
1862 	event.type = BRIGHTON_FLOAT;
1863 
1864 	bristolMidiSendMsg(fd, synth->sid, 127, 0, BRISTOL_ALL_NOTES_OFF);
1865 
1866 	if (c == 1) {
1867 		/* Stop */
1868 		event.value = BRIGHTON_LED_OFF;
1869 		brightonParamChange(synth->win, 4, 46, &event);
1870 		event.value = BRIGHTON_LED_RED;
1871 		brightonParamChange(synth->win, 4, 47, &event);
1872 
1873 		((bmMem *) synth->mem.param)->lastnote = -1;;
1874 
1875 		brightonFastTimer(0, 0, 0, BRIGHTON_FT_STOP, 0);
1876 		/* And send a MIDI all notes off */
1877 		bristolMidiSendMsg(fd, synth->sid, 127, 0, BRISTOL_ALL_NOTES_OFF);
1878 
1879 		ssEx = 1;
1880 		event.value = 0.0;
1881 		brightonParamChange(synth->win, 4, 44, &event);
1882 		bm->clearstep = bm->laststep;
1883 		bm->laststep = 0;
1884 	} else {
1885 		/*
1886 		 * There are two cases here, first press and second press. First press
1887 		 * will start the sequence, second will pause the sequence.
1888 		 *
1889 		 * When it is first press we need to clock the first element in the
1890 		 * list.
1891 		 */
1892 		if (bm->clearstep >= 0)
1893 		{
1894 			event.value = BRIGHTON_LED_OFF;
1895 			brightonParamChange(synth->win, bm->lastpage,
1896 				4 + bm->clearstep * 8, &event);
1897 		}
1898 		bm->clearstep = -1;
1899 
1900 		/* Turn off Stop LED */
1901 		event.value = BRIGHTON_LED_OFF;
1902 		brightonParamChange(synth->win, 4, 47, &event);
1903 
1904 		if (synth->mem.param[COFF + 45] != 0) {
1905 			/* Stopped - toggle to green and run */
1906 			event.value = BRIGHTON_LED_GREEN;
1907 		} else {
1908 			/* If we were not stopped then were we running */
1909 			if (synth->mem.param[COFF + 44] != 0) {
1910 				event.value = BRIGHTON_LED_GREEN;
1911 			} else {
1912 				event.value = BRIGHTON_LED_YELLOW_FLASHING;
1913 			}
1914 		}
1915 		brightonParamChange(synth->win, 4, 46, &event);
1916 
1917 		brightonFastTimer(0, 0, 0, BRIGHTON_FT_START, 0);
1918 
1919 		event.command = BRIGHTON_FAST_TIMER;
1920 		event.value = 1;
1921 		brightonParamChange(synth->win, bm->lastpage,
1922 			4 + bm->laststep * 8, &event);
1923 
1924 		ssEx = 1;
1925 		event.value = 0.0;
1926 		brightonParamChange(synth->win, 4, 45, &event);
1927 	}
1928 }
1929 
1930 /*
1931  * Any location initialisation required to run the callbacks. For bristol, this
1932  * will connect to the engine, and give it some base parameters.
1933  * May need to generate some application specific menus.
1934  * Will also then make specific requests to some of the devices to alter their
1935  * rendering.
1936  */
1937 static int
bmInit(brightonWindow * win)1938 bmInit(brightonWindow *win)
1939 {
1940 	guiSynth *synth = findSynth(global.synths, win);
1941 	dispatcher *dispatch;
1942 	int i;
1943 
1944 	if (synth == 0)
1945 	{
1946 		synth = findSynth(global.synths, 0);
1947 		if (synth == 0)
1948 		{
1949 			printf("cannot init\n");
1950 			return(0);
1951 		}
1952 	}
1953 
1954 	call.control[0] = (synthRoutine) bmCallNote;
1955 	call.control[1] = (synthRoutine) bmCallTranspose;
1956 	call.control[2] = (synthRoutine) bmCallVolume;
1957 	call.control[3] = (synthRoutine) bmCallController;
1958 	call.control[4] = (synthRoutine) bmCallLed;
1959 	call.control[5] = (synthRoutine) bmCallButton;
1960 	call.control[6] = (synthRoutine) bmCallPad1;
1961 	call.control[7] = (synthRoutine) bmCallPad2;
1962 
1963 	synth->win = win;
1964 
1965 	printf("Initialise the bm link to bristol: %p\n", synth->win);
1966 
1967 	synth->mem.param = (float *) brightonmalloc(sizeof(bmMem));
1968 	synth->mem.count = sizeof(bmMem) / sizeof(float);
1969 	synth->mem.active = ACTIVE_DEVS;
1970 	synth->dispatch = (dispatcher *)
1971 		brightonmalloc(DEVICE_COUNT * sizeof(dispatcher));
1972 	dispatch = synth->dispatch;
1973 
1974 	/*
1975 	 * We really want to have three connection mechanisms. These should be
1976 	 *	1. Unix named sockets.
1977 	 *	2. UDP sockets.
1978 	 *	3. MIDI pipe.
1979 	 */
1980 	if (!global.libtest)
1981 		if ((synth->sid = initConnection(&global, synth)) < 0)
1982 			return(-1);
1983 
1984 	for (i = 0; i < DEVICE_COUNT; i++)
1985 		synth->dispatch[i].routine = bmMidiSendMsg;
1986 
1987 	for (i = 0; i < PAGE_STEP * PAGE_COUNT * OP_COUNT; i++)
1988 	{
1989 		/* Page */
1990 		synth->dispatch[i].controller = i / (PAGE_STEP * OP_COUNT);
1991 		/* Step */
1992 		synth->dispatch[i].operator = (i / OP_COUNT) % PAGE_STEP;
1993 		/* Control index */
1994 		synth->dispatch[i].routine = call.control[i % OP_COUNT];
1995 	}
1996 
1997 	/* Control Panel Speed/Duty */
1998 	synth->dispatch[COFF + 0].controller = 1;
1999 	synth->dispatch[COFF + 1].controller = 2;
2000 	synth->dispatch[COFF + 0].routine
2001 		= synth->dispatch[COFF + 1].routine
2002 			= (synthRoutine) bmSpeed;
2003 
2004 	/* Dir */
2005 	synth->dispatch[COFF + 2].controller = 0;
2006 	synth->dispatch[COFF + 3].controller = 1;
2007 	synth->dispatch[COFF + 4].controller = 2;
2008 	synth->dispatch[COFF + 5].controller = 3;
2009 	synth->dispatch[COFF + 2].routine
2010 		= synth->dispatch[COFF + 3].routine
2011 		= synth->dispatch[COFF + 4].routine
2012 		= synth->dispatch[COFF + 5].routine
2013 			= (synthRoutine) bmDirection;
2014 
2015 	/* Select/Include */
2016 	synth->dispatch[COFF + 6].controller = 0;
2017 	synth->dispatch[COFF + 7].controller = 1;
2018 	synth->dispatch[COFF + 8].controller = 2;
2019 	synth->dispatch[COFF + 9].controller = 3;
2020 	synth->dispatch[COFF + 6].routine
2021 		= synth->dispatch[COFF + 7].routine
2022 		= synth->dispatch[COFF + 8].routine
2023 		= synth->dispatch[COFF + 9].routine
2024 			= (synthRoutine) bmPageSelect;
2025 
2026 	/* Edit */
2027 	synth->dispatch[COFF + 10].controller = 0;
2028 	synth->dispatch[COFF + 11].controller = 1;
2029 	synth->dispatch[COFF + 12].controller = 2;
2030 	synth->dispatch[COFF + 13].controller = 3;
2031 	synth->dispatch[COFF + 10].routine
2032 		= synth->dispatch[COFF + 11].routine
2033 		= synth->dispatch[COFF + 12].routine
2034 		= synth->dispatch[COFF + 13].routine
2035 			= (synthRoutine) bmPanelSwitch;
2036 
2037 	synth->dispatch[COFF + 32].controller = 0;
2038 	synth->dispatch[COFF + 33].controller = 1;
2039 	synth->dispatch[COFF + 34].controller = 2;
2040 	synth->dispatch[COFF + 35].controller = 3;
2041 	synth->dispatch[COFF + 36].controller = 4;
2042 	synth->dispatch[COFF + 37].controller = 5;
2043 	synth->dispatch[COFF + 38].controller = 6;
2044 	synth->dispatch[COFF + 39].controller = 7;
2045 	synth->dispatch[COFF + 40].controller = 8;
2046 	synth->dispatch[COFF + 41].controller = 9;
2047 
2048 	synth->dispatch[COFF + 42].controller = 10;
2049 	synth->dispatch[COFF + 43].controller = 11;
2050 
2051 	/* Start/Stop */
2052 	synth->dispatch[COFF + 44].controller = 0;
2053 	synth->dispatch[COFF + 45].controller = 1;
2054 	synth->dispatch[COFF + 44].routine = synth->dispatch[COFF + 45].routine
2055 		= (synthRoutine) bmStartStop;
2056 
2057 	synth->dispatch[COFF + 32].routine
2058 		= synth->dispatch[COFF + 33].routine
2059 		= synth->dispatch[COFF + 34].routine
2060 		= synth->dispatch[COFF + 35].routine
2061 		= synth->dispatch[COFF + 36].routine
2062 		= synth->dispatch[COFF + 37].routine
2063 		= synth->dispatch[COFF + 38].routine
2064 		= synth->dispatch[COFF + 39].routine
2065 		= synth->dispatch[COFF + 40].routine
2066 		= synth->dispatch[COFF + 41].routine
2067 		= synth->dispatch[COFF + 42].routine
2068 		= synth->dispatch[COFF + 43].routine
2069 			= (synthRoutine) bmMemory;
2070 
2071 	synth->dispatch[COFF + 55].controller = 0;
2072 	synth->dispatch[COFF + 56].controller = 1;
2073 	synth->dispatch[COFF + 57].controller = 2;
2074 	synth->dispatch[COFF + 58].controller = 3;
2075 	synth->dispatch[COFF + 55].routine
2076 		= synth->dispatch[COFF + 56].routine
2077 		= synth->dispatch[COFF + 57].routine
2078 		= synth->dispatch[COFF + 58].routine
2079 			= (synthRoutine) bmMenu;
2080 
2081 	return(0);
2082 }
2083 
2084 /*
2085  * This will be called to make any routine specific parameters available.
2086  */
2087 static int
bmConfigure(brightonWindow * win)2088 bmConfigure(brightonWindow *win)
2089 {
2090 	guiSynth *synth = findSynth(global.synths, win);
2091 	brightonEvent event;
2092 
2093 	if (synth == 0)
2094 	{
2095 		printf("problems going operational\n");
2096 		return(-1);
2097 	}
2098 
2099 	if (synth->flags & OPERATIONAL)
2100 		return(0);
2101 
2102 	printf("going operational\n");
2103 
2104 	synth->flags |= OPERATIONAL;
2105 	synth->keypanel = 1;
2106 	synth->keypanel2 = -1;
2107 	synth->transpose = BM_TRANSPOSE;
2108 
2109 	brightonPut(win,
2110 		"bitmaps/blueprints/bmshade.xpm", 0, 0, win->width, win->height);
2111 
2112 	event.type = BRIGHTON_EXPOSE;
2113 	event.intvalue = 1;
2114 	brightonParamChange(synth->win, 1, -1, &event);
2115 	brightonParamChange(synth->win, 2, -1, &event);
2116 	brightonParamChange(synth->win, 3, -1, &event);
2117 	event.intvalue = 0;
2118 	brightonParamChange(synth->win, 1, -1, &event);
2119 	brightonParamChange(synth->win, 2, -1, &event);
2120 	brightonParamChange(synth->win, 3, -1, &event);
2121 	event.intvalue = 1;
2122 	brightonParamChange(synth->win, 0, -1, &event);
2123 
2124 	event.type = BRIGHTON_FLOAT;
2125 	event.value = BRIGHTON_LED_YELLOW_FLASHING;
2126 	brightonParamChange(synth->win, 4, 24, &event);
2127 	/* Stop button */
2128 	event.value = BRIGHTON_LED_RED;
2129 	brightonParamChange(synth->win, 4, 47, &event);
2130 	event.value = 1.0;
2131 	brightonParamChange(synth->win, 4, 45, &event);
2132 
2133 	event.type = BRIGHTON_INT;
2134 	event.intvalue = 1;
2135 	event.value = 1;
2136 	brightonParamChange(synth->win, 0, 4, &event);
2137 	event.value = 18;
2138 	brightonParamChange(synth->win, 0, 11, &event);
2139 	event.value = 3;
2140 	brightonParamChange(synth->win, 0, 18, &event);
2141 	event.value = 1;
2142 	brightonParamChange(synth->win, 0, 25, &event);
2143 
2144 	loadMemory(synth, "bassmaker", 0, synth->location, synth->mem.active, 0,
2145 		BRISTOL_FORCE);
2146 	bmStuffCallbacks(synth);
2147 	bmMemShim(synth);
2148 
2149 	displayPanel(synth, "BASSMAKER", synth->location, 4, DISPLAY_DEV);
2150 
2151 	dc = brightonGetDCTimer(win->dcTimeout);
2152 
2153 	return(0);
2154 }
2155 
2156