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 #include <fcntl.h>
23 
24 #include "brighton.h"
25 #include "brightonMini.h"
26 #include "brightoninternals.h"
27 
28 static int realisticInit();
29 static int realisticConfigure();
30 static int realisticCallback(brightonWindow *, int, int, float);
31 static int realisticMidiCallback(brightonWindow *, int, int, float);
32 
33 extern guimain global;
34 
35 #include "brightonKeys.h"
36 
37 #define OPTS_PANEL 0
38 #define MOD_PANEL 1
39 #define KEY_PANEL 1
40 
41 #define FIRST_DEV 0
42 
43 #define MOD_COUNT 31
44 
45 #define OPTS_START 0
46 
47 #define ACTIVE_DEVS (MOD_COUNT - 3)
48 #define DEVICE_COUNT (MOD_COUNT)
49 
50 extern int memCallback(brightonWindow * , int, int, float);
51 extern brightonLocations mem[];
52 
53 /*
54  * This structure is for device definition. The structure is defined in
55  * include/brighton.h, further definitions in brighton/brightonDevtable.h and
56  * include/brightoninternals.h
57  *
58  *	typedef int (*brightonCallback)(int, float);
59  *	typedef struct BrightonLocations {
60  *		int device; 0=rotary, 1=scale, etc.
61  *		float relx, rely; relative position with regards to 1000 by 1000 window
62  *		float relw, relh; relative height.
63  *		int from, to;
64  *		brightonCallback callback; specific to this dev
65  *		char *image; bitmap. If zero take a device default.
66  *		int flags;
67  *	} brightonLocations;
68  *
69  * This example is for a realisticBristol type synth interface.
70  */
71 
72 #define R0 100
73 #define R1 (R0 + 80)
74 #define R2 (R0 + 180)
75 #define R3 570
76 #define R4 (R3 + 50)
77 #define R5 (R4 + 50)
78 
79 #define W1 20
80 #define W2 42
81 #define W3 170
82 #define W4 16
83 #define L1 280
84 #define L2 55
85 #define L3 150
86 
87 #define D1 48
88 #define D2 12
89 #define C1 40
90 #define C2 (C1 + D1)
91 #define C3 (C2 + D1)
92 #define C4 (C3 + D1 + D1)
93 #define C5 (C4 + D1 + D1)
94 #define C6 (C5 + D1)
95 #define C7 (C6 + D1)
96 #define C8 (C7 + D1 + D1)
97 #define C9 (C8 + D1 + D1)
98 #define C10 (C9 + D1)
99 #define C11 (C10 + D1 + 30)
100 #define C12 (C11 + D1)
101 #define C13 (C12 + D1)
102 #define C14 (C13 + D1)
103 #define C15 (C14 + D1)
104 
105 static brightonLocations locations[MOD_COUNT] = {
106 	/* Tune 0 */
107 	{"SynthTuning", 0, C1 - 10, R0 + 50, W3, W3, 0, 1, 0, "bitmaps/knobs/knob3.xpm", 0,
108 		BRIGHTON_NOTCH},
109 	{"PolyTuning", 0, C3 - 15, R0 + 50, W3, W3, 0, 1, 0, "bitmaps/knobs/knob3.xpm", 0,
110 		BRIGHTON_NOTCH},
111 
112 	/* Mods 2 */
113 	{"Mod-Tone", 1, C1, R3, W1, L1, 0, 1, 0,
114 		"bitmaps/knobs/knob7.xpm", 0, 0},
115 	{"Mod-Filter", 1, C2, R3, W1, L1, 0, 1, 0,
116 		"bitmaps/knobs/knob7.xpm", 0, 0},
117 	{"Mod-Glide", 1, C3, R3, W1, L1, 0, 1, 0,
118 		"bitmaps/knobs/knob7.xpm", 0, 0},
119 	{"Mod-LFO-Rate", 1, C4, R3, W1, L1, 0, 1, 0,
120 		"bitmaps/knobs/knob7.xpm", 0, 0},
121 	{"Mod-Shape", 2, C4 - D2, R0, W2, L2, 0, 2, 0, 0, 0,
122 		BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW|BRIGHTON_VERTICAL},
123 	{"Mod-EnvTrig", 2, C4 - D2, R2 + 50, W2, L2, 0, 1, 0, "bitmaps/buttons/sw3.xpm",
124 		"bitmaps/buttons/sw5.xpm", BRIGHTON_NOSHADOW|BRIGHTON_VERTICAL},
125 
126 	/* Osc-1 8 */
127 	{"Osc1-Sync", 2, C5, R1, W2, L2, 0, 1, 0,
128 		"bitmaps/buttons/sw3.xpm", "bitmaps/buttons/sw5.xpm",
129 		BRIGHTON_NOSHADOW|BRIGHTON_VERTICAL},
130 	{"Osc1-Transpose", 2, C6 + 20, R0 + 40, W4, L3, 0, 2, 0,
131 		0, 0, BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW},
132 	{"Osc1-Waveform", 2, C7 + 15, R1, W2, L2, 0, 1, 0,
133 		"bitmaps/buttons/sw3.xpm", "bitmaps/buttons/sw5.xpm",
134 		BRIGHTON_NOSHADOW|BRIGHTON_VERTICAL},
135 
136 	/* Osc-2 11 */
137 	{"Osc2-Detune", 1, C5, R3, W1, L1, 0, 1, 0,
138 		"bitmaps/knobs/knob7.xpm", 0, BRIGHTON_NOTCH},
139 	{"Osc2-Transpose", 2, C6 + 20, R4 + 40, W4, L3, 0, 2, 0,
140 		0, 0, BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW},
141 	{"Osc2-Waveform", 2, C7 + 15, R5, W2, L2, 0, 1, 0,
142 		"bitmaps/buttons/sw3.xpm", "bitmaps/buttons/sw5.xpm",
143 		BRIGHTON_NOSHADOW|BRIGHTON_VERTICAL},
144 
145 	/* Contour 14 */
146 	{"Env-AR/ASR", 2, C8 + 6, R0, W2, L2, 0, 2, 0,
147 		"bitmaps/buttons/sw3.xpm", "bitmaps/buttons/sw5.xpm",
148 		BRIGHTON_NOSHADOW|BRIGHTON_VERTICAL},
149 	{"Env-Trigger", 2, C8 + 6, R2, W2, L2, 0, 2, 0,
150 		0, 0, BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW|BRIGHTON_VERTICAL},
151 	{"Env-Attack", 1, C9, R0, W1, L1, 0, 1, 0,
152 		"bitmaps/knobs/knob7.xpm", 0, 0},
153 	{"Env-Release", 1, C10, R0, W1, L1, 0, 1, 0,
154 		"bitmaps/knobs/knob7.xpm", 0, 0},
155 
156 	/* Filter 18 */
157 	{"VCF-KeyTrack", 2, C8 + 6, R5, W2, L2, 0, 2, 0,
158 		0, 0, BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW|BRIGHTON_VERTICAL},
159 	{"VCF-Cutoff", 1, C9 - 25, R3, W1, L1, 0, 1, 0,
160 		"bitmaps/knobs/knob7.xpm", 0, 0},
161 	{"VCF-Emphasis", 1, C9 + 25, R3, W1, L1, 0, 1, 0,
162 		"bitmaps/knobs/knob7.xpm", 0, 0},
163 	{"VCF-Env", 1, C10 + 20, R3, W1, L1, 0, 1, 0,
164 		"bitmaps/knobs/knob7.xpm", 0, 0},
165 
166 	/* Mixer 22 */
167 	{"Mix-Osc1", 1, C11, R3, W1, L1, 0, 1, 0,
168 		"bitmaps/knobs/knob7.xpm", 0, 0},
169 	{"Mix-Osc2", 1, C12, R3, W1, L1, 0, 1, 0,
170 		"bitmaps/knobs/knob7.xpm", 0, 0},
171 	{"Mix-Noise", 1, C13, R3, W1, L1, 0, 1, 0,
172 		"bitmaps/knobs/knob7.xpm", 0, 0},
173 	{"Mix-Bell", 1, C14, R3, W1, L1, 0, 1, 0,
174 		"bitmaps/knobs/knob7.xpm", 0, 0},
175 	{"Mix-Poly", 1, C15, R3, W1, L1, 0, 1, 0,
176 		"bitmaps/knobs/knob7.xpm", 0, 0},
177 
178 	/* Volume 27 */
179 	{"MasterVolume", 0, C13 - 15, R0 + 50, W3, W3, 0, 1, 0, "bitmaps/knobs/knob3.xpm", 0, 0},
180 
181 	/* Midi Up/Down, save */
182 	{"", 2, C15, R0, W1, 100, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
183 		"bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_WITHDRAWN},
184 	{"", 2, C15, R2, W1, 100, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
185 		"bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_WITHDRAWN},
186 	{"", 2, C15, R2 + 120, W1, 100, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
187 		"bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON},
188 };
189 
190 #define S1 200
191 
192 /*
193  * This is a set of globals for the main window rendering. Again taken from
194  * include/brighton.h
195  */
196 brightonApp realisticApp = {
197 	"realistic",
198 	0, /* no blueprint on wood background. */
199 	"bitmaps/textures/metal6.xpm",
200 	BRIGHTON_STRETCH,
201 	realisticInit,
202 	realisticConfigure, /* 3 callbacks */
203 	realisticMidiCallback,
204 	0,
205 	/* This looks like 32 voices however the synth is single voice in preops */
206 	{32, 100, 2, 2, 5, 520, 0, 0},
207 	600, 320, 0, 0,
208 	2, /* panel count */
209 	{
210 		{
211 			"Mods",
212 			"bitmaps/blueprints/realistic.xpm",
213 			0,
214 			BRIGHTON_STRETCH,
215 			0,
216 			0,
217 			realisticCallback,
218 			22, 0, 975, 500,
219 			MOD_COUNT,
220 			locations
221 		},
222 		{
223 			"Keyboard",
224 			0,
225 			"bitmaps/newkeys/ekbg.xpm", /* flags */
226 			0x020|BRIGHTON_STRETCH,
227 			0,
228 			0,
229 			keyCallback,
230 			100, 570, 810, 430,
231 			KEY_COUNT_2OCTAVE2,
232 			keys2octave2
233 		},
234 	}
235 };
236 
237 /*static dispatcher dispatch[DEVICE_COUNT]; */
238 
239 static int
realisticMidiSendMsg(void * synth,int fd,int chan,int c,int o,int v)240 realisticMidiSendMsg(void *synth, int fd, int chan, int c, int o, int v)
241 {
242 /* printf("realisticMidiSendMsg(%i, %i, %i)\n", c, o, v); */
243 	bristolMidiSendMsg(fd, chan, c, o, v);
244 	return(0);
245 }
246 
247 /*
248  * For the sake of ease of use, links have been placed here to be called
249  * by any of the devices created. They would be better in some other file,
250  * perhaps with this as a dispatch.
251  *
252  * Param refers to the device index in the locations table given below.
253  */
254 static int
realisticCallback(brightonWindow * win,int panel,int index,float value)255 realisticCallback(brightonWindow * win, int panel, int index, float value)
256 {
257 	guiSynth *synth = findSynth(global.synths, win);
258 	int sendvalue;
259 
260 /*	printf("realisticCallback(%i, %i, %f): %x\n", panel, index, value, synth); */
261 
262 	if (synth == 0)
263 		return(0);
264 
265 	if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0))
266 		return(0);
267 
268 	if (realisticApp.resources[panel].devlocn[index].to == 1)
269 		sendvalue = value * C_RANGE_MIN_1;
270 	else
271 		sendvalue = value;
272 
273 	switch (panel) {
274 		case OPTS_PANEL:
275 			index += OPTS_START;
276 			break;
277 	}
278 
279 	synth->mem.param[index] = value;
280 
281 	if ((!global.libtest) || (index >= ACTIVE_DEVS))
282 		synth->dispatch[index].routine(synth,
283 			global.controlfd, synth->sid,
284 			synth->dispatch[index].controller,
285 			synth->dispatch[index].operator,
286 			sendvalue);
287 #define DEBUG
288 #ifdef DEBUG
289 	else
290 		printf("dispatch[%p,%i](%i, %i, %i, %i, %i)\n", synth, index,
291 			global.controlfd, synth->sid,
292 			synth->dispatch[index].controller,
293 			synth->dispatch[index].operator,
294 			sendvalue);
295 #endif
296 
297 	return(0);
298 }
299 
300 static void
realisticOscTransp(guiSynth * synth,int fd,int chan,int cont,int op,int value)301 realisticOscTransp(guiSynth *synth, int fd, int chan, int cont, int op, int value)
302 {
303 printf("transp %i %i\n", cont, value);
304 	if (cont == 0) {
305 		switch (value) {
306 			case 0:
307 				value = 2;
308 				break;
309 			case 1:
310 				value = 1;
311 				break;
312 			case 2:
313 				value = 0;
314 				break;
315 		}
316 		bristolMidiSendMsg(global.controlfd, synth->sid, cont, 1, value);
317 	} else {
318 		switch (value) {
319 			case 0:
320 				value = 3;
321 				break;
322 			case 1:
323 				value = 2;
324 				break;
325 			case 2:
326 				value = 1;
327 				break;
328 		}
329 		bristolMidiSendMsg(global.controlfd, synth->sid, cont, 1, value);
330 	}
331 }
332 
333 static void
realisticGate(guiSynth * synth,int fd,int chan,int cont,int op,int value)334 realisticGate(guiSynth *synth, int fd, int chan, int cont, int op, int value)
335 {
336 printf("gate %i %i\n", cont, value);
337 	/*
338 	 * Whatever we do we have to send the gate value to the engine
339 	 */
340 	bristolMidiSendMsg(global.controlfd, synth->sid, cont, op, value);
341 
342 	/*
343 	 * Now, if the value is 0 we have been requested continuous notes. Need to
344 	 * decide what that means, but it could be interpreted as no note off
345 	 * events for the mono synth?
346 	 */
347 }
348 
349 static void
realisticOscWave(guiSynth * synth,int fd,int chan,int cont,int op,int value)350 realisticOscWave(guiSynth *synth, int fd, int chan, int cont, int op, int value)
351 {
352 printf("wave %i %i\n", cont, value);
353 	if (value == 0) {
354 		bristolMidiSendMsg(global.controlfd, synth->sid, cont, 5, 0);
355 		bristolMidiSendMsg(global.controlfd, synth->sid, cont, 6, 1);
356 	} else {
357 		bristolMidiSendMsg(global.controlfd, synth->sid, cont, 5, 1);
358 		bristolMidiSendMsg(global.controlfd, synth->sid, cont, 6, 0);
359 	}
360 }
361 
362 static void
realisticDecay(guiSynth * synth,int fd,int chan,int cont,int op,int value)363 realisticDecay(guiSynth *synth, int fd, int chan, int cont, int op, int value)
364 {
365 	int iv = synth->mem.param[17] * C_RANGE_MIN_1;
366 
367 	/* Always configure the DR values */
368 	bristolMidiSendMsg(global.controlfd, synth->sid, 4, 1, iv);
369 	bristolMidiSendMsg(global.controlfd, synth->sid, 4, 3, iv);
370 
371 	if (synth->mem.param[14] == 0)
372 		bristolMidiSendMsg(global.controlfd, synth->sid, 4, 2, 16383);
373 	else
374 		bristolMidiSendMsg(global.controlfd, synth->sid, 4, 2, 0);
375 
376 return;
377 	/*
378 	 * Couple of oddities here. Firstly this is AR or ASR so we need to check
379 	 * the value of the sustain switch. Also, if we have autotrigger its just
380 	 * going to set sustain to 0.
381 	 */
382 	if (synth->mem.param[14] == 0) {
383 		/* Sustain is on, see if trigger allows it */
384 		if (synth->mem.param[7] != 0) {
385 printf("1: sustain on, trigger off\n");
386 			bristolMidiSendMsg(global.controlfd, synth->sid, 4, 2, 16383);
387 		} else {
388 printf("2: sustain on, trigger on\n");
389 			bristolMidiSendMsg(global.controlfd, synth->sid, 4, 2, 0);
390 		}
391 	} else {
392 		/* Sustain is off, turn it off */
393 printf("3: sustain off\n");
394 		bristolMidiSendMsg(global.controlfd, synth->sid, 4, 2, 0);
395 	}
396 
397 	/* And set the trigger if desired */
398 	if (cont == 126) {
399 		if (value == 1) {
400 			if (synth->mem.param[14] == 0) {
401 printf("4: sustain on, trigger off\n");
402 				bristolMidiSendMsg(global.controlfd, synth->sid, 4, 2, 16383);
403 			} else {
404 printf("5: sustain off, trigger off\n");
405 				bristolMidiSendMsg(global.controlfd, synth->sid, 4, 2, 0);
406 			}
407 		}
408 
409 		bristolMidiSendMsg(global.controlfd, synth->sid, 126, 9, value);
410 	}
411 }
412 
413 static void
realisticFiltKey(guiSynth * synth,int fd,int chan,int cont,int op,int value)414 realisticFiltKey(guiSynth *synth, int fd, int chan, int cont, int op, int value)
415 {
416 	int v;
417 
418 printf("filter key %i\n", value);
419 
420 	switch (value) {
421 		default:
422 		case 0:
423 			v = 16383;
424 			break;
425 		case 1:
426 			v = 4096;
427 			break;
428 		case 2:
429 			v = 0;
430 			break;
431 	}
432 	bristolMidiSendMsg(global.controlfd, synth->sid, 3, 3, v);
433 }
434 
435 static void
realisticMonoTuning(guiSynth * synth,int fd,int chan,int cont,int op,int value)436 realisticMonoTuning(guiSynth *synth, int fd, int chan, int cont, int op, int value)
437 {
438 	bristolMidiSendMsg(global.controlfd, synth->sid, 0, 10, value);
439 	bristolMidiSendMsg(global.controlfd, synth->sid, 1, 10, value);
440 }
441 
442 static void
realisticMemory(guiSynth * synth,int fd,int chan,int cont,int op,int value)443 realisticMemory(guiSynth *synth, int fd, int chan, int cont, int op, int value)
444 {
445 printf("Memory: %i, %i\n", synth->location, value);
446 
447 	if (synth->flags & SUPPRESS)
448 		return;
449 
450 	saveMemory(synth, "realistic", 0, synth->location, 0);
451 }
452 
453 static int
realisticMidiCallback(brightonWindow * win,int command,int value,float v)454 realisticMidiCallback(brightonWindow *win, int command, int value, float v)
455 {
456 	guiSynth *synth = findSynth(global.synths, win);
457 
458 	printf("midi callback: %x, %i\n", command, value);
459 
460 	switch(command)
461 	{
462 		case MIDI_PROGRAM:
463 			printf("midi program: %x, %i\n", command, value);
464 			synth->location = value;
465 
466 			realisticMemory(synth, global.controlfd, synth->sid,
467 				synth->dispatch[OPTS_START].controller,
468 				synth->dispatch[OPTS_START].operator, 1.0f);
469 
470 			break;
471 		case MIDI_BANK_SELECT:
472 			printf("midi banksel: %x, %i\n", command, value);
473 			synth->bank = value;
474 			break;
475 	}
476 	return(0);
477 }
478 
479 /*
480  * Any location initialisation required to run the callbacks. For bristol, this
481  * will connect to the engine, and give it some base parameters.
482  * May need to generate some application specific menus.
483  * Will also then make specific requests to some of the devices to alter their
484  * rendering.
485  */
486 static int
realisticInit(brightonWindow * win)487 realisticInit(brightonWindow *win)
488 {
489 	guiSynth *synth = findSynth(global.synths, win);
490 	dispatcher *dispatch;
491 	int i;
492 
493 	if (synth == 0)
494 	{
495 		synth = findSynth(global.synths, 0);
496 		if (synth == 0)
497 		{
498 			printf("cannot init\n");
499 			return(0);
500 		}
501 	}
502 
503 	synth->win = win;
504 
505 	printf("Initialise the Realistic link to bristol: %p\n", synth->win);
506 
507 	synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float));
508 	synth->mem.count = DEVICE_COUNT;
509 	synth->mem.active = ACTIVE_DEVS;
510 	synth->dispatch = (dispatcher *)
511 		brightonmalloc(DEVICE_COUNT * sizeof(dispatcher));
512 	dispatch = synth->dispatch;
513 
514 	/*
515 	 * We really want to have three connection mechanisms. These should be
516 	 *	1. Unix named sockets.
517 	 *	2. UDP sockets.
518 	 *	3. MIDI pipe.
519 	 */
520 	if (!global.libtest)
521 		if ((synth->sid = initConnection(&global, synth)) < 0)
522 			return(-1);
523 
524 	for (i = 0; i < DEVICE_COUNT; i++)
525 		synth->dispatch[i].routine = realisticMidiSendMsg;
526 
527 	synth->dispatch[MOD_COUNT - 1].routine
528 			= (synthRoutine) realisticMemory;
529 
530 	/* Mono tuning */
531 	dispatch[0].controller = 7;
532 	dispatch[0].operator = 10;
533 	dispatch[0].routine = (synthRoutine) realisticMonoTuning;
534 	/* Poly tuning */
535 	dispatch[1].controller = 7;
536 	dispatch[1].operator = 10;
537 
538 	/* Mods */
539 	dispatch[2].controller = 126;
540 	dispatch[2].operator = 4;
541 	dispatch[3].controller = 126;
542 	dispatch[3].operator = 5;
543 
544 	/* Glide */
545 	dispatch[4].controller = 126;
546 	dispatch[4].operator = 0;
547 
548 	/* LFO rate */
549 	dispatch[5].controller = 2;
550 	dispatch[5].operator = 0;
551 	/* LFO waveform */
552 	dispatch[6].controller = 126;
553 	dispatch[6].operator = 6;
554 	/* LFO Trigger */
555 	dispatch[7].controller = 126;
556 	dispatch[7].operator = 9;
557 
558 	/* Osc-1 sync, transpose, waveform */
559 	dispatch[8].controller = 1;
560 	dispatch[8].operator = 7;
561 	dispatch[9].controller = 0;
562 	dispatch[9].operator = 0;
563 	dispatch[9].routine = (synthRoutine) realisticOscTransp;
564 	dispatch[10].controller = 0;
565 	dispatch[10].operator = 0;
566 	dispatch[10].routine = (synthRoutine) realisticOscWave;
567 
568 	/* Osc-2 detune, transpose, waveform */
569 	dispatch[11].controller = 1;
570 	dispatch[11].operator = 2;
571 	dispatch[12].controller = 1;
572 	dispatch[12].operator = 0;
573 	dispatch[12].routine = (synthRoutine) realisticOscTransp;
574 	dispatch[13].controller = 1;
575 	dispatch[13].operator = 0;
576 	dispatch[13].routine = (synthRoutine) realisticOscWave;
577 
578 	/* Contour */
579 	dispatch[14].routine = (synthRoutine) realisticDecay;
580 	dispatch[15].controller = 126;
581 	dispatch[15].operator = 10;
582 	dispatch[15].routine = (synthRoutine) realisticGate;
583 	dispatch[16].controller = 4;
584 	dispatch[16].operator = 0;
585 	dispatch[17].routine = (synthRoutine) realisticDecay;
586 
587 	/* Filter tracking, freq, emf, contour */
588 	dispatch[18].routine = (synthRoutine) realisticFiltKey;
589 	dispatch[19].controller = 3;
590 	dispatch[19].operator = 0;
591 	dispatch[20].controller = 3;
592 	dispatch[20].operator = 1;
593 	dispatch[21].controller = 126;
594 	dispatch[21].operator = 11;
595 
596 	/* Osc-1 Mix */
597 	dispatch[22].controller = 126;
598 	dispatch[22].operator = 2;
599 	/* Osc-2 Mix */
600 	dispatch[23].controller = 126;
601 	dispatch[23].operator = 3;
602 	/* Noise Mix */
603 	dispatch[24].controller = 126;
604 	dispatch[24].operator = 7;
605 	/* Bell Mix */
606 	dispatch[25].controller = 9;
607 	dispatch[25].operator = 2;
608 	/* Poly Mix */
609 	dispatch[26].controller = 7;
610 	dispatch[26].operator = 3;
611 
612 	/* Master Volume */
613 	dispatch[27].controller = 126;
614 	dispatch[27].operator = 8;
615 
616 	/*
617 	 * We have a few parameters that need to be set here to control the
618 	 * poly grooming envelope
619 	 */
620 	bristolMidiSendMsg(global.controlfd, synth->sid, 8, 0, 10);
621 	bristolMidiSendMsg(global.controlfd, synth->sid, 8, 1, 10);
622 	bristolMidiSendMsg(global.controlfd, synth->sid, 8, 2, 8192);
623 	bristolMidiSendMsg(global.controlfd, synth->sid, 8, 3, 10);
624 	bristolMidiSendMsg(global.controlfd, synth->sid, 8, 4, 16383);
625 	/* Gain of poly osc */
626 	bristolMidiSendMsg(global.controlfd, synth->sid, 7, 0, 16383);
627 	bristolMidiSendMsg(global.controlfd, synth->sid, 7, 6, 1);
628 	/* Global tuning */
629 	bristolMidiSendMsg(global.controlfd, synth->sid, 126, 1, 8192);
630 	/* Mono waveform */
631 	bristolMidiSendMsg(global.controlfd, synth->sid, 0, 0, 16383);
632 	bristolMidiSendMsg(global.controlfd, synth->sid, 0, 3, 16383);
633 	bristolMidiSendMsg(global.controlfd, synth->sid, 1, 3, 16383);
634 	bristolMidiSendMsg(global.controlfd, synth->sid, 0, 7, 0);
635 	bristolMidiSendMsg(global.controlfd, synth->sid, 1, 0, 8192);
636 	/* Ring mod */
637 	bristolMidiSendMsg(global.controlfd, synth->sid, 9, 0, 16383);
638 	bristolMidiSendMsg(global.controlfd, synth->sid, 9, 1, 16383);
639 	bristolMidiSendMsg(global.controlfd, synth->sid, 9, 2, 16383);
640 	/* Noise gain */
641 	bristolMidiSendMsg(global.controlfd, synth->sid, 6, 0, 16383);
642 	/* Mono env */
643 	bristolMidiSendMsg(global.controlfd, synth->sid, 4, 2, 16383);
644 	bristolMidiSendMsg(global.controlfd, synth->sid, 4, 4, 16383);
645 	/* LFO Sync */
646 	bristolMidiSendMsg(global.controlfd, synth->sid, 2, 1, 1);
647 	/* Filter Type */
648 	bristolMidiSendMsg(global.controlfd, synth->sid, 3, 4, 4);
649 
650 	return(0);
651 }
652 
653 /*
654  * This will be called to make any routine specific parameters available.
655  */
656 static int
realisticConfigure(brightonWindow * win)657 realisticConfigure(brightonWindow *win)
658 {
659 	guiSynth *synth = findSynth(global.synths, win);
660 	brightonEvent event;
661 
662 	if (synth == 0)
663 	{
664 		printf("problems going operational\n");
665 		return(-1);
666 	}
667 
668 	if (synth->flags & OPERATIONAL)
669 		return(0);
670 
671 	printf("going operational\n");
672 
673 	synth->flags |= OPERATIONAL;
674 	synth->keypanel = KEY_PANEL;
675 	synth->keypanel2 = -1;
676 	synth->transpose = 41;
677 /*	loadMemory(synth, "realistic", 0, synth->location, synth->mem.active, */
678 /*		FIRST_DEV, 0); */
679 
680 	loadMemory(synth, "realistic", 0, synth->location, ACTIVE_DEVS, 0,
681 		BRISTOL_FORCE);
682 
683 	brightonPut(win,
684 		"bitmaps/blueprints/realshade.xpm", 0, 0, win->width, win->height);
685 
686 	/*
687 	 * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only
688 	 * occurs on first paint, so we suppress the first paint, and then request
689 	 * an expose here.
690 	 */
691 	event.type = BRIGHTON_EXPOSE;
692 	event.intvalue = 1;
693 	brightonParamChange(synth->win, KEY_PANEL, -1, &event);
694 	/*
695 	event.type = BRIGHTON_FLOAT;
696 	event.value = 1;
697 	brightonParamChange(synth->win, 0, 0, &event);
698 	*/
699 	configureGlobals(synth);
700 
701 	return(0);
702 }
703 
704