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 /* Korg Poly6 UI */
23 /* Bend depth and modes need to be implemented. */
24 
25 #include <fcntl.h>
26 
27 #include "brighton.h"
28 #include "brightonMini.h"
29 #include "brightoninternals.h"
30 
31 static int initmem, width;
32 
33 static int poly6Init();
34 static int poly6Configure();
35 static int poly6Callback(brightonWindow *, int, int, float);
36 static int poly6ModCallback(brightonWindow *, int, int, float);
37 static int midiCallback(brightonWindow *, int, int, float);
38 
39 extern guimain global;
40 
41 #include "brightonKeys.h"
42 
43 #define DEVICE_COUNT (53)
44 #define ACTIVE_DEVS (DEVICE_COUNT - 20)
45 
46 #define MEM_START ACTIVE_DEVS
47 #define MIDI_START (MEM_START + 18)
48 
49 #define P6_BEND 2
50 #define KEY_HOLD 17
51 #define CHORUS (32)
52 
53 #define RADIOSET_1 MEM_START
54 #define RADIOSET_2 (MEM_START + 1)
55 #define RADIOSET_3 17 /* MODE */
56 
57 #define KEY_PANEL 1
58 
59 /*
60  * This structure is for device definition. The structure is defined in
61  * include/brighton.h, further definitions in brighton/brightonDevtable.h and
62  * include/brightoninternals.h
63  *
64  *	typedef int (*brightonCallback)(int, float);
65  *	typedef struct BrightonLocations {
66  *		int device; 0=rotary, 1=scale, etc.
67  *		float relx, rely; relative position with regards to 1000 by 1000 window
68  *		float relw, relh; relative height.
69  *		int from, to;
70  *		brightonCallback callback; specific to this dev
71  *		char *image; bitmap. If zero take a device default.
72  *		int flags;
73  *	} brightonLocations;
74  *
75  * This example is for a poly6Bristol type synth interface.
76  */
77 #define R0 200
78 #define R1 465
79 
80 #define D0 8
81 #define D1 41
82 #define D2 23
83 
84 #define C0 25
85 #define C1 (C0 + D1 + D0)
86 #define C2 (C1 + D1 + D0)
87 #define C3 (C2 + D1)
88 #define C4 (C3 + D1)
89 #define C5 (C4 + D1)
90 #define C6 (C5 + D1)
91 #define C7 (C6 + D1)
92 #define C8 (C7 + D1)
93 #define C9 (C8 + D1)
94 #define C10 (C9 + D1)
95 #define C11 (C10 + D1 + D0)
96 #define C12 (C11 + D1)
97 #define C13 (C12 + D1)
98 #define C14 (C13 + D1)
99 
100 #define C15 (C14 + D1 + D0)
101 #define C16 (C15 + D1)
102 
103 #define C17 (C16 + D1)
104 #define C18 (C17 + D2)
105 #define C19 (C18 + D2)
106 #define C20 (C19 + D2)
107 #define C21 (C20 + D2)
108 #define C22 (C21 + D2)
109 #define C23 (C22 + D2)
110 #define C24 (C23 + D2)
111 #define C25 (C24 + D2)
112 
113 #define C26 (C25 + D2 + 9)
114 
115 #define S1 140
116 #define S2 12
117 #define S3 180
118 #define S4 10
119 
120 static brightonLocations locations[DEVICE_COUNT] = {
121 	{"MasterVolume", 0, C0, R0, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
122 	{"MasterTuning", 0, C1, R0, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, BRIGHTON_NOTCH},
123 	{"BendDepth", 0, C1, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
124 
125 	/* VCO 1 */
126 	{"OSC-Transpose", 0, C2, R0, S1, S1, 0, 3, 0, "bitmaps/knobs/knob6.xpm", 0,
127 		BRIGHTON_STEPPED},
128 	{"OSC-WaveForm", 0, C3, R0, S1, S1, 0, 3, 0, "bitmaps/knobs/knob6.xpm", 0,
129 		BRIGHTON_STEPPED},
130 	{"OSC-PWM", 0, C4, R0, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
131 	{"Osc-Tuning", 0, C5, R0, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
132 	{"Osc-Subwave", 2, C6 - 5, R0 + 10, S4, S3, 0, 2, 0, 0, 0,
133 		BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW},
134 
135 	/* Noise - Mods 8 */
136 	{"Noise", 0, C2, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
137 	{"LFO-Freq", 0, C3, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
138 	{"LFO-Delay", 0, C4, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
139 	{"LFO-Level", 0, C5, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
140 	{"LFO-Dest", 2, C6 - 5, R1 + 20, S4, S3, 0, 2, 0, 0, 0,
141 		BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW},
142 
143 	/* Filter 13 */
144 	{"VCF-Freq", 0, C7, R0, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
145 	{"VCF-Res", 0, C8, R0, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
146 	{"VCF-Env", 0, C9, R0, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
147 	{"VCF-KBD", 0, C10, R0, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
148 
149 	/* Mode 17 */
150 	{"MODE Hold", 2, C8 + 8, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffw.xpm",
151 		"bitmaps/buttons/pressonw.xpm", BRIGHTON_RADIOBUTTON},
152 	{"MODE Mono", 2, C9 + 8, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffw.xpm",
153 		"bitmaps/buttons/pressonw.xpm", BRIGHTON_RADIOBUTTON},
154 	{"MODE Mono", 2, C10 + 8, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffw.xpm",
155 		"bitmaps/buttons/pressonw.xpm", BRIGHTON_RADIOBUTTON},
156 
157 	/* ENV 20 */
158 	{"FiltEnv-Attack", 0, C11, R0, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
159 	{"FiltEnv-Decay", 0, C12, R0, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
160 	{"FiltEnv-Sustain", 0, C13, R0, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
161 	{"FiltEnv-Relase", 0, C14, R0, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
162 
163 	/* ENV 24 */
164 	{"Env-Attack", 0, C11, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
165 	{"Env-Decay", 0, C12, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
166 	{"Env-Sustain", 0, C13, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
167 	{"Env-Release", 0, C14, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
168 
169 	/* Amp - Effects 28 */
170 	{"Amp-Env/Gate", 2, C15, R0 + 20, S4, S1 - 20, 0, 1, 0,
171 		"bitmaps/buttons/sw1.xpm", "bitmaps/buttons/sw2.xpm", BRIGHTON_NOSHADOW},
172 	{"Amp-Gain", 0, C16, R0, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
173 	{"Chorus-Mode", 0, C15, R1, S1, S1, 0, 3, 0, "bitmaps/knobs/knob6.xpm", 0,
174 		BRIGHTON_STEPPED},
175 	{"Chorus-Depth", 0, C16, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
176 	/* Glide */
177 	{"Glide", 0, C0, R1, S1, S1, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
178 
179 	/* Memory - MIDI 33 */
180 	{"", 2, C17, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffo.xpm",
181 		"bitmaps/buttons/pressono.xpm", BRIGHTON_CHECKBUTTON},
182 
183 	{"", 2, C18, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
184 		"bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
185 	{"", 2, C19, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
186 		"bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
187 	{"", 2, C20, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
188 		"bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
189 	{"", 2, C21, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
190 		"bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
191 	{"", 2, C22, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
192 		"bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
193 	{"", 2, C23, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
194 		"bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
195 	{"", 2, C24, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
196 		"bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
197 	{"", 2, C25, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
198 		"bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
199 
200 	{"", 2, C18, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
201 		"bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
202 	{"", 2, C19, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
203 		"bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
204 	{"", 2, C20, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
205 		"bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
206 	{"", 2, C21, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
207 		"bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
208 	{"", 2, C22, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
209 		"bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
210 	{"", 2, C23, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
211 		"bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
212 	{"", 2, C24, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
213 		"bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
214 	{"", 2, C25, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffg.xpm",
215 		"bitmaps/buttons/pressong.xpm", BRIGHTON_RADIOBUTTON},
216 	/* Load */
217 	{"", 2, C17, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffw.xpm",
218 		"bitmaps/buttons/pressonw.xpm", BRIGHTON_CHECKBUTTON},
219 
220 	{"", 2, C26, R0, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffw.xpm",
221 		"bitmaps/buttons/pressonw.xpm", BRIGHTON_CHECKBUTTON},
222 	{"", 2, C26, R1, S2, S1, 0, 1, 0, "bitmaps/buttons/pressoffw.xpm",
223 		"bitmaps/buttons/pressonw.xpm", BRIGHTON_CHECKBUTTON},
224 };
225 
226 /*
227  */
228 
229 /*
230  * This is a set of globals for the main window rendering. Again taken from
231  * include/brighton.h
232  */
233 brightonApp poly6App = {
234 	"poly",
235 	0, /* no blueprint on wood background. */
236 	"bitmaps/textures/metal6.xpm",
237 	BRIGHTON_STRETCH,
238 	poly6Init,
239 	poly6Configure, /* 3 callbacks, unused? */
240 	midiCallback,
241 	destroySynth,
242 	{6, 100, 2, 2, 5, 520, 0, 0},
243 	800, 240, 0, 0,
244 	5, /* one panel only */
245 	{
246 		{
247 			"Poly6",
248 			"bitmaps/blueprints/poly6.xpm",
249 			"bitmaps/textures/metal4.xpm",
250 			BRIGHTON_STRETCH, /* flags */
251 			0,
252 			0,
253 			poly6Callback,
254 			12, 0, 976, 560,
255 			DEVICE_COUNT,
256 			locations
257 		},
258 		{
259 			"Keyboard",
260 			0,
261 			"bitmaps/newkeys/kbg.xpm", /* flags */
262 			0x020|BRIGHTON_STRETCH,
263 			0,
264 			0,
265 			keyCallback,
266 			105, 550, 908, 435,
267 			KEY_COUNT,
268 			keys
269 		},
270 		{
271 			"Mods",
272 			"bitmaps/blueprints/polymods.xpm",
273 			"bitmaps/textures/metal6.xpm", /* flags */
274 			BRIGHTON_STRETCH,
275 			0,
276 			0,
277 			poly6ModCallback,
278 			15, 550, 90, 435,
279 			2,
280 			mods
281 		},
282 		{
283 			"Edge",
284 			0,
285 			"bitmaps/textures/metal4.xpm",
286 			BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */
287 			0,
288 			0,
289 			0,
290 			0, 0, 15, 995,
291 			0,
292 			0
293 		},
294 		{
295 			"Edge",
296 			0,
297 			"bitmaps/textures/metal4.xpm",
298 			BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /* flags */
299 			0,
300 			0,
301 			0,
302 			988, 0, 12, 995,
303 			0,
304 			0
305 		},
306 	}
307 };
308 
309 static int
midiCallback(brightonWindow * win,int controller,int value,float n)310 midiCallback(brightonWindow *win, int controller, int value, float n)
311 {
312 	guiSynth *synth = findSynth(global.synths, win);
313 
314 	printf("midi callback: %x, %i\n", controller, value);
315 
316 	switch(controller)
317 	{
318 		case MIDI_PROGRAM:
319 			printf("midi program: %x, %i\n", controller, value);
320 			synth->location = value;
321 			loadMemory(synth, "poly", 0,
322 				synth->bank + synth->location,
323 				synth->mem.active, 0, 0);
324 			break;
325 		case MIDI_BANK_SELECT:
326 			printf("midi banksel: %x, %i\n", controller, value);
327 			synth->bank = value;
328 			break;
329 	}
330 	return(0);
331 }
332 
333 /*static dispatcher dispatch[DEVICE_COUNT]; */
334 
335 static int
poly6ModCallback(brightonWindow * win,int panel,int index,float value)336 poly6ModCallback(brightonWindow *win, int panel, int index, float value)
337 {
338 	guiSynth *synth = findSynth(global.synths, win);
339 	float bend = synth->mem.param[P6_BEND];
340 
341 /*printf("poly6ModCallback(%x, %i, %i, %f)\n", synth, panel, index, value); */
342 
343 	/*
344 	 * If this is controller 0 it is the frequency control, otherwise a
345 	 * generic controller 1. The depth of the bend wheel is a parameter, so
346 	 * we need to scale the value here.
347 	 */
348 	if (index == 0)
349 	{
350 		/*
351 		 * Value is between 0 and 1 latching at 0.5. Have to scale the value
352 		 * and subtrace if from the mid point
353 		 */
354 		bristolMidiSendMsg(global.controlfd, synth->midichannel,
355 			BRISTOL_EVENT_PITCH, 0,
356 			(int) (((0.5 - bend / 2) + (value * bend)) * C_RANGE_MIN_1));
357 	} else {
358 		bristolMidiControl(global.controlfd, synth->midichannel,
359 			0, 1, ((int) (value * C_RANGE_MIN_1)) >> 7);
360 	}
361 	return(0);
362 }
363 
364 static int
poly6MidiSendMsg(void * synth,int fd,int chan,int c,int o,int v)365 poly6MidiSendMsg(void *synth, int fd, int chan, int c, int o, int v)
366 {
367 /*printf("%i, %i, %i\n", c, o, v); */
368 	bristolMidiSendMsg(fd, chan, c, o, v);
369 	return(0);
370 }
371 
372 static void
poly6Hold(guiSynth * synth)373 poly6Hold(guiSynth *synth)
374 {
375 	if (((synth->flags & OPERATIONAL) == 0) || (global.libtest))
376 		return;
377 
378 	if (synth->mem.param[KEY_HOLD])
379 		bristolMidiSendMsg(global.controlfd, synth->sid,
380 			127, 0, BRISTOL_HOLD|1);
381 	else
382 		bristolMidiSendMsg(global.controlfd, synth->sid,
383 			127, 0, BRISTOL_HOLD|0);
384 }
385 
386 static void
fixModes(guiSynth * synth,int fd,int chan,int c,int o,int v)387 fixModes(guiSynth *synth, int fd, int chan, int c, int o, int v)
388 {
389 	/*
390 	 * Look into the memory at 18 and 19 to find the current mode and send it
391 	 * to the engine.
392 	 */
393 	if (synth->mem.param[18] != 0)
394 		bristolMidiSendMsg(fd, chan, 126, 7, 1);
395 	else
396 		bristolMidiSendMsg(fd, chan, 126, 8, 1);
397 
398 	poly6Hold(synth);
399 }
400 
401 int
poly6loadMemory(guiSynth * synth,char * algo,char * name,int location,int active,int skip,int flags)402 poly6loadMemory(guiSynth *synth, char *algo, char *name, int location,
403 int active, int skip, int flags)
404 {
405 	brightonEvent event;
406 
407 	loadMemory(synth, "poly", 0, location, synth->mem.active, 0, 0);
408 	fixModes(synth, synth->sid, synth->midichannel, 0, 0, 0);
409 
410 	event.type = BRISTOL_FLOAT;
411 	event.value = 1;
412 	brightonParamChange(synth->win, 0, MEM_START + location / 10, &event);
413 	brightonParamChange(synth->win, 0, MEM_START+8+(location % 10), &event);
414 
415 	return(0);
416 }
417 
418 static void
poly6Memory(guiSynth * synth,int fd,int chan,int c,int o,int v)419 poly6Memory(guiSynth *synth, int fd, int chan, int c, int o, int v)
420 {
421 	brightonEvent event;
422 
423 	if (synth->flags & MEM_LOADING)
424 		return;
425 
426 	switch(c) {
427 		case 0:
428 			saveMemory(synth, "poly", 0,
429 				synth->bank + synth->location, 0);
430 			return;
431 			break;
432 		case 17:
433 			loadMemory(synth, "poly", 0,
434 				synth->bank + synth->location,
435 				synth->mem.active, 0, 0);
436 			fixModes(synth, fd, chan, c, o, v);
437 			return;
438 			break;
439 		case 1:
440 		case 2:
441 		case 3:
442 		case 4:
443 		case 5:
444 		case 6:
445 		case 7:
446 		case 8:
447 			if (synth->dispatch[RADIOSET_1].other2)
448 			{
449 				synth->dispatch[RADIOSET_1].other2 = 0;
450 				return;
451 			}
452 			if (synth->dispatch[RADIOSET_1].other1 != -1)
453 			{
454 				synth->dispatch[RADIOSET_1].other2 = 1;
455 
456 				if (synth->dispatch[RADIOSET_1].other1 != c)
457 					event.value = 0;
458 				else
459 					event.value = 1;
460 
461 				brightonParamChange(synth->win, synth->panel,
462 					synth->dispatch[RADIOSET_1].other1 + MEM_START, &event);
463 			}
464 			synth->dispatch[RADIOSET_1].other1 = c;
465 			synth->bank = c * 10;
466 			break;
467 		case 9:
468 		case 10:
469 		case 11:
470 		case 12:
471 		case 13:
472 		case 14:
473 		case 15:
474 		case 16:
475 			if (synth->dispatch[RADIOSET_2].other2)
476 			{
477 				synth->dispatch[RADIOSET_2].other2 = 0;
478 				return;
479 			}
480 			if (synth->dispatch[RADIOSET_2].other1 != -1)
481 			{
482 				synth->dispatch[RADIOSET_2].other2 = 1;
483 
484 				if (synth->dispatch[RADIOSET_2].other1 != c)
485 					event.value = 0;
486 				else
487 					event.value = 1;
488 
489 				brightonParamChange(synth->win, synth->panel,
490 					synth->dispatch[RADIOSET_2].other1 + MEM_START, &event);
491 			}
492 			synth->dispatch[RADIOSET_2].other1 = c;
493 			/* Do radio buttons */
494 			synth->location = c - 8;
495 			break;
496 	}
497 }
498 
499 static void
poly6PWM(guiSynth * synth,int fd,int chan,int c,int o,int v)500 poly6PWM(guiSynth *synth, int fd, int chan, int c, int o, int v)
501 {
502 	/*
503 	 * This has two functions, it sets the PW of the osc and also the gain
504 	 * of PWM.
505 	 */
506 	bristolMidiSendMsg(fd, chan, 0, 0, v);
507 	bristolMidiSendMsg(fd, chan, 126, 4, v);
508 }
509 
510 static void
poly6Waveform(guiSynth * synth,int fd,int chan,int c,int o,int v)511 poly6Waveform(guiSynth *synth, int fd, int chan, int c, int o, int v)
512 {
513 	if (c == 1)
514 	{
515 		/*
516 		 * Subosc 2 == off
517 		 */
518 		if (v == 2)
519 			bristolMidiSendMsg(fd, chan, 1, 6, 0);
520 		if (v == 1)
521 		{
522 			bristolMidiSendMsg(fd, chan, 1, 1, 1);
523 			bristolMidiSendMsg(fd, chan, 1, 6, 1);
524 		}
525 		if (v == 0)
526 		{
527 			bristolMidiSendMsg(fd, chan, 1, 1, 0);
528 			bristolMidiSendMsg(fd, chan, 1, 6, 1);
529 		}
530 		return;
531 	}
532 
533 	switch(v) {
534 		case 0:
535 			/*
536 			 * Ramp off, square off, tri on
537 			 */
538 			bristolMidiSendMsg(fd, chan, 0, 4, 0);
539 			bristolMidiSendMsg(fd, chan, 0, 6, 0);
540 			bristolMidiSendMsg(fd, chan, 0, 5, 1);
541 
542 			bristolMidiSendMsg(fd, chan, 126, 5, 0);
543 			break;
544 		case 1:
545 			bristolMidiSendMsg(fd, chan, 0, 5, 0);
546 			bristolMidiSendMsg(fd, chan, 0, 6, 0);
547 			bristolMidiSendMsg(fd, chan, 0, 4, 1);
548 
549 			bristolMidiSendMsg(fd, chan, 126, 5, 0);
550 			break;
551 		case 2:
552 			bristolMidiSendMsg(fd, chan, 0, 4, 0);
553 			bristolMidiSendMsg(fd, chan, 0, 5, 0);
554 			bristolMidiSendMsg(fd, chan, 0, 6, 1);
555 
556 			bristolMidiSendMsg(fd, chan, 126, 5, 0);
557 			break;
558 		case 3:
559 			bristolMidiSendMsg(fd, chan, 0, 4, 0);
560 			bristolMidiSendMsg(fd, chan, 0, 5, 0);
561 			bristolMidiSendMsg(fd, chan, 0, 6, 1);
562 
563 			bristolMidiSendMsg(fd, chan, 126, 5, 1);
564 			break;
565 	}
566 }
567 
568 static int
poly6Midi(guiSynth * synth,int fd,int chan,int c,int o,int v)569 poly6Midi(guiSynth *synth, int fd, int chan, int c, int o, int v)
570 {
571 	int newchan;
572 
573 	if ((synth->flags & OPERATIONAL) == 0)
574 		return(0);
575 
576 	if (c == 1) {
577 		if ((newchan = synth->midichannel - 1) < 0)
578 		{
579 			synth->midichannel = 0;
580 			return(0);
581 		}
582 	} else {
583 		if ((newchan = synth->midichannel + 1) >= 15)
584 		{
585 			synth->midichannel = 15;
586 			return(0);
587 		}
588 	}
589 
590 	if (global.libtest == 0)
591 	{
592 		bristolMidiSendMsg(global.controlfd, synth->sid,
593 			127, 0, BRISTOL_MIDICHANNEL|newchan);
594 	}
595 
596 	synth->midichannel = newchan;
597 
598 	return(0);
599 }
600 
601 /*
602  * For the sake of ease of use, links have been placed here to be called
603  * by any of the devices created. They would be better in some other file,
604  * perhaps with this as a dispatch.
605  *
606  * Param refers to the device index in the locations table given below.
607  */
608 static int
poly6Callback(brightonWindow * win,int panel,int index,float value)609 poly6Callback(brightonWindow * win, int panel, int index, float value)
610 {
611 	guiSynth *synth = findSynth(global.synths, win);
612 	int sendvalue;
613 
614 	/* printf("poly6Callback(%i, %f): %x\n", index, value, synth); */
615 
616 	if (synth == 0)
617 		return(0);
618 
619 	if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0))
620 		return(0);
621 
622 	if (poly6App.resources[0].devlocn[index].to == 1)
623 		sendvalue = value * C_RANGE_MIN_1;
624 	else
625 		sendvalue = value;
626 
627 		synth->mem.param[index] = value;
628 
629 	if ((!global.libtest) || (index >= ACTIVE_DEVS))
630 		synth->dispatch[index].routine(synth,
631 			global.controlfd, synth->sid,
632 			synth->dispatch[index].controller,
633 			synth->dispatch[index].operator,
634 			sendvalue);
635 #define DEBUG
636 #ifdef DEBUG
637 	else
638 		printf("dispatch[%p,%i](%i, %i, %i, %i, %i)\n", synth, index,
639 			global.controlfd, synth->sid,
640 			synth->dispatch[index].controller,
641 			synth->dispatch[index].operator,
642 			sendvalue);
643 #endif
644 
645 	return(0);
646 }
647 
648 static void
poly6Gain(guiSynth * synth,int fd,int chan,int c,int o,int v)649 poly6Gain(guiSynth *synth, int fd, int chan, int c, int o, int v)
650 {
651 	switch (c)
652 	{
653 		case 6:
654 		case 101:
655 			/*
656 			 * Gain controls
657 			 */
658 			bristolMidiSendMsg(global.controlfd, synth->sid, 6, 4,
659 				((int) (synth->mem.param[0] * synth->mem.param[29]
660 					* C_RANGE_MIN_1)));
661 			break;
662 		case 100:
663 			/*
664 			 * This is the attentuator switch, 1 == gate.
665 			 */
666 			if (synth->mem.param[28])
667 			{
668 				/*
669 				 * Configure a gate.
670 				 */
671 				bristolMidiSendMsg(global.controlfd, synth->sid, 6, 0, 512);
672 				bristolMidiSendMsg(global.controlfd, synth->sid, 6, 1, 16383);
673 				bristolMidiSendMsg(global.controlfd, synth->sid, 6, 2, 16383);
674 				bristolMidiSendMsg(global.controlfd, synth->sid, 6, 3, 512);
675 			} else {
676 				/*
677 				 * Configure the env
678 				 */
679 				bristolMidiSendMsg(global.controlfd, synth->sid, 6, 0,
680 					(int) (synth->mem.param[24] * C_RANGE_MIN_1));
681 				bristolMidiSendMsg(global.controlfd, synth->sid, 6, 1,
682 					(int) (synth->mem.param[25] * C_RANGE_MIN_1));
683 				bristolMidiSendMsg(global.controlfd, synth->sid, 6, 2,
684 					(int) (synth->mem.param[26] * C_RANGE_MIN_1));
685 				bristolMidiSendMsg(global.controlfd, synth->sid, 6, 3,
686 					(int) (synth->mem.param[27] * C_RANGE_MIN_1));
687 			}
688 			break;
689 		case 99:
690 			if (synth->mem.param[28] == 0)
691 				bristolMidiSendMsg(global.controlfd, synth->sid, 6, o, v);
692 			bristolMidiSendMsg(global.controlfd, synth->sid, 8, 3, v);
693 			break;
694 	}
695 }
696 
697 static int
poly6Mode(guiSynth * synth,int fd,int chan,int c,int o,int v)698 poly6Mode(guiSynth *synth, int fd, int chan, int c, int o, int v)
699 {
700 	brightonEvent event;
701 
702 	if (synth->flags & MEM_LOADING)
703 		return(0);
704 
705 	if (synth->dispatch[RADIOSET_3].other2)
706 		return(synth->dispatch[RADIOSET_3].other2 = 0);
707 
708 	if (synth->dispatch[RADIOSET_3].other1 != -1)
709 	{
710 		synth->dispatch[RADIOSET_3].other2 = 1;
711 
712 		if (synth->dispatch[RADIOSET_3].other1 != c)
713 			event.value = 0;
714 		else
715 			event.value = 1;
716 
717 		brightonParamChange(synth->win, synth->panel,
718 			synth->dispatch[RADIOSET_3].other1, &event);
719 	}
720 	synth->dispatch[RADIOSET_3].other1 = c;
721 
722 /*	bristolMidiSendMsg(global.controlfd, synth->sid, 126, o, v); */
723 
724 	poly6Hold(synth);
725 
726 	switch (c) {
727 		case 18:
728 			bristolMidiSendMsg(global.controlfd, synth->sid, 126, 7, 1);
729 			break;
730 		case 19:
731 			bristolMidiSendMsg(global.controlfd, synth->sid, 126, 8, 1);
732 			break;
733 	}
734 	return(0);
735 }
736 
737 /*
738  * Any location initialisation required to run the callbacks. For bristol, this
739  * will connect to the engine, and give it some base parameters.
740  * May need to generate some application specific menus.
741  * Will also then make specific requests to some of the devices to alter their
742  * rendering.
743  */
744 static int
poly6Init(brightonWindow * win)745 poly6Init(brightonWindow *win)
746 {
747 	guiSynth *synth = findSynth(global.synths, win);
748 	dispatcher *dispatch;
749 	int i;
750 
751 	if (synth == 0)
752 	{
753 		synth = findSynth(global.synths, 0);
754 		if (synth == 0)
755 		{
756 			printf("cannot init\n");
757 			return(0);
758 		}
759 	}
760 
761 	if ((initmem = synth->location) == 0)
762 		initmem = 11;
763 
764 	synth->win = win;
765 
766 	printf("Initialise the poly6 link to bristol: %p\n", synth->win);
767 
768 	synth->mem.param = (float *) brightonmalloc(DEVICE_COUNT * sizeof(float));
769 	synth->mem.count = DEVICE_COUNT;
770 	synth->mem.active = ACTIVE_DEVS;
771 	synth->dispatch = (dispatcher *)
772 		brightonmalloc(DEVICE_COUNT * sizeof(dispatcher));
773 	dispatch = synth->dispatch;
774 
775 	/*
776 	 * We really want to have three connection mechanisms. These should be
777 	 *	1. Unix named sockets.
778 	 *	2. UDP sockets.
779 	 *	3. MIDI pipe.
780 	 */
781 
782 	if (synth->voices == BRISTOL_VOICECOUNT)
783 		synth->voices = 6;
784 	if (!global.libtest)
785 		if ((synth->sid = initConnection(&global, synth)) < 0)
786 			return(-1);
787 
788 	for (i = 0; i < DEVICE_COUNT; i++)
789 		synth->dispatch[i].routine = poly6MidiSendMsg;
790 
791 	/* Vol tune bend - NOT FINNISHED */
792 	dispatch[0].controller = 6;
793 	dispatch[0].operator = 4;
794 	dispatch[0].routine = (synthRoutine) poly6Gain;
795 	dispatch[1].controller = 126;
796 	dispatch[1].operator = 1;
797 	dispatch[2].controller = 126;
798 	dispatch[2].operator = 2;
799 
800 	/* VCO */
801 	dispatch[3].controller = 0;
802 	dispatch[3].operator = 1;
803 	dispatch[4].controller = 0;
804 	dispatch[4].operator = 50;
805 	dispatch[4].routine = (synthRoutine) poly6Waveform;
806 	dispatch[5].controller = 0;
807 	dispatch[5].operator = 0;
808 	dispatch[5].routine = (synthRoutine) poly6PWM;
809 	dispatch[6].controller = 10;
810 	dispatch[6].operator = 0;
811 	/* Subosc */
812 	dispatch[7].controller = 1;
813 	dispatch[7].operator = 0;
814 	dispatch[7].routine = (synthRoutine) poly6Waveform;
815 	/* Noise */
816 	dispatch[8].controller = 7;
817 	dispatch[8].operator = 0;
818 
819 	/* Mods */
820 	dispatch[9].controller = 2;
821 	dispatch[9].operator = 0;
822 	dispatch[10].controller = 8;
823 	dispatch[10].operator = 0;
824 	dispatch[11].controller = 8;
825 	dispatch[11].operator = 4;
826 	dispatch[12].controller = 126;
827 	dispatch[12].operator = 6;
828 
829 	/* Filter */
830 	dispatch[13].controller = 3;
831 	dispatch[13].operator = 0;
832 	dispatch[14].controller = 3;
833 	dispatch[14].operator = 1;
834 	dispatch[15].controller = 3;
835 	dispatch[15].operator = 2;
836 	dispatch[16].controller = 3;
837 	dispatch[16].operator = 3;
838 
839 	/* MODE NOT DONE */
840 	/*
841 	 * Hold - no key off events
842 	 * Mono - unison
843 	 * Poly - poly
844 	 */
845 	dispatch[17].controller = 17;
846 	dispatch[17].operator = 1;
847 	dispatch[18].controller = 18;
848 	dispatch[18].operator = 7;
849 	dispatch[19].controller = 19;
850 	dispatch[19].operator = 8;
851 	dispatch[17].routine = dispatch[18].routine = dispatch[19].routine
852 		= (synthRoutine) poly6Mode;
853 
854 	/* Filter Env */
855 	dispatch[20].controller = 4;
856 	dispatch[20].operator = 0;
857 	dispatch[21].controller = 4;
858 	dispatch[21].operator = 1;
859 	dispatch[22].controller = 4;
860 	dispatch[22].operator = 2;
861 	dispatch[23].controller = 4;
862 	dispatch[23].operator = 3;
863 	/* Env */
864 	dispatch[24].controller = 99; /* Will be 6, but interpreted */
865 	dispatch[24].operator = 0;
866 	dispatch[25].controller = 99;
867 	dispatch[25].operator = 1;
868 	dispatch[26].controller = 99;
869 	dispatch[26].operator = 2;
870 	dispatch[27].controller = 99;
871 	dispatch[27].operator = 3;
872 
873 	/* VCA NOT DONE */
874 	dispatch[28].controller = 100;
875 	dispatch[28].operator = 0;
876 	dispatch[29].controller = 101;
877 	dispatch[29].operator = 1;
878 	dispatch[28].routine = dispatch[29].routine
879 		= dispatch[24].routine = dispatch[25].routine
880 		= dispatch[26].routine = dispatch[27].routine
881 		= (synthRoutine) poly6Gain;
882 	/* Effect */
883 	dispatch[30].controller = 100;
884 	dispatch[30].operator = 0;
885 	dispatch[31].controller = 100;
886 	dispatch[31].operator = 1;
887 
888 	dispatch[32].controller = 126;
889 	dispatch[32].operator = 0;
890 
891 	dispatch[MEM_START + 0].controller = 0;
892 	dispatch[MEM_START + 1].controller = 1;
893 	dispatch[MEM_START + 2].controller = 2;
894 	dispatch[MEM_START + 3].controller = 3;
895 	dispatch[MEM_START + 4].controller = 4;
896 	dispatch[MEM_START + 5].controller = 5;
897 	dispatch[MEM_START + 6].controller = 6;
898 	dispatch[MEM_START + 7].controller = 7;
899 	dispatch[MEM_START + 8].controller = 8;
900 	dispatch[MEM_START + 9].controller = 9;
901 	dispatch[MEM_START + 10].controller = 10;
902 	dispatch[MEM_START + 11].controller = 11;
903 	dispatch[MEM_START + 12].controller = 12;
904 	dispatch[MEM_START + 13].controller = 13;
905 	dispatch[MEM_START + 14].controller = 14;
906 	dispatch[MEM_START + 15].controller = 15;
907 	dispatch[MEM_START + 16].controller = 16;
908 	dispatch[MEM_START + 17].controller = 17;
909 
910 	dispatch[MEM_START + 0].routine =
911 		dispatch[MEM_START + 1].routine =
912 		dispatch[MEM_START + 2].routine =
913 		dispatch[MEM_START + 3].routine =
914 		dispatch[MEM_START + 4].routine =
915 		dispatch[MEM_START + 5].routine =
916 		dispatch[MEM_START + 6].routine =
917 		dispatch[MEM_START + 7].routine =
918 		dispatch[MEM_START + 8].routine =
919 		dispatch[MEM_START + 9].routine =
920 		dispatch[MEM_START + 10].routine =
921 		dispatch[MEM_START + 11].routine =
922 		dispatch[MEM_START + 12].routine =
923 		dispatch[MEM_START + 13].routine =
924 		dispatch[MEM_START + 14].routine =
925 		dispatch[MEM_START + 15].routine =
926 		dispatch[MEM_START + 16].routine =
927 		dispatch[MEM_START + 17].routine
928 			= (synthRoutine) poly6Memory;
929 
930 	dispatch[RADIOSET_1].other1 = -1;
931 	dispatch[RADIOSET_2].other1 = -1;
932 	dispatch[RADIOSET_3].other1 = -1;
933 
934 	dispatch[MIDI_START].controller = 1;
935 	dispatch[MIDI_START + 1].controller = 2;
936 	dispatch[MIDI_START].routine = dispatch[MIDI_START + 1].routine =
937 		(synthRoutine) poly6Midi;
938 
939 	/* Put in diverse defaults settings */
940 	/* Gain on filter env */
941 	bristolMidiSendMsg(global.controlfd, synth->sid, 4, 4, C_RANGE_MIN_1);
942 	bristolMidiSendMsg(global.controlfd, synth->sid, 3, 4, 4);
943 	/* Waveform subosc */
944 	bristolMidiSendMsg(global.controlfd, synth->sid, 1, 0, C_RANGE_MIN_1);
945 	bristolMidiSendMsg(global.controlfd, synth->sid, 1, 6, C_RANGE_MIN_1);
946 	/* LFO Env parameters. */
947 	bristolMidiSendMsg(global.controlfd, synth->sid, 8, 1, 12000);
948 	bristolMidiSendMsg(global.controlfd, synth->sid, 8, 2, 16383);
949 	bristolMidiSendMsg(global.controlfd, synth->sid, 8, 3, 0);
950 	bristolMidiSendMsg(global.controlfd, synth->sid, 8, 4, 16383);
951 	bristolMidiSendMsg(global.controlfd, synth->sid, 8, 5, 0);
952 
953 	return(0);
954 }
955 
956 /*
957  * This will be called to make any routine specific parameters available.
958  */
959 static int
poly6Configure(brightonWindow * win)960 poly6Configure(brightonWindow *win)
961 {
962 	guiSynth *synth = findSynth(global.synths, win);
963 	brightonEvent event;
964 
965 	if (synth == 0)
966 	{
967 		printf("problems going operational\n");
968 		return(-1);
969 	}
970 
971 	if (synth->flags & OPERATIONAL)
972 		return(0);
973 
974 	printf("going operational\n");
975 
976 	synth->flags |= OPERATIONAL;
977 	synth->keypanel = 1;
978 	synth->keypanel2 = -1;
979 	synth->transpose = 36;
980 
981 	brightonPut(win,
982 		"bitmaps/blueprints/poly6shade.xpm", 0, 0, win->width, win->height);
983 	width = win->width;
984 
985 	if (synth->location == 0)
986 	{
987 		synth->bank = 10;
988 		synth->location = 1;
989 	} else {
990 		synth->bank = (synth->location % 100) / 10 * 10;
991 		synth->location = synth->location % 10;
992 	}
993 
994 	event.type = BRISTOL_FLOAT;
995 	event.value = 1;
996 	brightonParamChange(synth->win, synth->panel, MEM_START + synth->bank / 10,
997 		&event);
998 	brightonParamChange(synth->win, synth->panel, MEM_START+8+synth->location,
999 		&event);
1000 	/* Poly */
1001 	brightonParamChange(synth->win, synth->panel, 19, &event);
1002 
1003 	loadMemory(synth, "poly", 0, initmem, synth->mem.active, 0, 0);
1004 	fixModes(synth, synth->sid, synth->midichannel, 0, 0, 0);
1005 
1006 	/*
1007 	 * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only
1008 	 * occurs on first paint, so we suppress the first paint, and then request
1009 	 * an expose here.
1010 	 */
1011 	event.type = BRIGHTON_EXPOSE;
1012 	event.intvalue = 1;
1013 	brightonParamChange(synth->win, KEY_PANEL, -1, &event);
1014 	event.type = BRIGHTON_FLOAT;
1015 	event.value = 0.1;
1016 	brightonParamChange(synth->win, 2, 1, &event);
1017 	configureGlobals(synth);
1018 
1019 	synth->loadMemory = (loadRoutine) poly6loadMemory;
1020 
1021 	return(0);
1022 }
1023 
1024