1 
2 /*
3 
4 Check out
5 
6 	parameter to effects
7 	gain of tri wave
8 	bit error in triwave
9 	touch response
10 
11  *  Diverse Bristol audio routines.
12  *  Copyright (c) by Nick Copeland <nickycopeland@hotmail.com> 1996,2012
13  *
14  *
15  *   This program is free software; you can redistribute it and/or modify
16  *   it under the terms of the GNU General Public License as published by
17  *   the Free Software Foundation; either version 3 of the License, or
18  *   (at your option) any later version.
19  *
20  *   This program is distributed in the hope that it will be useful,
21  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
22  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  *   GNU General Public License for more details.
24  *
25  *   You should have received a copy of the GNU General Public License
26  *   along with this program; if not, see <http://www.gnu.org/licenses/>.
27  *
28  */
29 
30 #include <fcntl.h>
31 
32 #include "brighton.h"
33 #include "brightonMini.h"
34 #include "brightoninternals.h"
35 
36 static int roadrunnerInit();
37 static int roadrunnerConfigure();
38 static int roadrunnerCallback(brightonWindow *, int, int, float);
39 static int midiCallback(brightonWindow *, int, int, float);
40 
41 extern guimain global;
42 static int dc, shade_id;
43 
44 #include "brightonKeys.h"
45 
46 #define OPTS_PANEL 0
47 #define MOD_PANEL 4
48 #define KEY_PANEL 2
49 #define MEM_PANEL 3
50 
51 #define MODS_COUNT 4
52 #define OPTS_COUNT 22
53 #define MEM_COUNT 14
54 
55 #define MODS_START 0
56 #define OPTS_START MODS_COUNT
57 #define MEM_START (OPTS_COUNT + OPTS_START)
58 
59 /* We use '+2' so that bass and treble get saved with memory */
60 #define ACTIVE_DEVS (MODS_COUNT + OPTS_COUNT + 2)
61 #define DEVICE_COUNT (ACTIVE_DEVS + MEM_COUNT - 2)
62 
63 /*
64  * This structure is for device definition. The structure is defined in
65  * include/brighton.h, further definitions in brighton/brightonDevtable.h and
66  * include/brightoninternals.h
67  *
68  *	typedef int (*brightonCallback)(int, float);
69  *	typedef struct BrightonLocations {
70  *		int device; 0=rotary, 1=scale, etc.
71  *		float relx, rely; relative position with regards to 1000 by 1000 window
72  *		float relw, relh; relative height.
73  *		int from, to;
74  *		brightonCallback callback; specific to this dev
75  *		char *image; bitmap. If zero take a device default.
76  *		int flags;
77  *	} brightonLocations;
78  *
79  * This example is for a roadrunnerBristol type synth interface.
80  */
81 
82 #define R1 400
83 
84 #define C1 15
85 #define C2 (C1 + 114)
86 #define C3 (C2 + 114)
87 #define C4 (C3 + 114)
88 
89 #define W1 100
90 #define L1 600
91 
92 static brightonLocations modspanel[MODS_COUNT] = {
93 	{"Tune", 1, C1, R1, W1, L1, 0, 1, 0, 0, 0,
94 		BRIGHTON_VERTICAL|BRIGHTON_REVERSE|BRIGHTON_NOSHADOW|BRIGHTON_NOTCH},
95 	{"LFO Frequency", 1, C2, R1, W1, L1, 0, 1, 0, 0, 0,
96 		BRIGHTON_VERTICAL|BRIGHTON_REVERSE|BRIGHTON_NOSHADOW},
97 	{"Vibrato", 1, C3, R1, W1, L1, 0, 1, 0, 0, 0,
98 		BRIGHTON_VERTICAL|BRIGHTON_REVERSE|BRIGHTON_NOSHADOW},
99 	{"Volume", 1, C4, R1, W1, L1, 0, 1, 0, 0, 0,
100 		BRIGHTON_VERTICAL|BRIGHTON_REVERSE|BRIGHTON_NOSHADOW},
101 };
102 
103 #define S1 200
104 
105 #define oW1 35
106 #define oL1 500
107 
108 #define oC1 16
109 #define oC2 66
110 #define oC3 116
111 
112 #define oC4 172
113 #define oC5 220
114 
115 #define oC6 270
116 
117 #define oC7 735
118 #define oC8 782
119 #define oC9 835
120 #define oC10 884
121 #define oC11 933
122 
123 #define oC12 592
124 #define oC13 642
125 #define oC14 692
126 
127 #define oC15 500
128 #define oC16 549
129 
130 #define WFS 308
131 #define oC50 (WFS + 0)
132 #define oC51 (WFS + 28)
133 #define oC52 (WFS + 69)
134 #define oC53 (WFS + 97)
135 #define oC54 (WFS + 138)
136 #define oC55 (WFS + 166)
137 
138 #define oC56 (WFS + 202)
139 
140 #define oR1 140
141 #define oR2 300
142 #define oR3 500
143 #define oR4 700
144 
145 static brightonLocations options[OPTS_COUNT] = {
146 	/* Osc parameters */
147 	{"Detune", 0, oC1, oR1, oW1, oL1, 0, 1, 0, 0, 0, BRIGHTON_REVERSE|BRIGHTON_NOTCH},
148 	{"PulseWidth", 0, oC2, oR1, oW1, oL1, 0, 1, 0, 0, 0, 0},
149 	{"PulseWidthMod", 0, oC3, oR1, oW1, oL1, 0, 1, 0, 0, 0, 0},
150 	/* waveforms */
151 	{"Bass 1", 2, oC50, 100, 27, 600, 0, 1, 0, "bitmaps/buttons/rockersmoothBB.xpm",
152 		"bitmaps/buttons/rockersmoothBBd.xpm", 0},
153 	{"Bass 2", 2, oC51, 100, 27, 600, 0, 1, 0, "bitmaps/buttons/rockersmoothBB.xpm",
154 		"bitmaps/buttons/rockersmoothBBd.xpm", 0},
155 	{"Mid 1", 2, oC52, 100, 27, 600, 0, 1, 0, "bitmaps/buttons/rockersmoothBBL.xpm",
156 		"bitmaps/buttons/rockersmoothBBLd.xpm", 0},
157 	{"Mid 2", 2, oC53, 100, 27, 600, 0, 1, 0, "bitmaps/buttons/rockersmoothBBL.xpm",
158 		"bitmaps/buttons/rockersmoothBBLd.xpm", 0},
159 	{"Treble 1", 2, oC54, 100, 27, 600, 0, 1, 0, "bitmaps/buttons/rockersmoothBC.xpm",
160 		"bitmaps/buttons/rockersmoothBCd.xpm", 0},
161 	{"Treble 2", 2, oC55, 100, 27, 600, 0, 1, 0, "bitmaps/buttons/rockersmoothBC.xpm",
162 		"bitmaps/buttons/rockersmoothBCd.xpm", BRIGHTON_NOSHADOW},
163 
164 	/* The remaining envelope parameters */
165 	{"Decay", 0, oC4, oR1, oW1, oL1, 0, 1, 0, 0, 0, 0},
166 	{"Release", 0, oC5, oR1, oW1, oL1, 0, 1, 0, 0, 0, 0},
167 	{"TouchSense", 2, oC6, 100, 27, 600, 0, 1, 0, "bitmaps/buttons/rockersmoothBW.xpm",
168 		"bitmaps/buttons/rockersmoothBWd.xpm", 0},
169 
170 	/* Tremelo */
171 	{"Tremelo", 0, oC16, oR1, oW1, oL1, 0, 1, 0, 0, 0, 0},
172 
173 	/* Chorus */
174 	{"Choris Wet", 0, oC7, oR1, oW1, oL1, 0, 1, 0, 0, 0, 0},
175 	{"ChorusD1", 0, oC8, oR1, oW1, oL1, 0, 1, 0, 0, 0, 0},
176 	{"ChorusD2", 0, oC9, oR1, oW1, oL1, 0, 1, 0, 0, 0, 0},
177 	{"ChorusSpeed", 0, oC10, oR1, oW1, oL1, 0, 1, 0, 0, 0, 0},
178 
179 	/* Reverb */
180 	{"Reberb Wet", 0, oC11, oR1, oW1, oL1, 0, 1, 0, 0, 0, 0},
181 	{"Reverb Cross", 0, oC12, oR1, oW1, oL1, 0, 1, 0, 0, 0, 0},
182 	{"Reverb Feed", 0, oC13, oR1, oW1, oL1, 0, 1, 0, 0, 0, 0},
183 	{"Reverg Length", 0, oC14, oR1, oW1, oL1, 0, 1, 0, 0, 0, 0},
184 
185 	/* Single/Multi LFO */
186 	{"LFO Multi", 2, oC56, 100, 27, 600, 0, 1, 0, "bitmaps/buttons/rockersmoothBGR.xpm",
187 		"bitmaps/buttons/rockersmoothBGRd.xpm", 0},
188 };
189 
190 #define mR1 100
191 #define mR2 600
192 #define mR3 820
193 
194 #define mC0 (120)
195 #define mC1 (mC0 +  129)
196 #define mC2 (mC1 +  129)
197 #define mC3 (mC2 +  129)
198 #define mC4 (mC3 +  129)
199 #define mC4s (mC4 + 129)
200 
201 #define mC5 50
202 #define mC6 550
203 #define mC7 650
204 #define mC8 780
205 #define mC9 900
206 
207 #define mC11 100
208 #define mC12 255
209 #define mC13 410
210 #define mC14 565
211 #define mC15 720
212 #define mC16 874
213 
214 #define S3 100
215 #define S4 80
216 #define S5 120
217 #define S6 150
218 
219 static
220 brightonLocations mem[MEM_COUNT] = {
221 	{"Bass", 0, mC2 -  70, mR2, 260, 260, 0, 1, 0, 0, 0, 0},
222 	{"Treble", 0, mC4 - 100, mR2, 260, 260, 0, 1, 0, 0, 0, 0},
223 
224 	/* memories */
225 	{"Mem-0", 2, mC0, mR1, 125, 400, 0, 1, 0, "bitmaps/buttons/rockersmoothBB.xpm",
226 		"bitmaps/buttons/rockersmoothBBd.xpm", 0}, /* -127 65 */
227 	{"Mem-1", 2, mC1, mR1, 125, 400, 0, 1, 0, "bitmaps/buttons/rockersmoothBG.xpm",
228 		"bitmaps/buttons/rockersmoothBGd.xpm", 0},
229 	{"Mem-2", 2, mC2, mR1, 125, 400, 0, 1, 0, "bitmaps/buttons/rockersmoothBBL.xpm",
230 		"bitmaps/buttons/rockersmoothBBLd.xpm", 0}, /* 190 31 -3 */
231 	{"Mem-3", 2, mC3, mR1, 125, 400, 0, 1, 0, "bitmaps/buttons/rockersmoothBGR.xpm",
232 		"bitmaps/buttons/rockersmoothBGRd.xpm", 0},
233 	{"Mem-4", 2, mC4, mR1, 125, 400, 0, 1, 0, "bitmaps/buttons/rockersmoothBC.xpm",
234 		"bitmaps/buttons/rockersmoothBCd.xpm", 0},
235 	{"Mem-5", 2, mC4s, mR1, 125, 400, 0, 1, 0, "bitmaps/buttons/rockersmoothBW.xpm",
236 		"bitmaps/buttons/rockersmoothBWd.xpm", 0},
237 
238 	{"", 1, 0, 0, 50, 50, 0, 1, 0, "bitmaps/knobs/sliderpointL.xpm", 0,
239 		BRIGHTON_VERTICAL|BRIGHTON_REVERSE|BRIGHTON_WITHDRAWN},
240 	{"", 1, 0, 0, 50, 50, 0, 1, 0, "bitmaps/knobs/sliderpointL.xpm", 0,
241 		BRIGHTON_VERTICAL|BRIGHTON_REVERSE|BRIGHTON_WITHDRAWN},
242 
243 	/* mem U/D, midi U/D, Load + Save */
244 	{"", 2, mC0 + 35, mR3, S4, S6, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
245 		"bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW},
246 	{"", 2, mC0 + 35, mR2, S4, S6, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
247 		"bitmaps/buttons/pressong.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW},
248 	{"", 2, mC8 + 7, mR3, S4, S6, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
249 		"bitmaps/buttons/presson.xpm", BRIGHTON_NOSHADOW},
250 	{"", 2, mC8 + 7, mR2, S4, S6, 0, 1, 0, "bitmaps/buttons/pressoffo.xpm",
251 		"bitmaps/buttons/pressono.xpm", BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW},
252 };
253 
254 int singleclick = 0;
255 
256 /*
257  * Should try and make this one as generic as possible, and try to use it as
258  * a general memory routine. has Midi u/d, mem u/d, load/save and a display.
259  */
260 static int
memCallback(brightonWindow * win,int panel,int index,float value)261 memCallback(brightonWindow* win, int panel, int index, float value)
262 {
263 	guiSynth *synth = findSynth(global.synths, win);
264 
265 /* printf("memCallback(%i, %i, %f) %i, %s\n", panel, index, value, */
266 /* synth->mem.active, synth->resources->name); */
267 
268 	if (synth->flags & SUPPRESS)
269 		return(0);
270 
271 	/*
272 	 * The first ten buttons are exclusive highlighting, we use the first mem
273 	 * pointer to handle this.
274 	 */
275 	if (synth->dispatch[MEM_START].other2)
276 	{
277 		synth->dispatch[MEM_START].other2 = 0;
278 		return(0);
279 	}
280 
281 	if (index < 2)
282 	{
283 		bristolMidiSendMsg(global.controlfd, synth->sid, 2 - index, 3,
284 			(int) (value * C_RANGE_MIN_1));
285 		return(0);
286 	}
287 
288 	if (index == 13)
289 	{
290 		if (brightonDoubleClick(dc)) {
291 			synth->location = synth->dispatch[MEM_START].other1 - 2;
292 			saveMemory(synth, "roadrunner", 0, synth->bank + synth->location,0);
293 			singleclick = 0;
294 		} else {
295 			singleclick = 1;
296 		}
297 		return(0);
298 	}
299 
300 	if (index < 8)
301 	{
302 		int i;
303 		brightonEvent event;
304 
305 		event.command = BRIGHTON_PARAMCHANGE;
306 		event.type = BRIGHTON_FLOAT;
307 		event.value = 0;
308 
309 		/*
310 		 * This is a numeric. We need to force exclusion.
311 		 */
312 		if (synth->dispatch[MEM_START].other1 != -1)
313 		{
314 			synth->dispatch[MEM_START].other2 = 1;
315 
316 			if (synth->dispatch[MEM_START].other1 != index)
317 				event.value = 0;
318 			else
319 				event.value = 1;
320 
321 			brightonParamChange(synth->win, panel,
322 				synth->dispatch[MEM_START].other1, &event);
323 		}
324 
325 		synth->location = index - 2;
326 
327 		/*
328 		 * If the last button pressed was the save button (just once) then save
329 		 * to the new location.
330 		 */
331 		if (singleclick) {
332 			saveMemory(synth, "roadrunner", 0, synth->bank + synth->location,0);
333 			singleclick = 0;
334 			synth->dispatch[MEM_START].other1 = index;
335 			return(0);
336 		}
337 
338 		loadMemory(synth, "roadrunner", 0, synth->bank + synth->location,
339 			synth->mem.active, 0, BRISTOL_NOCALLS|BRISTOL_FORCE);
340 
341 		/*
342 		 * We have loaded the memory but cannot call the devices as they have
343 		 * various panels.
344 		 */
345 		for (i = 0; i < MODS_COUNT; i++)
346 		{
347 			event.value = synth->mem.param[i];
348 			brightonParamChange(synth->win, MOD_PANEL, i, &event);
349 		}
350 
351 		for (; i < MEM_START; i++)
352 		{
353 			event.value = synth->mem.param[i];
354 			brightonParamChange(synth->win, OPTS_PANEL, i - OPTS_START, &event);
355 		}
356 
357 		event.value = synth->mem.param[i];
358 		brightonParamChange(synth->win, MEM_PANEL, i - MEM_START, &event);
359 		i++;
360 		event.value = synth->mem.param[i];
361 		brightonParamChange(synth->win, MEM_PANEL, i - MEM_START, &event);
362 
363 		synth->dispatch[MEM_START].other1 = index;
364 	} else {
365 		int newchan;
366 
367 		/*
368 		 * This is a control button.
369 		 */
370 		switch(index) {
371 			case 10:
372 				/*
373 				 * Midi Down
374 				 */
375 				if ((newchan = synth->midichannel - 1) < 0)
376 				{
377 					synth->midichannel = 0;
378 					return(0);
379 				}
380 
381 				if (global.libtest)
382 				{
383 					printf("midi chan %i\n", newchan);
384 					synth->midichannel = newchan;
385 					return(0);
386 				}
387 
388 				bristolMidiSendMsg(global.controlfd, synth->sid,
389 					127, 0, BRISTOL_MIDICHANNEL|newchan);
390 
391 				synth->midichannel = newchan;
392 				break;
393 			case 11:
394 				/*
395 				 * Midi Up
396 				 */
397 				if ((newchan = synth->midichannel + 1) > 15)
398 				{
399 					synth->midichannel = 15;
400 					return(0);
401 				}
402 
403 				if (global.libtest)
404 				{
405 					printf("midi chan %i\n", newchan);
406 					synth->midichannel = newchan;
407 					return(0);
408 				}
409 
410 				bristolMidiSendMsg(global.controlfd, synth->sid,
411 					127, 0, BRISTOL_MIDICHANNEL|newchan);
412 
413 				synth->midichannel = newchan;
414 				break;
415 		}
416 	}
417 
418 	singleclick = 0;
419 
420 	return(0);
421 }
422 
423 /*
424  * This is a set of globals for the main window rendering. Again taken from
425  * include/brighton.h
426  */
427 brightonApp roadrunnerApp = {
428 	"roadrunner",
429 	0, /* no blueprint on wood background. */
430 	"bitmaps/textures/leather.xpm",
431 	0,
432 	roadrunnerInit,
433 	roadrunnerConfigure, /* 3 callbacks */
434 	midiCallback,
435 	destroySynth,
436 	{-1, 0, 2, 2, 5, 520, 0, 0},
437 	660, 138, 0, 0,
438 	7, /* panel count */
439 	{
440 		{
441 			"Options panel",
442 			"bitmaps/blueprints/roadrunneropts.xpm",
443 			"bitmaps/textures/metal5.xpm", /* flags */
444 			0x020,
445 			0,
446 			0,
447 			roadrunnerCallback,
448 			/*30, 50, 940, 365, */
449 			15, 9, 970, 300,
450 			OPTS_COUNT,
451 			options
452 		},
453 		{
454 			"RoadRunner",
455 			0,
456 			"bitmaps/textures/leather.xpm", /* flags */
457 			0,
458 			0,
459 			0,
460 			0,
461 			15, 9, 970, 300,
462 			0,
463 			0
464 		},
465 		{
466 			"Keyboard",
467 			0,
468 			"bitmaps/newkeys/kbg.xpm", /* flags */
469 			0x020|BRIGHTON_STRETCH,
470 			0,
471 			0,
472 			keyCallback,
473 			204, 305, 790, 555,
474 			KEY_COUNT,
475 			keysprofile
476 		},
477 		{
478 			"Memory Panel",
479 			0,
480 			"bitmaps/textures/metal5.xpm",
481 			0,
482 			0,
483 			0,
484 			roadrunnerCallback,
485 			15, 300, 189, 560,
486 			MEM_COUNT,
487 			mem
488 		},
489 		{
490 			"Front Panel Mods",
491 			"bitmaps/blueprints/roadrunnermods.xpm",
492 			0,
493 			0,
494 			0,
495 			0,
496 			roadrunnerCallback,
497 			15, 860, 970, 140,
498 			MODS_COUNT,
499 			modspanel,
500 		},
501 		{
502 			"Metal Side",
503 			0,
504 			"bitmaps/textures/metal4.xpm",
505 			BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */
506 			0,
507 			0,
508 			0,
509 			0, 0, 15, 1000,
510 			0,
511 			0
512 		},
513 		{
514 			"Metal Side",
515 			0,
516 			"bitmaps/textures/metal4.xpm",
517 			BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */
518 			0,
519 			0,
520 			0,
521 			985, 0, 15, 1000,
522 			0,
523 			0
524 		},
525 	}
526 };
527 
528 /*static dispatcher dispatch[DEVICE_COUNT]; */
529 
530 static int
midiCallback(brightonWindow * win,int controller,int value,float n)531 midiCallback(brightonWindow *win, int controller, int value, float n)
532 {
533 	guiSynth *synth = findSynth(global.synths, win);
534 
535 	printf("midi callback: %x, %i\n", controller, value);
536 
537 	switch(controller)
538 	{
539 		case MIDI_PROGRAM:
540 			printf("midi program: %x, %i\n", controller, value);
541 			synth->location = value;
542 			loadMemory(synth, synth->resources->name, 0,
543 				synth->bank + synth->location, synth->mem.active, 0, 0);
544 			break;
545 		case MIDI_BANK_SELECT:
546 			printf("midi banksel: %x, %i\n", controller, value);
547 			synth->bank = value;
548 			break;
549 	}
550 	return(0);
551 }
552 
553 static void
panelSwitch(guiSynth * id,int fd,int chan,int cont,int op,int value)554 panelSwitch(guiSynth *id, int fd, int chan, int cont, int op, int value)
555 {
556 	brightonEvent event;
557 
558 	/*
559 	 * If the sendvalue is zero, then withdraw the opts window, draw the
560 	 * slider window, and vice versa.
561 	 */
562 	if (value == 0)
563 	{
564 		event.type = BRIGHTON_EXPOSE;
565 		event.intvalue = 0;
566 		brightonParamChange(id->win, 0, -1, &event);
567 		event.intvalue = 1;
568 		brightonParamChange(id->win, 1, -1, &event);
569 
570 		shade_id = brightonPut(id->win,
571 			"bitmaps/blueprints/roadrunnershade.xpm", 0, 0, id->win->width,
572 				id->win->height);
573 	} else {
574 		event.type = BRIGHTON_EXPOSE;
575 		event.intvalue = 0;
576 		brightonParamChange(id->win, 1, -1, &event);
577 		event.intvalue = 1;
578 		brightonParamChange(id->win, 0, -1, &event);
579 
580 		brightonRemove(id->win, shade_id);
581 	}
582 }
583 
584 static int
roadrunnerMidiNull(void * synth,int fd,int chan,int c,int o,int v)585 roadrunnerMidiNull(void *synth, int fd, int chan, int c, int o, int v)
586 {
587 /*	printf("%i, %i, %i\n", c, o, v); */
588 	return(0);
589 }
590 
591 static int
roadrunnerMidiDetune(guiSynth * synth,int fd,int chan,int c,int o,int v)592 roadrunnerMidiDetune(guiSynth *synth, int fd, int chan, int c, int o, int v)
593 {
594 	if ((v = 8192 - v) >= 8192)
595 		v = 8191;
596 	if (v <= -8191)
597 		v = -8191;
598 
599 	bristolMidiSendMsg(global.controlfd, synth->sid, 0, 2, 8192);
600 	bristolMidiSendMsg(global.controlfd, synth->sid, 1, 2, 8192 + v);
601 	bristolMidiSendMsg(global.controlfd, synth->sid, 2, 2, 8192 - v);
602 
603 	return(0);
604 }
605 
606 static int
roadrunnerMidiWF(guiSynth * synth,int fd,int chan,int c,int o,int v)607 roadrunnerMidiWF(guiSynth *synth, int fd, int chan, int c, int o, int v)
608 {
609 	int cont, square = 0, tri = 0, ramp = 0;
610 
611 	/*
612 	 * Find out which pair this is, B/M/T, if they are both up then select
613 	 * a triangular wave, otherwise they represent their respective waves.
614 	 */
615 	switch (c) {
616 		default:
617 		case OPTS_START + 3:
618 		case OPTS_START + 4:
619 			/* Bass oscillator */
620 			cont = 30;
621 			switch ((int) synth->mem.param[OPTS_START + 3]) {
622 				case 0:
623 					if (synth->mem.param[OPTS_START + 4] == 0)
624 						/*
625 						 * Tri on, rest off
626 						 */
627 						tri = 1;
628 					else
629 						/*
630 						 * Tri off, ramp off, square on
631 						 */
632 						square = 1;
633 					break;
634 				default:
635 					if (synth->mem.param[OPTS_START + 4] == 0)
636 						/*
637 						 * ramp on, rest off
638 						 */
639 						ramp = 1;
640 					else {
641 						/*
642 						 * Tri off, ramp on, square on
643 						 */
644 						ramp = 1;
645 						square = 1;
646 					}
647 					break;
648 			}
649 			break;
650 		case OPTS_START + 5:
651 		case OPTS_START + 6:
652 			/* Oscillator */
653 			cont = 10;
654 			switch ((int) synth->mem.param[OPTS_START + 5]) {
655 				case 0:
656 					if (synth->mem.param[OPTS_START + 6] != 0)
657 						/*
658 						 * Tri off, ramp off, square on
659 						 */
660 						square = 1;
661 					break;
662 				default:
663 					if (synth->mem.param[OPTS_START + 6] == 0.0)
664 						/*
665 						 * ramp on, rest off
666 						 */
667 						ramp = 1;
668 					else {
669 						/*
670 						 * Tri off, ramp on, square on
671 						 */
672 						ramp = 1;
673 						square = 1;
674 					}
675 					break;
676 			}
677 			break;
678 		case OPTS_START + 7:
679 		case OPTS_START + 8:
680 			/* Treble oscillator */
681 			cont = 20;
682 			switch ((int) synth->mem.param[OPTS_START + 7]) {
683 				case 0:
684 					if (synth->mem.param[OPTS_START + 8] == 0)
685 						/*
686 						 * Tri on, rest off
687 						 */
688 						tri = 1;
689 					else
690 						/*
691 						 * Tri off, ramp off, square on
692 						 */
693 						square = 1;
694 					break;
695 				default:
696 					if (synth->mem.param[OPTS_START + 8] == 0)
697 						/*
698 						 * ramp on, rest off
699 						 */
700 						ramp = 1;
701 					else {
702 						/*
703 						 * Tri off, ramp on, square on
704 						 */
705 						ramp = 1;
706 						square = 1;
707 					}
708 					break;
709 			}
710 			break;
711 	}
712 
713 	bristolMidiSendMsg(global.controlfd, synth->sid, 126, cont + 0, ramp);
714 	bristolMidiSendMsg(global.controlfd, synth->sid, 126, cont + 1, square);
715 	bristolMidiSendMsg(global.controlfd, synth->sid, 126, cont + 2, tri);
716 
717 	return(0);
718 }
719 
720 static int
roadrunnerMidiPW(guiSynth * synth,int fd,int chan,int c,int o,int v)721 roadrunnerMidiPW(guiSynth *synth, int fd, int chan, int c, int o, int v)
722 {
723 	bristolMidiSendMsg(global.controlfd, synth->sid, 0, 0, v / 2);
724 	bristolMidiSendMsg(global.controlfd, synth->sid, 1, 0, v * 3 / 4);
725 	bristolMidiSendMsg(global.controlfd, synth->sid, 2, 0, v);
726 	return(0);
727 }
728 
729 static int
roadrunnerMidiSendMsg(void * synth,int fd,int chan,int c,int o,int v)730 roadrunnerMidiSendMsg(void *synth, int fd, int chan, int c, int o, int v)
731 {
732 /*	printf("%i, %i, %i\n", c, o, v); */
733 	bristolMidiSendMsg(fd, chan, c, o, v);
734 	return(0);
735 }
736 
737 /*
738  * For the sake of ease of use, links have been placed here to be called
739  * by any of the devices created. They would be better in some other file,
740  * perhaps with this as a dispatch.
741  *
742  * Param refers to the device index in the locations table given below.
743  */
744 static int
roadrunnerCallback(brightonWindow * win,int panel,int index,float value)745 roadrunnerCallback(brightonWindow *win, int panel, int index, float value)
746 {
747 	guiSynth *synth = findSynth(global.synths, win);
748 	int sendvalue;
749 
750 	if (synth == 0)
751 		return(0);
752 
753 	if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0))
754 		return(0);
755 
756 	if (roadrunnerApp.resources[panel].devlocn[index].to == 1)
757 		sendvalue = value * C_RANGE_MIN_1;
758 	else
759 		sendvalue = value;
760 
761 	switch (panel) {
762 		case OPTS_PANEL:
763 			index+=OPTS_START;
764 			break;
765 		case MOD_PANEL:
766 			break;
767 		case MEM_PANEL:
768 			if (index == 12) {
769 				panelSwitch(synth, 0, 0, 0, 0, value);
770 				return(0);
771 			} else if (index > 1) {
772 				memCallback(win, panel, index, value);
773 				return(0);
774 			} else
775 				index+=MEM_START;
776 	}
777 
778 	synth->mem.param[index] = value;
779 
780 	if ((!global.libtest) || (index >= ACTIVE_DEVS))
781 		synth->dispatch[index].routine(synth,
782 			global.controlfd, synth->sid,
783 			synth->dispatch[index].controller,
784 			synth->dispatch[index].operator,
785 			sendvalue);
786 #define DEBUG
787 #ifdef DEBUG
788 	else
789 		printf("dispatch[%p,%i](%i, %i, %i, %i, %i)\n", synth, index,
790 			global.controlfd, synth->sid,
791 			synth->dispatch[index].controller,
792 			synth->dispatch[index].operator,
793 			sendvalue);
794 #endif
795 
796 	return(0);
797 }
798 
799 /*
800  * Any location initialisation required to run the callbacks. For bristol, this
801  * will connect to the engine, and give it some base parameters.
802  * May need to generate some application specific menus.
803  * Will also then make specific requests to some of the devices to alter their
804  * rendering.
805  */
806 static int
roadrunnerInit(brightonWindow * win)807 roadrunnerInit(brightonWindow* win)
808 {
809 	guiSynth *synth = findSynth(global.synths, win);
810 	dispatcher *dispatch;
811 	int i;
812 
813 	if (synth == 0)
814 	{
815 		synth = findSynth(global.synths, 0);
816 		if (synth == 0)
817 		{
818 			printf("cannot init\n");
819 			return(0);
820 		}
821 	}
822 
823 	synth->win = win;
824 
825 	printf("Initialise the roadrunner link to bristol: %p\n", synth->win);
826 
827 	synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float));
828 	synth->mem.count = DEVICE_COUNT;
829 	synth->mem.active = ACTIVE_DEVS;
830 	synth->dispatch = (dispatcher *)
831 		brightonmalloc(DEVICE_COUNT * sizeof(dispatcher));
832 	dispatch = synth->dispatch;
833 
834 	/*
835 	 * We really want to have three connection mechanisms. These should be
836 	 *	1. Unix named sockets.
837 	 *	2. UDP sockets.
838 	 *	3. MIDI pipe.
839 	 */
840 	if (!global.libtest)
841 		if ((synth->sid = initConnection(&global, synth)) < 0)
842 			return(-1);
843 
844 	for (i = 0; i < DEVICE_COUNT; i++)
845 		synth->dispatch[i].routine = roadrunnerMidiNull;
846 
847 	/* Front panel - tune, lfo, vibrato, volume */
848 	synth->dispatch[MODS_START + 0].controller = 126; /* Tuning */
849 	synth->dispatch[MODS_START + 0].operator = 1;
850 	synth->dispatch[MODS_START + 1].controller = 5; /* LFO frequency */
851 	synth->dispatch[MODS_START + 1].operator = 0;
852 	synth->dispatch[MODS_START + 2].controller = 126; /* vibrato */
853 	synth->dispatch[MODS_START + 2].operator = 7;
854 	synth->dispatch[MODS_START + 3].controller = 3; /* gain */
855 	synth->dispatch[MODS_START + 3].operator = 4;
856 
857 	synth->dispatch[MODS_START + 0].routine
858 	 	= synth->dispatch[MODS_START + 1].routine
859 	 	= synth->dispatch[MODS_START + 2].routine
860 	 	= synth->dispatch[MODS_START + 3].routine
861 			= roadrunnerMidiSendMsg;
862 
863 	/* EQ controls from memory panel - not in memories */
864 	synth->dispatch[MEM_START + 0].controller = 2; /* Bass gain */
865 	synth->dispatch[MEM_START + 0].operator = 3;
866 	synth->dispatch[MEM_START + 1].controller = 1; /* Treble gain */
867 	synth->dispatch[MEM_START + 1].operator = 3;
868 
869 	synth->dispatch[MEM_START + 0].routine
870 	 	= synth->dispatch[MEM_START + 1].routine
871 			= roadrunnerMidiSendMsg;
872 
873 	/*
874 	 * The rest are from the options panel that is normally hidden.
875 	 */
876 	synth->dispatch[OPTS_START + 0].routine
877 		= (synthRoutine) roadrunnerMidiDetune;
878 	synth->dispatch[OPTS_START + 1].routine
879 		= (synthRoutine) roadrunnerMidiPW;
880 	synth->dispatch[OPTS_START + 2].controller = 126; /* PWM and LFO */
881 	synth->dispatch[OPTS_START + 2].operator = 3;
882 
883 	/* Waveforms */
884 	synth->dispatch[OPTS_START + 3].controller = OPTS_START + 3;
885 	synth->dispatch[OPTS_START + 4].controller = OPTS_START + 4;
886 	synth->dispatch[OPTS_START + 5].controller = OPTS_START + 5;
887 	synth->dispatch[OPTS_START + 6].controller = OPTS_START + 6;
888 	synth->dispatch[OPTS_START + 7].controller = OPTS_START + 7;
889 	synth->dispatch[OPTS_START + 8].controller = OPTS_START + 8;
890 
891 	synth->dispatch[OPTS_START + 3].routine
892 		= synth->dispatch[OPTS_START + 4].routine
893 		= synth->dispatch[OPTS_START + 5].routine
894 		= synth->dispatch[OPTS_START + 6].routine
895 		= synth->dispatch[OPTS_START + 7].routine
896 		= synth->dispatch[OPTS_START + 8].routine
897 			= (synthRoutine) roadrunnerMidiWF;
898 
899 	synth->dispatch[OPTS_START + 9].controller = 3; /* Env - 2 parameters */
900 	synth->dispatch[OPTS_START + 9].operator = 1;
901 	synth->dispatch[OPTS_START + 10].controller = 3;
902 	synth->dispatch[OPTS_START + 10].operator = 3;
903 	synth->dispatch[OPTS_START + 11].controller = 3;
904 	synth->dispatch[OPTS_START + 11].operator = 5;
905 
906 	synth->dispatch[OPTS_START + 12].controller = 126; /* Tremelo */
907 	synth->dispatch[OPTS_START + 12].operator = 8;
908 
909 /* Almost done effects - a couple may have to be compound parameters */
910 	synth->dispatch[OPTS_START + 13].controller = 98; /* Effects */
911 	synth->dispatch[OPTS_START + 13].operator = 0;
912 	synth->dispatch[OPTS_START + 14].controller = 98; /* Effects */
913 	synth->dispatch[OPTS_START + 14].operator = 1;
914 	synth->dispatch[OPTS_START + 15].controller = 98; /* Effects */
915 	synth->dispatch[OPTS_START + 15].operator = 2;
916 	synth->dispatch[OPTS_START + 16].controller = 98; /* Effects */
917 	synth->dispatch[OPTS_START + 16].operator = 3;
918 
919 	synth->dispatch[OPTS_START + 17].controller = 99; /* Effects */
920 	synth->dispatch[OPTS_START + 17].operator = 0;
921 	synth->dispatch[OPTS_START + 18].controller = 99; /* Effects */
922 	synth->dispatch[OPTS_START + 18].operator = 1;
923 	synth->dispatch[OPTS_START + 19].controller = 99; /* Effects */
924 	synth->dispatch[OPTS_START + 19].operator = 2;
925 	synth->dispatch[OPTS_START + 20].controller = 99; /* Effects */
926 	synth->dispatch[OPTS_START + 20].operator = 3;
927 	synth->dispatch[OPTS_START + 21].controller = 126; /* Multi LFO */
928 	synth->dispatch[OPTS_START + 21].operator = 4;
929 
930 	synth->dispatch[OPTS_START + 2].routine
931 		= synth->dispatch[OPTS_START + 9].routine
932 		= synth->dispatch[OPTS_START + 10].routine
933 		= synth->dispatch[OPTS_START + 11].routine
934 		= synth->dispatch[OPTS_START + 12].routine
935 		= synth->dispatch[OPTS_START + 13].routine
936 		= synth->dispatch[OPTS_START + 14].routine
937 		= synth->dispatch[OPTS_START + 15].routine
938 		= synth->dispatch[OPTS_START + 16].routine
939 		= synth->dispatch[OPTS_START + 17].routine
940 		= synth->dispatch[OPTS_START + 19].routine
941 		= synth->dispatch[OPTS_START + 19].routine
942 		= synth->dispatch[OPTS_START + 20].routine
943 		= synth->dispatch[OPTS_START + 21].routine
944 		= roadrunnerMidiSendMsg;
945 
946 	/*
947 	 * These will be replaced by some opts controllers. We need to tie the
948 	 * envelope parameters for decay, sustain. We need to fix a few parameters
949 	 * of the oscillators too - transpose, tune and gain.
950 	 */
951 	bristolMidiSendMsg(global.controlfd, synth->sid, 3, 1, 10);
952 	bristolMidiSendMsg(global.controlfd, synth->sid, 3, 2, 16382);
953 
954 	/* Oscillators */
955 	bristolMidiSendMsg(global.controlfd, synth->sid, 0, 3, 16383);
956 	bristolMidiSendMsg(global.controlfd, synth->sid, 1, 3, 16383);
957 	bristolMidiSendMsg(global.controlfd, synth->sid, 1, 1, 3);
958 	bristolMidiSendMsg(global.controlfd, synth->sid, 2, 1, 1);
959 
960 	return(0);
961 }
962 
963 /*
964  * This will be called to make any routine specific parameters available.
965  */
966 static int
roadrunnerConfigure(brightonWindow * win)967 roadrunnerConfigure(brightonWindow *win)
968 {
969 	guiSynth *synth = findSynth(global.synths, win);
970 	brightonEvent event;
971 
972 	if (synth == 0)
973 	{
974 		printf("problems going operational\n");
975 		return(-1);
976 	}
977 
978 	if (synth->flags & OPERATIONAL)
979 		return(0);
980 
981 printf("going operational\n");
982 
983 	synth->flags |= OPERATIONAL;
984 	synth->keypanel = KEY_PANEL;
985 	synth->keypanel2 = -1;
986 	synth->transpose = 36;
987 
988 	/*
989 	 * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only
990 	 * occurs on first paint, so we suppress the first paint, and then request
991 	 * an expose here.
992 	 */
993 	event.type = BRIGHTON_EXPOSE;
994 	event.intvalue = 1;
995 	brightonParamChange(synth->win, KEY_PANEL, -1, &event);
996 	configureGlobals(synth);
997 
998 	shade_id = brightonPut(synth->win,
999 		"bitmaps/blueprints/roadrunnershade.xpm", 0, 0, synth->win->width,
1000 			synth->win->height);
1001 
1002 	/* Fix the env attack and sustain */
1003 	bristolMidiSendMsg(global.controlfd, synth->sid, 3, 0, 2);
1004 	bristolMidiSendMsg(global.controlfd, synth->sid, 3, 2, 0);
1005 	/* Fix the pulsewidths of the first two osc */
1006 	bristolMidiSendMsg(global.controlfd, synth->sid, 0, 0, 8192);
1007 	bristolMidiSendMsg(global.controlfd, synth->sid, 1, 0, 4096);
1008 	/* detune all oscs just a small amount */
1009 	bristolMidiSendMsg(global.controlfd, synth->sid, 0, 2, 8192);
1010 	bristolMidiSendMsg(global.controlfd, synth->sid, 1, 2, 8292);
1011 	bristolMidiSendMsg(global.controlfd, synth->sid, 2, 2, 8092);
1012 	/* LFO to restart on NOTE_ON */
1013 	bristolMidiSendMsg(global.controlfd, synth->sid, 5, 1, 8092);
1014 
1015 	/* Configure no split point */
1016 	bristolMidiSendMsg(global.controlfd, synth->sid, 126, 5, 127);
1017 	bristolMidiSendMsg(global.controlfd, synth->sid, 126, 6, 0);
1018 
1019 	event.command = BRIGHTON_PARAMCHANGE;
1020 	event.type = BRIGHTON_FLOAT;
1021 	event.value = 1;
1022 	panelSwitch(synth, 0, 0, 0, 0, 1);
1023 	brightonParamChange(synth->win, MEM_PANEL, 2, &event);
1024 	panelSwitch(synth, 0, 0, 0, 0, 0);
1025 
1026 	loadMemory(synth, "roadrunner", 0, 0, synth->mem.active-6, 0, 0);
1027 
1028 	synth->dispatch[MEM_START].other1 = 2;
1029 	synth->dispatch[MEM_START].other2 = 0;
1030 
1031 	dc = brightonGetDCTimer(win->dcTimeout);
1032 
1033 	return(0);
1034 }
1035 
1036