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 "brightonKeys.h"
28 #include "brightoninternals.h"
29 
30 static int initmem;
31 
32 static int prophet52Init();
33 static int prophet52Configure();
34 static int prophet52Callback(brightonWindow *, int, int, float);
35 /*static int keyCallback(brightonWindow *, int, int, float); */
36 /*static int modCallback(brightonWindow *, int, int, float); */
37 static int midiCallback(brightonWindow *, int, int, float);
38 
39 extern guimain global;
40 
41 #include "brightonKeys.h"
42 
43 #define LAST_DEV 51
44 #define DEV_OFFSET 2
45 
46 #define FIRST_DEV 0
47 #define DEVICE_COUNT (69 + FIRST_DEV)
48 #define ACTIVE_DEVS (51 + FIRST_DEV)
49 #define DISPLAY_DEV (DEVICE_COUNT - 1 + FIRST_DEV)
50 #define RADIOSET_1 (LAST_DEV + 1)
51 
52 #define KEY_PANEL 1
53 
54 #define R1 140
55 #define RB1 160
56 #define R2 425
57 #define RB2 445
58 #define R3 710
59 #define RB3 730
60 
61 #define C1 17
62 #define C2 66
63 #define CB1 60
64 #define CB2 88
65 #define C3 116
66 #define C4 143
67 #define C5 172
68 
69 #define C6 217
70 #define CB6 258
71 #define CB7 287
72 #define C7 320
73 #define CB8 370
74 
75 #define C9 262
76 #define CB9 310
77 #define CB10 340
78 #define CB11 370
79 #define C10 410
80 #define CB12 460
81 #define CB13 490
82 
83 #define C11 418
84 #define C12 466
85 #define C13 513
86 
87 #define C14 565
88 #define C15 613
89 #define C16 658
90 #define C17 705
91 
92 #define C18 761
93 #define C19 810
94 #define C20 860
95 #define C21 910
96 
97 #define C22 877
98 #define C23 964
99 
100 #define S1 120
101 
102 #define B1 14
103 #define B2 80
104 
105 /*
106  * This structure is for device definition. The structure is defined in
107  * include/brighton.h, further definitions in brighton/brightonDevtable.h and
108  * include/brightoninternals.h
109  *
110  *	typedef int (*brightonCallback)(int, float);
111  *	typedef struct BrightonLocations {
112  *		int device; 0=rotary, 1=scale, etc.
113  *		float relx, rely; relative position with regards to 1000 by 1000 window
114  *		float relw, relh; relative height.
115  *		int from, to;
116  *		brightonCallback callback; specific to this dev
117  *		char *image; bitmap. If zero take a device default.
118  *		int flags;
119  *	} brightonLocations;
120  *
121  * This example is for a prophet52Bristol type synth interface.
122  */
123 static brightonLocations locations[DEVICE_COUNT] = {
124 /* poly mod */
125 	{"PolyMod-Filt", 0, C1, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
126 	{"PolyMod-OscB", 0, C2, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
127 	{"PolyMod2Freq-A", 2, C3, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0},
128 	{"PolyMod2PW-A", 2, C4, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0},
129 	{"PolyMod2Filt", 2, C5, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0},
130 /* lfo */
131 	{"LFO-Freq", 0, C2, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
132 	{"LFO-Ramp", 2, C3, RB2, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0},
133 	{"LFO-Tri", 2, C4, RB2, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0},
134 	{"LFO-Square", 2, C5, RB2, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0},
135 /* wheel mod */
136 	{"Wheel-Mix", 0, C1, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
137 	{"Whell-FreqA", 2, CB1, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0},
138 	{"Whell-FreqB", 2, CB2, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0},
139 	{"Wheel-PW-A", 2, C3, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0},
140 	{"Wheel-PW-B", 2, C4, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0},
141 	{"Wheel-Filt", 2, C5, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0},
142 /* osc a */
143 	{"OscA-Transpose", 0, C6, R1, S1, S1, 0, 5, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
144 	{"OscA-Ramp", 2, CB6, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0},
145 	{"OscA-Pulse", 2, CB7, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0},
146 	{"OscA-PW", 0, C7, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
147 	{"OscA-Sync", 2, CB8, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0},
148 /* osc b */
149 	{"OscB-Transpose", 0, C6, R2, S1, S1, 0, 5, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
150 	{"OscB-Tunine", 0, C9, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, BRIGHTON_NOTCH},
151 	{"OscB-Ramp", 2, CB9, RB2, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0},
152 	{"OscB-Tri", 2, CB10, RB2, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0},
153 	{"OscB-Pulse", 2, CB11, RB2, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0},
154 	{"OscB-PW", 0, C10, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
155 	{"OscB-LFO", 2, CB12, RB2, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0},
156 	{"OscB-KBD", 2, CB13, RB2, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0},
157 /* glide, etc */
158 	{"Glide", 0, C6, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
159 	{"Unison", 2, CB7, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0},
160 /* mixer */
161 	{"Mix-OscA", 0, C11, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
162 	{"Mix-OscB", 0, C12, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
163 	{"Mix-Noise", 0, C13, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
164 /* filter + env */
165 	{"VCF-Cutoff", 0, C14, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
166 	{"VCF-Resonance", 0, C15, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
167 	{"VCF-Envelope", 0, C16, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
168 	{"VCF-KBD", 2, C17 + 6, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm", "bitmaps/buttons/presson.xpm", 0},
169 	{"VCF-Attack", 0, C14, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
170 	{"VCF-Decay", 0, C15, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
171 	{"VCF-Sustain", 0, C16, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
172 	{"VCF-Release", 0, C17, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
173 /* main env */
174 	{"VCA-Attack", 0, C18, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
175 	{"VCA-Decay", 0, C19, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
176 	{"VCA-Sustain", 0, C20, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
177 	{"VCA-Release", 0, C21, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
178 /* tune + vol */
179 	{"MasterTuning", 0, C18, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob3.xpm", 0, BRIGHTON_NOTCH},
180 	{"MasterVolume", 0, C23, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob3.xpm", 0, 0},
181 /* Chorus */
182 	{"Chorus-Speed", 0, C18, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
183 	{"Chorus-Depth", 0, C19, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
184 	{"Chorus-Phase", 0, C20, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
185 	{"Chorus-Gain", 0, C21, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob2.xpm", 0, 0},
186 /* opts */
187 	{"Release", 2, C23 + 7, RB2, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
188 		"bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON},
189 	{"A-440", 2, C19 + 7, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
190 		"bitmaps/buttons/pressong.xpm", 0},
191 	{"Tune", 2, C23 + 7, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
192 		"bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON},
193 /* memories */
194 	{"", 2, C14 + 10, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
195 		"bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
196 	{"", 2, C14 + 30, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
197 		"bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
198 	{"", 2, C14 + 50, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
199 		"bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
200 	{"", 2, C14 + 70, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
201 		"bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
202 	{"", 2, C14 + 90, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
203 		"bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
204 	{"", 2, C14 + 110, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
205 		"bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
206 	{"", 2, C14 + 130, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
207 		"bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
208 	{"", 2, C14 + 150, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
209 		"bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
210 /* L/S */
211 	{"", 2, CB8 - 10, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
212 		"bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON},
213 	{"", 2, CB8 + 20, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffo.xpm",
214 		"bitmaps/buttons/pressono.xpm", BRIGHTON_CHECKBUTTON},
215 	{"", 2, CB8 + 50, RB3, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
216 		"bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON},
217 /* Midi, perhaps eventually file import/export buttons */
218 	{"", 2, C20 + 10, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
219 		"bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON},
220 	{"", 2, C21 + 10, RB1, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
221 		"bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON},
222 	/* */
223 	{"", 4, 840, 1025, 140, 130, 0, 1, 0, "bitmaps/images/prophet55.xpm", 0, 0},
224 	/* Display */
225 	{"", 3, CB8 + 75, RB3, 120, B2, 0, 1, 0, 0,
226 		"bitmaps/images/alphadisplay3.xpm", 0}
227 };
228 
229 /*
230  */
231 
232 /*
233  * This is a set of globals for the main window rendering. Again taken from
234  * include/brighton.h
235  */
236 brightonApp prophet52App = {
237 	"prophet52",
238 	0, /* no blueprint on wood background. */
239 	"bitmaps/textures/wood7.xpm", /* was wood2.xpm */
240 	0, /* BRIGHTON_STRETCH, //flags */
241 	prophet52Init,
242 	prophet52Configure, /* 3 callbacks, unused? */
243 	midiCallback,
244 	destroySynth,
245 	{5, 100, 2, 2, 5, 520, 0, 0},
246 	753, 310, 0, 0,
247 	6, /* one panel only */
248 	{
249 		{
250 			"Prophet",
251 			"bitmaps/blueprints/prophet52.xpm",
252 			"bitmaps/textures/metal4.xpm",
253 			0, /*BRIGHTON_STRETCH, // flags */
254 			0,
255 			0,
256 			prophet52Callback,
257 			15, 25, 970, 540,
258 			DEVICE_COUNT,
259 			locations
260 		},
261 		{
262 			"Keyboard",
263 			0,
264 			"bitmaps/newkeys/kbg.xpm", /* flags */
265 			0x020|BRIGHTON_STRETCH,
266 			0,
267 			0,
268 			keyCallback,
269 			110, 660, 900, 320,
270 			KEY_COUNT,
271 			keysprofile
272 		},
273 		{
274 			"Mods",
275 			"bitmaps/blueprints/prophetmod.xpm",
276 			"bitmaps/textures/metal4.xpm", /* flags */
277 			BRIGHTON_REVERSE,
278 			0,
279 			0,
280 			modCallback,
281 			15, 660, 95, 320,
282 			2,
283 			mods
284 		},
285 		{
286 			"Prophet",
287 			0,
288 			"bitmaps/textures/wood7.xpm",
289 			BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */
290 			0,
291 			0,
292 			0,
293 			0, 0, 15, 1000,
294 			0,
295 			0
296 		},
297 		{
298 			"Prophet",
299 			0,
300 			"bitmaps/textures/wood7.xpm",
301 			BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /*flags */
302 			0,
303 			0,
304 			0,
305 			985, 0, 15, 1000,
306 			0,
307 			0
308 		},
309 		{
310 			"Prophet",
311 			0,
312 			"bitmaps/textures/wood4.xpm",
313 			0, /*BRIGHTON_STRETCH|BRIGHTON_VERTICAL, //flags */
314 			0,
315 			0,
316 			0,
317 			15, 980, 970, 20,
318 			0,
319 			0
320 		}
321 	}
322 };
323 
324 /*static dispatcher dispatch[DEVICE_COUNT]; */
325 
326 static int
midiCallback(brightonWindow * win,int controller,int value,float n)327 midiCallback(brightonWindow *win, int controller, int value, float n)
328 {
329 	guiSynth *synth = findSynth(global.synths, win);
330 
331 	printf("midi callback: %x, %i\n", controller, value);
332 
333 	switch(controller)
334 	{
335 		case MIDI_PROGRAM:
336 			printf("midi program: %x, %i\n", controller, value);
337 			synth->location = value;
338 			loadMemory(synth, "prophet52", 0, synth->bank + synth->location,
339 				synth->mem.active, FIRST_DEV, 0);
340 			break;
341 		case MIDI_BANK_SELECT:
342 			printf("midi banksel: %x, %i\n", controller, value);
343 			synth->bank = value;
344 			break;
345 	}
346 	return(0);
347 }
348 
349 static int
prophet52MidiSendMsg(void * synth,int fd,int chan,int c,int o,int v)350 prophet52MidiSendMsg(void *synth, int fd, int chan, int c, int o, int v)
351 {
352 	bristolMidiSendMsg(fd, chan, c, o, v);
353 	return(0);
354 }
355 
356 static void
multiTune(guiSynth * synth,int fd,int chan,int c,int o,int v)357 multiTune(guiSynth *synth, int fd, int chan, int c, int o, int v)
358 {
359 	brightonEvent event;
360 
361 	/*
362 	 * Configures all the tune settings to zero (ie, 0.5). Do the Osc-A first,
363 	 * since it is not visible, and then request the GUI to configure Osc-B.
364 	 */
365 	bristolMidiSendMsg(fd, synth->sid, 0, 2, 8191);
366 	event.type = BRIGHTON_FLOAT;
367 	event.value = 0.5;
368 	brightonParamChange(synth->win, synth->panel, FIRST_DEV + 45,
369 		&event);
370 	brightonParamChange(synth->win, synth->panel, FIRST_DEV + 21,
371 		&event);
372 }
373 
374 static void
midiRelease(guiSynth * synth,int fd,int chan,int c,int o,int v)375 midiRelease(guiSynth *synth, int fd, int chan, int c, int o, int v)
376 {
377 	if (!global.libtest)
378 	{
379 		bristolMidiSendMsg(fd, synth->sid, 127, 0,
380 			BRISTOL_ALL_NOTES_OFF);
381 	}
382 }
383 
384 static void
prophet52Memory(guiSynth * synth,int fd,int chan,int c,int o,int v)385 prophet52Memory(guiSynth *synth, int fd, int chan, int c, int o, int v)
386 {
387 	brightonEvent event;
388 
389 /* printf("prophet52Memory(%i)\n", c); */
390 
391 	if (synth->flags & MEM_LOADING)
392 		return;
393 	if ((synth->flags & OPERATIONAL) == 0)
394 		return;
395 
396 	if (synth->dispatch[RADIOSET_1].other2)
397 	{
398 		synth->dispatch[RADIOSET_1].other2 = 0;
399 		return;
400 	}
401 
402 	switch (c) {
403 		default:
404 		case 0:
405 			/*
406 			 * We want to make these into memory buttons. To do so we need to
407 			 * know what the last active button was, and deactivate its
408 			 * display, then send any message which represents the most
409 			 * recently configured value. Since this is a memory button we do
410 			 * not have much issue with the message, but we are concerned with
411 			 * the display.
412 			 */
413 			if (synth->dispatch[RADIOSET_1].other1 != -1)
414 			{
415 				synth->dispatch[RADIOSET_1].other2 = 1;
416 
417 				if (synth->dispatch[RADIOSET_1].other1 != o)
418 					event.value = 0;
419 				else
420 					event.value = 1;
421 
422 				brightonParamChange(synth->win, synth->panel,
423 					synth->dispatch[RADIOSET_1].other1 + LAST_DEV + 2, &event);
424 			}
425 			synth->dispatch[RADIOSET_1].other1 = o;
426 
427 			if (synth->flags & BANK_SELECT) {
428 				if ((synth->bank * 10 + o * 10) >= 1000)
429 				{
430 					synth->location = o;
431 					synth->flags &= ~BANK_SELECT;
432 
433 					if (loadMemory(synth, "prophet52", 0,
434 						synth->bank + synth->location, synth->mem.active,
435 							FIRST_DEV, BRISTOL_STAT) < 0)
436 						displayText(synth, "FRE", synth->bank + synth->location,
437 							DISPLAY_DEV);
438 					else
439 						displayText(synth, "PRG", synth->bank + synth->location,
440 							DISPLAY_DEV);
441 				} else {
442 					synth->bank = synth->bank * 10 + o * 10;
443 					displayText(synth, "BANK", synth->bank + synth->location,
444 						DISPLAY_DEV);
445 				}
446 			} else {
447 				if (synth->bank < 10)
448 					synth->bank = 10;
449 				synth->location = o;
450 				if (loadMemory(synth, "prophet52", 0,
451 					synth->bank + synth->location, synth->mem.active,
452 						FIRST_DEV, BRISTOL_STAT) < 0)
453 					displayText(synth, "FRE", synth->bank + synth->location,
454 						DISPLAY_DEV);
455 				else
456 					displayText(synth, "PRG", synth->bank + synth->location,
457 						DISPLAY_DEV);
458 			}
459 			break;
460 		case 1:
461 			if (synth->bank < 10)
462 				synth->bank = 10;
463 			if (synth->location == 0)
464 				synth->location = 1;
465 			if (loadMemory(synth, "prophet52", 0, synth->bank + synth->location,
466 				synth->mem.active, FIRST_DEV, 0) < 0)
467 				displayText(synth, "FRE", synth->bank + synth->location,
468 					DISPLAY_DEV);
469 			else
470 				displayText(synth, "PRG", synth->bank + synth->location,
471 					DISPLAY_DEV);
472 			synth->flags &= ~BANK_SELECT;
473 			break;
474 		case 2:
475 			if (synth->bank < 10)
476 				synth->bank = 10;
477 			if (synth->location == 0)
478 				synth->location = 1;
479 			saveMemory(synth, "prophet52", 0, synth->bank + synth->location,
480 				FIRST_DEV);
481 			displayText(synth, "PRG", synth->bank + synth->location,
482 				DISPLAY_DEV);
483 			synth->flags &= ~BANK_SELECT;
484 			break;
485 		case 3:
486 			if (synth->flags & BANK_SELECT) {
487 				synth->flags &= ~BANK_SELECT;
488 				if (loadMemory(synth, "prophet52", 0,
489 					synth->bank + synth->location, synth->mem.active,
490 						FIRST_DEV, BRISTOL_STAT) < 0)
491 					displayText(synth, "FRE", synth->bank + synth->location,
492 						DISPLAY_DEV);
493 				else
494 					displayText(synth, "PRG", synth->bank + synth->location,
495 						DISPLAY_DEV);
496 			} else {
497 				synth->bank = 0;
498 				displayText(synth, "BANK", synth->bank, DISPLAY_DEV);
499 				synth->flags |= BANK_SELECT;
500 			}
501 			break;
502 	}
503 /*	printf("	prophet52Memory(B: %i L %i: %i)\n", */
504 /*		synth->bank, synth->location, o); */
505 }
506 
507 static int
prophet52Midi(guiSynth * synth,int fd,int chan,int c,int o,int v)508 prophet52Midi(guiSynth *synth, int fd, int chan, int c, int o, int v)
509 {
510 	int newchan;
511 
512 	if ((synth->flags & OPERATIONAL) == 0)
513 		return(0);
514 
515 	if (c == 1) {
516 		if ((newchan = synth->midichannel - 1) < 0)
517 		{
518 			synth->midichannel = 0;
519 			return(0);
520 		}
521 	} else {
522 		if ((newchan = synth->midichannel + 1) >= 16)
523 		{
524 			synth->midichannel = 15;
525 			return(0);
526 		}
527 	}
528 
529 	if (global.libtest == 0)
530 	{
531 		bristolMidiSendMsg(global.controlfd, synth->sid,
532 			127, 0, BRISTOL_MIDICHANNEL|newchan);
533 	}
534 
535 	displayText(synth, "MIDI", newchan + 1, DISPLAY_DEV);
536 
537 	synth->midichannel = newchan;
538 
539 /*	printf("P: going to display: %x, %x\n", synth, synth->win); */
540 /*		displayText(synth, "MIDI", synth->midichannel + 1, DISPLAY_DEV); */
541 
542 	return(0);
543 }
544 
545 /*
546  * For the sake of ease of use, links have been placed here to be called
547  * by any of the devices created. They would be better in some other file,
548  * perhaps with this as a dispatch.
549  *
550  * Param refers to the device index in the locations table given below.
551  */
552 static int
prophet52Callback(brightonWindow * win,int panel,int index,float value)553 prophet52Callback(brightonWindow * win, int panel, int index, float value)
554 {
555 	guiSynth *synth = findSynth(global.synths, win);
556 	int sendvalue;
557 
558 /* printf("prophet52Callback(%i, %f): %x\n", index, value, synth); */
559 
560 	if (synth == 0)
561 		return(0);
562 
563 	if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0))
564 		return(0);
565 
566 	if (prophet52App.resources[0].devlocn[index].to == 1.0)
567 		sendvalue = value * (CONTROLLER_RANGE - 1);
568 	else
569 		sendvalue = value;
570 
571 	synth->mem.param[index] = value;
572 
573 	if ((!global.libtest) || (index >= ACTIVE_DEVS))
574 		synth->dispatch[index].routine(synth,
575 			global.controlfd, synth->sid,
576 			synth->dispatch[index].controller,
577 			synth->dispatch[index].operator,
578 			sendvalue);
579 
580 #ifdef DEBUG
581 	else
582 		printf("dispatch[%p,%i](%i, %i, %i, %i, %i)\n", synth, index,
583 			global.controlfd, synth->sid,
584 			synth->dispatch[index].controller,
585 			synth->dispatch[index].operator,
586 			sendvalue);
587 #endif
588 
589 	return(0);
590 }
591 
592 static void
keyTracking(guiSynth * synth,int fd,int chan,int c,int o,int v)593 keyTracking(guiSynth *synth, int fd, int chan, int c, int o, int v)
594 {
595 	bristolMidiSendMsg(fd, synth->sid, 4, 3, v / 2);
596 }
597 
598 /*
599  * Any location initialisation required to run the callbacks. For bristol, this
600  * will connect to the engine, and give it some base parameters.
601  * May need to generate some application specific menus.
602  * Will also then make specific requests to some of the devices to alter their
603  * rendering.
604  */
605 static int
prophet52Init(brightonWindow * win)606 prophet52Init(brightonWindow *win)
607 {
608 	guiSynth *synth = findSynth(global.synths, win);
609 	dispatcher *dispatch;
610 	int i;
611 
612 	if (synth == 0)
613 	{
614 		synth = findSynth(global.synths, (int) 0);
615 		if (synth == 0)
616 		{
617 			printf("cannot init\n");
618 			return(0);
619 		}
620 	}
621 
622 	synth->win = win;
623 
624 	if ((initmem = synth->location) == 0)
625 		initmem = 11;
626 
627 	printf("Initialise the prophet52 link to bristol: %p\n", synth->win);
628 
629 	synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float));
630 	synth->mem.count = DEVICE_COUNT;
631 	synth->mem.active = ACTIVE_DEVS;
632 	synth->dispatch = (dispatcher *)
633 		brightonmalloc(DEVICE_COUNT * sizeof(dispatcher));
634 	dispatch = synth->dispatch;
635 
636 	/*
637 	 * We really want to have three connection mechanisms. These should be
638 	 *	1. Unix named sockets.
639 	 *	2. UDP sockets.
640 	 *	3. MIDI pipe.
641 	 */
642 	if (!global.libtest)
643 	{
644 		if ((synth->sid = initConnection(&global, synth)) < 0)
645 			return(-1);
646 	}
647 
648 	for (i = 0; i < DEVICE_COUNT; i++)
649 	{
650 		synth->dispatch[i].routine = prophet52MidiSendMsg;
651 	}
652 
653 	dispatch[FIRST_DEV].controller = 126;
654 	dispatch[FIRST_DEV].operator = 6;
655 	dispatch[FIRST_DEV + 1].controller = 126;
656 	dispatch[FIRST_DEV + 1].operator = 7;
657 	dispatch[FIRST_DEV + 2].controller = 126;
658 	dispatch[FIRST_DEV + 2].operator = 8;
659 	dispatch[FIRST_DEV + 3].controller = 126;
660 	dispatch[FIRST_DEV + 3].operator = 9;
661 	dispatch[FIRST_DEV + 4].controller = 126;
662 	dispatch[FIRST_DEV + 4].operator = 10;
663 
664 	dispatch[FIRST_DEV + 5].controller = 2;
665 	dispatch[FIRST_DEV + 5].operator = 0;
666 	dispatch[FIRST_DEV + 6].controller = 126;
667 	dispatch[FIRST_DEV + 6].operator = 24;
668 	dispatch[FIRST_DEV + 7].controller = 126;
669 	dispatch[FIRST_DEV + 7].operator = 25;
670 	dispatch[FIRST_DEV + 8].controller = 126;
671 	dispatch[FIRST_DEV + 8].operator = 26;
672 
673 	dispatch[FIRST_DEV + 9].controller = 126;
674 	dispatch[FIRST_DEV + 9].operator = 11;
675 	dispatch[FIRST_DEV + 10].controller = 126;
676 	dispatch[FIRST_DEV + 10].operator = 12;
677 	dispatch[FIRST_DEV + 11].controller = 126;
678 	dispatch[FIRST_DEV + 11].operator = 13;
679 	dispatch[FIRST_DEV + 12].controller = 126;
680 	dispatch[FIRST_DEV + 12].operator = 14;
681 	dispatch[FIRST_DEV + 13].controller = 126;
682 	dispatch[FIRST_DEV + 13].operator = 15;
683 	dispatch[FIRST_DEV + 14].controller = 126;
684 	dispatch[FIRST_DEV + 14].operator = 16;
685 
686 	dispatch[FIRST_DEV + 15].controller = 0;
687 	dispatch[FIRST_DEV + 15].operator = 1;
688 	dispatch[FIRST_DEV + 16].controller = 0;
689 	dispatch[FIRST_DEV + 16].operator = 4;
690 	dispatch[FIRST_DEV + 17].controller = 0;
691 	dispatch[FIRST_DEV + 17].operator = 6;
692 	dispatch[FIRST_DEV + 18].controller = 0;
693 	dispatch[FIRST_DEV + 18].operator = 0;
694 	dispatch[FIRST_DEV + 19].controller = 0;
695 	dispatch[FIRST_DEV + 19].operator = 7;
696 
697 	dispatch[FIRST_DEV + 20].controller = 1;
698 	dispatch[FIRST_DEV + 20].operator = 1;
699 	dispatch[FIRST_DEV + 21].controller = 1;
700 	dispatch[FIRST_DEV + 21].operator = 2;
701 	dispatch[FIRST_DEV + 22].controller = 1;
702 	dispatch[FIRST_DEV + 22].operator = 4;
703 	dispatch[FIRST_DEV + 23].controller = 1;
704 	dispatch[FIRST_DEV + 23].operator = 5;
705 	dispatch[FIRST_DEV + 24].controller = 1;
706 	dispatch[FIRST_DEV + 24].operator = 6;
707 	dispatch[FIRST_DEV + 25].controller = 1;
708 	dispatch[FIRST_DEV + 25].operator = 0;
709 	dispatch[FIRST_DEV + 26].controller = 126;
710 	dispatch[FIRST_DEV + 26].operator = 18;
711 	dispatch[FIRST_DEV + 27].controller = 126;
712 	dispatch[FIRST_DEV + 27].operator = 19;
713 
714 	dispatch[FIRST_DEV + 28].controller = 126;
715 	dispatch[FIRST_DEV + 28].operator = 0;
716 	dispatch[FIRST_DEV + 29].controller = 126;
717 	dispatch[FIRST_DEV + 29].operator = 1;
718 
719 	dispatch[FIRST_DEV + 30].controller = 126;
720 	dispatch[FIRST_DEV + 30].operator = 20;
721 	dispatch[FIRST_DEV + 31].controller = 126;
722 	dispatch[FIRST_DEV + 31].operator = 21;
723 	dispatch[FIRST_DEV + 32].controller = 126;
724 	dispatch[FIRST_DEV + 32].operator = 22;
725 
726 	dispatch[FIRST_DEV + 33].controller = 4;
727 	dispatch[FIRST_DEV + 33].operator = 0;
728 	dispatch[FIRST_DEV + 34].controller = 4;
729 	dispatch[FIRST_DEV + 34].operator = 1;
730 	dispatch[FIRST_DEV + 35].controller = 126;
731 	dispatch[FIRST_DEV + 35].operator = 23;
732 	dispatch[FIRST_DEV + 36].controller = 4;
733 	dispatch[FIRST_DEV + 36].operator = 3;
734 	dispatch[FIRST_DEV + 36].routine = (synthRoutine) keyTracking;
735 	dispatch[FIRST_DEV + 37].controller = 3;
736 	dispatch[FIRST_DEV + 37].operator = 0;
737 	dispatch[FIRST_DEV + 38].controller = 3;
738 	dispatch[FIRST_DEV + 38].operator = 1;
739 	dispatch[FIRST_DEV + 39].controller = 3;
740 	dispatch[FIRST_DEV + 39].operator = 2;
741 	dispatch[FIRST_DEV + 40].controller = 3;
742 	dispatch[FIRST_DEV + 40].operator = 3;
743 
744 	dispatch[FIRST_DEV + 41].controller = 5;
745 	dispatch[FIRST_DEV + 41].operator = 0;
746 	dispatch[FIRST_DEV + 42].controller = 5;
747 	dispatch[FIRST_DEV + 42].operator = 1;
748 	dispatch[FIRST_DEV + 43].controller = 5;
749 	dispatch[FIRST_DEV + 43].operator = 2;
750 	dispatch[FIRST_DEV + 44].controller = 5;
751 	dispatch[FIRST_DEV + 44].operator = 3;
752 
753 	dispatch[FIRST_DEV + 45].controller = 126;
754 	dispatch[FIRST_DEV + 45].operator = 2;
755 	dispatch[FIRST_DEV + 46].controller = 5;
756 	dispatch[FIRST_DEV + 46].operator = 4;
757 
758 	dispatch[FIRST_DEV + 47].controller = 126;
759 	dispatch[FIRST_DEV + 47].operator = 32;
760 	dispatch[FIRST_DEV + 48].controller = 126;
761 	dispatch[FIRST_DEV + 48].operator = 31;
762 	dispatch[FIRST_DEV + 49].controller = 126;
763 	dispatch[FIRST_DEV + 49].operator = 30;
764 	dispatch[FIRST_DEV + 50].controller = 126;
765 	dispatch[FIRST_DEV + 50].operator = 33;
766 
767 	dispatch[DEV_OFFSET + 49].controller = 1;
768 	dispatch[DEV_OFFSET + 49].operator = 1;
769 	dispatch[DEV_OFFSET + 49].routine = (synthRoutine) midiRelease;
770 	dispatch[DEV_OFFSET + 50].controller = 126;
771 	dispatch[DEV_OFFSET + 50].operator = 3;
772 	dispatch[DEV_OFFSET + 51].controller = 1;
773 	dispatch[DEV_OFFSET + 51].operator = 1;
774 	dispatch[DEV_OFFSET + 51].routine = (synthRoutine) multiTune;
775 
776 	dispatch[DEV_OFFSET + 52].operator = 1;
777 	dispatch[DEV_OFFSET + 53].operator = 2;
778 	dispatch[DEV_OFFSET + 54].operator = 3;
779 	dispatch[DEV_OFFSET + 55].operator = 4;
780 	dispatch[DEV_OFFSET + 56].operator = 5;
781 	dispatch[DEV_OFFSET + 57].operator = 6;
782 	dispatch[DEV_OFFSET + 58].operator = 7;
783 	dispatch[DEV_OFFSET + 59].operator = 8;
784 
785 	dispatch[DEV_OFFSET + 60].controller = 1;
786 	dispatch[DEV_OFFSET + 61].controller = 2;
787 	dispatch[DEV_OFFSET + 62].controller = 3;
788 
789 	dispatch[DEV_OFFSET + 52].routine =
790 		dispatch[DEV_OFFSET + 53].routine =
791 		dispatch[DEV_OFFSET + 54].routine =
792 		dispatch[DEV_OFFSET + 55].routine =
793 		dispatch[DEV_OFFSET + 56].routine =
794 		dispatch[DEV_OFFSET + 57].routine =
795 		dispatch[DEV_OFFSET + 58].routine =
796 		dispatch[DEV_OFFSET + 59].routine =
797 		dispatch[DEV_OFFSET + 60].routine =
798 		dispatch[DEV_OFFSET + 61].routine =
799 		dispatch[DEV_OFFSET + 62].routine
800 			= (synthRoutine) prophet52Memory;
801 
802 	dispatch[DEV_OFFSET + 63].routine = dispatch[DEV_OFFSET + 64].routine =
803 		(synthRoutine) prophet52Midi;
804 	dispatch[DEV_OFFSET + 63].controller = 1;
805 	dispatch[DEV_OFFSET + 64].controller = 2;
806 
807 	dispatch[RADIOSET_1].other1 = -1;
808 
809 	/* Tune osc-1 */
810 	bristolMidiSendMsg(global.controlfd, synth->sid, 0, 2, 8192);
811 	/* Gain on filter contour */
812 	bristolMidiSendMsg(global.controlfd, synth->sid, 3, 4,
813 		CONTROLLER_RANGE - 1);
814 	bristolMidiSendMsg(global.controlfd, synth->sid, 4, 4, 4);
815 
816 	return(0);
817 }
818 
819 /*
820  * This will be called to make any routine specific parameters available.
821  */
822 static int
prophet52Configure(brightonWindow * win)823 prophet52Configure(brightonWindow *win)
824 {
825 	guiSynth *synth = findSynth(global.synths, win);
826 	brightonEvent event;
827 
828 	if (synth == 0)
829 	{
830 		printf("problems going operational\n");
831 		return(-1);
832 	}
833 
834 	if (synth->flags & OPERATIONAL)
835 		return(0);
836 
837 printf("going operational\n");
838 
839 	synth->flags |= OPERATIONAL;
840 	synth->keypanel = 1;
841 	synth->keypanel2 = -1;
842 	synth->transpose = 36;
843 
844 	if (synth->location == 0)
845 	{
846 		synth->bank = 10;
847 		synth->location = 1;
848 	}
849 	loadMemory(synth, "prophet52", 0, initmem, synth->mem.active, FIRST_DEV, 0);
850 
851 	brightonPut(win,
852 		"bitmaps/blueprints/prophet52shade.xpm", 0, 0, win->width, win->height);
853 
854 	/*
855 	 * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only
856 	 * occurs on first paint, so we suppress the first paint, and then request
857 	 * an expose here.
858 	 */
859 	event.type = BRIGHTON_EXPOSE;
860 	event.intvalue = 1;
861 	brightonParamChange(synth->win, KEY_PANEL, -1, &event);
862 	configureGlobals(synth);
863 
864 	return(0);
865 }
866 
867