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 #include <fcntl.h>
24 
25 #include "brighton.h"
26 #include "brightonMini.h"
27 #include "brightoninternals.h"
28 
29 static int initmem;
30 
31 static int pro1Init();
32 static int pro1Configure();
33 static int pro1Callback(brightonWindow *, int, int, float);
34 /*static int keyCallback(void *, int, int, float); */
35 static int proOneKeyCallback(brightonWindow *, int, int, float);
36 /*static int modCallback(void *, int, int, float); */
37 static int midiCallback(brightonWindow *, int, int, float);
38 
39 extern guimain global;
40 static int seqLearn = 0;
41 
42 #include "brightonKeys.h"
43 
44 #define DEVICE_COUNT 72
45 #define ACTIVE_DEVS 52
46 #define DISPLAY_DEV (DEVICE_COUNT - 1)
47 #define MEM_START (ACTIVE_DEVS + 2) // 54
48 
49 #define KEY_PANEL 1
50 
51 #define R1 150
52 #define R1S (R1 + 20)
53 #define R2 (R1 + 245)
54 #define R2S (R2 + 20)
55 #define R3 (R2 + 245)
56 #define R3S (R3 + 20)
57 #define R4 (R3 + 275)
58 
59 #define RA (R1 - 38)
60 #define RB (RA + 144)
61 #define RC (RB + 142)
62 #define RD (RC + 145)
63 #define RE (RD + 144)
64 
65 #define CD1 63
66 
67 #define C1 31
68 #define C2 (C1 + 60)
69 #define C3 (C2 + 56)
70 
71 #define C4 (C1 + 155)
72 #define C4a (C4 + 60)
73 #define C4b (C4a + 31)
74 #define C4c (C4b + 31)
75 #define C5 (C4 + CD1 + 3)
76 #define C6 (C5 + 58)
77 #define C7 (C6 + 31)
78 #define C7S (C7 + 31)
79 #define C8 (C5 + 124)
80 #define C8a (C8 + 29)
81 #define C8b (C8a + 59)
82 #define C8c (C8b + 32)
83 
84 #define C7a (C7 + 58)
85 
86 #define C9 (C8 + 59)
87 
88 #define C10 (C8 + 102)
89 #define C11 (C10 + CD1)
90 #define C11a (C11 + 15)
91 #define C11b (C11a + 60)
92 #define C11c (C11 + 3)
93 #define C11d (C11 + 44)
94 #define C11e (C11 + 83)
95 #define C12 (C11 + CD1)
96 
97 #define C13 (C12 + 75)
98 #define C14 (C13 + CD1)
99 #define C15 (C14 + CD1)
100 #define C16 (C15 + CD1)
101 
102 #define C17 (C16 + 70)
103 
104 #define S1 100
105 #define S2 12
106 #define S3 70
107 #define S4 11
108 #define S5 90
109 #define S6 15
110 #define S7 50
111 
112 /*
113  * This structure is for device definition. The structure is defined in
114  * include/brighton.h, further definitions in brighton/brightonDevtable.h and
115  * include/brightoninternals.h
116  *
117  *	typedef int (*brightonCallback)(int, float);
118  *	typedef struct BrightonLocations {
119  *		int device; 0=rotary, 1=scale, etc.
120  *		float relx, rely; relative position with regards to 1000 by 1000 window
121  *		float relw, relh; relative height.
122  *		int from, to;
123  *		brightonCallback callback; specific to this dev
124  *		char *image; bitmap. If zero take a device default.
125  *		int flags;
126  *	} brightonLocations;
127  *
128  * This example is for a pro1Bristol type synth interface.
129  */
130 static brightonLocations locations[DEVICE_COUNT] = {
131 /* mod */
132 	{"ModFiltEnv", 0, C1, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0,
133 		BRIGHTON_REDRAW},
134 	{"ModFiltEnv", 2, C2, R1S, S2, S3, 0, 1.01, 0,
135 		"bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL},
136 	{"ModOscBMod", 0, C1, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0,
137 		BRIGHTON_REDRAW},
138 	{"ModOscBRt", 2, C2, R2S, S2, S3, 0, 1.01, 0,
139 		"bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL},
140 	{"ModLfo", 0, C1, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0,
141 		BRIGHTON_REDRAW},
142 	{"ModLfoRt", 2, C2, R3S, S2, S3, 0, 1.01, 0,
143 		"bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL},
144 
145 	{"ModOSCAFr", 1, C3, RA, S4, S5, 0, 2, 0,
146 		"bitmaps/buttons/klunk3.xpm", 0, 0},
147 	{"ModOSCAPWM", 1, C3, RB, S4, S5, 0, 2, 0,
148 		"bitmaps/buttons/klunk3.xpm", 0, 0},
149 	{"ModOSCBFr", 1, C3, RC, S4, S5, 0, 2, 0,
150 		"bitmaps/buttons/klunk3.xpm", 0, 0},
151 	{"ModOSCBPWM", 1, C3, RD, S4, S5, 0, 2, 0,
152 		"bitmaps/buttons/klunk3.xpm", 0, 0},
153 	{"ModFilter", 1, C3, RE, S4, S5, 0, 2, 0,
154 		"bitmaps/buttons/klunk3.xpm", 0, 0},
155 /* Osc-A */
156 	{"OscAFine", 0, C4, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0,
157 		BRIGHTON_REDRAW|BRIGHTON_NOTCH},
158 	{"OscAOct", 0, C5, R1, S1, S1, 0, 3, 0, "bitmaps/knobs/knob9.xpm", 0,
159 		BRIGHTON_REDRAW|BRIGHTON_STEPPED},
160 	{"OscASaw", 2, C6, R1S, S2, S3, 0, 1.01, 0,
161 		"bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL},
162 	{"OscAPuls", 2, C7, R1S, S2, S3, 0, 1.01, 0,
163 		"bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL},
164 	{"OscAPW", 0, C8, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0,
165 		BRIGHTON_REDRAW},
166 	{"OscASync", 2, C9, R1S, S2, S3, 0, 1.01, 0,
167 		"bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL},
168 /* Osc-B */
169 	{"OscBFine", 0, C4, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0,
170 		BRIGHTON_REDRAW|BRIGHTON_NOTCH},
171 	{"OscBOct", 0, C5, R2, S1, S1, 0, 3, 0, "bitmaps/knobs/knob9.xpm", 0,
172 		BRIGHTON_REDRAW|BRIGHTON_STEPPED},
173 	{"OscBSaw", 2, C6, R2S, S2, S3, 0, 1.01, 0,
174 		"bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL},
175 	{"OscBTri", 2, C7, R2S, S2, S3, 0, 1.01, 0,
176 		"bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL},
177 	{"OscBPuls", 2, C7S, R2S, S2, S3, 0, 1.01, 0,
178 		"bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL},
179 	{"OscBPW", 0, C8a, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0,
180 		BRIGHTON_REDRAW},
181 	{"OscBLFO", 2, C8b, R2S, S2, S3, 0, 1.01, 0,
182 		"bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL},
183 	{"OscBKEY", 2, C8c, R2S, S2, S3, 0, 1.01, 0,
184 		"bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL},
185 /* LFO */
186 	{"LFORATE", 0, C4, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0,
187 		BRIGHTON_REDRAW},
188 	{"LFOSAW", 2, C4a, R3S, S2, S3, 0, 1.01, 0,
189 		"bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL},
190 	{"LFOTRI", 2, C4b, R3S, S2, S3, 0, 1.01, 0,
191 		"bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL},
192 	{"LFOPuls", 2, C4c, R3S, S2, S3, 0, 1.01, 0,
193 		"bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL},
194 /* Seq */
195 	{"SEQ 1/2", 2, C8 - 6, R3S, S2, S3, 0, 1.01, 0,
196 		"bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL},
197 	{"Rec/Play", 2, C8a + 5, R3S, S2, S3, 0, 1.01, 0,
198 		"bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL},
199 /* Arpeg */
200 	{"Up/Down", 1, C10 - 4, R3S - 5, S4, S5, 0, 2, 0,
201 		"bitmaps/buttons/klunk3.xpm", 0, 0},
202 /* Mode */
203 	{"Metro", 2, C11c, R3S, S2, S3, 0, 1.01, 0,
204 		"bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL},
205 	{"Repeat", 2, C11d, R3S, S2, S3, 0, 1.01, 0,
206 		"bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL},
207 	{"Drone", 2, C11e, R3S, S2, S3, 0, 1.01, 0,
208 		"bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL},
209 /* Mixer */
210 	{"OSCAMix", 0, C10, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0,
211 		BRIGHTON_REDRAW},
212 	{"OSCBMix", 0, C11, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0,
213 		BRIGHTON_REDRAW},
214 	{"Noise Mix", 0, C12, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0,
215 		BRIGHTON_REDRAW},
216 /* Glide */
217 	{"Glide", 0, C11a, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0,
218 		BRIGHTON_REDRAW},
219 	{"Auto", 2, C11b, R2S, S2, S3, 0, 1.01, 0,
220 		"bitmaps/buttons/klunk4.xpm", 0, BRIGHTON_VERTICAL},
221 /* Filter */
222 	{"Cutoff", 0, C13, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0,
223 		BRIGHTON_REDRAW},
224 	{"Emphasis", 0, C14, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0,
225 		BRIGHTON_REDRAW},
226 	{"EnvAmt", 0, C15, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0,
227 		BRIGHTON_REDRAW},
228 	{"KeyAmt", 0, C16, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0,
229 		BRIGHTON_REDRAW},
230 /* ENV */
231 	{"Filt Attack", 0, C13, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0,
232 		BRIGHTON_REDRAW},
233 	{"Filt Decay", 0, C14, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0,
234 		BRIGHTON_REDRAW},
235 	{"Filt Sustain", 0, C15, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0,
236 		BRIGHTON_REDRAW},
237 	{"Filt Release", 0, C16, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0,
238 		BRIGHTON_REDRAW},
239 /* ENV */
240 	{"Attack", 0, C13, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0,
241 		BRIGHTON_REDRAW|BRIGHTON_HALFSHADOW},
242 	{"Decay", 0, C14, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0,
243 		BRIGHTON_REDRAW|BRIGHTON_HALFSHADOW},
244 	{"Sustain", 0, C15, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0,
245 		BRIGHTON_REDRAW|BRIGHTON_HALFSHADOW},
246 	{"Release", 0, C16, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0,
247 		BRIGHTON_REDRAW|BRIGHTON_HALFSHADOW},
248 /* Tune Vol */
249 	{"VolumeTuning", 0, C17, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0,
250 		BRIGHTON_NOTCH|BRIGHTON_REDRAW},
251 	{"MasterVolume", 0, C17, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob9.xpm", 0,
252 		BRIGHTON_REDRAW|BRIGHTON_HALFSHADOW},
253 /* memories */
254 	{"", 2, C10 + 10, R4, S6, S7, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
255 		"bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
256 	{"", 2, C10 + 30, R4, S6, S7, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
257 		"bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
258 	{"", 2, C10 + 50, R4, S6, S7, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
259 		"bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
260 	{"", 2, C10 + 70, R4, S6, S7, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
261 		"bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
262 	{"", 2, C10 + 90, R4, S6, S7, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
263 		"bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
264 	{"", 2, C10 + 110, R4, S6, S7, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
265 		"bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
266 	{"", 2, C10 + 130, R4, S6, S7, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
267 		"bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
268 	{"", 2, C10 + 150, R4, S6, S7, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
269 		"bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
270 	{"", 2, C4, R4, S6, S7, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
271 		"bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON},
272 	{"", 2, C4 + 30, R4, S6, S7, 0, 1, 0, "bitmaps/buttons/pressoffo.xpm",
273 		"bitmaps/buttons/pressono.xpm", BRIGHTON_CHECKBUTTON},
274 	{"", 2, C4 + 60, R4, S6, S7, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
275 		"bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON},
276 	/* Mem search buttons */
277 	{"", 2, C10 + 180, R4, S6, S7, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
278 		"bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON},
279 	{"", 2, C10 + 210, R4, S6, S7, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
280 		"bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON},
281 	{"", 2, C10 + 240, R4, S6, S7, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
282 		"bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON},
283 
284 	{"", 4, 798, 870, 125, 100, 0, 1, 0, "bitmaps/images/pro1.xpm", 0, 0},
285 
286 /* Midi, perhaps eventually file import/export buttons */
287 	{"", 2, C1, R4, S6, S7, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
288 		"bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON},
289 	{"", 2, C2 + 5, R4, S6, S7, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
290 		"bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON},
291 
292 	{"", 3, C5 + 23, R4, 200, S7 - 10, 0, 1, 0, 0,
293 		"bitmaps/images/alphadisplay3.xpm", 0}
294 };
295 
296 /*
297  * These are new mod controls for the Pro-1. May be used elsewhere
298  */
299 static brightonLocations promods[2] = {
300 	{"", BRIGHTON_MODWHEEL, 300, 220, 150, 350, 0, 1, 0,
301 		"bitmaps/knobs/modwheel.xpm", 0,
302 		BRIGHTON_HSCALE|BRIGHTON_NOSHADOW|BRIGHTON_CENTER|BRIGHTON_NOTCH},
303 	{"", BRIGHTON_MODWHEEL, 640, 220, 150, 350, 0, 1, 0,
304 		"bitmaps/knobs/modwheel.xpm", 0,
305 		BRIGHTON_HSCALE|BRIGHTON_NOSHADOW},
306 };
307 
308 /*
309  * This is a set of globals for the main window rendering. Again taken from
310  * include/brighton.h
311  */
312 brightonApp pro1App = {
313 	"pro1",
314 	0, /* no blueprint on wood background. */
315 	"bitmaps/textures/metal4.xpm",//"bitmaps/textures/metal7.xpm",
316 	BRIGHTON_STRETCH,//|BRIGHTON_REVERSE|BRIGHTON_VERTICAL, //flags
317 	pro1Init,
318 	pro1Configure, /* 3 callbacks, unused? */
319 	midiCallback,
320 	destroySynth,
321 	{1, 100, 2, 2, 5, 520, 0, 0},
322 	895, 500, 0, 0,
323 	5,
324 	{
325 		{
326 			"Pro1",
327 			"bitmaps/blueprints/pro1.xpm",
328 			0, // "bitmaps/textures/metal5.xpm",
329 			0, /*BRIGHTON_STRETCH, // flags */
330 			0,
331 			0,
332 			pro1Callback,
333 			25, 0, 950, 650,
334 			DEVICE_COUNT,
335 			locations
336 		},
337 		{
338 			"Keyboard",
339 			0,
340 			"bitmaps/newkeys/ekbg.xpm", /* flags */
341 			0x020|BRIGHTON_STRETCH,
342 			0,
343 			0,
344 			proOneKeyCallback,
345 			140, 680, 845, 300,
346 			KEY_COUNT_3OCTAVE,
347 			keys3octave
348 		},
349 		{
350 			"Mods",
351 			0, //"bitmaps/blueprints/pro1mod.xpm",
352 			"bitmaps/buttons/blue.xpm", /* flags */
353 			0,
354 			0,
355 			0,
356 			modCallback,
357 			25, 680, 110, 320,
358 			2,
359 			promods
360 		},
361 		{
362 			"Metal side",
363 			0,
364 			"bitmaps/textures/wood4.xpm",
365 			BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */
366 			0,
367 			0,
368 			0,
369 			0, 0, 25, 1000,
370 			0,
371 			0
372 		},
373 		{
374 			"Metal side",
375 			0,
376 			"bitmaps/textures/wood4.xpm",
377 			BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */
378 			0,
379 			0,
380 			0,
381 			976, 0, 25, 1000,
382 			0,
383 			0
384 		},
385 	}
386 };
387 
388 static void
pro1SeqInsert(guiSynth * synth,int note,int layer)389 pro1SeqInsert(guiSynth *synth, int note, int layer)
390 {
391 	arpeggiatorMemory *seq = (arpeggiatorMemory *) synth->seq1.param;
392 
393 	if (seq->s_max == 0)
394 		seq->s_dif = note + synth->transpose;
395 
396 	seq->sequence[(int) (seq->s_max)] =
397 //		(float) (note + synth->transpose - seq->s_dif);
398 		(float) (note + synth->transpose);
399 
400 //	if (pro10Debug(synth, 0))
401 		printf("Seq put %i into %i\n", (int) seq->sequence[(int) (seq->s_max)],
402 			(int) (seq->s_max));
403 
404 	if ((seq->s_max += 1) >= BRISTOL_SEQ_MAX)
405 		seq->s_max = BRISTOL_SEQ_MAX;
406 }
407 
408 static int
proOneKeyCallback(brightonWindow * win,int panel,int index,float value)409 proOneKeyCallback(brightonWindow * win, int panel, int index, float value)
410 {
411 	guiSynth *synth = findSynth(global.synths, win);
412 
413 	if (global.libtest)
414 		return(0);
415 
416 //printf("proOneKeyCallback(%i, %i, %f) %i\n", panel, index, value, seqLearn);
417 
418 	if ((seqLearn) && (value != 0))
419 		pro1SeqInsert(synth, index, panel);
420 
421 	/*
422 	 * Want to send a note event, on or off, for this index + transpose.
423 	 */
424 	if (value)
425 		bristolMidiSendMsg(global.controlfd, synth->midichannel,
426 			BRISTOL_EVENT_KEYON, 0, index + synth->transpose);
427 	else
428 		bristolMidiSendMsg(global.controlfd, synth->midichannel,
429 			BRISTOL_EVENT_KEYOFF, 0, index + synth->transpose);
430 
431 	return(0);
432 }
433 
434 static int
midiCallback(brightonWindow * win,int controller,int value,float n)435 midiCallback(brightonWindow *win, int controller, int value, float n)
436 {
437 	guiSynth *synth = findSynth(global.synths, win);
438 
439 	printf("midi callback: %x, %i\n", controller, value);
440 
441 	switch(controller)
442 	{
443 		case MIDI_PROGRAM:
444 			printf("midi program: %x, %i\n", controller, value);
445 			synth->bank = value - (value % 8);
446 			synth->location = value % 8;
447 			loadMemory(synth, "pro1", 0, synth->bank * 10 + synth->location,
448 				synth->mem.active, 0, 0);
449 			break;
450 		case MIDI_BANK_SELECT:
451 			printf("midi banksel: %x, %i\n", controller, value);
452 			synth->bank = value;
453 			break;
454 	}
455 	return(0);
456 }
457 
458 /*static dispatcher dispatch[DEVICE_COUNT]; */
459 
460 static int
pro1MidiSendMsg(void * synth,int fd,int chan,int c,int o,int v)461 pro1MidiSendMsg(void *synth, int fd, int chan, int c, int o, int v)
462 {
463 	bristolMidiSendMsg(fd, chan, c, o, v);
464 	return(0);
465 }
466 
467 static void
pro1Sequence(guiSynth * synth,int fd,int chan,int c,int o,int v)468 pro1Sequence(guiSynth *synth, int fd, int chan, int c, int o, int v)
469 {
470 	if (synth->seq1.param == NULL)
471 	{
472 		/* This does not actually reload a sequence..... FFS, see Pro10 code */
473 		loadSequence(&synth->seq1, "pro1", 0, 0);
474 		fillSequencer(synth, (arpeggiatorMemory *) synth->seq1.param, 0);
475 	}
476 	switch (o) {
477 		case 0:
478 			/* On/Off */
479 			if (v == 0) {
480 				seqLearn = 0;
481 				bristolMidiSendMsg(global.controlfd, synth->sid,
482 					BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_ENABLE, 0);
483 			} else {
484 				seqLearn = 0;
485 				bristolMidiSendMsg(global.controlfd, synth->sid,
486 					BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RESEQ, 0);
487 				bristolMidiSendMsg(global.controlfd, synth->sid,
488 					BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_DIR, BRISTOL_ARPEG_UP);
489 				bristolMidiSendMsg(global.controlfd, synth->sid,
490 					BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_TRIGGER, 1);
491 				bristolMidiSendMsg(global.controlfd, synth->sid,
492 					BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RANGE, 0);
493 				bristolMidiSendMsg(global.controlfd, synth->sid,
494 					BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_ENABLE, 1);
495 			}
496 			break;
497 		case 1:
498 			/* Record/Play */
499 			if (v == 0) {
500 				seqLearn = 0;
501 				/* Turn off sequence learning */
502 				bristolMidiSendMsg(global.controlfd, synth->sid,
503 					BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RESEQ, 0);
504 				/* If we are configured to play then start else stop */
505 				if (synth->mem.param[29] != 0) {
506 					bristolMidiSendMsg(global.controlfd, synth->sid,
507 						BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_TRIGGER, 1);
508 					bristolMidiSendMsg(global.controlfd, synth->sid,
509 						BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_DIR, BRISTOL_ARPEG_UP);
510 					bristolMidiSendMsg(global.controlfd, synth->sid,
511 						BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RANGE, 0);
512 					bristolMidiSendMsg(global.controlfd, synth->sid,
513 						BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_ENABLE, 1);
514 				} else
515 					bristolMidiSendMsg(global.controlfd, synth->sid,
516 						BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_ENABLE, 0);
517 			} else {
518 				arpeggiatorMemory *seq = (arpeggiatorMemory *) synth->seq1.param;
519 				seqLearn = 1;
520 				seq->s_max = 0;
521 
522 				bristolMidiSendMsg(global.controlfd, synth->sid,
523 					BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_ENABLE, 0);
524 				bristolMidiSendMsg(global.controlfd, synth->sid,
525 					BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RESEQ, 1);
526 			}
527 			break;
528 	}
529 }
530 
531 static void
pro1Arpeggiate(guiSynth * synth,int fd,int chan,int c,int o,int v)532 pro1Arpeggiate(guiSynth *synth, int fd, int chan, int c, int o, int v)
533 {
534 	/*
535 	 * See if this is rate. Send the request to both the LFO and the arpeg
536 	 */
537 	if (c != 126)
538 	{
539 		bristolMidiSendMsg(global.controlfd, synth->sid,
540 			BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_RATE, v);
541 		bristolMidiSendMsg(global.controlfd, synth->sid,
542 			BRISTOL_ARPEGGIATOR, BRISTOL_SEQ_RATE, v);
543 		bristolMidiSendMsg(global.controlfd, synth->sid,
544 			2, 0, v);
545 		return;
546 	}
547 
548 	switch (v) {
549 		case 2:
550 			/* Arpeggiation up */
551 			bristolMidiSendMsg(global.controlfd, synth->sid,
552 				BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_DIR, BRISTOL_ARPEG_UP);
553 			bristolMidiSendMsg(global.controlfd, synth->sid,
554 				BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_ENABLE, 1);
555 			break;
556 		case 1:
557 			/* Arpeggiation off */
558 			bristolMidiSendMsg(global.controlfd, synth->sid,
559 				BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_ENABLE, 0);
560 			bristolMidiSendMsg(global.controlfd, synth->sid,
561 				BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_TRIGGER, 1);
562 			bristolMidiSendMsg(global.controlfd, synth->sid,
563 				BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_RANGE, 2);
564 			break;
565 		case 0:
566 			/* Arpeggiation up/down */
567 			bristolMidiSendMsg(global.controlfd, synth->sid,
568 				BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_DIR, BRISTOL_ARPEG_UD);
569 			bristolMidiSendMsg(global.controlfd, synth->sid,
570 				BRISTOL_ARPEGGIATOR, BRISTOL_ARPEG_ENABLE, 1);
571 			break;
572 	}
573 }
574 
575 static void
pro1Memory(guiSynth * synth,int fd,int chan,int c,int o,int v)576 pro1Memory(guiSynth *synth, int fd, int chan, int c, int o, int v)
577 {
578 	brightonEvent event;
579 	int bank = synth->bank;
580 	int location = synth->location;
581 
582 	event.value = 1.0;
583 	event.type = BRISTOL_FLOAT;
584 
585 	if (synth->flags & MEM_LOADING)
586 		return;
587 	if ((synth->flags & OPERATIONAL) == 0)
588 		return;
589 
590 	if (synth->dispatch[MEM_START].other2)
591 	{
592 		synth->dispatch[MEM_START].other2 = 0;
593 		return;
594 	}
595 
596 	switch (c) {
597 		default:
598 		case 0:
599 			/*
600 			 * We want to make these into memory buttons. To do so we need to
601 			 * know what the last active button was, and deactivate its
602 			 * display, then send any message which represents the most
603 			 * recently configured value. Since this is a memory button we do
604 			 * not have much issue with the message, but we are concerned with
605 			 * the display.
606 			 */
607 			if (synth->dispatch[MEM_START].other1 != -1)
608 			{
609 				synth->dispatch[MEM_START].other2 = 1;
610 
611 				if (synth->dispatch[MEM_START].other1 != o)
612 					event.value = 0;
613 				else
614 					event.value = 1;
615 
616 				brightonParamChange(synth->win, synth->panel,
617 					synth->dispatch[MEM_START].other1 + MEM_START - 1, &event);
618 			}
619 			synth->dispatch[MEM_START].other1 = o;
620 
621 			if (synth->flags & BANK_SELECT) {
622 				if ((synth->bank * 10 + o) >= 100)
623 				{
624 					synth->location = o;
625 					synth->flags &= ~BANK_SELECT;
626 
627 					if (loadMemory(synth, "pro1", 0,
628 						synth->bank * 10 + synth->location, synth->mem.active,
629 							0, BRISTOL_STAT) < 0)
630 						displayText(synth, "FREE MEM",
631 							synth->bank * 10 + synth->location, DISPLAY_DEV);
632 					else
633 						displayText(synth, "PROGRAM",
634 							synth->bank * 10 + synth->location, DISPLAY_DEV);
635 				} else {
636 					synth->bank = synth->bank * 10 + o;
637 					displayText(synth, "BANK",
638 						synth->bank * 10 + synth->location, DISPLAY_DEV);
639 				}
640 			} else {
641 				if (synth->bank < 1)
642 					synth->bank = 1;
643 				synth->location = o;
644 				if (loadMemory(synth, "pro1", 0,
645 					synth->bank * 10 + synth->location, synth->mem.active,
646 						0, BRISTOL_STAT) < 0)
647 					displayText(synth, "FREE MEM",
648 						synth->bank * 10 + synth->location, DISPLAY_DEV);
649 				else
650 					displayText(synth, "PROGRAM",
651 						synth->bank * 10 + synth->location, DISPLAY_DEV);
652 			}
653 			break;
654 		case 1:
655 			if (synth->bank < 1)
656 				synth->bank = 1;
657 			if (synth->location == 0)
658 				synth->location = 1;
659 			if (loadMemory(synth, "pro1", 0, synth->bank * 10 + synth->location,
660 				synth->mem.active, 0, BRISTOL_FORCE) < 0)
661 				displayText(synth, "FREE MEM",
662 					synth->bank * 10 + synth->location, DISPLAY_DEV);
663 			else {
664 				displayText(synth, "PROGRAM",
665 					synth->bank * 10 + synth->location, DISPLAY_DEV);
666 				loadSequence(&synth->seq1,
667 					"pro1", synth->bank * 10 + synth->location, 0);
668 				fillSequencer(synth, (arpeggiatorMemory *) synth->seq1.param, 0);
669 			}
670 			synth->flags &= ~BANK_SELECT;
671 			break;
672 		case 2:
673 			if (synth->bank < 1)
674 				synth->bank = 1;
675 			if (synth->location == 0)
676 				synth->location = 1;
677 			saveMemory(synth, "pro1", 0, synth->bank * 10 + synth->location,
678 				0);
679 			saveSequence(synth, "pro1", synth->bank * 10 + synth->location, 0);
680 			displayText(synth, "PROGRAM", synth->bank * 10 + synth->location,
681 				DISPLAY_DEV);
682 			synth->flags &= ~BANK_SELECT;
683 			break;
684 		case 3:
685 			if (synth->flags & BANK_SELECT) {
686 				synth->flags &= ~BANK_SELECT;
687 				if (loadMemory(synth, "pro1", 0,
688 					synth->bank * 10 + synth->location, synth->mem.active,
689 						0, BRISTOL_STAT) < 0)
690 					displayText(synth, "FREE MEM",
691 						synth->bank * 10 + synth->location, DISPLAY_DEV);
692 				else {
693 					displayText(synth, "PROGRAM",
694 						synth->bank * 10 + synth->location, DISPLAY_DEV);
695 					loadSequence(&synth->seq1,
696 						"pro1", synth->bank * 10 + synth->location, 0);
697 					fillSequencer(synth, (arpeggiatorMemory *) synth->seq1.param, 0);
698 				}
699 			} else {
700 				synth->bank = 0;
701 				displayText(synth, "BANK", synth->bank, DISPLAY_DEV);
702 				synth->flags |= BANK_SELECT;
703 			}
704 			break;
705 		case 4:
706 			if (--location < 1) {
707 				location = 8;
708 				if (--bank < 1)
709 					bank = 88;
710 			}
711 			while (loadMemory(synth, "pro1", 0, bank * 10 + location,
712 				synth->mem.active, 0, BRISTOL_STAT) < 0)
713 			{
714 				if (--location < 1) {
715 					location = 8;
716 					if (--bank < 1)
717 						bank = 88;
718 				}
719 				if ((bank * 10 + location)
720 					== (synth->bank * 10 + synth->location))
721 					break;
722 			}
723 			displayText(synth, "PROGRAM", bank * 10 + location, DISPLAY_DEV);
724 			synth->bank = bank;
725 			synth->location = location;
726 			loadMemory(synth, "pro1", 0, bank * 10 + location,
727 				synth->mem.active, 0, BRISTOL_FORCE);
728 			loadSequence(&synth->seq1, "pro1", bank * 10 + location, 0);
729 			fillSequencer(synth, (arpeggiatorMemory *) synth->seq1.param, 0);
730 			brightonParamChange(synth->win, 0,
731 				MEM_START - 1 + synth->location, &event);
732 			break;
733 		case 5:
734 			if (++location > 8) {
735 				location = 1;
736 				if (++bank > 88)
737 					bank = 1;
738 			}
739 			while (loadMemory(synth, "pro1", 0, bank * 10 + location,
740 				synth->mem.active, 0, BRISTOL_STAT) < 0)
741 			{
742 				if (++location > 8) {
743 					location = 1;
744 					if (++bank > 88)
745 						bank = 1;
746 				}
747 				if ((bank * 10 + location)
748 					== (synth->bank * 10 + synth->location))
749 					break;
750 			}
751 			displayText(synth, "PROGRAM", bank * 10 + location, DISPLAY_DEV);
752 			synth->bank = bank;
753 			synth->location = location;
754 			loadMemory(synth, "pro1", 0, bank * 10 + location,
755 				synth->mem.active, 0, BRISTOL_FORCE);
756 			brightonParamChange(synth->win, 0,
757 				MEM_START - 1 + synth->location, &event);
758 			loadSequence(&synth->seq1, "pro1", bank * 10 + location, 0);
759 			fillSequencer(synth, (arpeggiatorMemory *) synth->seq1.param, 0);
760 			break;
761 		case 6:
762 			/* Find the next free mem */
763 			if (++location > 8) {
764 				location = 1;
765 				if (++bank > 88)
766 					bank = 1;
767 			}
768 
769 			while (loadMemory(synth, "pro1", 0, bank * 10 + location,
770 				synth->mem.active, 0, BRISTOL_STAT) >= 0)
771 			{
772 				if (++location > 8) {
773 					location = 1;
774 					if (++bank > 88)
775 						bank = 1;
776 				}
777 				if ((bank * 10 + location)
778 					== (synth->bank * 10 + synth->location))
779 					break;
780 			}
781 
782 			if (loadMemory(synth, "pro1", 0, bank * 10 + location,
783 				synth->mem.active, 0, BRISTOL_STAT) >= 0)
784 				displayText(synth, "PROGRAM",
785 					bank * 10 + location, DISPLAY_DEV);
786 			else
787 				displayText(synth, "FREE MEM",
788 					bank * 10 + location, DISPLAY_DEV);
789 
790 			synth->bank = bank;
791 			synth->location = location;
792 			brightonParamChange(synth->win, 0,
793 				MEM_START - 1 + synth->location, &event);
794 			break;
795 	}
796 /*	printf("	pro1Memory(B: %i L %i: %i)\n", */
797 /*		synth->bank, synth->location, o); */
798 }
799 
800 static int
pro1Midi(guiSynth * synth,int fd,int chan,int c,int o,int v)801 pro1Midi(guiSynth *synth, int fd, int chan, int c, int o, int v)
802 {
803 	int newchan;
804 
805 	if ((synth->flags & OPERATIONAL) == 0)
806 		return(0);
807 
808 	if (c == 1) {
809 		if ((newchan = synth->midichannel - 1) < 0)
810 		{
811 			synth->midichannel = 0;
812 			return(0);
813 		}
814 	} else {
815 		if ((newchan = synth->midichannel + 1) >= 16)
816 		{
817 			synth->midichannel = 15;
818 			return(0);
819 		}
820 	}
821 
822 	if (global.libtest == 0)
823 	{
824 		bristolMidiSendMsg(global.controlfd, synth->sid,
825 			127, 0, BRISTOL_MIDICHANNEL|newchan);
826 	}
827 
828 	synth->midichannel = newchan;
829 
830 /*	printf("P: going to display: %x, %x\n", synth, synth->win); */
831 	displayText(synth, "MIDI CH", synth->midichannel + 1, DISPLAY_DEV);
832 
833 	return(0);
834 }
835 
836 static void
pro1ShowParam(guiSynth * synth,int index,float value)837 pro1ShowParam(guiSynth *synth, int index, float value)
838 {
839 	char showthis[64];
840 
841 	if (index >= pro1App.resources[0].ndevices)
842 		return;
843 
844 	if (pro1App.resources[0].devlocn[index].name[0] == '\0') {
845 		if (pro1App.resources[0].devlocn[index].to == 1.0)
846 			sprintf(showthis, "%i: %1.3f", index, value);
847 		else
848 			sprintf(showthis, "%i: %1.1f", index, value);
849 	} else {
850 		if (pro1App.resources[0].devlocn[index].to == 1.0)
851 			sprintf(showthis, "%s: %1.3f",
852 				pro1App.resources[0].devlocn[index].name,
853 				value);
854 		else
855 			sprintf(showthis, "%s: %1.1f",
856 				pro1App.resources[0].devlocn[index].name,
857 				value);
858 	}
859 
860 	displayPanel(synth, showthis, index, 0, DISPLAY_DEV);
861 }
862 
863 /*
864  * For the sake of ease of use, links have been placed here to be called
865  * by any of the devices created. They would be better in some other file,
866  * perhaps with this as a dispatch.
867  *
868  * Param refers to the device index in the locations table given below.
869  */
870 static int
pro1Callback(brightonWindow * win,int panel,int index,float value)871 pro1Callback(brightonWindow * win, int panel, int index, float value)
872 {
873 	guiSynth *synth = findSynth(global.synths, win);
874 	int sendvalue;
875 
876 /* printf("pro1Callback(%i, %f): %x\n", index, value, synth); */
877 
878 	if ((synth->flags & MEM_LOADING) == 0)
879 		pro1ShowParam(synth, index, value);
880 
881 	if (synth == 0)
882 		return(0);
883 
884 	if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0))
885 		return(0);
886 
887 	if (pro1App.resources[0].devlocn[index].to == 1.0)
888 		sendvalue = value * (CONTROLLER_RANGE - 1);
889 	else
890 		sendvalue = value;
891 
892 	synth->mem.param[index] = value;
893 
894 	if ((!global.libtest) || (index >= ACTIVE_DEVS))
895 		synth->dispatch[index].routine(synth,
896 			global.controlfd, synth->sid,
897 			synth->dispatch[index].controller,
898 			synth->dispatch[index].operator,
899 			sendvalue);
900 
901 #ifdef DEBUG
902 	else
903 		printf("dispatch[%p,%i](%i, %i, %i, %i, %i)\n", synth, index,
904 			global.controlfd, synth->sid,
905 			synth->dispatch[index].controller,
906 			synth->dispatch[index].operator,
907 			sendvalue);
908 #endif
909 
910 	return(0);
911 }
912 
913 static void
pro1Hold(guiSynth * synth)914 pro1Hold(guiSynth *synth)
915 {
916 	if ((synth->flags & OPERATIONAL) == 0)
917 		return;
918 
919 	if (synth->mem.param[34])
920 		bristolMidiSendMsg(global.controlfd, synth->sid,
921 			127, 0, BRISTOL_HOLD|1);
922 	else
923 		bristolMidiSendMsg(global.controlfd, synth->sid,
924 			127, 0, BRISTOL_HOLD|0);
925 }
926 
927 /*
928  * Any location initialisation required to run the callbacks. For bristol, this
929  * will connect to the engine, and give it some base parameters.
930  * May need to generate some application specific menus.
931  * Will also then make specific requests to some of the devices to alter their
932  * rendering.
933  */
934 static int
pro1Init(brightonWindow * win)935 pro1Init(brightonWindow *win)
936 {
937 	guiSynth *synth = findSynth(global.synths, win);
938 	dispatcher *dispatch;
939 	int i;
940 
941 	if (synth == 0)
942 	{
943 		synth = findSynth(global.synths, (int) 0);
944 		if (synth == 0)
945 		{
946 			printf("cannot init\n");
947 			return(0);
948 		}
949 	}
950 
951 	if ((initmem = synth->location) == 0)
952 		initmem = 11;
953 
954 	synth->win = win;
955 
956 	printf("Initialise the pro1 link to bristol: %p\n", synth->win);
957 
958 	synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float));
959 	synth->mem.count = DEVICE_COUNT;
960 	synth->mem.active = ACTIVE_DEVS;
961 	synth->dispatch = (dispatcher *)
962 		brightonmalloc(DEVICE_COUNT * sizeof(dispatcher));
963 	dispatch = synth->dispatch;
964 
965 	/*
966 	 * We really want to have three connection mechanisms. These should be
967 	 *	1. Unix named sockets.
968 	 *	2. UDP sockets.
969 	 *	3. MIDI pipe.
970 	 */
971 	if (!global.libtest)
972 	{
973 		if ((synth->sid = initConnection(&global, synth)) < 0)
974 			return(-1);
975 	}
976 
977 	for (i = 0; i < DEVICE_COUNT; i++)
978 		synth->dispatch[i].routine = pro1MidiSendMsg;
979 
980 	/* Mods source */
981 	dispatch[0].controller = 3;
982 	dispatch[0].operator = 4;
983 	dispatch[1].controller = 126;
984 	dispatch[1].operator = 3;
985 	dispatch[2].controller = 126;
986 	dispatch[2].operator = 4;
987 	dispatch[3].controller = 126;
988 	dispatch[3].operator = 5;
989 	dispatch[4].controller = 126;
990 	dispatch[4].operator = 6;
991 	dispatch[5].controller = 126;
992 	dispatch[5].operator = 7;
993 
994 	/* Mods dest */
995 	dispatch[6].controller = 126;
996 	dispatch[6].operator = 10;
997 	dispatch[7].controller = 126;
998 	dispatch[7].operator = 11;
999 	dispatch[8].controller = 126;
1000 	dispatch[8].operator = 12;
1001 	dispatch[9].controller = 126;
1002 	dispatch[9].operator = 13;
1003 	dispatch[10].controller = 126;
1004 	dispatch[10].operator = 14;
1005 
1006 	/* Osc A */
1007 	dispatch[11].controller = 0;
1008 	dispatch[11].operator = 2;
1009 	dispatch[12].controller = 0;
1010 	dispatch[12].operator = 1;
1011 	dispatch[13].controller = 0;
1012 	dispatch[13].operator = 4;
1013 	dispatch[14].controller = 0;
1014 	dispatch[14].operator = 6;
1015 	dispatch[15].controller = 0;
1016 	dispatch[15].operator = 0;
1017 	dispatch[16].controller = 0;
1018 	dispatch[16].operator = 7;
1019 
1020 	/* Osc B */
1021 	dispatch[17].controller = 1;
1022 	dispatch[17].operator = 2;
1023 	dispatch[18].controller = 1;
1024 	dispatch[18].operator = 1;
1025 	dispatch[19].controller = 1;
1026 	dispatch[19].operator = 4;
1027 	dispatch[20].controller = 1;
1028 	dispatch[20].operator = 5;
1029 	dispatch[21].controller = 1;
1030 	dispatch[21].operator = 6;
1031 	dispatch[22].controller = 1;
1032 	dispatch[22].operator = 0;
1033 	dispatch[23].controller = 126;
1034 	dispatch[23].operator = 18;
1035 	dispatch[24].controller = 126;
1036 	dispatch[24].operator = 19;
1037 
1038 	/* LFO */
1039 	dispatch[25].controller = 2;
1040 	dispatch[25].operator = 0;
1041 	dispatch[25].routine = (synthRoutine) pro1Arpeggiate;
1042 	dispatch[26].controller = 126;
1043 	dispatch[26].operator = 24;
1044 	dispatch[27].controller = 126;
1045 	dispatch[27].operator = 25;
1046 	dispatch[28].controller = 126;
1047 	dispatch[28].operator = 26;
1048 
1049 	/* Seqx2/Arpeg/modex3 */
1050 	dispatch[29].controller = 126;
1051 	dispatch[29].operator = 0;
1052 	dispatch[29].routine = (synthRoutine) pro1Sequence;
1053 	dispatch[30].controller = 126;
1054 	dispatch[30].operator = 1;
1055 	dispatch[30].routine = (synthRoutine) pro1Sequence;
1056 	dispatch[31].controller = 126;
1057 	dispatch[31].operator = 101;
1058 	dispatch[31].routine = (synthRoutine) pro1Arpeggiate;
1059 	/* Modes, need to read up on function */
1060 	dispatch[32].controller = 126; /* multitrig envelope note */
1061 	dispatch[32].operator = 27;
1062 	dispatch[33].controller = 126; /* Track LFO as trigger */
1063 	dispatch[33].operator = 9;
1064 	dispatch[34].controller = 126; /* Force gate open */
1065 	dispatch[34].operator = 28;
1066 	dispatch[34].routine = (synthRoutine) pro1Hold; /* Drone */
1067 
1068 	/* Mixer */
1069 	dispatch[35].controller = 126;
1070 	dispatch[35].operator = 20;
1071 	dispatch[36].controller = 126;
1072 	dispatch[36].operator = 21;
1073 	dispatch[37].controller = 126;
1074 	dispatch[37].operator = 22;
1075 
1076 	/* Glide */
1077 	dispatch[38].controller = 126;
1078 	dispatch[38].operator = 0;
1079 	dispatch[39].controller = 126;
1080 	dispatch[39].operator = 8;
1081 
1082 	/* Filter and Env */
1083 	dispatch[40].controller = 4;
1084 	dispatch[40].operator = 0;
1085 	dispatch[41].controller = 4;
1086 	dispatch[41].operator = 1;
1087 	dispatch[42].controller = 126;
1088 	dispatch[42].operator = 23;
1089 	dispatch[43].controller = 4;
1090 	dispatch[43].operator = 3;
1091 	dispatch[44].controller = 3;
1092 	dispatch[44].operator = 0;
1093 	dispatch[45].controller = 3;
1094 	dispatch[45].operator = 1;
1095 	dispatch[46].controller = 3;
1096 	dispatch[46].operator = 2;
1097 	dispatch[47].controller = 3;
1098 	dispatch[47].operator = 3;
1099 
1100 	/* Env */
1101 	dispatch[48].controller = 5;
1102 	dispatch[48].operator = 0;
1103 	dispatch[49].controller = 5;
1104 	dispatch[49].operator = 1;
1105 	dispatch[50].controller = 5;
1106 	dispatch[50].operator = 2;
1107 	dispatch[51].controller = 5;
1108 	dispatch[51].operator = 3;
1109 
1110 	/* Tune and Master */
1111 	dispatch[52].controller = 126;
1112 	dispatch[52].operator = 2;
1113 	dispatch[53].controller = 5;
1114 	dispatch[53].operator = 4;
1115 
1116 	/* Memory and MIDI */
1117 	dispatch[MEM_START + 0].operator = 1;
1118 	dispatch[MEM_START + 1].operator = 2;
1119 	dispatch[MEM_START + 2].operator = 3;
1120 	dispatch[MEM_START + 3].operator = 4;
1121 	dispatch[MEM_START + 4].operator = 5;
1122 	dispatch[MEM_START + 5].operator = 6;
1123 	dispatch[MEM_START + 6].operator = 7;
1124 	dispatch[MEM_START + 7].operator = 8;
1125 
1126 	dispatch[MEM_START + 8].controller = 1;
1127 	dispatch[MEM_START + 9].controller = 2;
1128 	dispatch[MEM_START + 10].controller = 3;
1129 	dispatch[MEM_START + 11].controller = 4;
1130 	dispatch[MEM_START + 12].controller = 5;
1131 	dispatch[MEM_START + 13].controller = 6;
1132 
1133 	dispatch[MEM_START + 0].routine =
1134 		dispatch[MEM_START + 1].routine =
1135 		dispatch[MEM_START + 2].routine =
1136 		dispatch[MEM_START + 3].routine =
1137 		dispatch[MEM_START + 4].routine =
1138 		dispatch[MEM_START + 5].routine =
1139 		dispatch[MEM_START + 6].routine =
1140 		dispatch[MEM_START + 7].routine =
1141 		dispatch[MEM_START + 8].routine =
1142 		dispatch[MEM_START + 9].routine =
1143 		dispatch[MEM_START + 10].routine =
1144 		dispatch[MEM_START + 11].routine =
1145 		dispatch[MEM_START + 12].routine =
1146 		dispatch[MEM_START + 13].routine = (synthRoutine) pro1Memory;
1147 
1148 	dispatch[DEVICE_COUNT - 3].routine = dispatch[DEVICE_COUNT - 2].routine =
1149 		(synthRoutine) pro1Midi;
1150 	dispatch[DEVICE_COUNT - 3].controller = 1;
1151 	dispatch[DEVICE_COUNT - 2].controller = 2;
1152 
1153 	dispatch[MEM_START].other1 = -1;
1154 
1155 	/* No velocity on filter contour */
1156 	bristolMidiSendMsg(global.controlfd, synth->sid, 3, 5, 0);
1157 	/* LFO retrigger on keypress */
1158 	bristolMidiSendMsg(global.controlfd, synth->sid, 2, 1, 1);
1159 	bristolMidiSendMsg(global.controlfd, synth->sid, 4, 4, 4);
1160 
1161 	return(0);
1162 }
1163 
1164 /*
1165  * This will be called to make any routine specific parameters available.
1166  */
1167 static int
pro1Configure(brightonWindow * win)1168 pro1Configure(brightonWindow* win)
1169 {
1170 	guiSynth *synth = findSynth(global.synths, win);
1171 	brightonEvent event;
1172 
1173 	if (synth == 0)
1174 	{
1175 		printf("problems going operational\n");
1176 		return(-1);
1177 	}
1178 
1179 	if (synth->flags & OPERATIONAL)
1180 		return(0);
1181 
1182 printf("going operational\n");
1183 
1184 	synth->flags |= OPERATIONAL;
1185 	synth->keypanel = 1;
1186 	synth->keypanel2 = -1;
1187 	synth->transpose = 36;
1188 
1189 	if (synth->location == 0)
1190 	{
1191 		synth->bank = 1;
1192 		synth->location = 1;
1193 	} else {
1194 		synth->bank = synth->location / 10;
1195 		synth->location %= 10;
1196 	}
1197 	loadMemory(synth, "pro1", 0, initmem, synth->mem.active, 0, 0);
1198 	loadSequence(&synth->seq1, "pro1", initmem, 0);
1199 	fillSequencer(synth, (arpeggiatorMemory *) synth->seq1.param, 0);
1200 
1201 	brightonPut(win,
1202 		"bitmaps/blueprints/pro1shade.xpm", 0, 0, win->width, win->height);
1203 
1204 	event.type = BRIGHTON_FLOAT;
1205 	/* Tune */
1206 	event.value = 0.5;
1207 	brightonParamChange(synth->win, 0, ACTIVE_DEVS + 0, &event);
1208 	/* Volume */
1209 	event.value = 0.9;
1210 	brightonParamChange(synth->win, 0, ACTIVE_DEVS + 1, &event);
1211 	/* First memory location */
1212 	event.value = 1.0;
1213 	brightonParamChange(synth->win, 0, MEM_START, &event);
1214 	/* Some small amount of mod wheel */
1215 	event.value = 0.2;
1216 	brightonParamChange(synth->win, 2, 1, &event);
1217 
1218 	/*
1219 	 * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only
1220 	 * occurs on first paint, so we suppress the first paint, and then request
1221 	 * an expose here.
1222 	 */
1223 	event.type = BRIGHTON_EXPOSE;
1224 	event.intvalue = 1;
1225 	brightonParamChange(synth->win, KEY_PANEL, -1, &event);
1226 	configureGlobals(synth);
1227 	return(0);
1228 }
1229 
1230