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 MonoPoly */
23 
24 #include <fcntl.h>
25 
26 #include "brighton.h"
27 #include "brightonMini.h"
28 #include "brightoninternals.h"
29 
30 static int initmem, width;
31 
32 static int polyInit();
33 static int polyConfigure();
34 static int polyCallback(brightonWindow *, int, int, float);
35 /*static int keyCallback(void *, int, int, float); */
36 static int polyModCallback(brightonWindow *, int, int, float);
37 static int pmidiCallback(brightonWindow *, int, int, float);
38 
39 extern guimain global;
40 
41 #include "brightonKeys.h"
42 
43 #define FIRST_DEV 0
44 #define DEVICE_COUNT 74
45 #define ACTIVE_DEVS 56
46 #define MEM_START ACTIVE_DEVS
47 #define RADIOSET_1 MEM_START
48 #define RADIOSET_2 (MEM_START + 1)
49 #define RADIOSET_3 53
50 
51 #define KEY_PANEL 1
52 #define KEY_HOLD 52
53 
54 #define CDIFF 56
55 #define CDIFF2 12
56 
57 #define C0 25
58 #define C1 (C0 + CDIFF)
59 #define C2 (C1 + CDIFF + CDIFF2)
60 #define C3 (C2 + CDIFF + CDIFF2)
61 #define C4 (C3 + CDIFF)
62 #define C5 (C4 + CDIFF)
63 #define C6 (C5 + CDIFF)
64 #define C7 (C6 + CDIFF + CDIFF2)
65 #define C8 (C7 + CDIFF + CDIFF2)
66 #define C9 (C8 + CDIFF + CDIFF2)
67 #define C10 (C9 + CDIFF)
68 #define C11 (C10 + CDIFF)
69 #define C12 (C11 + CDIFF + CDIFF2)
70 #define C13 (C12 + CDIFF)
71 #define C14 (C13 + CDIFF)
72 #define C15 (C14 + CDIFF)
73 
74 #define R0 115
75 #define R1 (R0 + 205)
76 #define R2 (R1 + 205)
77 #define R3 (R2 + 205)
78 
79 #define R3u (R2 + 200)
80 #define R3d (R2 + 310)
81 
82 #define S1 60
83 #define S2 100
84 #define S3 90
85 #define B1 15
86 #define B2 60
87 
88 #define BOFF 11
89 
90 /*
91  * This structure is for device definition. The structure is defined in
92  * include/brighton.h, further definitions in brighton/brightonDevtable.h and
93  * include/brightoninternals.h
94  *
95  *	typedef int (*brightonCallback)(int, float);
96  *	typedef struct BrightonLocations {
97  *		int device; 0=rotary, 1=scale, etc.
98  *		float relx, rely; relative position with regards to 1000 by 1000 window
99  *		float relw, relh; relative height.
100  *		int from, to;
101  *		brightonCallback callback; specific to this dev
102  *		char *image; bitmap. If zero take a device default.
103  *		int flags;
104  *	} brightonLocations;
105  *
106  * This example is for a polyBristol type synth interface.
107  */
108 static brightonLocations locations[DEVICE_COUNT] = {
109 	/* Osc-1 - 0 */
110 	{"Osc-1 Wave", 0, C9, R0, S3, S3, 0, 3, 0, "bitmaps/knobs/knob6.xpm", 0,
111 		BRIGHTON_STEPPED},
112 	{"Osc-1 Transpose", 0, C10, R0, S3, S3, 0, 3, 0, "bitmaps/knobs/knob6.xpm", 0,
113 		BRIGHTON_STEPPED},
114 	{"Osc-1 Gain", 0, C11, R0, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
115 	/* Osc-2 - 3 */
116 	{"Osc-2 Tune", 0, C8, R1, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, BRIGHTON_NOTCH},
117 	{"Osc-2 Wave", 0, C9, R1, S3, S3, 0, 3, 0, "bitmaps/knobs/knob6.xpm", 0,
118 		BRIGHTON_STEPPED},
119 	{"Osc-2 Transpose", 0, C10, R1, S3, S3, 0, 3, 0, "bitmaps/knobs/knob6.xpm", 0,
120 		BRIGHTON_STEPPED},
121 	{"Osc-2 Gain", 0, C11, R1, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
122 	/* Osc-3 - 7 */
123 	{"Osc-3 Tune", 0, C8, R2, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, BRIGHTON_NOTCH},
124 	{"Osc-3 Wave", 0, C9, R2, S3, S3, 0, 3, 0, "bitmaps/knobs/knob6.xpm", 0,
125 		BRIGHTON_STEPPED},
126 	{"Osc-3 Transpose", 0, C10, R2, S3, S3, 0, 3, 0, "bitmaps/knobs/knob6.xpm", 0,
127 		BRIGHTON_STEPPED},
128 	{"Osc-3 Gain", 0, C11, R2, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
129 	/* Osc-4 - 11 */
130 	{"Osc-3 Wave", 0, C8, R3, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, BRIGHTON_NOTCH},
131 	{"Osc-4 Tune", 0, C9, R3, S3, S3, 0, 3, 0, "bitmaps/knobs/knob6.xpm", 0,
132 		BRIGHTON_STEPPED},
133 	{"Osc-4 Transpose", 0, C10, R3, S3, S3, 0, 3, 0, "bitmaps/knobs/knob6.xpm", 0,
134 		BRIGHTON_STEPPED},
135 	{"Osc-4 Gain", 0, C11, R3, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
136 	/* Filter - 15 */
137 	{"VCF-Cutoff", 0, C12, R0, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
138 	{"VCF-Resonance", 0, C13, R0, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
139 	{"VCF-Env", 0, C14, R0, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
140 	{"VCF-KBD", 0, C15, R0, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
141 	/* Filter Env - 19 */
142 	{"VCF-Attack", 0, C12, R1, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
143 	{"VCF-Decay", 0, C13, R1, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
144 	{"VCF-Sustain", 0, C14, R1, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
145 	{"VCF-Release", 0, C15, R1, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
146 	/* Env - 23 */
147 	{"VCA-Attack", 0, C12, R2, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
148 	{"VCA-Decay", 0, C13, R2, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
149 	{"VCA-Sustain", 0, C14, R2, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
150 	{"VCA-Release", 0, C15, R2, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
151 	/* Volume - 27 env gain and TO BE REASSIGNED */
152 	{"Volume", 0, C0, R1, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
153 	{"Arpeg Mode", 2, C1, R1, B1, S2, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW},
154 	/* Three LFO MG modes - 29 */
155 	{"MG-1 Gain", 0, C2, R1, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
156 	{"MG-1 Wave", 0, C2, R2, S3, S3, 0, 3, 0, "bitmaps/knobs/knob6.xpm", 0,
157 		BRIGHTON_STEPPED},
158 	{"MG-2 Gain", 0, C3, R1, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
159 	/* 3 PW and PWM - 32 */
160 	{"PW-Source", 2, C4, R1, B1, S2, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW},
161 	{"PWM", 0, C5, R1, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
162 	{"PW", 0, C6, R1, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
163 	/* 4, actually 5 mods. - 35 */
164 	{"Mod-X-Mod", 0, C3, R2, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
165 	{"Mod-Freq", 0, C4, R2, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
166 	{"Mod-Source", 2, C5 - 20, R2 + 20, B1, S1, 0, 1, 0,
167 		"bitmaps/buttons/sw1.xpm", "bitmaps/buttons/sw2.xpm", BRIGHTON_NOSHADOW},
168 	{"Mod-Mode", 2, C5 + BOFF * 2, R2, B1, S2, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW},
169 	{"Mod-Sng/Dbl", 2, C5 + BOFF * 5 + 10, R2 + 20, B1, S1, 0, 1, 0,
170 		"bitmaps/buttons/sw1.xpm", "bitmaps/buttons/sw2.xpm", BRIGHTON_NOSHADOW},
171 	/* Glide, detune - 40 */
172 	{"Glide", 0, C7, R0, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
173 	{"Detune", 0, C7, R1, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
174 	/* Transpose - 42 */
175 	{"Transpose", 2, C7 - BOFF, R2, B1, S2, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW},
176 	/* Noise - 43 */
177 	{"Noise", 0, C12, R3, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
178 	/* Trig, Damp - 44 */
179 	{"Trigger", 2, C13, R3 + 20, B1, S1, 0, 1, 0,
180 		"bitmaps/buttons/sw1.xpm", "bitmaps/buttons/sw2.xpm", BRIGHTON_NOSHADOW},
181 	{"Damp", 2, C14, R3 + 20, B1, S1, 0, 1, 0,
182 		"bitmaps/buttons/sw1.xpm", "bitmaps/buttons/sw2.xpm", BRIGHTON_NOSHADOW},
183 
184 	/* Effects - 46 */
185 	{"FX on/off", 2, C4 + BOFF, R3 + 20, B1, S1, 0, 1, 0, "bitmaps/buttons/pressoffw.xpm",
186 		"bitmaps/buttons/pressonw.xpm", 0},
187 
188 	/* Master Tune - 47 */
189 	{"MasterTuning", 0, C8, R0, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, BRIGHTON_NOTCH},
190 	/* Wheel gain */
191 	{"Bend-Depth", 0, C0, R2, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
192 	{"Bend-Dest", 2, C0, R3, B1, S2, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW},
193 	{"ModWheel-Depth", 0, C1, R2, S3, S3, 0, 1, 0, "bitmaps/knobs/knob6.xpm", 0, 0},
194 	{"ModWheel-Dest", 2, C1, R3, B1, S2, 0, 2, 0, 0, 0, BRIGHTON_THREEWAY|BRIGHTON_NOSHADOW},
195 
196 	/* Modes */
197 	{"Mode-Hold", 2, C2, R3, B1, S1, 0, 1, 0,
198 		"bitmaps/buttons/pressoffw.xpm", "bitmaps/buttons/pressonw.xpm", 0},
199 	{"Mode-Mono", 2, C2 + BOFF * 2 + 9, R3, B1, S1, 0, 1, 0,
200 		"bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0},
201 	{"Mode-Poly", 2, C3 - 9, R3, B1, S1, 0, 1, 0,
202 		"bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0},
203 	{"Mode-Share", 2, C3 + BOFF * 2, R3, B1, S1, 0, 1, 0,
204 		"bitmaps/buttons/pressoffg.xpm", "bitmaps/buttons/pressong.xpm", 0},
205 
206 	/* Memories - Save */
207 	{"", 2, C5, R3u, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffo.xpm",
208 		"bitmaps/buttons/pressono.xpm", BRIGHTON_CHECKBUTTON},
209 	{"", 2, C5 + BOFF* 2, R3u, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
210 		"bitmaps/buttons/presson.xpm", 0},
211 	{"", 2, C5 + BOFF* 4, R3u, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
212 		"bitmaps/buttons/presson.xpm", 0},
213 	{"", 2, C5 + BOFF* 6, R3u, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
214 		"bitmaps/buttons/presson.xpm", 0},
215 	{"", 2, C5 + BOFF* 8, R3u, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
216 		"bitmaps/buttons/presson.xpm", 0},
217 	{"", 2, C5 + BOFF* 10, R3u, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
218 		"bitmaps/buttons/presson.xpm", 0},
219 	{"", 2, C5 + BOFF* 12, R3u, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
220 		"bitmaps/buttons/presson.xpm", 0},
221 	{"", 2, C5 + BOFF* 14, R3u, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
222 		"bitmaps/buttons/presson.xpm", 0},
223 
224 	{"", 2, C5 + BOFF* 2, R3d, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
225 		"bitmaps/buttons/presson.xpm", 0},
226 	{"", 2, C5 + BOFF* 4, R3d, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
227 		"bitmaps/buttons/presson.xpm", 0},
228 	{"", 2, C5 + BOFF* 6, R3d, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
229 		"bitmaps/buttons/presson.xpm", 0},
230 	{"", 2, C5 + BOFF* 8, R3d, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
231 		"bitmaps/buttons/presson.xpm", 0},
232 	{"", 2, C5 + BOFF* 10, R3d, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
233 		"bitmaps/buttons/presson.xpm", 0},
234 	{"", 2, C5 + BOFF* 12, R3d, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
235 		"bitmaps/buttons/presson.xpm", 0},
236 	{"", 2, C5 + BOFF* 14, R3d, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
237 		"bitmaps/buttons/presson.xpm", 0},
238 	/* Load */
239 	{"", 2, C5, R3d, B1, B2, 0, 1, 0, "bitmaps/buttons/pressoffw.xpm",
240 		"bitmaps/buttons/pressonw.xpm", BRIGHTON_CHECKBUTTON},
241 
242 	/* Midi */
243 	{"", 2, C15, R3, B1, S1, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
244 		"bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON},
245 	{"", 2, C15 + BOFF * 2, R3, B1, S1, 0, 1, 0, "bitmaps/buttons/pressoff.xpm",
246 		"bitmaps/buttons/presson.xpm", BRIGHTON_CHECKBUTTON},
247 };
248 
249 /*
250  */
251 
252 /*
253  * This is a set of globals for the main window rendering. Again taken from
254  * include/brighton.h
255  */
256 brightonApp polyApp = {
257 	"monopoly",
258 	0, /* no blueprint on wood background. */
259 	"bitmaps/textures/wood4.xpm",
260 	0, /* BRIGHTON_STRETCH, //flags */
261 	polyInit,
262 	polyConfigure, /* 3 callbacks, unused? */
263 	pmidiCallback,
264 	destroySynth,
265 	{1, 100, 2, 2, 5, 520, 0, 0},
266 	750, 400, 0, 0,
267 	7,
268 	{
269 		{
270 			"Poly",
271 			"bitmaps/blueprints/poly.xpm",
272 			"bitmaps/textures/metal4.xpm",
273 			BRIGHTON_STRETCH, /* flags */
274 			0,
275 			0,
276 			polyCallback,
277 			15, 0, 970, 620,
278 			DEVICE_COUNT,
279 			locations
280 		},
281 		{
282 			"Keyboard",
283 			0,
284 			"bitmaps/newkeys/tkbg.xpm", /* flags */
285 			0x020|BRIGHTON_STRETCH,
286 			0,
287 			0,
288 			keyCallback,
289 			150, 620, 845, 350,
290 			KEY_COUNT_3OCTAVE,
291 			keys3octave2
292 		},
293 		{
294 			"Mods",
295 			"bitmaps/blueprints/polymods.xpm",
296 			"bitmaps/textures/metal4.xpm", /* flags */
297 			BRIGHTON_REVERSE,
298 			0,
299 			0,
300 			polyModCallback,
301 			15, 620, 135, 350,
302 			2,
303 			mods
304 		},
305 		{
306 			"Side wood",
307 			0,
308 			"bitmaps/textures/wood4.xpm",
309 			BRIGHTON_VERTICAL, /* flags */
310 			0,
311 			0,
312 			0,
313 			0, 0, 15, 1000,
314 			0,
315 			0
316 		},
317 		{
318 			"Side wood",
319 			0,
320 			"bitmaps/textures/wood.xpm",
321 			BRIGHTON_VERTICAL, /* flags */
322 			0,
323 			0,
324 			0,
325 			2, 5, 12, 985,
326 			0,
327 			0
328 		},
329 		{
330 			"Side wood",
331 			0,
332 			"bitmaps/textures/wood4.xpm",
333 			BRIGHTON_STRETCH|BRIGHTON_VERTICAL, /*flags */
334 			0,
335 			0,
336 			0,
337 			985, 0, 15, 1000,
338 			0,
339 			0
340 		},
341 		{
342 			"Side wood",
343 			0,
344 			"bitmaps/textures/wood.xpm",
345 			BRIGHTON_VERTICAL, /* flags */
346 			0,
347 			0,
348 			0,
349 			986, 5, 14, 985,
350 			0,
351 			0
352 		}
353 	}
354 };
355 
356 static void
fixModes(guiSynth * synth)357 fixModes(guiSynth *synth)
358 {
359 	brightonEvent event;
360 	int mode = 53;
361 
362 	event.value = 1;
363 	/*
364 	 * Operating modes are not configured when a memory is loaded, as that
365 	 * does not work correctly. After the memory is loaded, this routine is
366 	 * called to configure them.
367 	 */
368 	if (synth->mem.param[54] != 0)
369 		mode = 54;
370 	else if (synth->mem.param[55] != 0)
371 		mode = 55;
372 
373 	brightonParamChange(synth->win, synth->panel, mode, &event);
374 }
375 
376 int
ploadMemory(guiSynth * synth,char * algo,char * name,int location,int active,int skip,int flags)377 ploadMemory(guiSynth *synth, char *algo, char *name, int location,
378 int active, int skip, int flags)
379 {
380 	loadMemory(synth, "mono", 0, location, synth->mem.active, FIRST_DEV, 0);
381 	fixModes(synth);
382 	return(0);
383 }
384 
385 static int
pmidiCallback(brightonWindow * win,int controller,int value,float n)386 pmidiCallback(brightonWindow *win, int controller, int value, float n)
387 {
388 	guiSynth *synth = findSynth(global.synths, win);
389 
390 	printf("midi callback: %x, %i\n", controller, value);
391 
392 	switch(controller)
393 	{
394 		case MIDI_PROGRAM:
395 			printf("midi program: %x, %i\n", controller, value);
396 			synth->location = value;
397 			loadMemory(synth, "mono", 0, synth->bank + synth->location,
398 				synth->mem.active, FIRST_DEV, 0);
399 			fixModes(synth);
400 			break;
401 		case MIDI_BANK_SELECT:
402 			printf("midi banksel: %x, %i\n", controller, value);
403 			synth->bank = value;
404 			break;
405 	}
406 	return(0);
407 }
408 
409 static int
polyModCallback(brightonWindow * win,int panel,int index,float value)410 polyModCallback(brightonWindow *win, int panel, int index, float value)
411 {
412 	guiSynth *synth = findSynth(global.synths, win);
413 
414 /*	printf("polyModCallback(%x, %i, %i, %f)\n", synth, panel, index, value); */
415 
416 	/*
417 	 * If this is controller 0 it is the frequency control, otherwise a
418 	 * generic controller 1.
419 	 */
420 	if (index == 0)
421 		bristolMidiControl(global.controlfd, synth->midichannel,
422 			0, 2, ((int) (value * C_RANGE_MIN_1)) >> 7);
423 	else {
424 		bristolMidiControl(global.controlfd, synth->midichannel,
425 			0, 1, ((int) (value * C_RANGE_MIN_1)) >> 7);
426 	}
427 	return(0);
428 }
429 
430 static void
polyMG2(void * synth,int fd,int chan,int c,int o,int v)431 polyMG2(void *synth, int fd, int chan, int c, int o, int v)
432 {
433 	bristolMidiSendMsg(fd, chan, c, o, v);
434 	bristolMidiSendMsg(fd, chan, 126, 26, v);
435 }
436 
437 static int
polyMidiSendMsg(void * synth,int fd,int chan,int c,int o,int v)438 polyMidiSendMsg(void *synth, int fd, int chan, int c, int o, int v)
439 {
440 	bristolMidiSendMsg(fd, chan, c, o, v);
441 	return(0);
442 }
443 
444 static void
polyTranspose(guiSynth * synth,int fd,int chan,int c,int o,int v)445 polyTranspose(guiSynth *synth, int fd, int chan, int c, int o, int v)
446 {
447 	switch (v)
448 	{
449 		case 0:
450 			synth->transpose = 36;
451 			break;
452 		case 1:
453 			synth->transpose = 48;
454 			break;
455 		case 2:
456 			synth->transpose = 60;
457 			break;
458 	}
459 }
460 
461 static void
polyWaveform(guiSynth * synth,int fd,int chan,int c,int o,int v)462 polyWaveform(guiSynth *synth, int fd, int chan, int c, int o, int v)
463 {
464 	int offset;
465 
466 	/*
467 	 * 0 = tri, 1 = ramp, 2 and 3 are PW
468 	 */
469 	if (c == 34)
470 	{
471 		/*
472 		 * Pulse width of all osc.
473 		 */
474 		bristolMidiSendMsg(fd, chan, 0, 0, v);
475 		bristolMidiSendMsg(fd, chan, 1, 0, v);
476 		bristolMidiSendMsg(fd, chan, 2, 0, v);
477 		bristolMidiSendMsg(fd, chan, 8, 0, v);
478 		return;
479 	}
480 
481 	if ((offset = 22 + c) > 24)
482 		offset = 25;
483 
484 	switch(v) {
485 		case 0:
486 			/*
487 			 * Ramp off, square off, tri on
488 			 */
489 			bristolMidiSendMsg(fd, chan, c, 4, 0);
490 			bristolMidiSendMsg(fd, chan, c, 6, 0);
491 			bristolMidiSendMsg(fd, chan, c, 5, 1);
492 
493 			bristolMidiSendMsg(fd, chan, 126, offset, 0);
494 			break;
495 		case 1:
496 			bristolMidiSendMsg(fd, chan, c, 5, 0);
497 			bristolMidiSendMsg(fd, chan, c, 6, 0);
498 			bristolMidiSendMsg(fd, chan, c, 4, 1);
499 
500 			bristolMidiSendMsg(fd, chan, 126, offset, 0);
501 			break;
502 		case 2:
503 			bristolMidiSendMsg(fd, chan, c, 4, 0);
504 			bristolMidiSendMsg(fd, chan, c, 5, 0);
505 			bristolMidiSendMsg(fd, chan, c, 6, 1);
506 
507 			bristolMidiSendMsg(fd, chan, 126, offset, 1);
508 			break;
509 		case 3:
510 			bristolMidiSendMsg(fd, chan, c, 4, 0);
511 			bristolMidiSendMsg(fd, chan, c, 5, 0);
512 			bristolMidiSendMsg(fd, chan, c, 6, 1);
513 
514 			bristolMidiSendMsg(fd, chan, 126, offset, 0);
515 			break;
516 	}
517 }
518 
519 static int
polyMode(guiSynth * synth,int fd,int chan,int c,int o,int v)520 polyMode(guiSynth *synth, int fd, int chan, int c, int o, int v)
521 {
522 	brightonEvent event;
523 
524 	if (c == 52)
525 	{
526 		bristolMidiSendMsg(global.controlfd, synth->sid, 126, o, v);
527 		return(0);
528 	}
529 
530 	if (synth->flags & MEM_LOADING)
531 		return(0);
532 
533 	if (synth->dispatch[RADIOSET_3].other2)
534 		return(synth->dispatch[RADIOSET_3].other2 = 0);
535 
536 	if (synth->dispatch[RADIOSET_3].other1 != -1)
537 	{
538 		synth->dispatch[RADIOSET_3].other2 = 1;
539 
540 		if (synth->dispatch[RADIOSET_3].other1 != c)
541 			event.value = 0;
542 		else
543 			event.value = 1;
544 
545 		brightonParamChange(synth->win, synth->panel,
546 			synth->dispatch[RADIOSET_3].other1, &event);
547 	}
548 	synth->dispatch[RADIOSET_3].other1 = c;
549 
550 	bristolMidiSendMsg(global.controlfd, synth->sid, 126, o, v);
551 
552 	return(0);
553 }
554 
555 static void
polyMemory(guiSynth * synth,int fd,int chan,int c,int o,int v)556 polyMemory(guiSynth *synth, int fd, int chan, int c, int o, int v)
557 {
558 	brightonEvent event;
559 
560 /*	printf("	polyMemory(B: %i L %i: %i, %i)\n", */
561 /*		synth->bank, synth->location, c, o); */
562 
563 	switch(c) {
564 		case 0:
565 			saveMemory(synth, "mono", 0, synth->bank + synth->location,
566 				FIRST_DEV);
567 			return;
568 			break;
569 		case 15:
570 			loadMemory(synth, "mono", 0, synth->bank + synth->location,
571 				synth->mem.active, FIRST_DEV, 0);
572 			fixModes(synth);
573 			return;
574 			break;
575 		case 1:
576 		case 2:
577 		case 3:
578 		case 4:
579 		case 5:
580 		case 6:
581 		case 7:
582 			if (synth->dispatch[RADIOSET_1].other2)
583 			{
584 				synth->dispatch[RADIOSET_1].other2 = 0;
585 				return;
586 			}
587 			if (synth->dispatch[RADIOSET_1].other1 != -1)
588 			{
589 				synth->dispatch[RADIOSET_1].other2 = 1;
590 
591 				if (synth->dispatch[RADIOSET_1].other1 != c)
592 					event.value = 0;
593 				else
594 					event.value = 1;
595 
596 				brightonParamChange(synth->win, synth->panel,
597 					synth->dispatch[RADIOSET_1].other1 + MEM_START, &event);
598 			}
599 			synth->dispatch[RADIOSET_1].other1 = c;
600 			synth->bank = c * 10;
601 			break;
602 		case 8:
603 		case 9:
604 		case 10:
605 		case 11:
606 		case 12:
607 		case 13:
608 		case 14:
609 			if (synth->dispatch[RADIOSET_2].other2)
610 			{
611 				synth->dispatch[RADIOSET_2].other2 = 0;
612 				return;
613 			}
614 			if (synth->dispatch[RADIOSET_2].other1 != -1)
615 			{
616 				synth->dispatch[RADIOSET_2].other2 = 1;
617 
618 				if (synth->dispatch[RADIOSET_2].other1 != c)
619 					event.value = 0;
620 				else
621 					event.value = 1;
622 
623 				brightonParamChange(synth->win, synth->panel,
624 					synth->dispatch[RADIOSET_2].other1 + MEM_START, &event);
625 			}
626 			synth->dispatch[RADIOSET_2].other1 = c;
627 			/* Do radio buttons */
628 			synth->location = c - 7;
629 			break;
630 	}
631 }
632 
633 static void
polyEffect(guiSynth * synth,int fd,int chan,int c,int o,int v)634 polyEffect(guiSynth *synth, int fd, int chan, int c, int o, int v)
635 {
636 	brightonEvent event;
637 
638 	/*
639 	 * If we are turning this on the the original would also force MONO mode
640 	 * so we should do the same.
641 	 */
642 	if (v != 0)
643 	{
644 		event.value = 1;
645 		brightonParamChange(synth->win, synth->panel, 53, &event);
646 	}
647 	bristolMidiSendMsg(fd, chan, c, o, v);
648 }
649 
650 static void
polyMidi(guiSynth * synth,int fd,int chan,int c,int o,int v)651 polyMidi(guiSynth *synth, int fd, int chan, int c, int o, int v)
652 {
653 	int newchan;
654 
655 	if ((synth->flags & OPERATIONAL) == 0)
656 		return;
657 
658 	if (c == 1) {
659 		if ((newchan = synth->midichannel - 1) < 0)
660 		{
661 			synth->midichannel = 0;
662 			return;
663 		}
664 	} else {
665 		if ((newchan = synth->midichannel + 1) >= 16)
666 		{
667 			synth->midichannel = 15;
668 			return;
669 		}
670 	}
671 
672 	if (global.libtest == 0)
673 	{
674 		/*
675 #warning if we do not check for ack then socket might hang on exit
676 		 * To overcome that we should consider checking a sequence number in
677 		 * the message library? That is non trivial since it requires that
678 		 * our midi messges have a 'ack' flag included - we cannot check for
679 		 * ack here (actually, we could, and in the app is probably the right
680 		 * place to do it rather than the lib however both would have to be
681 		 * changed to suppor this - nc).
682 		 */
683 		bristolMidiSendMsg(global.controlfd, synth->sid,
684 			127, 0, BRISTOL_MIDICHANNEL|newchan);
685 	}
686 
687 	synth->midichannel = newchan;
688 }
689 
690 /*
691  * For the sake of ease of use, links have been placed here to be called
692  * by any of the devices created. They would be better in some other file,
693  * perhaps with this as a dispatch.
694  *
695  * Param refers to the device index in the locations table given below.
696  */
697 static int
polyCallback(brightonWindow * win,int panel,int index,float value)698 polyCallback(brightonWindow * win, int panel, int index, float value)
699 {
700 	guiSynth *synth = findSynth(global.synths, win);
701 	int sendvalue;
702 
703 /*printf("polyCallback(%i, %f): %x\n", index, value, synth); */
704 
705 	if (synth == 0)
706 		return(0);
707 
708 	if ((index >= DEVICE_COUNT) || ((synth->flags & OPERATIONAL) == 0))
709 		return(0);
710 
711 	if (polyApp.resources[0].devlocn[index].to == 1.0)
712 		sendvalue = value * (CONTROLLER_RANGE - 1);
713 	else
714 		sendvalue = value;
715 
716 	synth->mem.param[index] = value;
717 
718 	if ((!global.libtest) || (index >= ACTIVE_DEVS))
719 		synth->dispatch[index].routine(synth,
720 			global.controlfd, synth->sid,
721 			synth->dispatch[index].controller,
722 			synth->dispatch[index].operator,
723 			sendvalue);
724 
725 #ifdef DEBUG
726 	else
727 		printf("dispatch[%x,%i](%i, %i, %i, %i, %i)\n", synth, index,
728 			global.controlfd, synth->sid,
729 			synth->dispatch[index].controller,
730 			synth->dispatch[index].operator,
731 			sendvalue);
732 #endif
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
polyInit(brightonWindow * win)745 polyInit(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, (int) 0);
754 		if (synth == 0)
755 		{
756 			printf("cannot init\n");
757 			return(0);
758 		}
759 	}
760 
761 	synth->win = win;
762 
763 	if ((initmem = synth->location) == 0)
764 		initmem = 11;
765 
766 	printf("Initialise the poly 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 	if (!global.libtest)
782 	{
783 		synth->voices = 1;
784 		if ((synth->sid = initConnection(&global, synth)) < 0)
785 			return(-1);
786 	}
787 
788 	for (i = 0; i < DEVICE_COUNT; i++)
789 	{
790 		synth->dispatch[i].routine = polyMidiSendMsg;
791 	}
792 
793 	/* Osc-1 Waveform is a compound operator */
794 	dispatch[0].controller = 0;
795 	dispatch[0].operator = 0;
796 	dispatch[0].routine = (synthRoutine) polyWaveform;
797 	dispatch[1].controller = 0;
798 	dispatch[1].operator = 1;
799 	dispatch[2].controller = 126;
800 	dispatch[2].operator = 30;
801 	/* Osc-2 Waveform is a compound operator */
802 	dispatch[3].controller = 1;
803 	dispatch[3].operator = 10;
804 	dispatch[4].controller = 1;
805 	dispatch[4].operator = 0;
806 	dispatch[4].routine = (synthRoutine) polyWaveform;
807 	dispatch[5].controller = 1;
808 	dispatch[5].operator = 1;
809 	dispatch[6].controller = 126;
810 	dispatch[6].operator = 31;
811 	/* Osc-3 Waveform is a compound operator */
812 	dispatch[7].controller = 2;
813 	dispatch[7].operator = 10;
814 	dispatch[8].controller = 2;
815 	dispatch[8].operator = 0;
816 	dispatch[8].routine = (synthRoutine) polyWaveform;
817 	dispatch[9].controller = 2;
818 	dispatch[9].operator = 1;
819 	dispatch[10].controller = 126;
820 	dispatch[10].operator = 32;
821 	/* Osc-4 Waveform is a compound operator and different operator.... */
822 	dispatch[11].controller = 8;
823 	dispatch[11].operator = 10;
824 	dispatch[12].controller = 8;
825 	dispatch[12].operator = 0;
826 	dispatch[12].routine = (synthRoutine) polyWaveform;
827 	dispatch[13].controller = 8;
828 	dispatch[13].operator = 1;
829 	dispatch[14].controller = 126;
830 	dispatch[14].operator = 33;
831 
832 	/* Filter */
833 	dispatch[15].controller = 4;
834 	dispatch[15].operator = 0;
835 	dispatch[16].controller = 4;
836 	dispatch[16].operator = 1;
837 	dispatch[17].controller = 4;
838 	dispatch[17].operator = 2;
839 	dispatch[18].controller = 4;
840 	dispatch[18].operator = 3;
841 	/* Filter Env */
842 	dispatch[19].controller = 3;
843 	dispatch[19].operator = 0;
844 	dispatch[20].controller = 3;
845 	dispatch[20].operator = 1;
846 	dispatch[21].controller = 3;
847 	dispatch[21].operator = 2;
848 	dispatch[22].controller = 3;
849 	dispatch[22].operator = 3;
850 	/* Env */
851 	dispatch[23].controller = 5;
852 	dispatch[23].operator = 0;
853 	dispatch[24].controller = 5;
854 	dispatch[24].operator = 1;
855 	dispatch[25].controller = 5;
856 	dispatch[25].operator = 2;
857 	dispatch[26].controller = 5;
858 	dispatch[26].operator = 3;
859 	/* Env gain */
860 	dispatch[27].controller = 5;
861 	dispatch[27].operator = 4;
862 	/* This switch reassigned to arpeggiator direction, was for headphone output */
863 	dispatch[28].controller = 126;
864 	dispatch[28].operator = 28;
865 	/* LFO frequencies */
866 	dispatch[29].controller = 9;
867 	dispatch[29].operator = 0;
868 	dispatch[30].controller = 126;
869 	dispatch[30].operator = 3;
870 	dispatch[31].controller = 10;
871 	dispatch[31].operator = 0;
872 	/* Needs a dispatcher since it has dual operation - arpeg and LFO2 */
873 	dispatch[31].routine = (synthRoutine) polyMG2;
874 	/* PWM */
875 	dispatch[32].controller = 126;
876 	dispatch[32].operator = 4;
877 	dispatch[33].controller = 126;
878 	dispatch[33].operator = 5;
879 	/* PW */
880 	dispatch[34].controller = 34;
881 	dispatch[34].operator = 34;
882 	dispatch[34].routine = (synthRoutine) polyWaveform;
883 
884 	/* Modulators 35 though 39 NOT DONE */
885 	dispatch[35].controller = 126;
886 	dispatch[35].operator = 6;
887 	dispatch[36].controller = 126;
888 	dispatch[36].operator = 7;
889 	dispatch[37].controller = 126;
890 	dispatch[37].operator = 8;
891 	dispatch[38].controller = 126;
892 	dispatch[38].operator = 9;
893 	dispatch[39].controller = 126;
894 	dispatch[39].operator = 10;
895 /*	dispatch[35].routine = dispatch[36].routine = dispatch[37].routine = */
896 /*	dispatch[38].routine = dispatch[39].routine = (synthRoutine) polyEffect; */
897 
898 	/* Glide */
899 	dispatch[40].controller = 126;
900 	dispatch[40].operator = 0;
901 
902 	/* Detune. */
903 	dispatch[41].controller = 126;
904 	dispatch[41].operator = 11;
905 
906 	/* Transpose */
907 	dispatch[42].controller = 0;
908 	dispatch[42].operator = 0;
909 	dispatch[42].routine = (synthRoutine) polyTranspose;
910 
911 	/* Noise level */
912 	dispatch[43].controller = 7;
913 	dispatch[43].operator = 0;
914 
915 	/* Trigger */
916 	dispatch[44].controller = 126;
917 	dispatch[44].operator = 12;
918 	/* Damp */
919 	dispatch[45].controller = 126;
920 	dispatch[45].operator = 13;
921 
922 	/* Effects NOT DONE */
923 	dispatch[46].controller = 126;
924 	dispatch[46].operator = 14;
925 	dispatch[46].routine = (synthRoutine) polyEffect;
926 
927 	/* Global tune */
928 	dispatch[47].controller = 126;
929 	dispatch[47].operator = 2;
930 
931 	/* MG1 */
932 	dispatch[48].controller = 126;
933 	dispatch[48].operator = 15;
934 	dispatch[49].controller = 126;
935 	dispatch[49].operator = 16;
936 	/* MG2 */
937 	dispatch[50].controller = 126;
938 	dispatch[50].operator = 17;
939 	dispatch[51].controller = 126;
940 	dispatch[51].operator = 18;
941 
942 	/*
943 	 * Hold
944 	 *
945 	 * Mono - two button
946 	 *
947 	 * Poly - two buttons
948 	 *
949      * Propose
950 	 *	Mono - fat synth = UNISON
951 	 *	Poly - 4 voice thin synth
952 	 *	Share:
953 	 *		One key all voices (fat synth)
954 	 *		Key keys two notes each (2VCO synth)
955 	 *		Three or more, one note each (thin synth).
956 	 */
957 	dispatch[52].controller = 52;
958 	dispatch[52].operator = 27;
959 	dispatch[53].controller = 53;
960 	dispatch[53].operator = 19;
961 	dispatch[54].controller = 54; /* Does not do anything = Unison off */
962 	dispatch[54].operator = 20;
963 	dispatch[55].controller = 55;
964 	dispatch[55].operator = 21;
965 	dispatch[52].routine =
966 		dispatch[53].routine =
967 		dispatch[54].routine =
968 		dispatch[55].routine = (synthRoutine) polyMode;
969 
970 	dispatch[56].controller = 0;
971 	dispatch[57].controller = 1;
972 	dispatch[58].controller = 2;
973 	dispatch[59].controller = 3;
974 	dispatch[60].controller = 4;
975 	dispatch[61].controller = 5;
976 	dispatch[62].controller = 6;
977 	dispatch[63].controller = 7;
978 	dispatch[64].controller = 8;
979 	dispatch[65].controller = 9;
980 	dispatch[66].controller = 10;
981 	dispatch[67].controller = 11;
982 	dispatch[68].controller = 12;
983 	dispatch[69].controller = 13;
984 	dispatch[70].controller = 14;
985 	dispatch[71].controller = 15;
986 
987 	dispatch[56].routine =
988 		dispatch[57].routine =
989 		dispatch[58].routine =
990 		dispatch[59].routine =
991 		dispatch[60].routine =
992 		dispatch[61].routine =
993 		dispatch[62].routine =
994 		dispatch[63].routine =
995 		dispatch[64].routine =
996 		dispatch[65].routine =
997 		dispatch[66].routine =
998 		dispatch[67].routine =
999 		dispatch[68].routine =
1000 		dispatch[69].routine =
1001 		dispatch[70].routine =
1002 		dispatch[71].routine
1003 			= (synthRoutine) polyMemory;
1004 
1005 	dispatch[RADIOSET_1].other1 = -1;
1006 	dispatch[RADIOSET_2].other1 = -1;
1007 	dispatch[RADIOSET_3].other1 = -1;
1008 
1009 	dispatch[72].controller = 1;
1010 	dispatch[73].controller = 2;
1011 	dispatch[72].routine = dispatch[73].routine =
1012 		(synthRoutine) polyMidi;
1013 
1014 	/* Tune osc-1
1015 	bristolMidiSendMsg(global.controlfd, synth->sid, 0, 10, 8192);
1016 	*/
1017 	/*
1018 	 * We put all the osc on SYNC/MAXgain, but manipulate the sync buffer in the
1019 	 * engine.
1020 	 */
1021 	bristolMidiSendMsg(global.controlfd, synth->sid, 0, 7, 8192);
1022 	bristolMidiSendMsg(global.controlfd, synth->sid, 1, 7, 8192);
1023 	bristolMidiSendMsg(global.controlfd, synth->sid, 2, 7, 8192);
1024 	bristolMidiSendMsg(global.controlfd, synth->sid, 8, 7, 8192);
1025 
1026 	bristolMidiSendMsg(global.controlfd, synth->sid, 4, 4, 4);
1027 
1028 	bristolMidiSendMsg(global.controlfd, synth->sid, 0, 3, C_RANGE_MIN_1);
1029 	bristolMidiSendMsg(global.controlfd, synth->sid, 1, 3, C_RANGE_MIN_1);
1030 	bristolMidiSendMsg(global.controlfd, synth->sid, 2, 3, C_RANGE_MIN_1);
1031 	bristolMidiSendMsg(global.controlfd, synth->sid, 8, 3, C_RANGE_MIN_1);
1032 
1033 	/* Gain on filter contour */
1034 	bristolMidiSendMsg(global.controlfd, synth->sid, 3, 4, C_RANGE_MIN_1);
1035 	/* LFO Options */
1036 	bristolMidiSendMsg(global.controlfd, synth->sid, 10, 2, 8192);
1037 
1038 	return(0);
1039 }
1040 
1041 /*
1042  * This will be called to make any routine specific parameters available.
1043  */
1044 static int
polyConfigure(brightonWindow * win)1045 polyConfigure(brightonWindow* win)
1046 {
1047 	guiSynth *synth = findSynth(global.synths, win);
1048 	brightonEvent event;
1049 
1050 	if (synth == 0)
1051 	{
1052 		printf("problems going operational\n");
1053 		return(-1);
1054 	}
1055 
1056 	if (synth->flags & OPERATIONAL)
1057 		return(0);
1058 
1059 printf("going operational\n");
1060 
1061 	synth->flags |= OPERATIONAL;
1062 	synth->keypanel = 1;
1063 	synth->keypanel2 = -1;
1064 	synth->transpose = 36;
1065 
1066 	if (synth->location == 0)
1067 	{
1068 		synth->bank = 1;
1069 		synth->location = 1;
1070 	}
1071 
1072 	event.value = 1;
1073 	brightonParamChange(synth->win, synth->panel, MEM_START + 1, &event);
1074 	brightonParamChange(synth->win, synth->panel, MEM_START + 8, &event);
1075 
1076 	loadMemory(synth, "mono", 0, initmem, synth->mem.active, FIRST_DEV, 0);
1077 	fixModes(synth);
1078 
1079 	brightonPut(win,
1080 		"bitmaps/blueprints/monoshade.xpm", 0, 0, win->width, win->height);
1081 	width = win->width;
1082 
1083 	/*
1084 	 * Hm. This is a hack for a few bits of bad rendering of a keyboard. Only
1085 	 * occurs on first paint, so we suppress the first paint, and then request
1086 	 * an expose here.
1087 	 */
1088 	event.type = BRIGHTON_EXPOSE;
1089 	event.intvalue = 1;
1090 	brightonParamChange(synth->win, KEY_PANEL, -1, &event);
1091 
1092 	/*
1093 	 * Touch a key on/off
1094 	 */
1095 	bristolMidiSendMsg(global.controlfd, synth->midichannel,
1096 		BRISTOL_EVENT_KEYON, 0, 10 + synth->transpose);
1097 	bristolMidiSendMsg(global.controlfd, synth->midichannel,
1098 		BRISTOL_EVENT_KEYOFF, 0, 10 + synth->transpose);
1099 	configureGlobals(synth);
1100 
1101 	synth->loadMemory = (loadRoutine) ploadMemory;
1102 
1103 	return(0);
1104 }
1105 
1106