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 junoInit();
30 static int junoConfigure();
31 static int junoCallback(brightonWindow *, int, int, float);
32 static int midiCallback(brightonWindow *, int, int, float);
33 
34 extern guimain global;
35 
36 #include "brightonKeys.h"
37 
38 #define FIRST_DEV 0
39 #define DEVICE_COUNT (56 + FIRST_DEV)
40 #define ACTIVE_DEVS (39 + FIRST_DEV)
41 #define DISPLAY_DEV (DEVICE_COUNT - 1)
42 #define MEM_MGT ACTIVE_DEVS
43 #define MIDI_MGT (MEM_MGT + 12)
44 #define KEY_TRANSPOSE (FIRST_DEV + 6)
45 #define KEY_HOLD (FIRST_DEV + 7)
46 #define CHORUS (FIRST_DEV + 32)
47 
48 #define KEY_PANEL 1
49 
50 /*
51  * This structure is for device definition. The structure is defined in
52  * include/brighton.h, further definitions in brighton/brightonDevtable.h and
53  * include/brightoninternals.h
54  *
55  *	typedef int (*brightonCallback)(int, float);
56  *	typedef struct BrightonLocations {
57  *		int device; 0=rotary, 1=scale, etc.
58  *		float relx, rely; relative position with regards to 1000 by 1000 window
59  *		float relw, relh; relative height.
60  *		int from, to;
61  *		brightonCallback callback; specific to this dev
62  *		char *image; bitmap. If zero take a device default.
63  *		int flags;
64  *	} brightonLocations;
65  *
66  * This example is for a junoBristol type synth interface.
67  */
68 #define D3 80
69 #define BR1 300
70 #define BR2 BR1 + D3
71 #define BR3 BR2 + D3
72 #define BR4 BR3 + D3
73 
74 #define MBR2 BR4
75 #define MBR1 MBR2 - 100
76 #define MBR3 MBR2 + 100
77 #define MBR4 MBR3 + 100
78 
79 #define R1 200
80 #define R2 275
81 #define R3 450
82 #define R4 650
83 
84 #define D1 15
85 #define D2 31
86 
87 #define C1 10
88 #define C2 C1 + D2 - 1
89 #define C3 C2 + D1 + 1
90 #define C4 C3 + D2 - 7
91 #define C5 C4 + D2 + 4
92 #define C6 C5 + D1 + 2
93 /* Need to insert a few for the arpeg */
94 #define C6_1 C6 + D2 - 6
95 #define C6_2 C6_1 + D2 - 4
96 #define C6_3 C6_2 + D2 - 2
97 #define C6_4 C6_3 + D2 - 1
98 #define C7 275
99 #define C8 C7 + D1
100 #define C9 C8 + D2 - 9
101 #define C10 C9 + D2 - 6
102 #define C11 C10 + D1 + 4
103 #define C12 C11 + D2 - 12
104 #define C13 C12 + D1 + D2 + 4 /* text space */
105 #define C14 C13 + 15
106 #define C15 C14 + 15
107 #define C16 C15 + D2 + 3
108 #define C17 C16 + D1
109 
110 #define C18 C17 + D2 + 2 /* HPF */
111 #define C19 C18 + D2 + 5
112 #define C20 C19 + D1 + 1
113 #define C21 C20 + D2 - 6
114 #define C22 C21 + D2 - 10
115 #define C23 C22 + D1 + 2
116 #define C24 C23 + D1 + 3
117 
118 #define C25 C24 + D2 + 5
119 #define C26 C25 + D1 - 2
120 
121 #define C27 C26 + D2 - 3
122 #define C28 C27 + D1 + 4
123 #define C29 C28 + D1 + 2
124 #define C30 C29 + D1 + 3
125 
126 #define C31 C30 + D2
127 #define C32 C31 + 15
128 #define C33 C32 + 16
129 
130 #define C34 C33 + D2 + D1 - 13
131 #define C35 C34 + D1 + 3
132 #define C36 C35 + D1 + 3
133 #define C37 C36 + D1 + 3
134 #define C38 C37 + D1 + 3
135 
136 #define W1 14
137 #define L1 485
138 
139 #define S2 120
140 
141 #define BS1 17
142 #define BS2 100
143 #define BS3 115
144 #define BS4 12
145 #define BS5 160
146 
147 static brightonLocations locations[DEVICE_COUNT] = {
148 	/* Power, etc */
149 	{"On/Off", 2, C1, BR2, 18, BS5, 0, 1, 0,
150 		"bitmaps/buttons/touchoff.xpm",
151 		"bitmaps/buttons/touch.xpm", BRIGHTON_NOSHADOW},
152 	{"DCO Mod", 1, C2, R2, W1, L1, 0, 1, 0,
153 		"bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW},
154 	{"VCF Mod", 1, C3, R2, W1, L1, 0, 1, 0,
155 		"bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW},
156 	{"Tuning", 0, C4, R2, S2, S2, 0, 1, 0,
157 		"bitmaps/knobs/knob1.xpm", 0, BRIGHTON_NOTCH},
158 	{"Glide", 0, C4, R3 + 20, S2, S2, 0, 1, 0,
159 		"bitmaps/knobs/knob1.xpm", 0, 0},
160 	{"LFO Manual", 2, C4 + 3, R4, BS1, BS2 + 40, 0, 1, 0,
161 		"bitmaps/buttons/touchoff.xpm",
162 		"bitmaps/buttons/touch.xpm", BRIGHTON_NOSHADOW},
163 	/* Transpose - 6 */
164 	{"Transpose", 2, C5 + 1, BR2 + 30, 12, 180, 0, 2, 0,
165 		0, 0, BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW},
166 	{"Hold", 2, C6 + 2, BR2, BS1, BS5, 0, 1, 0,
167 		"bitmaps/buttons/touchoy.xpm",
168 		"bitmaps/buttons/touchy.xpm", BRIGHTON_NOSHADOW},
169 	{"LFO Rate", 1, C7, R2, W1, L1, 0, 1, 0,
170 		"bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW},
171 	{"LFO Delay", 1, C8, R2, W1, L1, 0, 1, 0,
172 		"bitmaps/knobs/sliderblack4.xpm", 0, BRIGHTON_HALFSHADOW},
173 	{"Man/Auto", 2, C9, BR2 + 70, BS4, BS3, 0, 1, 0,
174 		"bitmaps/buttons/sw1.xpm",
175 		"bitmaps/buttons/sw2.xpm", BRIGHTON_NOSHADOW},
176 	/* DCO - 11 */
177 	{"DCO-LFO Mod", 1, C10, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0,
178 		BRIGHTON_HALFSHADOW},
179 	{"PWM", 1, C11, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0,
180 		BRIGHTON_HALFSHADOW},
181 	{"PWM Source", 2, C12 + 1, BR2 + 30, 12, 180, 0, 2, 0,
182 		0, 0, BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW},
183 	{"Pulse", 2, C13 - 7, BR2, BS1, BS5, 0, 1, 0,
184 		"bitmaps/buttons/touchow.xpm",
185 		"bitmaps/buttons/touchw.xpm", BRIGHTON_NOSHADOW},
186 	{"Ramp", 2, C14 - 3, BR2, BS1, BS5, 0, 1, 0,
187 		"bitmaps/buttons/touchoy.xpm",
188 		"bitmaps/buttons/touchy.xpm", BRIGHTON_NOSHADOW},
189 	{"Square", 2, C15 + 2, BR2, BS1, BS5, 0, 1, 0,
190 		"bitmaps/buttons/touchoo.xpm",
191 		"bitmaps/buttons/toucho.xpm", BRIGHTON_NOSHADOW},
192 	{"SubOsc", 1, C16, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0,
193 		BRIGHTON_HALFSHADOW},
194 	{"Noise", 1, C17, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0,
195 		BRIGHTON_HALFSHADOW},
196 	/* hpf - 19 */
197 	{"HPF", 1, C18, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0,
198 		BRIGHTON_HALFSHADOW},
199 	/* filter - 20 */
200 	{"Filter Freq", 1, C19, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0,
201 		BRIGHTON_HALFSHADOW},
202 	{"Resonance", 1, C20, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0,
203 		BRIGHTON_HALFSHADOW},
204 	{"Env +/-", 2, C21, BR2 + 70, BS4, BS3, 0, 1, 0,
205 		"bitmaps/buttons/sw1.xpm",
206 		"bitmaps/buttons/sw2.xpm", BRIGHTON_NOSHADOW},
207 	{"FilterEnvMod", 1, C22, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0,
208 		BRIGHTON_HALFSHADOW},
209 	{"FilterLFOMod", 1, C23, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0,
210 		BRIGHTON_HALFSHADOW},
211 	{"Filter KBD", 1, C24, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0,
212 		BRIGHTON_HALFSHADOW},
213 	/* VCA - 26  */
214 	{"Amp Env/Gate", 2, C25 - 10, BR2 + 70, BS4, BS3, 0, 1, 0,
215 		"bitmaps/buttons/sw1.xpm",
216 		"bitmaps/buttons/sw2.xpm", BRIGHTON_NOSHADOW},
217 	{"Amp Level", 1, C26, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0,
218 		BRIGHTON_HALFSHADOW},
219 	/* adsr - 28 */
220 	{"Attack", 1, C27, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0,
221 		BRIGHTON_HALFSHADOW},
222 	{"Decay", 1, C28, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0,
223 		BRIGHTON_HALFSHADOW},
224 	{"Sustain", 1, C29, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0,
225 		BRIGHTON_HALFSHADOW},
226 	{"Release", 1, C30, R2, W1, L1, 0, 1, 0, "bitmaps/knobs/sliderblack4.xpm", 0,
227 		BRIGHTON_HALFSHADOW},
228 	/* chorus - 32 */
229 	{"Chorus 1", 2, C31 - 9, BR2, BS1, BS5, 0, 1, 0,
230 		"bitmaps/buttons/touchow.xpm",
231 		"bitmaps/buttons/touchw.xpm", BRIGHTON_NOSHADOW},
232 	{"Chorus 2", 2, C32 - 4, BR2, BS1, BS5, 0, 2, 0,
233 		"bitmaps/buttons/touchoy.xpm",
234 		"bitmaps/buttons/touchy.xpm", BRIGHTON_NOSHADOW},
235 	{"Chorus 3", 2, C33, BR2, BS1, BS5, 0, 4, 0,
236 		"bitmaps/buttons/touchoo.xpm",
237 		"bitmaps/buttons/toucho.xpm", BRIGHTON_NOSHADOW},
238 	/* Arpeggiator - 35 */
239 	{"Arpeg On", 2, C6_1, BR2, BS1, BS5, 0, 1, 0,
240 		"bitmaps/buttons/touchoo.xpm",
241 		"bitmaps/buttons/toucho.xpm", BRIGHTON_NOSHADOW},
242 	{"Arpeg UpDown", 2, C6_2, BR2 + 30, 12, 180, 0, 2, 0,
243 		0, 0, BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW},
244 	{"Arpeg Range", 2, C6_3, BR2 + 30, 12, 180, 0, 2, 0,
245 		0, 0, BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW},
246 	{"Arpeg Rate", 1, C6_4, R2, W1, L1, 0, 1, 0,
247 		"bitmaps/knobs/sliderblack4.xpm", 0,
248 		BRIGHTON_HALFSHADOW|BRIGHTON_REVERSE},
249 /* memory tablet */
250 	{"", 2, C34, MBR2, BS1, BS2, 0, 1, 0,
251 		"bitmaps/buttons/touchnlw.xpm",
252 		"bitmaps/buttons/touchnlw.xpm", 0},
253 	{"", 2, C35, MBR2, BS1, BS2, 0, 1, 0,
254 		"bitmaps/buttons/touchnlw.xpm",
255 		"bitmaps/buttons/touchnlw.xpm", 0},
256 	{"", 2, C36, MBR2, BS1, BS2, 0, 1, 0,
257 		"bitmaps/buttons/touchnlw.xpm",
258 		"bitmaps/buttons/touchnlw.xpm", 0},
259 	{"", 2, C37, MBR2, BS1, BS2, 0, 1, 0,
260 		"bitmaps/buttons/touchnlw.xpm",
261 		"bitmaps/buttons/touchnlw.xpm", 0},
262 	{"", 2, C38, MBR2, BS1, BS2, 0, 1, 0,
263 		"bitmaps/buttons/touchnlw.xpm",
264 		"bitmaps/buttons/touchnlw.xpm", 0},
265 	{"", 2, C34, MBR3, BS1, BS2, 0, 1, 0,
266 		"bitmaps/buttons/touchnlw.xpm",
267 		"bitmaps/buttons/touchnlw.xpm", 0},
268 	{"", 2, C35, MBR3, BS1, BS2, 0, 1, 0,
269 		"bitmaps/buttons/touchnlw.xpm",
270 		"bitmaps/buttons/touchnlw.xpm", 0},
271 	{"", 2, C36, MBR3, BS1, BS2, 0, 1, 0,
272 		"bitmaps/buttons/touchnlw.xpm",
273 		"bitmaps/buttons/touchnlw.xpm", 0},
274 	{"", 2, C37, MBR3, BS1, BS2, 0, 1, 0,
275 		"bitmaps/buttons/touchnlw.xpm",
276 		"bitmaps/buttons/touchnlw.xpm", 0},
277 	{"", 2, C38, MBR3, BS1, BS2, 0, 1, 0,
278 		"bitmaps/buttons/touchnlw.xpm",
279 		"bitmaps/buttons/touchnlw.xpm", 0},
280 	{"", 2, C37, MBR1, BS1, BS2, 0, 1, 0,
281 		"bitmaps/buttons/touchnl.xpm",
282 		"bitmaps/buttons/touchnl.xpm", 0},
283 	{"", 2, C38, MBR1, BS1, BS2, 0, 1, 0,
284 		"bitmaps/buttons/touchnlo.xpm",
285 		"bitmaps/buttons/touchnlo.xpm", 0},
286 	{"", 2, C34, MBR1, BS1, BS2, 0, 1, 0,
287 		"bitmaps/buttons/touchnl.xpm",
288 		"bitmaps/buttons/touchnl.xpm", 0},
289 	{"", 2, C35, MBR1, BS1, BS2, 0, 1, 0,
290 		"bitmaps/buttons/touchnl.xpm",
291 		"bitmaps/buttons/touchnl.xpm", 0},
292 	{"", 2, C34, MBR4, BS1, BS2, 0, 1, 0,
293 		"bitmaps/buttons/touchnl.xpm",
294 		"bitmaps/buttons/touchnl.xpm", 0},
295 	{"", 2, C38, MBR4, BS1, BS2, 0, 1, 0,
296 		"bitmaps/buttons/touchnl.xpm",
297 		"bitmaps/buttons/touchnl.xpm", 0},
298 	{"", 3, C34 - 5, R1, 100, BS2, 0, 1, 0, 0,
299 		"bitmaps/images/alphadisplay3.xpm", 0},
300 };
301 
302 /*
303  */
304 
305 /*
306  * This is a set of globals for the main window rendering. Again taken from
307  * include/brighton.h
308  */
309 brightonApp junoApp = {
310 	"juno",
311 	0, /* no blueprint on wood background. */
312 	"bitmaps/textures/metal4.xpm",
313 	BRIGHTON_STRETCH,
314 	junoInit,
315 	junoConfigure, /* 3 callbacks, unused? */
316 	midiCallback,
317 	destroySynth,
318 	{6, 100, 1, 2, 5, 520, 0, 0},
319 	820, 250, 0, 0,
320 	5, /* panels */
321 	{
322 		{
323 			"Juno",
324 			"bitmaps/blueprints/juno.xpm",
325 			"bitmaps/textures/metal6.xpm",
326 			BRIGHTON_STRETCH, /* flags */
327 			0,
328 			0,
329 			junoCallback,
330 			25, 20, 953, 550,
331 			DEVICE_COUNT,
332 			locations
333 		},
334 		{
335 			"Keyboard",
336 			0,
337 			"bitmaps/newkeys/nkbg.xpm", /* flags */
338 			0x020|BRIGHTON_STRETCH,
339 			0,
340 			0,
341 			keyCallback,
342 			114, 562, 889, 425,
343 			KEY_COUNT,
344 			//keys
345 			keysprofile2
346 		},
347 		{
348 			"Mods",
349 			0, //"bitmaps/blueprints/mods.xpm",
350 			"bitmaps/keys/vkbg.xpm", /* flags */
351 			BRIGHTON_STRETCH,
352 			0,
353 			0,
354 			modCallback,
355 			25, 562, 90, 410,
356 			2,
357 			mods
358 		},
359 		{
360 			"Wood",
361 			0,
362 			"bitmaps/textures/wood.xpm",
363 			BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */
364 			0,
365 			0,
366 			0,
367 			2, 5, 22, 985,
368 			0,
369 			0
370 		},
371 		{
372 			"Wood",
373 			0,
374 			"bitmaps/textures/wood.xpm",
375 			BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */
376 			0,
377 			0,
378 			0,
379 			979, 5, 21, 985,
380 			0,
381 			0
382 		},
383 	}
384 };
385 
386 /*static dispatcher dispatch[DEVICE_COUNT]; */
387 
388 static int
midiCallback(brightonWindow * win,int controller,int value,float n)389 midiCallback(brightonWindow *win, int controller, int value, float n)
390 {
391 	guiSynth *synth = findSynth(global.synths, win);
392 
393 	printf("midi callback: %x, %i\n", controller, value);
394 
395 	switch(controller)
396 	{
397 		case MIDI_PROGRAM:
398 			printf("midi program: %x, %i\n", controller, value);
399 			synth->location = value;
400 			if (loadMemory(synth, "juno", 0, synth->bank + synth->location,
401 				synth->mem.active, FIRST_DEV, 0) < 0)
402 				displayText(synth, "FRE", synth->location, DISPLAY_DEV);
403 			else
404 				displayText(synth, "PRG", synth->location, DISPLAY_DEV);
405 			break;
406 		case MIDI_BANK_SELECT:
407 			printf("midi banksel: %x, %i\n", controller, value);
408 			synth->bank = value;
409 			synth->location = (synth->location % 10) + value * 10;
410 			if (loadMemory(synth, "juno", 0, synth->bank + synth->location,
411 				synth->mem.active, FIRST_DEV, 0) < 0)
412 				displayText(synth, "FRE", synth->location, DISPLAY_DEV);
413 			else
414 				displayText(synth, "PRG", synth->location, DISPLAY_DEV);
415 			break;
416 	}
417 	return(0);
418 }
419 
420 static int
junoMidiSendMsg(void * synth,int fd,int chan,int c,int o,int v)421 junoMidiSendMsg(void *synth, int fd, int chan, int c, int o, int v)
422 {
423 /*printf("%i, %i, %i\n", c, o, v); */
424 	bristolMidiSendMsg(fd, chan, c, o, v);
425 	return(0);
426 }
427 
428 static void
junoMemory(guiSynth * synth,int fd,int chan,int c,int o,int v)429 junoMemory(guiSynth *synth, int fd, int chan, int c, int o, int v)
430 {
431 	if (synth->flags & MEM_LOADING)
432 		return;
433 	if ((synth->flags & OPERATIONAL) == 0)
434 		return;
435 
436 	switch (c) {
437 		default:
438 		case 0:
439 			synth->location = synth->location * 10 + o;
440 
441 			if (synth->location >= 1000)
442 				synth->location = o;
443 			if (loadMemory(synth, "juno", 0, synth->bank + synth->location,
444 				synth->mem.active, FIRST_DEV, BRISTOL_STAT) < 0)
445 				displayText(synth, "FRE", synth->location, DISPLAY_DEV);
446 			else
447 				displayText(synth, "PRG", synth->location, DISPLAY_DEV);
448 			break;
449 		case 1:
450 			if (loadMemory(synth, "juno", 0, synth->bank + synth->location,
451 				synth->mem.active, FIRST_DEV, 0) < 0)
452 				displayText(synth, "FRE", synth->location, DISPLAY_DEV);
453 			else
454 				displayText(synth, "PRG", synth->bank + synth->location,
455 					DISPLAY_DEV);
456 			break;
457 		case 2:
458 			saveMemory(synth, "juno", 0, synth->bank + synth->location,
459 				FIRST_DEV);
460 			displayText(synth, "PRG", synth->bank + synth->location,
461 				DISPLAY_DEV);
462 			break;
463 		case 3:
464 			while (loadMemory(synth, "juno", 0, --synth->location,
465 				synth->mem.active, FIRST_DEV, 0) < 0)
466 			{
467 				if (synth->location < 0)
468 					synth->location = 1000;
469 			}
470 			displayText(synth, "PRG", synth->location, DISPLAY_DEV);
471 			break;
472 		case 4:
473 			while (loadMemory(synth, "juno", 0, ++synth->location,
474 				synth->mem.active, FIRST_DEV, 0) < 0)
475 			{
476 				if (synth->location > 999)
477 					synth->location = -1;
478 			}
479 			displayText(synth, "PRG", synth->location, DISPLAY_DEV);
480 			break;
481 	}
482 }
483 
484 static void
junoMidi(guiSynth * synth,int fd,int chan,int c,int o,int v)485 junoMidi(guiSynth *synth, int fd, int chan, int c, int o, int v)
486 {
487 	int newchan;
488 
489 	if ((synth->flags & OPERATIONAL) == 0)
490 		return;
491 
492 	if (c == 1) {
493 		if ((newchan = synth->midichannel - 1) < 0)
494 		{
495 			synth->midichannel = 0;
496 			return;
497 		}
498 	} else {
499 		if ((newchan = synth->midichannel + 1) >= 15)
500 		{
501 			synth->midichannel = 15;
502 			return;
503 		}
504 	}
505 
506 	if (global.libtest == 0)
507 	{
508 		bristolMidiSendMsg(global.controlfd, synth->sid,
509 			127, 0, BRISTOL_MIDICHANNEL|newchan);
510 	}
511 
512 	synth->midichannel = newchan;
513 
514 	displayText(synth, "MIDI", synth->midichannel + 1, DISPLAY_DEV);
515 }
516 
517 /*
518  * For the sake of ease of use, links have been placed here to be called
519  * by any of the devices created. They would be better in some other file,
520  * perhaps with this as a dispatch.
521  *
522  * Param refers to the device index in the locations table given below.
523  */
524 static int
junoCallback(brightonWindow * win,int panel,int index,float value)525 junoCallback(brightonWindow * win, int panel, int index, float value)
526 {
527 	guiSynth *synth = findSynth(global.synths, win);
528 	int sendvalue;
529 
530 	/*printf("junoCallback(%i, %f): %x\n", index, value, synth); */
531 
532 	if (synth == 0)
533 		return(0);
534 
535 	if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0))
536 		return(0);
537 
538 	if (junoApp.resources[0].devlocn[index].to == 1)
539 		sendvalue = value * C_RANGE_MIN_1;
540 	else
541 		sendvalue = value;
542 
543 		synth->mem.param[index] = value;
544 
545 	if ((!global.libtest) || (index >= ACTIVE_DEVS))
546 		synth->dispatch[index].routine(synth,
547 			global.controlfd, synth->sid,
548 			synth->dispatch[index].controller,
549 			synth->dispatch[index].operator,
550 			sendvalue);
551 #define DEBUG
552 #ifdef DEBUG
553 	else
554 		printf("dispatch[%p,%i](%i, %i, %i, %i, %i)\n", synth, index,
555 			global.controlfd, synth->sid,
556 			synth->dispatch[index].controller,
557 			synth->dispatch[index].operator,
558 			sendvalue);
559 #endif
560 
561 	return(0);
562 }
563 
564 static void
junoChorus(guiSynth * synth)565 junoChorus(guiSynth *synth)
566 {
567 	int value = 0;
568 
569 	if (synth->mem.param[CHORUS])
570 		value++;
571 	if (synth->mem.param[CHORUS + 1])
572 		value+=2;
573 	if (synth->mem.param[CHORUS + 2])
574 		value+=4;
575 
576 	bristolMidiSendMsg(global.controlfd, synth->sid, 100, 0, value);
577 }
578 
579 static void
junoSublevel(guiSynth * synth)580 junoSublevel(guiSynth *synth)
581 {
582 	/*printf("junoSublevel %f %f\n", synth->mem.param[16], synth->mem.param[17]); */
583 
584 	if (synth->mem.param[16] == 0)
585 	{
586 		bristolMidiSendMsg(global.controlfd, synth->sid,
587 			1, 6, 0);
588 		return;
589 	}
590 
591 	bristolMidiSendMsg(global.controlfd, synth->sid,
592 		1, 6, ((int) (synth->mem.param[17] * C_RANGE_MIN_1)));
593 }
594 
595 static void
junoTranspose(guiSynth * synth)596 junoTranspose(guiSynth *synth)
597 {
598 	if ((synth->flags & OPERATIONAL) == 0)
599 		return;
600 
601 	//printf("junoTranspose %f\n", synth->mem.param[KEY_TRANSPOSE]);
602 
603 	bristolMidiSendMsg(global.controlfd, synth->sid, 127, 0,
604 		BRISTOL_TRANSPOSE + (int) (synth->mem.param[KEY_TRANSPOSE] * 12) - 12);
605 
606 /*
607 	if (synth->mem.param[KEY_TRANSPOSE] == 0)
608 		synth->transpose = 24;
609 	else if (synth->mem.param[KEY_TRANSPOSE] == 1)
610 			synth->transpose = 36;
611 	else
612 		synth->transpose = 48;
613 */
614 }
615 
616 static void
junoHold(guiSynth * synth)617 junoHold(guiSynth *synth)
618 {
619 	if ((synth->flags & OPERATIONAL) == 0)
620 		return;
621 
622 	/*printf("junoHold %x\n", synth); */
623 
624 	if (synth->mem.param[KEY_HOLD])
625 		bristolMidiSendMsg(global.controlfd, synth->sid,
626 			127, 0, BRISTOL_HOLD|1);
627 	else
628 		bristolMidiSendMsg(global.controlfd, synth->sid,
629 			127, 0, BRISTOL_HOLD|0);
630 
631 }
632 
633 /*
634  * Any location initialisation required to run the callbacks. For bristol, this
635  * will connect to the engine, and give it some base parameters.
636  * May need to generate some application specific menus.
637  * Will also then make specific requests to some of the devices to alter their
638  * rendering.
639  */
640 static int
junoInit(brightonWindow * win)641 junoInit(brightonWindow *win)
642 {
643 	guiSynth *synth = findSynth(global.synths, win);
644 	dispatcher *dispatch;
645 	int i;
646 
647 	if (synth == 0)
648 	{
649 		synth = findSynth(global.synths, 0);
650 		if (synth == 0)
651 		{
652 			printf("cannot init\n");
653 			return(0);
654 		}
655 	}
656 
657 	synth->win = win;
658 
659 	printf("Initialise the juno link to bristol: %p\n", synth->win);
660 
661 	synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float));
662 	synth->mem.count = DEVICE_COUNT;
663 	synth->mem.active = ACTIVE_DEVS;
664 	synth->dispatch = (dispatcher *)
665 		brightonmalloc(DEVICE_COUNT * sizeof(dispatcher));
666 	dispatch = synth->dispatch;
667 
668 	/*
669 	 * We really want to have three connection mechanisms. These should be
670 	 *	1. Unix named sockets.
671 	 *	2. UDP sockets.
672 	 *	3. MIDI pipe.
673 	 */
674 	if (!global.libtest)
675 		if ((synth->sid = initConnection(&global, synth)) < 0)
676 			return(-1);
677 
678 	for (i = 0; i < DEVICE_COUNT; i++)
679 		synth->dispatch[i].routine = junoMidiSendMsg;
680 
681 	dispatch[FIRST_DEV].controller = 126;
682 	dispatch[FIRST_DEV + 0].operator = 17;
683 	dispatch[FIRST_DEV + 1].controller = 126;
684 	dispatch[FIRST_DEV + 1].operator = 9;
685 	dispatch[FIRST_DEV + 2].controller = 126;
686 	dispatch[FIRST_DEV + 2].operator = 16;
687 	dispatch[FIRST_DEV + 3].controller = 126;
688 	dispatch[FIRST_DEV + 3].operator = 1;
689 	dispatch[FIRST_DEV + 4].controller = 126;
690 	dispatch[FIRST_DEV + 4].operator = 0;
691 	dispatch[FIRST_DEV + 5].controller = 126;
692 	dispatch[FIRST_DEV + 5].operator = 3;
693 
694 	dispatch[FIRST_DEV + 6].routine = (synthRoutine) junoTranspose;
695 	dispatch[FIRST_DEV + 7].routine = (synthRoutine) junoHold;
696 
697 	dispatch[FIRST_DEV + 8].controller = 0;
698 	dispatch[FIRST_DEV + 8].operator = 2;
699 	dispatch[FIRST_DEV + 9].controller = 7;
700 	dispatch[FIRST_DEV + 9].operator = 0;
701 	dispatch[FIRST_DEV + 10].controller = 126;
702 	dispatch[FIRST_DEV + 10].operator = 4;
703 	dispatch[FIRST_DEV + 11].controller = 126;
704 	dispatch[FIRST_DEV + 11].operator = 5;
705 	dispatch[FIRST_DEV + 12].controller = 126;
706 	dispatch[FIRST_DEV + 12].operator = 7;
707 	dispatch[FIRST_DEV + 13].controller = 126;
708 	dispatch[FIRST_DEV + 13].operator = 6;
709 
710 	dispatch[FIRST_DEV + 14].controller = 1;
711 	dispatch[FIRST_DEV + 14].operator = 7;
712 	dispatch[FIRST_DEV + 15].controller = 1;
713 	dispatch[FIRST_DEV + 15].operator = 4;
714 	dispatch[FIRST_DEV + 16].controller = 1;
715 	dispatch[FIRST_DEV + 16].operator = 6;
716 	dispatch[FIRST_DEV + 17].controller = 1;
717 	dispatch[FIRST_DEV + 17].operator = 6;
718 	dispatch[FIRST_DEV + 16].routine = dispatch[FIRST_DEV + 17].routine
719 		= (synthRoutine) junoSublevel;
720 	dispatch[FIRST_DEV + 18].controller = 6;
721 	dispatch[FIRST_DEV + 18].operator = 0;
722 
723 	dispatch[FIRST_DEV + 19].controller = 2;
724 	dispatch[FIRST_DEV + 19].operator = 0;
725 
726 	dispatch[FIRST_DEV + 20].controller = 3;
727 	dispatch[FIRST_DEV + 20].operator = 0;
728 	dispatch[FIRST_DEV + 21].controller = 3;
729 	dispatch[FIRST_DEV + 21].operator = 1;
730 	dispatch[FIRST_DEV + 22].controller = 126;
731 	dispatch[FIRST_DEV + 22].operator = 11;
732 	dispatch[FIRST_DEV + 23].controller = 126;
733 	dispatch[FIRST_DEV + 23].operator = 12;
734 	dispatch[FIRST_DEV + 24].controller = 126;
735 	dispatch[FIRST_DEV + 24].operator = 13;
736 	dispatch[FIRST_DEV + 25].controller = 3;
737 	dispatch[FIRST_DEV + 25].operator = 3;
738 
739 	dispatch[FIRST_DEV + 26].controller = 126;
740 	dispatch[FIRST_DEV + 26].operator = 8;
741 	dispatch[FIRST_DEV + 27].controller = 126;
742 	dispatch[FIRST_DEV + 27].operator = 15;
743 
744 	dispatch[FIRST_DEV + 28].controller = 4;
745 	dispatch[FIRST_DEV + 28].operator = 0;
746 	dispatch[FIRST_DEV + 29].controller = 4;
747 	dispatch[FIRST_DEV + 29].operator = 1;
748 	dispatch[FIRST_DEV + 30].controller = 4;
749 	dispatch[FIRST_DEV + 30].operator = 2;
750 	dispatch[FIRST_DEV + 31].controller = 4;
751 	dispatch[FIRST_DEV + 31].operator = 3;
752 
753 	dispatch[FIRST_DEV + 32].controller = 100;
754 	dispatch[FIRST_DEV + 32].operator = 0;
755 	dispatch[FIRST_DEV + 33].controller = 100;
756 	dispatch[FIRST_DEV + 33].operator = 0;
757 	dispatch[FIRST_DEV + 34].controller = 100;
758 	dispatch[FIRST_DEV + 34].operator = 0;
759 	dispatch[CHORUS].routine = dispatch[CHORUS + 1].routine
760 		= dispatch[CHORUS + 2].routine
761 		= (synthRoutine) junoChorus;
762 
763 	dispatch[FIRST_DEV + 35].controller = BRISTOL_ARPEGGIATOR;
764 	dispatch[FIRST_DEV + 35].operator = BRISTOL_ARPEG_ENABLE;
765 	/* The next two may need shimming due to damaged values. */
766 	dispatch[FIRST_DEV + 36].controller = BRISTOL_ARPEGGIATOR;
767 	dispatch[FIRST_DEV + 36].operator = BRISTOL_ARPEG_DIR;
768 	dispatch[FIRST_DEV + 37].controller = BRISTOL_ARPEGGIATOR;
769 	dispatch[FIRST_DEV + 37].operator = BRISTOL_ARPEG_RANGE;
770 	dispatch[FIRST_DEV + 38].controller = BRISTOL_ARPEGGIATOR;
771 	dispatch[FIRST_DEV + 38].operator = BRISTOL_ARPEG_RATE;
772 
773 	/* Memory management */
774 	dispatch[MEM_MGT].operator = 0;
775 	dispatch[MEM_MGT + 1].operator = 1;
776 	dispatch[MEM_MGT + 2].operator = 2;
777 	dispatch[MEM_MGT + 3].operator = 3;
778 	dispatch[MEM_MGT + 4].operator = 4;
779 	dispatch[MEM_MGT + 5].operator = 5;
780 	dispatch[MEM_MGT + 6].operator = 6;
781 	dispatch[MEM_MGT + 7].operator = 7;
782 	dispatch[MEM_MGT + 8].operator = 8;
783 	dispatch[MEM_MGT + 9].operator = 9;
784 
785 	dispatch[MEM_MGT + 10].controller = 1;
786 	dispatch[MEM_MGT + 11].controller = 2;
787 	dispatch[MEM_MGT + 14].controller = 3;
788 	dispatch[MEM_MGT + 15].controller = 4;
789 
790 	dispatch[MEM_MGT].routine = dispatch[MEM_MGT + 1].routine =
791 		dispatch[MEM_MGT + 2].routine = dispatch[MEM_MGT + 3].routine =
792 		dispatch[MEM_MGT + 4].routine = dispatch[MEM_MGT + 5].routine =
793 		dispatch[MEM_MGT + 6].routine = dispatch[MEM_MGT + 7].routine =
794 		dispatch[MEM_MGT + 8].routine = dispatch[MEM_MGT + 9].routine =
795 		dispatch[MEM_MGT + 10].routine = dispatch[MEM_MGT + 11].routine =
796 		dispatch[MEM_MGT + 14].routine = dispatch[MEM_MGT + 15].routine
797 			= (synthRoutine) junoMemory;
798 
799 	/* Midi management */
800 	dispatch[MIDI_MGT].routine = dispatch[MIDI_MGT + 1].routine =
801 		(synthRoutine) junoMidi;
802 	dispatch[MIDI_MGT].controller = 2;
803 	dispatch[MIDI_MGT + 1].controller = 1;
804 
805 	/* Filter type */
806 	bristolMidiSendMsg(global.controlfd, synth->sid, 3, 4, 4);
807 	/*bristol paramchange 126 17 1 */
808 	bristolMidiSendMsg(global.controlfd, synth->sid, 126, 17, 1);
809 	/*after 500 bristol paramchange 7 1 12000 */
810 	/*after 500 bristol paramchange 7 2 16383 */
811 	/*after 500 bristol paramchange 7 3 0 */
812 	/*after 500 bristol paramchange 7 4 16383 */
813 	/*after 500 bristol paramchange 7 5 0 */
814 	bristolMidiSendMsg(global.controlfd, synth->sid, 7, 1, 12000);
815 	bristolMidiSendMsg(global.controlfd, synth->sid, 7, 2, 16383);
816 	bristolMidiSendMsg(global.controlfd, synth->sid, 7, 3, 0);
817 	bristolMidiSendMsg(global.controlfd, synth->sid, 7, 4, 16383);
818 	bristolMidiSendMsg(global.controlfd, synth->sid, 7, 5, 0);
819 
820 	bristolMidiSendMsg(global.controlfd, synth->sid, BRISTOL_ARPEGGIATOR,
821 		BRISTOL_ARPEG_TRIGGER, 1);
822 
823 	return(0);
824 }
825 
826 /*
827  * This will be called to make any routine specific parameters available.
828  */
829 static int
junoConfigure(brightonWindow * win)830 junoConfigure(brightonWindow *win)
831 {
832 	guiSynth *synth = findSynth(global.synths, win);
833 	brightonEvent event;
834 
835 	if (synth == 0)
836 	{
837 		printf("problems going operational\n");
838 		return(-1);
839 	}
840 
841 	if (synth->flags & OPERATIONAL)
842 		return(0);
843 
844 	printf("going operational\n");
845 
846 	synth->flags |= OPERATIONAL;
847 	synth->keypanel = 1;
848 	synth->keypanel2 = -1;
849 	synth->transpose = 36;
850 	loadMemory(synth, "juno", 0, synth->location, synth->mem.active,
851 		FIRST_DEV, 0);
852 
853 	brightonPut(win,
854 		"bitmaps/blueprints/junoshade.xpm", 0, 0, win->width, win->height);
855 
856 	/*
857 	 * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only
858 	 * occurs on first paint, so we suppress the first paint, and then request
859 	 * an expose here.
860 	 */
861 	event.type = BRIGHTON_EXPOSE;
862 	event.intvalue = 1;
863 	brightonParamChange(synth->win, KEY_PANEL, -1, &event);
864 	configureGlobals(synth);
865 
866 	return(0);
867 }
868 
869