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