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 "bristolmidi.h"
28 #include "brightoninternals.h"
29 
30 static int miniInit();
31 static int miniConfigure();
32 static int midiCallback(brightonWindow *, int, int, float);
33 static int miniCallback(brightonWindow * , int, int, float);
34 
35 extern guimain global;
36 
37 #include "brightonKeys.h"
38 
39 #define KEY_PANEL 1
40 
41 #define FIRST_DEV 0
42 #define DEVICE_COUNT (61 + FIRST_DEV)
43 #define ACTIVE_DEVS (42 + FIRST_DEV)
44 
45 #define R1 128
46 #define R5 698
47 #define R3 (R1 + (R5 - R1) / 2)
48 #define R2 (R1 + (R3 - R1) / 2)
49 #define R4 (R3 + (R5 - R3) / 2)
50 #define R6 782
51 #define R7 889
52 #define C1 168
53 #define C2 234
54 #define C3 318
55 #define C4 398
56 #define C5 472
57 #define C6 548
58 #define C7 673
59 #define C8 753
60 #define C9 827
61 #define C10 905
62 #define C11 622
63 #define C12 140
64 
65 #define S1 120
66 #define S2 170
67 #define S3 180
68 #define S4 35
69 #define S5 60
70 
71 #define B1 40
72 #define B2 16
73 #define B3 110
74 
75 /*
76  * This structure is for device definition. The structure is defined in
77  * include/brighton.h, further definitions in brighton/brightonDevtable.h and
78  * include/brightoninternals.h
79  *
80  *	typedef int (*brightonCallback)(int, float);
81  *	typedef struct BrightonLocations {
82  *		int device; 0=rotary, 1=scale, etc.
83  *		float relx, rely; relative position with regards to 1000 by 1000 window
84  *		float relw, relh; relative height.
85  *		int from, to;
86  *		brightonCallback callback; specific to this dev
87  *		char *image; bitmap. If zero take a device default.
88  *		int flags;
89  *	} brightonLocations;
90  *
91  * This example is for a miniBristol type synth interface.
92  */
93 static brightonLocations locations[DEVICE_COUNT] = {
94 /* CONTROL */
95 	{"Tune", 0, 47, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
96 		0, BRIGHTON_NOTCH},
97 	{"Glide", 0, 18, R4, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
98 		0, 0},
99 	{"Mod", 0, 80, R4, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
100 		0, 0}, /*3 */
101 /* OSCILATORS */
102 	{"Osc1 Transpose", 0, C1, R1, S1, S1, 0, 5, 0, "bitmaps/knobs/knob4.xpm",
103 		0, 0},
104 	{"Osc2 Transpose", 0, C1, R3, S1, S1, 0, 5, 0, "bitmaps/knobs/knob4.xpm",
105 		0, 0},
106 	{"Osc3 Transpose", 0, C1, R5, S1, S1, 0, 5, 0, "bitmaps/knobs/knob4.xpm",
107 		0, 0},
108 /*	{"", 0, C2, 382, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm", 0, 0}, */
109 	{"Osc2 Tuning", 0, C2, 382, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
110 		0, BRIGHTON_NOTCH},
111 	{"Osc3 Tuning", 0, C2, 660, S2, S2, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
112 		0, BRIGHTON_NOTCH},
113 	{"Osc1 Waveform", 0, C3, R1, S1, S1, 0, 5, 0, "bitmaps/knobs/knob4.xpm",
114 		0, 0},
115 	{"Osc2 Waveform", 0, C3, R3, S1, S1, 0, 5, 0, "bitmaps/knobs/knob4.xpm",
116 		0, 0},
117 	{"Osc3 Waveform", 0, C3, R5, S1, S1, 0, 5, 0, "bitmaps/knobs/knob4.xpm",
118 		0, 0}, /*11 */
119 /* MIXER */
120 	{"Osc1 Mix lvl", 0, C4, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
121 		0, 0},
122 	{"Ext Mix lvl", 0, C6, R2, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
123 		0, 0},
124 	{"Osc2 Mix lvl", 0, C4, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
125 		0, 0},
126 	{"Noise Mix lvl", 0, C6, R4, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
127 		0, 0},
128 	{"Osc3 Mix lvl", 0, C4, R5, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
129 		0, 0}, /*16 */
130 /* FILTER */
131 	{"Filter Freq", 0, C7, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
132 		0, 0},
133 	{"Filter Emph", 0, C8, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
134 		0, 0},
135 	{"Filter Contour", 0, C9, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
136 		0, 0}, /*19 */
137 /* ADSR */
138 	{"Filter Attack", 0, C7, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
139 		0, 0},
140 	{"Filter Decay", 0, C8, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
141 		0, 0},
142 	{"Filter Release", 0, C9, R3, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
143 		0, 0}, /*22 */
144 /* another ADSR */
145 	{"Attack", 0, C7, R5, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
146 		0, 0},
147 	{"Decay", 0, C8, R5, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
148 		0, 0},
149 	{"Release", 0, C9, R5, S1, S1, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
150 		0, 0}, /*25 */
151 /* MAIN OUT 25 */
152 	{"MasterVolume", 0, C10, R1, S3, S3, 0, 1, 0, "bitmaps/knobs/knob4.xpm",
153 		0, 0},
154 	{"On/Off", 2, C10 + 7, R1 - 92, B1, B1, 0, 1, 0,
155 		"bitmaps/buttons/rockerblue.xpm", 0, 0},
156 	{"A-440", 2, C10 + 7, R2 + 75, B1, B1, 0, 1, 0,
157 		"bitmaps/buttons/rockerblue.xpm", 0, 0}, /*28 */
158 /* MIX BUTTONS - 28 */
159 	{"Mix Osc1", 2, C5, R1 + 45, B1, B1, 0, 1, 0,
160 		"bitmaps/buttons/rockerblue.xpm", 0, 0},
161 	{"Mix Ext", 2, C5, R2 + 45, B1, B1, 0, 1, 0,
162 		"bitmaps/buttons/rockerblue.xpm", 0, 0},
163 	{"Mix Osc2", 2, C5, R3 + 45, B1, B1, 0, 1, 0,
164 		"bitmaps/buttons/rockerblue.xpm", 0, 0},
165 	{"Mix Noise", 2, C5, R4 + 45, B1, B1, 0, 1, 0,
166 		"bitmaps/buttons/rockerblue.xpm", 0, 0},
167 	{"Mix Osc3", 2, C5, R5 + 45, B1, B1, 0, 1, 0,
168 		"bitmaps/buttons/rockerblue.xpm", 0, 0}, /*33 */
169 /* NOISE BUTTON - 33 */
170 	{"White/Pink", 2, C11 - 6, C6, B2, B3, 0, 1, 0,
171 		"bitmaps/buttons/rockerblue.xpm", 0, BRIGHTON_VERTICAL}, /*34 */
172 /* CONTROL BUTTONS - 34 */
173 	{"Osc Mod 1", 2, C12 - 22, R2 - 13, B1, B1, 0, 1, 0, 0, 0, 0},
174 	{"Osc Mod 2", 2, C12 - 22, R2 + 97, B1, B1, 0, 1, 0, 0, 0, 0},
175 	{"Osc 3 LFO", 2, C12 - 9, R5 + 15, B2, B3, 0, 1, 0, 0, 0, BRIGHTON_VERTICAL},
176 	{"Release", 2, 78, 765, B1, B1, 0, 1, 0,
177 		"bitmaps/buttons/rockerwhite.xpm", 0, 0},
178 	{"Multitrig", 2, 78, 825, B1, B1, 0, 1, 0,
179 		"bitmaps/buttons/rockerwhite.xpm", 0, 0}, /*39 */
180 /* FILTER BUTTONS - 39 */
181 	{"Filter Mod1", 2, C11 - 5, R1 + 30, B1, B1, 0, 1, 0, 0, 0, 0},
182 	{"Filter Velocity", 2, C11 - 5, R1 + 170, B1, B1, 0, 1, 0, 0, 0, 0},
183 	{"Filter KBD", 2, C11 - 5, R3, B1, B1, 0, 1, 0, 0, 0}, /*42 */
184 /* Memory tablet */
185 	{"", 2, R7, R6 - S5 * 3, S4, S5, 0, 1, 0,
186 		"bitmaps/digits/L.xpm", 0, BRIGHTON_CHECKBUTTON},
187 	{"", 2, R7 + S4 * 2, R6 - S5 * 3, S4, S5, 0, 1, 0,
188 		"bitmaps/digits/S.xpm", 0, BRIGHTON_CHECKBUTTON},
189 	{"", 2, R7 + S4, R6 - S5 * 3, S4, S5, 0, 1, 0,
190 		"bitmaps/digits/0.xpm", 0, BRIGHTON_CHECKBUTTON},
191 	{"", 2, R7, R6 - S5 * 2, S4, S5, 0, 1, 0,
192 		"bitmaps/digits/1.xpm", 0, BRIGHTON_CHECKBUTTON},
193 	{"", 2, R7 + S4, R6 - S5 * 2, S4, S5, 0, 1, 0,
194 		"bitmaps/digits/2.xpm", 0, BRIGHTON_CHECKBUTTON},
195 	{"", 2, R7 + S4 * 2, R6 - S5 * 2, S4, S5, 0, 1, 0,
196 		"bitmaps/digits/3.xpm", 0, BRIGHTON_CHECKBUTTON},
197 	{"", 2, R7, R6 - S5, S4, S5, 0, 1, 0,
198 		"bitmaps/digits/4.xpm", 0, BRIGHTON_CHECKBUTTON},
199 	{"", 2, R7 + S4, R6 - S5, S4, S5, 0, 1, 0,
200 		"bitmaps/digits/5.xpm", 0, BRIGHTON_CHECKBUTTON},
201 	{"", 2, R7 + S4 * 2, R6 - S5, S4, S5, 0, 1, 0,
202 		"bitmaps/digits/6.xpm", 0, BRIGHTON_CHECKBUTTON},
203 	{"", 2, R7, R6, S4, S5, 0, 1, 0,
204 		"bitmaps/digits/7.xpm", 0, BRIGHTON_CHECKBUTTON},
205 	{"", 2, R7 + S4, R6, S4, S5, 0, 1, 0,
206 		"bitmaps/digits/8.xpm", 0, BRIGHTON_CHECKBUTTON},
207 	{"", 2, R7 + S4 * 2, R6, S4, S5, 0, 1, 0,
208 		"bitmaps/digits/9.xpm", 0, BRIGHTON_CHECKBUTTON},
209 	/* Up down midi */
210 	{"", 2, R7 + S4, 415, S4, S5, 0, 1, 0,
211 		"bitmaps/digits/Down.xpm", 0, BRIGHTON_CHECKBUTTON},
212 	{"", 2, R7 + S4 * 2, 415, S4, S5, 0, 1, 0,
213 		"bitmaps/digits/Up.xpm", 0, BRIGHTON_CHECKBUTTON},
214 	/* Up Down memory */
215 	{"", 2, R7, R6 + S5, S4, S5, 0, 1, 0,
216 		"bitmaps/digits/Down.xpm", 0, BRIGHTON_CHECKBUTTON},
217 	{"", 2, R7 + S4 * 2, R6 + S5, S4, S5, 0, 1, 0,
218 		"bitmaps/digits/Up.xpm", 0, BRIGHTON_CHECKBUTTON},
219 	{"", 3, R7, 430 + S5, 105, 54, 0, 1, 0, 0,
220 		"bitmaps/images/alphadisplay3.xpm", 0}, /*display 60 */
221 	{"", 3, R7, 425 + S5 + 55, 105, 54, 0, 1, 0, 0,
222 		"bitmaps/images/alphadisplay2.xpm", 0}, /*display 60 */
223 	{"", 4, 820, 1015, 175, 140, 0, 1, 0,
224 		"bitmaps/images/mini.xpm", 0, 0},
225 };
226 
227 /*
228  * This is a set of globals for the main window rendering. Again taken from
229  * include/brighton.h
230  */
231 brightonApp miniApp = {
232 	"mini",
233 	0, /* no blueprint on wood background. */
234 	"bitmaps/textures/wood6.xpm",
235 	0, /*BRIGHTON_STRETCH, // default is tesselate */
236 	miniInit,
237 	miniConfigure, /* 3 callbacks, unused? */
238 	midiCallback,
239 	destroySynth, /* 0, */
240 	{1, 100, 2, 2, 5, 520, 0, 0},
241 	700, 400, 0, 0, /*/367, */
242 	9,
243 	{
244 		{
245 			"Mini",
246 			"bitmaps/blueprints/mini.xpm",
247 			"bitmaps/textures/metal6.xpm",
248 			BRIGHTON_STRETCH, /* flags */
249 			0,
250 			miniConfigure,
251 			miniCallback,
252 			15, 25, 970, 570,
253 			DEVICE_COUNT,
254 			locations
255 		},
256 		{
257 			"Keyboard",
258 			0,
259 			"bitmaps/newkeys/ekbg.xpm",
260 			0x020|BRIGHTON_STRETCH|BRIGHTON_KEY_PANEL,
261 			0,
262 			0,
263 			keyCallback,
264 			150, 700, 845, 280,
265 			KEY_COUNT_3OCTAVE,
266 			keys3octave
267 		},
268 		{
269 			"Mods",
270 			"bitmaps/blueprints/mods.xpm",
271 			"bitmaps/textures/metal6.xpm", /* flags */
272 			BRIGHTON_STRETCH,
273 			0,
274 			0,
275 			modCallback,
276 			15, 700, 145, 280,
277 			2,
278 			mods
279 		},
280 		{
281 			"SP2",
282 			0,
283 			"bitmaps/textures/wood4.xpm",
284 			0, /*BRIGHTON_STRETCH|BRIGHTON_VERTICAL, // flags */
285 			0,
286 			0,
287 			0,
288 			15, 0, 970, 25,
289 			0,
290 			0
291 		},
292 		{
293 			"SP1",
294 			0,
295 			"bitmaps/textures/wood2.xpm",
296 			BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */
297 			0,
298 			0,
299 			0,
300 			0, 0, 15, 1000,
301 			0,
302 			0
303 		},
304 		{
305 			"SP2",
306 			0,
307 			"bitmaps/textures/wood2.xpm",
308 			BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */
309 			0,
310 			0,
311 			0,
312 			985, 0, 17, 1000,
313 			0,
314 			0
315 		},
316 		{
317 			"SP2",
318 			0,
319 			"bitmaps/textures/wood.xpm",
320 			BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */
321 			0,
322 			0,
323 			0,
324 			2, 597, 11, 390,
325 			0,
326 			0
327 		},
328 		{
329 			"SP2",
330 			0,
331 			"bitmaps/textures/wood.xpm",
332 			BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */
333 			0,
334 			0,
335 			0,
336 			986, 597, 14, 390,
337 			0,
338 			0
339 		},
340 		{
341 			"SP2",
342 			0,
343 			"bitmaps/textures/wood2.xpm",
344 			0, /*BRIGHTON_STRETCH|BRIGHTON_VERTICAL, // flags */
345 			0,
346 			0,
347 			0,
348 			15, 982, 970, 18,
349 			0,
350 			0
351 		}
352 	}
353 };
354 
355 static int
midiCallback(brightonWindow * win,int controller,int value,float n)356 midiCallback(brightonWindow *win, int controller, int value, float n)
357 {
358 	guiSynth *synth = findSynth(global.synths, win);
359 
360 	//printf("midi callback: %x, %i\n", controller, value);
361 
362 	switch(controller)
363 	{
364 		case MIDI_PROGRAM:
365 			//printf("midi program: %x, %i\n", controller, value);
366 			synth->location = value + synth->bank * 10;
367 			if (loadMemory(synth, synth->resources->name, 0,
368 				synth->location, synth->mem.active, FIRST_DEV, 0) < 0)
369 				displayText(synth, "FRE", synth->location, FIRST_DEV + 59);
370 			else
371 				displayText(synth, "PRG", synth->location, FIRST_DEV + 59);
372 			break;
373 		case MIDI_BANK_SELECT:
374 			//printf("midi banksel: %x, %i\n", controller, value);
375 			synth->bank = value;
376 			synth->location = (synth->location % 10) + value * 10;
377 			if (loadMemory(synth, synth->resources->name, 0,
378 				synth->location, synth->mem.active, FIRST_DEV, 0) < 0)
379 				displayText(synth, "FRE", synth->location, FIRST_DEV + 59);
380 			else
381 				displayText(synth, "PRG", synth->location, FIRST_DEV + 59);
382 			break;
383 	}
384 	return(0);
385 }
386 
387 /*static dispatcher dispatch[DEVICE_COUNT]; */
388 
389 static int
miniMidiSendMsg(void * synth,int fd,int chan,int c,int o,int v)390 miniMidiSendMsg(void *synth, int fd, int chan, int c, int o, int v)
391 {
392 	bristolMidiSendMsg(fd, chan, c, o, v);
393 	return(0);
394 }
395 
396 static void
miniDualFilterDecay(guiSynth * synth,int fd,int chan,int c,int o,int v)397 miniDualFilterDecay(guiSynth *synth, int fd, int chan, int c, int o, int v)
398 {
399 	bristolMidiSendMsg(fd, chan, c, 1, v);
400 
401 	if (synth->mem.param[FIRST_DEV + 37])
402 		bristolMidiSendMsg(fd, chan, c, 3, v);
403 	else
404 		bristolMidiSendMsg(fd, chan, c, 3, 1024);
405 }
406 
407 static void
miniDualDecay(guiSynth * synth,int fd,int chan,int c,int o,int v)408 miniDualDecay(guiSynth *synth, int fd, int chan, int c, int o, int v)
409 {
410 	bristolMidiSendMsg(fd, chan, 5, 1,
411 		(int) (synth->mem.param[FIRST_DEV + 23] * C_RANGE_MIN_1));
412 
413 	if (synth->mem.param[FIRST_DEV + 37])
414 		bristolMidiSendMsg(fd, chan, 5, 3,
415 			(int) (synth->mem.param[FIRST_DEV + 23] * C_RANGE_MIN_1));
416 	else
417 		bristolMidiSendMsg(fd, chan, 5, 3, 1024);
418 }
419 
420 static void
miniMemory(guiSynth * synth,int fd,int chan,int c,int o,int v)421 miniMemory(guiSynth *synth, int fd, int chan, int c, int o, int v)
422 {
423 /*	printf("miniMemory(%i %i %i %i %i)\n", fd, chan, c, o, v); */
424 
425 	switch (c) {
426 		default:
427 		case 0:
428 			synth->location = synth->location * 10 + o;
429 
430 			if (synth->location >= 1000)
431 				synth->location = o;
432 			if (loadMemory(synth, "mini", 0, synth->location,
433 				synth->mem.active, FIRST_DEV, BRISTOL_STAT) < 0)
434 				displayText(synth, "FRE", synth->location, FIRST_DEV + 59);
435 			else
436 				displayText(synth, "PRG", synth->location, FIRST_DEV + 59);
437 			break;
438 		case 1:
439 			loadMemory(synth, "mini", 0, synth->location, synth->mem.active,
440 				FIRST_DEV, 0);
441 			displayText(synth, "PRG", synth->location, FIRST_DEV + 59);
442 /*			synth->location = 0; */
443 			break;
444 		case 2:
445 			saveMemory(synth, "mini", 0, synth->location, FIRST_DEV);
446 			displayText(synth, "PRG", synth->location, FIRST_DEV + 59);
447 /*			synth->location = 0; */
448 			break;
449 		case 3:
450 			while (loadMemory(synth, "mini", 0, --synth->location,
451 				synth->mem.active, FIRST_DEV, 0) < 0)
452 			{
453 				if (synth->location < 0)
454 				{
455 					synth->location = 1000;
456 					break;
457 				}
458 			}
459 			displayText(synth, "PRG", synth->location, FIRST_DEV + 59);
460 			break;
461 		case 4:
462 			while (loadMemory(synth, "mini", 0, ++synth->location,
463 				synth->mem.active, FIRST_DEV, 0) < 0)
464 			{
465 				if (synth->location > 999)
466 				{
467 					synth->location = -1;
468 					break;
469 				}
470 			}
471 			displayText(synth, "PRG", synth->location, FIRST_DEV + 59);
472 			break;
473 	}
474 
475 }
476 
477 static void
miniMidi(guiSynth * synth,int fd,int chan,int c,int o,int v)478 miniMidi(guiSynth *synth, int fd, int chan, int c, int o, int v)
479 {
480 	int newchan;
481 
482 /*	printf("miniMidi(%x, %i %i %i %i %i)\n", synth, fd, chan, c, o, v); */
483 
484 	if ((synth->flags & OPERATIONAL) == 0)
485 		return;
486 
487 	if (c == 1) {
488 		if ((newchan = synth->midichannel - 1) < 0)
489 		{
490 			synth->midichannel = 0;
491 			return;
492 		}
493 	} else {
494 		if ((newchan = synth->midichannel + 1) >= 16)
495 		{
496 			synth->midichannel = 15;
497 			return;
498 		}
499 	}
500 
501 	if (global.libtest == 0)
502 	{
503 		bristolMidiSendMsg(global.controlfd, synth->sid,
504 			127, 0, BRISTOL_MIDICHANNEL|newchan);
505 	}
506 
507 	synth->midichannel = newchan;
508 
509 	displayText(synth, "MIDI", newchan + 1, FIRST_DEV + 58);
510 }
511 
512 /*
513  * For the sake of ease of use, links have been placed here to be called
514  * by any of the devices created. They would be better in some other file,
515  * perhaps with this as a dispatch.
516  *
517  * Param refers to the device index in the locations table given below.
518  */
519 static int
miniCallback(brightonWindow * win,int panel,int index,float value)520 miniCallback(brightonWindow * win, int panel, int index, float value)
521 {
522 	guiSynth *synth = findSynth(global.synths, win);
523 	int sendvalue;
524 
525 /*	printf("miniCallback(%x(%x), %i, %i, %f): %i %x\n", */
526 /*		win, synth, panel, index, value, synth); */
527 
528 	if (synth == 0)
529 		return(0);
530 
531 	if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0))
532 		return(0);
533 	if (synth->dispatch[index].controller >= DEVICE_COUNT)
534 		return(0);
535 
536 	if (miniApp.resources[0].devlocn[index].to == 1.0)
537 		sendvalue = value * (CONTROLLER_RANGE - 1);
538 	else
539 		sendvalue = value;
540 
541 	synth->mem.param[index] = value;
542 
543 	if ((!global.libtest) || (index >= ACTIVE_DEVS))
544 		synth->dispatch[index].routine(synth,
545 			global.controlfd, synth->sid,
546 			synth->dispatch[index].controller,
547 			synth->dispatch[index].operator,
548 			sendvalue);
549 /*
550 	else
551 		printf("dispatch[%x,%i](%i, %i, %i, %i, %i)\n", synth, index,
552 			global.controlfd, synth->sid,
553 			synth->dispatch[index].controller,
554 			synth->dispatch[index].operator,
555 			sendvalue);
556 */
557 
558 	return(0);
559 }
560 
561 /*
562  * Any location initialisation required to run the callbacks. For bristol, this
563  * will connect to the engine, and give it some base parameters.
564  * May need to generate some application specific menus.
565  * Will also then make specific requests to some of the devices to alter their
566  * rendering.
567  */
568 static int
miniInit(brightonWindow * win)569 miniInit(brightonWindow *win)
570 {
571 	guiSynth *synth = findSynth(global.synths, win);
572 	dispatcher *dispatch;
573 	int i;
574 
575 	if (synth == 0)
576 	{
577 		synth = findSynth(global.synths, (int) 0);
578 		if (synth == 0)
579 		{
580 			printf("cannot init\n");
581 			return(0);
582 		}
583 	}
584 
585 	synth->win = win;
586 
587 	printf("Initialise the mini link to bristol: %p\n", synth->win);
588 
589 	synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float));
590 	synth->mem.count = DEVICE_COUNT;
591 	synth->mem.active = ACTIVE_DEVS;
592 	synth->dispatch = (dispatcher *)
593 		brightonmalloc(DEVICE_COUNT * sizeof(dispatcher));
594 	dispatch = synth->dispatch;
595 
596 	/*
597 	 * We really want to have three connection mechanisms. These should be
598 	 *	1. Unix named sockets.
599 	 *	2. UDP sockets.
600 	 *	3. MIDI pipe.
601 	 */
602 	if (!global.libtest)
603 		if ((synth->sid = initConnection(&global, synth)) < 0)
604 			return(-1);
605 
606 	for (i = 0; i < DEVICE_COUNT; i++)
607 		synth->dispatch[i].routine = miniMidiSendMsg;
608 
609 	/* Tune, Glide, Modmix */
610 	dispatch[FIRST_DEV + 0].controller = 10;
611 	dispatch[FIRST_DEV + 0].operator = 0;
612 	dispatch[FIRST_DEV + 1].controller = 9;
613 	dispatch[FIRST_DEV + 1].operator = 0;
614 	dispatch[FIRST_DEV + 2].controller = 11;
615 	dispatch[FIRST_DEV + 2].operator = 1;
616 
617 	/* Osc */
618 	dispatch[FIRST_DEV + 3].controller = 0;
619 	dispatch[FIRST_DEV + 3].operator = 1;
620 	dispatch[FIRST_DEV + 4].controller = 1;
621 	dispatch[FIRST_DEV + 4].operator = 1;
622 	dispatch[FIRST_DEV + 5].controller = 2;
623 	dispatch[FIRST_DEV + 5].operator = 1;
624 	dispatch[FIRST_DEV + 6].controller = 1;
625 	dispatch[FIRST_DEV + 6].operator = 2;
626 	dispatch[FIRST_DEV + 7].controller = 2;
627 	dispatch[FIRST_DEV + 7].operator = 2;
628 	dispatch[FIRST_DEV + 8].controller = 0;
629 	dispatch[FIRST_DEV + 8].operator = 0;
630 	dispatch[FIRST_DEV + 9].controller = 1;
631 	dispatch[FIRST_DEV + 9].operator = 0;
632 	dispatch[FIRST_DEV + 10].controller = 2;
633 	dispatch[FIRST_DEV + 10].operator = 0;
634 
635 	/* MIX */
636 	dispatch[FIRST_DEV + 11].controller = 0;
637 	dispatch[FIRST_DEV + 11].operator = 3;
638 	dispatch[FIRST_DEV + 12].controller = 8;
639 	dispatch[FIRST_DEV + 12].operator = 0;
640 	dispatch[FIRST_DEV + 13].controller = 1;
641 	dispatch[FIRST_DEV + 13].operator = 3;
642 	dispatch[FIRST_DEV + 14].controller = 7;
643 	dispatch[FIRST_DEV + 14].operator = 0;
644 	dispatch[FIRST_DEV + 15].controller = 2;
645 	dispatch[FIRST_DEV + 15].operator = 3;
646 
647 	dispatch[FIRST_DEV + 16].controller = 4;
648 	dispatch[FIRST_DEV + 16].operator = 0;
649 	dispatch[FIRST_DEV + 17].controller = 4;
650 	dispatch[FIRST_DEV + 17].operator = 1;
651 	dispatch[FIRST_DEV + 18].controller = 4;
652 	dispatch[FIRST_DEV + 18].operator = 2;
653 
654 	dispatch[FIRST_DEV + 19].controller = 3;
655 	dispatch[FIRST_DEV + 19].operator = 0;
656 	dispatch[FIRST_DEV + 20].controller = 3;
657 	dispatch[FIRST_DEV + 20].operator = 1; /* special */
658 	dispatch[FIRST_DEV + 20].routine = (synthRoutine) miniDualFilterDecay;
659 	dispatch[FIRST_DEV + 21].controller = 3;
660 	dispatch[FIRST_DEV + 21].operator = 2;
661 
662 	dispatch[FIRST_DEV + 22].controller = 5;
663 	dispatch[FIRST_DEV + 22].operator = 0;
664 	dispatch[FIRST_DEV + 23].controller = 5;
665 	dispatch[FIRST_DEV + 23].operator = 1; /* special */
666 	dispatch[FIRST_DEV + 23].routine = (synthRoutine) miniDualDecay;
667 	dispatch[FIRST_DEV + 24].controller = 5;
668 	dispatch[FIRST_DEV + 24].operator = 2;
669 
670 	dispatch[FIRST_DEV + 25].controller = 5;
671 	dispatch[FIRST_DEV + 25].operator = 4;
672 	dispatch[FIRST_DEV + 26].controller = 12;
673 	dispatch[FIRST_DEV + 26].operator = 7;
674 	dispatch[FIRST_DEV + 27].controller = 12;
675 	dispatch[FIRST_DEV + 27].operator = 6;
676 
677 	dispatch[FIRST_DEV + 28].controller = 12;
678 	dispatch[FIRST_DEV + 28].operator = 10;
679 	dispatch[FIRST_DEV + 29].controller = 12;
680 	dispatch[FIRST_DEV + 29].operator = 13;
681 	dispatch[FIRST_DEV + 30].controller = 12;
682 	dispatch[FIRST_DEV + 30].operator = 11;
683 	dispatch[FIRST_DEV + 31].controller = 12;
684 	dispatch[FIRST_DEV + 31].operator = 14;
685 	dispatch[FIRST_DEV + 32].controller = 12;
686 	dispatch[FIRST_DEV + 32].operator = 12;
687 	dispatch[FIRST_DEV + 33].controller = 7;
688 	dispatch[FIRST_DEV + 33].operator = 1;
689 
690 	dispatch[FIRST_DEV + 34].controller = 12;
691 	dispatch[FIRST_DEV + 34].operator = 1;
692 	dispatch[FIRST_DEV + 35].controller = 12;
693 	dispatch[FIRST_DEV + 35].operator = 4;
694 	dispatch[FIRST_DEV + 36].controller = 12;
695 	dispatch[FIRST_DEV + 36].operator = 0;
696 
697 	dispatch[FIRST_DEV + 37].routine = (synthRoutine) miniDualDecay;
698 	dispatch[FIRST_DEV + 38].controller = 12;
699 	dispatch[FIRST_DEV + 38].operator = 15;
700 
701 	dispatch[FIRST_DEV + 39].controller = 12;
702 	dispatch[FIRST_DEV + 39].operator = 2;
703 	dispatch[FIRST_DEV + 40].controller = 4;
704 	dispatch[FIRST_DEV + 40].operator = 3;
705 	dispatch[FIRST_DEV + 41].controller = 5;
706 	dispatch[FIRST_DEV + 41].operator = 5;
707 
708 	dispatch[ACTIVE_DEVS +0].routine = dispatch[ACTIVE_DEVS +1].routine =
709 		dispatch[ACTIVE_DEVS +2].routine = dispatch[ACTIVE_DEVS +3].routine =
710 		dispatch[ACTIVE_DEVS +4].routine = dispatch[ACTIVE_DEVS +5].routine =
711 		dispatch[ACTIVE_DEVS +6].routine = dispatch[ACTIVE_DEVS +7].routine =
712 		dispatch[ACTIVE_DEVS +8].routine = dispatch[ACTIVE_DEVS +9].routine =
713 		dispatch[ACTIVE_DEVS +10].routine = dispatch[ACTIVE_DEVS +11].routine =
714 		dispatch[ACTIVE_DEVS +14].routine = dispatch[ACTIVE_DEVS +15].routine
715 		= (synthRoutine) miniMemory;
716 
717 	dispatch[ACTIVE_DEVS + 0].controller = 1;
718 	dispatch[ACTIVE_DEVS + 1].controller = 2;
719 	dispatch[ACTIVE_DEVS + 2].operator = 0;
720 	dispatch[ACTIVE_DEVS + 3].operator = 1;
721 	dispatch[ACTIVE_DEVS + 4].operator = 2;
722 	dispatch[ACTIVE_DEVS + 5].operator = 3;
723 	dispatch[ACTIVE_DEVS + 6].operator = 4;
724 	dispatch[ACTIVE_DEVS + 7].operator = 5;
725 	dispatch[ACTIVE_DEVS + 8].operator = 6;
726 	dispatch[ACTIVE_DEVS + 9].operator = 7;
727 	dispatch[ACTIVE_DEVS + 10].operator = 8;
728 	dispatch[ACTIVE_DEVS + 11].operator = 9;
729 	dispatch[ACTIVE_DEVS + 14].controller = 3;
730 	dispatch[ACTIVE_DEVS + 15].controller = 4;
731 
732 	dispatch[ACTIVE_DEVS + 12].controller = 1;
733 	dispatch[ACTIVE_DEVS + 13].controller = 2;
734 	dispatch[ACTIVE_DEVS + 12].routine = dispatch[ACTIVE_DEVS + 13].routine
735 		= (synthRoutine) miniMidi;
736 
737 	/* Tune osc-1 */
738 	bristolMidiSendMsg(global.controlfd, synth->sid, 0, 2, 8192);
739 	/* Gain on filter contour */
740 	bristolMidiSendMsg(global.controlfd, synth->sid, 3, 4,
741 		CONTROLLER_RANGE - 1);
742 	/*
743 	 * Filter type, this selects a Houvilainen filter
744 	 */
745 	bristolMidiSendMsg(global.controlfd, synth->sid, 4, 4, 4);
746 	/*
747 	 * Pink filter configuration
748 	 */
749 	bristolMidiSendMsg(global.controlfd, synth->sid, 7, 2, 4096);
750 
751 	return(0);
752 }
753 
754 static void
configureKeylatch(guiSynth * synth)755 configureKeylatch(guiSynth *synth)
756 {
757 	if (synth->keypanel < 0)
758 		return;
759 
760    	if (synth->flags & NO_LATCHING_KEYS)
761    	{
762    		int i, p = synth->keypanel;
763 
764    		for (i = 0; i < synth->win->app->resources[p].ndevices; i++)
765    			synth->win->app->resources[p].devlocn[i].flags
766    				|= BRIGHTON_NO_TOGGLE;
767 
768    		if (synth->keypanel2 < 0)
769    			return;
770 
771 	   	p = synth->keypanel2;
772 
773    		for (i = 0; i < synth->win->app->resources[p].ndevices; i++)
774    			synth->win->app->resources[p].devlocn[i].flags
775 	   			|= BRIGHTON_NO_TOGGLE;
776    	}
777 }
778 
779 
780 /*
781  * These aught to be moved into a more common file, brightonRoutines.c or
782  * similar.
783  */
784 int
configureGlobals(guiSynth * synth)785 configureGlobals(guiSynth *synth)
786 {
787 	if (global.libtest)
788 	{
789 		int count = 10;
790 
791 		printf("libtest flagged");
792 
793 		while (global.libtest)
794 		{
795 			usleep(100000);
796 			if (--count == 0)
797 				break;
798 		}
799 
800 		if (count)
801 			printf(", cleared\n");
802 		else
803 			printf("\n");
804 	}
805 
806 	if (!global.libtest)
807 	{
808 		configureKeylatch(synth);
809 
810 		if (synth->flags & REQ_MIDI_DEBUG)
811 		{
812 			bristolMidiSendNRP(global.controlfd, synth->midichannel,
813 				BRISTOL_NRP_DEBUG, 1);
814 			if (synth->sid2 != 0)
815 				bristolMidiSendNRP(global.manualfd, synth->midichannel+1,
816 					BRISTOL_NRP_DEBUG, 1);
817 		}
818 		if (synth->flags & REQ_MIDI_DEBUG2)
819 		{
820 			bristolMidiSendNRP(global.controlfd, synth->midichannel,
821 				BRISTOL_NRP_DEBUG, 2);
822 			if (synth->sid2 != 0)
823 				bristolMidiSendNRP(global.manualfd, synth->midichannel+1,
824 					BRISTOL_NRP_DEBUG, 2);
825 		}
826 
827 		/* Send debug level request to engine and also setup local debugging */
828 		bristolMidiSendMsg(global.controlfd, synth->sid,
829 			BRISTOL_SYSTEM, 0,
830 				BRISTOL_REQ_DEBUG|((synth->flags&REQ_DEBUG_MASK)>>12));
831 		if (synth->sid2 != 0)
832 			bristolMidiSendMsg(global.manualfd, synth->sid2,
833 				BRISTOL_SYSTEM, 0,
834 					BRISTOL_REQ_DEBUG|((synth->flags&REQ_DEBUG_MASK)>>12));
835 
836 		bristolMidiOption(global.controlfd, BRISTOL_NRP_DEBUG,
837 			(synth->flags&REQ_DEBUG_MASK)>>12);
838 		if (synth->sid2 != 0)
839 			bristolMidiOption(global.manualfd, BRISTOL_NRP_DEBUG,
840 				(synth->flags&REQ_DEBUG_MASK)>>12);
841 
842 		bristolMidiSendNRP(global.controlfd, synth->midichannel,
843 			BRISTOL_NRP_GLIDE, synth->glide * C_RANGE_MIN_1 / 30);
844 		bristolMidiSendNRP(global.controlfd, synth->midichannel,
845 			BRISTOL_NRP_GAIN, synth->gain);
846 		bristolMidiSendNRP(global.controlfd, synth->midichannel,
847 			BRISTOL_NRP_DETUNE, synth->detune);
848 		bristolMidiSendRP(global.controlfd, synth->midichannel,
849 			MIDI_RP_PW, synth->pwd);
850 		bristolMidiSendNRP(global.controlfd, synth->midichannel,
851 			BRISTOL_NRP_VELOCITY, synth->velocity);
852 		bristolMidiSendNRP(global.controlfd, synth->midichannel,
853 			BRISTOL_NRP_LWF, synth->lwf);
854 		bristolMidiSendNRP(global.controlfd, synth->midichannel,
855 			BRISTOL_NRP_MNL_PREF, synth->notepref);
856 		bristolMidiSendNRP(global.controlfd, synth->midichannel,
857 			BRISTOL_NRP_MNL_TRIG, synth->notetrig);
858 		bristolMidiSendNRP(global.controlfd, synth->midichannel,
859 			BRISTOL_NRP_MNL_VELOC, synth->legatovelocity);
860 
861 		/* Global message forwarding on/off */
862 		bristolMidiSendNRP(global.controlfd, synth->midichannel,
863 			BRISTOL_NRP_FORWARD, synth->flags & REQ_FORWARD? 1:0);
864 		bristolMidiOption(global.controlfd, BRISTOL_NRP_FORWARD,
865 			synth->flags & REQ_FORWARD? 1:0);
866 
867 		if (synth->flags & MIDI_NRP)
868 			bristolMidiSendNRP(global.controlfd, synth->midichannel,
869 				BRISTOL_NRP_ENABLE_NRP, 1);
870 		else
871 			bristolMidiSendNRP(global.controlfd, synth->midichannel,
872 				BRISTOL_NRP_ENABLE_NRP, 0);
873 
874 		bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0,
875 			BRISTOL_LOWKEY|synth->lowkey);
876 		bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0,
877 			BRISTOL_HIGHKEY|synth->highkey);
878 
879 		if (synth->sid2 != 0) {
880 			bristolMidiSendNRP(global.controlfd, synth->midichannel+1,
881 				BRISTOL_NRP_GLIDE, synth->glide * C_RANGE_MIN_1 / 30);
882 			bristolMidiSendNRP(global.controlfd, synth->midichannel+1,
883 				BRISTOL_NRP_GAIN, synth->gain);
884 			bristolMidiSendNRP(global.controlfd, synth->midichannel+1,
885 				BRISTOL_NRP_DETUNE, synth->detune);
886 			bristolMidiSendRP(global.controlfd, synth->midichannel+1,
887 				MIDI_RP_PW, synth->pwd);
888 			bristolMidiSendNRP(global.controlfd, synth->midichannel+1,
889 				BRISTOL_NRP_VELOCITY, synth->velocity);
890 			bristolMidiSendNRP(global.controlfd, synth->midichannel+1,
891 				BRISTOL_NRP_LWF, synth->lwf);
892 			if (synth->flags & MIDI_NRP)
893 				bristolMidiSendNRP(global.controlfd, synth->midichannel+1,
894 					BRISTOL_NRP_ENABLE_NRP, 1);
895 			else
896 				bristolMidiSendNRP(global.controlfd, synth->midichannel+1,
897 					BRISTOL_NRP_ENABLE_NRP, 0);
898 
899 			bristolMidiSendMsg(global.controlfd, synth->sid2, 127, 0,
900 				BRISTOL_LOWKEY|synth->lowkey);
901 			bristolMidiSendMsg(global.controlfd, synth->sid2, 127, 0,
902 				BRISTOL_HIGHKEY|synth->highkey);
903 		}
904 
905 		if (synth->flags & REQ_LOCAL_FORWARD)
906 		{
907 			bristolMidiOption(global.controlfd, BRISTOL_NRP_FORWARD, 1);
908 			bristolMidiOption(global.controlfd, BRISTOL_NRP_MIDI_GO, 1);
909 			bristolMidiOption(global.controlfd, BRISTOL_NRP_REQ_FORWARD, 1);
910 		}
911 
912 		/* Forwarding options for this emulator */
913 		if (synth->flags & REQ_REMOTE_FORWARD)
914 			bristolMidiSendMsg(global.controlfd, synth->sid,
915 				BRISTOL_SYSTEM, 0, BRISTOL_REQ_FORWARD|1);
916 
917 		/* Forwarding options disabled for second manual, local and remote */
918 		if (global.manualfd != 0)
919 		{
920 			bristolMidiOption(global.manualfd, BRISTOL_NRP_REQ_SYSEX, 1);
921 			bristolMidiSendMsg(global.manualfd, synth->sid2,
922 				BRISTOL_SYSTEM, 0, BRISTOL_REQ_FORWARD);
923 		}
924 
925 		bristolMidiSendNRP(global.controlfd, synth->midichannel,
926 			BRISTOL_NRP_MIDI_GO, 1024);
927 	}
928 	/*
929 	 * We should consider seeding the synth with a short note blip
930 	if ((global.synths->notepref == BRIGHTON_HNP)
931 		|| (global.synths->notepref == BRIGHTON_LNP))
932 	{
933 		sleep(1);
934 		bristolMidiSendMsg(global.controlfd,
935 			synth->midichannel, BRISTOL_EVENT_KEYON, 0, 5);
936 		sleep(1);
937 		bristolMidiSendMsg(global.controlfd,
938 			synth->midichannel, BRISTOL_EVENT_KEYOFF, 0, 5);
939 	}
940 	 */
941 	return(0);
942 }
943 
944 /*
945  * This will be called to make any routine specific parameters available.
946  */
947 static int
miniConfigure(brightonWindow * win)948 miniConfigure(brightonWindow *win)
949 {
950 	guiSynth *synth = findSynth(global.synths, win);
951 	brightonEvent event;
952 
953 	memset(&event, 0, sizeof(brightonEvent));
954 
955 	if (synth == 0)
956 	{
957 		printf("problems going operational\n");
958 		return(-1);
959 	}
960 
961 	if (synth->flags & OPERATIONAL)
962 		return(0);
963 
964 	printf("going operational: %p, %p\n", synth, win);
965 
966 	synth->flags |= OPERATIONAL;
967 	synth->transpose = 36;
968 	synth->keypanel = KEY_PANEL;
969 	synth->keypanel2 = -1;
970 
971 	/*
972 	 * We now want to set a couple of parameters provided by switches in the
973 	 * 0.9 release but configurable per synth. These are detune and gain to
974 	 * start with. Some of this code could be separated as it is likely to be
975 	 * common to each synth. These parameters will be sent to the engine using
976 	 * midi non-registered parameters. These will be sent as NRP-98/99 and Data
977 	 * Entry-6/38. To simplify the interface we should be able to make one call
978 	 * send a NRP including the number and its 14 bit value. It is up to the
979 	 * interface to decide how to send it depending on whether it is a repeat
980 	 * message or not.
981 	 */
982 	configureGlobals(synth);
983 
984 	loadMemory(synth, "mini", 0, synth->location, synth->mem.active,
985 		FIRST_DEV, 0);
986 
987 	brightonPut(win, "bitmaps/blueprints/minishade.xpm",
988 		0, 0, win->width, win->height);
989 
990 	/*
991 	 * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only
992 	 * occurs on first paint, so we suppress the first paint and then request
993 	 * an expose here.
994 	 */
995 	event.type = BRIGHTON_EXPOSE;
996 	event.intvalue = 1;
997 	brightonParamChange(synth->win, KEY_PANEL, -1, &event);
998 
999 	return(0);
1000 }
1001 
1002