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 #include <signal.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <sys/time.h>
26 
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <unistd.h>
30 
31 #include <pthread.h>
32 
33 #include "brighton.h"
34 #include "brightonMini.h"
35 #include "bristolmidi.h"
36 #include "brightonhelp.h"
37 
38 #include "brightonKeyboards.h"
39 
40 #include "brightonVImages.h"
41 
42 extern brightonApp miniApp;
43 extern brightonApp prophetApp;
44 extern brightonApp hammondApp;
45 extern brightonApp junoApp;
46 extern brightonApp dxApp;
47 extern brightonApp explorerApp;
48 extern brightonApp mixApp;
49 extern brightonApp hammondB3App;
50 extern brightonApp voxApp;
51 extern brightonApp rhodesApp;
52 extern brightonApp rhodesBassApp;
53 extern brightonApp pro10App;
54 extern brightonApp prophet52App;
55 extern brightonApp obxApp;
56 extern brightonApp obxaApp;
57 extern brightonApp polyApp;
58 extern brightonApp poly6App;
59 extern brightonApp axxeApp;
60 extern brightonApp odysseyApp;
61 extern brightonApp memMoogApp;
62 extern brightonApp arp2600App;
63 extern brightonApp sAksApp;
64 extern brightonApp ms20App;
65 extern brightonApp solinaApp;
66 extern brightonApp roadrunnerApp;
67 extern brightonApp granularApp;
68 extern brightonApp realisticApp;
69 extern brightonApp voxM2App;
70 extern brightonApp jupiterApp;
71 extern brightonApp bitoneApp;
72 extern brightonApp bit99App;
73 extern brightonApp bit100App;
74 extern brightonApp masterApp;
75 extern brightonApp cs80App;
76 extern brightonApp pro1App;
77 extern brightonApp voyagerApp;
78 extern brightonApp sonic6App;
79 extern brightonApp trilogyApp;
80 extern brightonApp stratusApp;
81 extern brightonApp poly800App;
82 extern brightonApp bme700App;
83 extern brightonApp bmApp;
84 extern brightonApp sidApp;
85 extern brightonApp sid2App;
86 
87 extern int brightonCLIcheck(guimain *);
88 extern int brightonCLIinit(guimain *, int *);
89 
90 #define BRIGHTON_BIT99APP (BRISTOL_SYNTHCOUNT + 1)
91 
92 char *bristolhome = NULL;
93 
94 guimain global;
95 
96 brightonApp *synthesisers[BRISTOL_SYNTHCOUNT];
97 #include "brightonreadme.h"
98 
99 static char *defname = "bristol";
100 
101 void *eventMgr();
102 
103 static int readMe = 0;
104 static int gmc = 0;
105 static int opacity = 60;
106 static int gs = 1;
107 static int nar = 0;
108 static int azoom = 0;
109 static int quality = 6;
110 static int deswidth = -1;
111 static float scale = 1.0;
112 static float antialias = 0.0;
113 static int aliastype = 0;
114 static int library = 1;
115 static int dcTimeout = 500000;
116 static int sampleRate = 44100;
117 static int sampleCount = 256;
118 static int mwt = 50000;
119 static int activeSense = 2000;
120 static int activeSensePeriod = 15000;
121 static int bwflags = BRIGHTON_POST_WINDOW;
122 static int rlflags = BRIGHTON_SET_RAISE|BRIGHTON_SET_LOWER;
123 static int nrpcc = BRIGHTON_NRP_COUNT;
124 static int cli = 0;
125 static int cli_fd[2];
126 
127 static char defaultcdev[16];
128 
129 extern int vuInterval;
130 void printBrightonHelp(int);
131 void printBrightonReadme();
132 
133 extern int brightonMidiInput(bristolMidiMsg *);
134 extern void brightonControlKeyInput(brightonWindow *, int, int);
135 
136 /*
137  * Some of the emulations really benefit from a bit of detune, this is the
138  * value they will use unless another has been requested.
139  */
140 #define NON_DEF_DETUNE 100
141 
142 static int asc, emStart = 0, midiHandle = -1;
143 
144 volatile sig_atomic_t ladiRequest = 0;
145 
146 static void
savehandler()147 savehandler()
148 {
149 	if (global.synths->flags & LADI_ENABLE && global.synths->ladimode)
150 		ladiRequest = 1;
151 	else
152 		ladiRequest = 0;
153 }
154 
155 static void
loadhandler()156 loadhandler()
157 {
158 	if (global.synths->flags & LADI_ENABLE && global.synths->ladimode)
159 		ladiRequest = 2;
160 	else
161 		ladiRequest = 0;
162 }
163 
164 static void
printSummaryText()165 printSummaryText()
166 {
167 	int i;
168 
169 	for (i = 0 ; i < BRISTOL_SYNTHCOUNT; i++)
170 	{
171 		if ((synthesisers[i] != NULL)
172 			&& (synthesisers[i]->name != NULL)
173 			&& (synthesisers[i]->name[0] != '\0'))
174 			printf("%s ", synthesisers[i]->name);
175 	}
176 	printf("\n");
177 }
178 
179 static void
brightonFindEmulation(int argc,char ** argv)180 brightonFindEmulation(int argc, char **argv)
181 {
182 	int argCount, i, found = -1;
183 
184 	for (argCount = 1; argCount < argc; argCount++)
185 	{
186 		if (argv[argCount][0] != '-')
187 			continue;
188 
189 		for (i = 0 ; i < BRISTOL_SYNTHCOUNT; i++)
190 		{
191 			if (synthesisers[i] == NULL)
192 				continue;
193 
194 			/* Check for a few aliases */
195 			if (strcmp("-2600", argv[argCount]) == 0)
196 				found = global.synths->synthtype = BRISTOL_2600;
197 			if (strcmp("-mg1", argv[argCount]) == 0)
198 				found = global.synths->synthtype = BRISTOL_REALISTIC;
199 			if (strcmp("-bme700", argv[argCount]) == 0)
200 				found = global.synths->synthtype = BRISTOL_BME700;
201 			if (strcmp("-pro10", argv[argCount]) == 0)
202 				found = global.synths->synthtype = BRISTOL_PROPHET10;
203 			if (strcmp("-pro52", argv[argCount]) == 0)
204 				found = global.synths->synthtype = BRISTOL_PRO52;
205 			if ((strcmp("-poly6", argv[argCount]) == 0)
206 				|| (strcmp("-polysix", argv[argCount]) == 0))
207 				found = global.synths->synthtype = BRISTOL_POLY6;
208 			if ((strcmp("-memmoog", argv[argCount]) == 0)
209 				|| (strcmp("-memorymoog", argv[argCount]) == 0))
210 				found = global.synths->synthtype = BRISTOL_MEMMOOG;
211 
212 			if ((strcmp("-emulate", argv[argCount]) == 0)
213 				&& (argCount < (argc - 1)))
214 			{
215 				if (strcmp(synthesisers[i]->name, argv[argCount + 1]) == 0)
216 					found = global.synths->synthtype = i;
217 			} else {
218 				if (strcmp(synthesisers[i]->name, &argv[argCount][1]) == 0)
219 					found = global.synths->synthtype = i;
220 			}
221 		}
222 	}
223 
224 	/*
225 	 * Global.synths->synthtype will now either be the last emulator found or
226 	 * will be the usual default (b3). Stuff this back into i, that is nicely
227 	 * confusing but makes the lines shorter. Hm.
228 	 */
229 	i = global.synths->synthtype;
230 
231 	if (found > 0)
232 		printf("%s emulation defaults:\n", synthesisers[i]->name);
233 	else {
234 		printf("emulation defaults:\n");
235 	}
236 
237 	if ((global.synths->voices = synthesisers[i]->emulate.voices) < 0)
238 	{
239 		printf("    -voices  %i\n", BRISTOL_VOICECOUNT);
240 		global.synths->voices = BRISTOL_VOICECOUNT;
241 	} else
242 		printf("    -voices  %i\n",synthesisers[i]->emulate.voices);
243 
244 	if (global.synths->voices == 1)
245 	{
246 		printf("    -retrig\n");
247 		printf("    -lvel\n");
248 		printf("    -hnp\n");
249 		printf("    -wwf\n");
250 		global.synths->lwf = 2;
251 		global.synths->legatovelocity = 1;
252 		global.synths->notepref = BRIGHTON_HNP;
253 		global.synths->notetrig = 1;
254 	}
255 
256 	if (i == BRISTOL_2600)
257 		printf("    -multi   4\n");
258 	printf("    -detune  %i\n", synthesisers[i]->emulate.detune);
259 	printf("    -gain    %i\n",	synthesisers[i]->emulate.gain);
260 	printf("    -pwd     %i\n",	synthesisers[i]->emulate.pwd);
261 	printf("    -glide   %i\n",	synthesisers[i]->emulate.glide);
262 	printf("    -curve   %i\n",	synthesisers[i]->emulate.velocity);
263 
264 	global.synths->detune = synthesisers[i]->emulate.detune;
265 	global.synths->gain = synthesisers[i]->emulate.gain * 16;
266 	global.synths->pwd = synthesisers[i]->emulate.pwd;
267 	global.synths->glide = synthesisers[i]->emulate.glide;
268 	global.synths->velocity = synthesisers[i]->emulate.velocity;
269 	if (synthesisers[i]->emulate.opacity != 0)
270 		printf("    -opacity %i\n",
271 			opacity = synthesisers[i]->emulate.opacity);
272 }
273 
274 /*
275  * Need to make this multithreaded?
276  */
277 int
main(int argc,char ** argv)278 main(int argc, char **argv)
279 {
280 	int argCount = 1, i, j, logtype = BRISTOL_LOG_BRIGHTON;
281 	pthread_t emgrThread, logthread;
282 	char appname[65], *devname = defname;
283 	int reqW = 0, reqH = 0, reqX = 0, reqY = 0;
284 
285 	signal(SIGINT, cleanupBristol);
286 	signal(SIGPIPE, cleanupBristolQuietly);
287 	signal(SIGHUP, cleanupBristol);
288 	signal(SIGUSR1, savehandler);
289 	signal(SIGUSR2, loadhandler);
290 
291 	global.home = getenv("BRISTOL");
292 
293 	global.synths = (guiSynth *) brightonmalloc(sizeof(guiSynth));
294 
295 	global.controlfd = -1;
296 	global.voices = BRISTOL_VOICECOUNT;
297 	global.synths->voices = BRISTOL_VOICECOUNT;
298 	global.synths->pwd = 2;
299 	global.synths->gain = 32;
300 	global.synths->ladimem = 1024;
301 	global.synths->synthtype = BRISTOL_HAMMONDB3;
302 	global.synths->velocity = 510;  /* linear tracking */
303 	global.synths->glide = 5;  /* maximum glide delay - up to 30s */
304 	global.synths->detune = 40;
305 	global.synths->lowkey = 0;
306 	global.synths->highkey = 127;
307 	global.synths->lwf = 0; //3;
308 	global.synths->mbi = 0;
309 	global.synths->notepref = BRIGHTON_POLYPHONIC;
310 	global.synths->notetrig = 0;
311 	global.synths->win = NULL;
312 	global.synths->flags =
313 		REQ_FORWARD|REQ_LOCAL_FORWARD|REQ_REMOTE_FORWARD|NO_LATCHING_KEYS;
314 	global.port = 5028;
315 	snprintf(defaultcdev, 16, "localhost");
316 	global.host = defaultcdev;
317 
318 	memset(synthesisers, 0, sizeof(synthesisers));
319 
320 	synthesisers[BRISTOL_MINI] = &miniApp;
321 	synthesisers[BRISTOL_PROPHET] = &prophetApp;
322 	synthesisers[BRISTOL_PRO52] = &prophet52App;
323 	synthesisers[BRISTOL_HAMMOND] = &hammondB3App;
324 	synthesisers[BRISTOL_JUNO] = &junoApp;
325 	synthesisers[BRISTOL_DX] = &dxApp;
326 	synthesisers[BRISTOL_EXPLORER] = &explorerApp;
327 	synthesisers[BRISTOL_HAMMONDB3] = &hammondB3App;
328 	synthesisers[BRISTOL_VOX] = &voxApp;
329 	synthesisers[BRISTOL_RHODES] = &rhodesApp;
330 	synthesisers[BRISTOL_RHODES_BASS] = &rhodesBassApp;
331 	synthesisers[BRISTOL_PROPHET10] = &pro10App;
332 	synthesisers[BRISTOL_MIXER] = &mixApp;
333 	synthesisers[BRISTOL_OBX] = &obxApp;
334 	synthesisers[BRISTOL_OBXA] = &obxaApp;
335 	synthesisers[BRISTOL_POLY] = &polyApp;
336 	synthesisers[BRISTOL_POLY6] = &poly6App;
337 	synthesisers[BRISTOL_AXXE] = &axxeApp;
338 	synthesisers[BRISTOL_ODYSSEY] = &odysseyApp;
339 	synthesisers[BRISTOL_MEMMOOG] = &memMoogApp;
340 	synthesisers[BRISTOL_2600] = &arp2600App;
341 	synthesisers[BRISTOL_SAKS] = &sAksApp;
342 	synthesisers[BRISTOL_MS20] = &ms20App;
343 	synthesisers[BRISTOL_SOLINA] = &solinaApp;
344 	synthesisers[BRISTOL_ROADRUNNER] = &roadrunnerApp;
345 	synthesisers[BRISTOL_GRANULAR] = &granularApp;
346 	synthesisers[BRISTOL_REALISTIC] = &realisticApp;
347 	synthesisers[BRISTOL_VOXM2] = &voxM2App;
348 	synthesisers[BRISTOL_JUPITER8] = &jupiterApp;
349 	synthesisers[BRISTOL_BIT_ONE] = &bitoneApp;
350 	synthesisers[BRISTOL_MASTER] = &masterApp;
351 	synthesisers[BRISTOL_CS80] = &cs80App;
352 	synthesisers[BRISTOL_PRO1] = &pro1App;
353 	synthesisers[BRISTOL_VOYAGER] = &voyagerApp;
354 	synthesisers[BRISTOL_SONIC6] = &sonic6App;
355 	synthesisers[BRISTOL_TRILOGY] = &trilogyApp;
356 	synthesisers[BRISTOL_STRATUS] = &stratusApp;
357 	synthesisers[BRISTOL_POLY800] = &poly800App;
358 	synthesisers[BRISTOL_BME700] = &bme700App;
359 	synthesisers[BRISTOL_BASSMAKER] = &bmApp;
360 	synthesisers[BRISTOL_SID_M1] = &sidApp;
361 	synthesisers[BRISTOL_SID_M2] = &sid2App;
362 
363 	readme[BRISTOL_PRO52] = readme[BRISTOL_PROPHET];
364 	readme[BRISTOL_VOYAGER] = readme[BRISTOL_EXPLORER];
365 
366 	if (argc == 1)
367 	{
368 		printf("You probably prefer to use the startBristol script.\n");
369 		exit(0);
370 	}
371 
372 	if (strcmp(argv[1], "-console") == 0)
373 		logtype = BRISTOL_LOG_CONSOLE;
374 
375 	if (strcmp(argv[1], "-readme") == 0)
376 	{
377 		readMe = 1;
378 		logtype = BRISTOL_LOG_CONSOLE;
379 		if (argc == 2)
380 		{
381 			printBrightonReadme();
382 			exit(0);
383 		}
384 	}
385 
386 	if (((strcmp(argv[argCount], "-V") == 0)
387 		|| (strcmp(argv[argCount], "-version") == 0))
388 		&& (strlen(argv[argCount]) == 2))
389 	{
390 		printf("Version %s\n", VERSION);
391 		exit(0);
392 	}
393 
394 	if ((argc > 1) && (strcmp(argv[1], "--summary") == 0))
395 	{
396 		printSummaryText();
397 		exit(0);
398 	}
399 	if ((argc > 1) && (strcmp(argv[1], "-summary") == 0))
400 	{
401 		printf("%s\n", summarytext);
402 		exit(0);
403 	}
404 
405 	if (argc < 2) {
406 		printf("You probably prefer to use the startBristol script.\n");
407 		exit(1);
408 	}
409 
410 	if ((argc == 2)
411 		&& ((strcmp(argv[argCount], "--help") == 0)
412 		|| (strcmp(argv[argCount], "-help") == 0)
413 		|| (strcmp(argv[argCount], "-h") == 0)
414 		|| (strcmp(argv[argCount], "--h") == 0)))
415 	{
416 #ifdef BRISTOL_BUILD
417 		if (BRISTOL_BUILD == 0)
418 			printf("bristol %i.%i.%i: ",
419 				BRISTOL_MAJOR, BRISTOL_MINOR, BRISTOL_PATCH);
420 		else
421 			printf("bristol %i.%i.%i-%i: ",
422 				BRISTOL_MAJOR, BRISTOL_MINOR, BRISTOL_PATCH, BRISTOL_BUILD);
423 #else
424 			printf("bristol %s\n", VERSION);
425 #endif
426 		printf("%s", helptext);
427 		exit(0);
428 	}
429 
430 	if (readMe == 0)
431 		printf("%s", gplnotice);
432 
433 	global.synths->location = 0;
434 
435 	if ((getenv("BRISTOL_LOG_CONSOLE") != NULL)
436 		&& (strcmp(getenv("BRISTOL_LOG_CONSOLE"), "true") == 0))
437 		logtype = BRISTOL_LOG_CONSOLE;
438 
439 	cli_fd[0] = 0;//dup(0);
440 	cli_fd[1] = 1;//dup(1);
441 
442 	logthread = bristolOpenStdio(logtype);
443 
444 	/* Set up a default SYSEX ID, may get changed later */
445 	bristolMidiOption(0, BRISTOL_NRP_SYSID_H, 0x534C);
446 	bristolMidiOption(0, BRISTOL_NRP_SYSID_L, 0x6162);
447 
448 	brightonFindEmulation(argc, argv);
449 
450 	/*
451 	 * close our standard input, create a pipe which will never be used.
452 	 */
453 	while (argc > argCount)
454 	{
455 		if ((strcmp(argv[argCount], "-log") == 0)
456 			&& (logtype != BRISTOL_LOG_CONSOLE))
457 			bristolOpenStdio(BRISTOL_LOG_DAEMON);
458 
459 		if ((strcmp(argv[argCount], "-syslog") == 0)
460 			&& (logtype != BRISTOL_LOG_CONSOLE))
461 			bristolOpenStdio(BRISTOL_LOG_SYSLOG);
462 
463 		if ((strcmp(argv[argCount], "-V") == 0)
464 			&& (strlen(argv[argCount]) == 2))
465 		{
466 #ifdef BRISTOL_BUILD
467 			if (BRISTOL_BUILD == 0)
468 				printf("brighton version %i.%i.%i\n",
469 					BRISTOL_MAJOR, BRISTOL_MINOR, BRISTOL_PATCH);
470 			else
471 				printf("brighton version %i.%i.%i-%i\n",
472 					BRISTOL_MAJOR, BRISTOL_MINOR, BRISTOL_PATCH, BRISTOL_BUILD);
473 #endif
474 			exit(0);
475 		}
476 
477 		if (strcmp(argv[argCount], "-libtest") == 0)
478 			global.libtest = 1 - global.libtest;
479 
480 		if (strcmp(argv[argCount], "-pixmap") == 0)
481 			library = 0;
482 
483 		if ((strcmp(argv[argCount], "-synth") == 0)
484 			&& (argCount < argc))
485 		{
486 			int i;
487 
488 			for (i = 0 ; i < BRISTOL_SYNTHCOUNT; i++)
489 			{
490 				if (synthesisers[i] == NULL)
491 					continue;
492 
493 				if (strcmp(synthesisers[i]->name, argv[argCount + 1]) == 0)
494 				{
495 					printf("found %s at %i\n", synthesisers[i]->name, i);
496 					global.synths->synthtype = i;
497 					break;
498 				}
499 			}
500 
501 			if (i == BRISTOL_SYNTHCOUNT) {
502 				printf("Could not find synth named \"%s\"\n",
503 					argv[argCount + 1]);
504 				exit(-1);
505 			} else {
506 				/*
507 				 * We found the emulation, now we should put in the default
508 				 * from its application definition.
509 				 */
510 				printf("emulation defaults:\n");
511 				printf("	-voices  %i\n", synthesisers[i]->emulate.voices);
512 				printf("	-detune: %i\n", synthesisers[i]->emulate.detune);
513 				printf("	-gain:   %i\n",	synthesisers[i]->emulate.gain);
514 				printf("	-pwd:    %i\n",	synthesisers[i]->emulate.pwd);
515 				printf("	-glide:  %i\n",	synthesisers[i]->emulate.glide);
516 				printf("	-curve:  %i\n",	synthesisers[i]->emulate.velocity);
517 
518 				if ((global.synths->voices = synthesisers[i]->emulate.voices)
519 					< 0)
520 					global.synths->voices = BRISTOL_VOICECOUNT;
521 				global.synths->detune = synthesisers[i]->emulate.detune;
522 				global.synths->gain = synthesisers[i]->emulate.gain * 128;
523 				global.synths->pwd = synthesisers[i]->emulate.pwd;
524 				global.synths->glide = synthesisers[i]->emulate.glide;
525 				global.synths->velocity = synthesisers[i]->emulate.velocity;
526 				if (synthesisers[i]->emulate.opacity != 0)
527 					printf("    -opacity:%i\n",
528 						opacity = synthesisers[i]->emulate.opacity);
529 				if (global.synths->voices == 1)
530 					global.synths->notepref = BRIGHTON_HNP;
531 				devname = argv[argCount + 1];
532 			}
533 			argCount++;
534 			continue;
535 		}
536 
537 		if (((strcmp(argv[argCount], "-geometry") == 0)
538 			|| (strcmp(argv[argCount], "-geom") == 0))
539 			&& (argCount < argc))
540 		{
541 			int i = 0;
542 			char *yp;
543 
544 			argCount++;
545 
546 			/*
547 			 * We want WxH+x+y
548 			 * If we only have +-x+-y then don't apply w.h
549 			 * If we have H+x+y then use H as a width and use it to scale
550 			 * the image to a given bitmap. If we have W+H then automatically
551 			 * set -ar.
552 			 */
553 
554 			/*
555 			 * Start looking for width
556 			 */
557 			while ((argv[argCount][i] != '-')
558 				&& (argv[argCount][i] != '+')
559 				&& (argv[argCount][i] != '\0')
560 				&& (argv[argCount][i] != 'x'))
561 			{
562 				reqW = reqW * 10 + argv[argCount][i] - 48;
563 				i++;
564 			}
565 
566 			if (argv[argCount][i] == 'x')
567 				i++;
568 
569 			/* Look for height */
570 			while ((argv[argCount][i] != '-')
571 				&& (argv[argCount][i] != '+')
572 				&& (argv[argCount][i] != '\0')
573 				&& (argv[argCount][i] != 'x'))
574 			{
575 				reqH = reqH * 10 + argv[argCount][i] - 48;
576 				i++;
577 			}
578 
579 			/* Take an X if it is available */
580 			if (argv[argCount][i] != '\0')
581 				reqX = atoi(&argv[argCount][i]);
582 			if ((reqX == 0) && (argv[argCount][i] == '-'))
583 				reqX = -1;
584 
585 			if ((yp = strchr(&argv[argCount][++i], '+')))
586 				reqY = atoi(yp);
587 			else if ((yp = strchr(&argv[argCount][++i], '-')))
588 				reqY = atoi(yp);
589 			if ((reqY == 0) && (argv[argCount][i] == '-'))
590 				reqY = -1;
591 		}
592 
593 		if (strcmp(argv[argCount], "-iconify") == 0)
594 			bwflags &= ~BRIGHTON_POST_WINDOW;
595 
596 		if ((strcmp(argv[argCount], "-quality") == 0) && (argCount < argc))
597 		{
598 			if ((quality = atoi(argv[argCount + 1])) < 2)
599 				quality = 2;
600 			else if (quality > 8)
601 				quality = 8;
602 			argCount++;
603 			continue;
604 		}
605 
606 		if ((strcmp(argv[argCount], "-aliastype") == 0) && (argCount < argc))
607 		{
608 			/*
609 			 * I want this to take a text value and if not recognised then
610 			 * an integer. Text will be 'texture' or 'all'.
611 			 */
612 			if (strcmp(argv[argCount + 1], "texture") == 0) {
613 				aliastype = 1;
614 				argCount++;
615 				if (antialias == 0.0)
616 					antialias = 0.3;
617 				continue;
618 			} else if (strcmp(argv[argCount + 1], "pre") == 0) {
619 				aliastype = 5;
620 				argCount++;
621 				if (antialias == 0.0)
622 					antialias = 0.3;
623 				continue;
624 			} else if (strcmp(argv[argCount + 1], "all") == 0) {
625 				aliastype = 3;
626 				argCount++;
627 				if (antialias == 0.0)
628 					antialias = 0.3;
629 				continue;
630 			} else if ((aliastype = atoi(argv[argCount + 1])) < 0) {
631 				aliastype = 0;
632 				continue;
633 			} else if (aliastype > 4) {
634 				aliastype = 0;
635 				continue;
636 			}
637 			argCount++;
638 			continue;
639 		}
640 
641 		if ((strcmp(argv[argCount], "-antialias") == 0) && (argCount < argc))
642 		{
643 			if ((antialias = (float) atoi(argv[argCount + 1])) < 0)
644 				antialias = 0.0;
645 			else if (antialias > 99)
646 				antialias = 0.01;
647 			else
648 				antialias = 1.0 - antialias / 100.0;
649 
650 			if (aliastype == 0)
651 				aliastype = 1;
652 
653 			argCount++;
654 			continue;
655 		}
656 
657 		if ((strcmp(argv[argCount], "-jsmuuid") == 0) && (argCount < argc))
658 		{
659 			global.synths->ladimem += atoi(argv[argCount + 1]);
660 			argCount++;
661 			continue;
662 		}
663 
664 		/*
665 		 * LADI level 1 options:
666 		 */
667 		if ((strcmp(argv[argCount], "-ladi") == 0) && (argCount < argc))
668 		{
669 			global.synths->flags |= LADI_ENABLE;
670 
671 			if (strcmp(argv[argCount + 1], "both") == 0)
672 				global.synths->ladimode = 1;
673 			else if (strcmp(argv[argCount + 1], "bristol") == 0)
674 				global.synths->ladimode = 0;
675 			else if (strcmp(argv[argCount + 1], "brighton") == 0)
676 				global.synths->ladimode = 1;
677 			else {
678 				if ((global.synths->ladimem = atoi(argv[argCount + 1])) <= 0)
679 				{
680 					global.synths->ladimem = 1024;
681 					global.synths->ladiStateFile = argv[argCount + 1];
682 				}
683 			}
684 
685 			/*
686 			 * We also need to force the startup to open this memory location
687 			 * as well, that can get overridden if there is a -load option
688 			 * anywhere later on the command line.
689 			 */
690 			global.synths->location = global.synths->ladimem;
691 
692 			global.synths->mbi = (global.synths->location / 1000) * 1000;
693 			global.synths->location = global.synths->location % 1000;
694 
695 			argCount++;
696 			continue;
697 		}
698 
699 		if ((strcmp(argv[argCount], "-audiodev") == 0) && (argCount < argc))
700 		{
701 			argCount++;
702 			devname = argv[argCount];
703 		}
704 		if ((strcmp(argv[argCount], "-register") == 0)
705 			&& (argCount < argc)
706 			&& (argv[argCount + 1][0] != '-'))
707 		{
708 			argCount++;
709 			devname = argv[argCount];
710 		}
711 
712 		if ((strcmp(argv[argCount], "-lowkey") == 0) && (argCount < argc))
713 		{
714 			argCount++;
715 			global.synths->lowkey = atoi(argv[argCount]);
716 		}
717 
718 		if ((strcmp(argv[argCount], "-highkey") == 0) && (argCount < argc))
719 		{
720 			argCount++;
721 			global.synths->highkey = atoi(argv[argCount]);
722 		}
723 
724 		if (strcmp(argv[argCount], "-rate") == 0)
725 		{
726 			if ((sampleRate = atoi(argv[argCount + 1])) <= 0)
727 				sampleRate = 44100;
728 
729 			argCount++;
730 			continue;
731 		}
732 
733 		if (strcmp(argv[argCount], "-count") == 0)
734 		{
735 			if ((sampleCount = atoi(argv[argCount + 1])) <= 0)
736 				sampleCount = 256;
737 
738 			argCount++;
739 
740 			continue;
741 		}
742 
743 		if (((strcmp(argv[argCount], "-activesense") == 0)
744 			|| (strcmp(argv[argCount], "-as") == 0))
745 			&& (argCount < argc))
746 		{
747 			activeSense = atoi(argv[argCount + 1]);
748 
749 			if ((activeSense != 0) && (activeSense < 50))
750 				activeSense = 50;
751 
752 			/*
753 			 * This is now set to the default timer to pass to the engine
754 			 * It is defaulted to three times the update rate. We should do
755 			 * a quick check to ensure this is larger than the sample period
756 			 * count by a little bit but we can only do that later.
757 			 */
758 			if (activeSense > 5000)
759 				activeSense = 5000;
760 
761 			if ((activeSensePeriod = activeSense * 3) > 16000)
762 				activeSensePeriod = 16000;
763 
764 			argCount++;
765 		}
766 
767 		if ((strcmp(argv[argCount], "-ast") == 0)
768 			&& (argCount < argc))
769 		{
770 			if ((activeSensePeriod = atoi(argv[argCount + 1])) < 50)
771 				activeSensePeriod = 50;
772 
773 			if (activeSensePeriod < activeSense * 2)
774 				activeSensePeriod = activeSense * 3;
775 
776 			if (activeSensePeriod > 16000)
777 				activeSensePeriod = 16000;
778 
779 			/*
780 			 * This is now set to the default timer to pass to the engine
781 			 * It is defaulted to three times the update rate.
782 			activeSensePeriod = activeSensePeriod * sampleRate / 1000;
783 			 */
784 
785 			argCount++;
786 		}
787 
788 		if (strcmp(argv[argCount], "-gmc") == 0)
789 			gmc = 1;
790 
791 		if ((strcmp(argv[argCount], "-mct") == 0)
792 			&& (argCount < argc))
793 		{
794 			if ((mwt = atoi(argv[argCount + 1]) * 1000) < 0)
795 				mwt = 50000;
796 			argCount++;
797 		}
798 
799 		if ((strcmp(argv[argCount], "-dct") == 0)
800 			&& (argCount < argc))
801 		{
802 			if ((dcTimeout = atoi(argv[argCount + 1]) * 1000) < 10000)
803 				dcTimeout = 250000;
804 
805 			argCount++;
806 		}
807 
808 		if ((strcmp(argv[argCount], "-opacity") == 0) && (argCount < argc))
809 		{
810 			if ((opacity = atoi(argv[argCount + 1])) < 20)
811 				opacity = 20;
812 			else if (opacity > 100)
813 				opacity = 100;
814 			argCount++;
815 			continue;
816 		}
817 
818 		if ((strcmp(argv[argCount], "-width") == 0) && (argCount < argc))
819 		{
820 			deswidth = atoi(argv[argCount + 1]);
821 			argCount++;
822 		}
823 
824 		if ((strcmp(argv[argCount], "-scale") == 0) && (argCount < argc))
825 		{
826 			if ((strcmp(argv[argCount + 1], "fs") == 0)
827 				|| (strcmp(argv[argCount + 1], "fullscreen") == 0))
828 			{
829 				aliastype = 5;
830 				scale = 100.0;
831 				argCount++;
832 				continue;
833 			}
834 			if ((scale = atof(argv[argCount + 1])) > 0)
835 			{
836 				if ((scale > 1.1) || (scale < 0.9))
837 					aliastype = 5;
838 				else
839 					aliastype = 0;
840 				argCount++;
841 				continue;
842 			}
843 			scale = 1.0;
844 		}
845 
846 		if (strcmp(argv[argCount], "-raise") == 0)
847 			rlflags &= ~BRIGHTON_SET_RAISE;
848 		if (strcmp(argv[argCount], "-lower") == 0)
849 			rlflags &= ~BRIGHTON_SET_LOWER;
850 
851 		if ((strcmp(argv[argCount], "-rotaryUD") == 0)
852 			|| (strcmp(argv[argCount], "-rud") == 0))
853 			rlflags |= BRIGHTON_ROTARY_UD;
854 
855 		if (strcmp(argv[argCount], "-autozoom") == 0)
856 		{
857 			azoom = 1;
858 			if (deswidth < 1)
859 				deswidth = 100;
860 		}
861 
862 		if ((strcmp(argv[argCount], "-ar") == 0) ||
863 			(strcmp(argv[argCount], "-nar") == 0) ||
864 			(strcmp(argv[argCount], "-aspect") == 0))
865 			nar = 1;
866 
867 		if (((strcmp(argv[argCount], "-gs") == 0) ||
868 			(strcmp(argv[argCount], "-grayscale") == 0) ||
869 			(strcmp(argv[argCount], "-greyscale") == 0)) && (argCount < argc))
870 		{
871 			gs = atoi(argv[argCount + 1]);
872 			argCount++;
873 		}
874 
875 		if ((strcmp(argv[argCount], "-detune") == 0) && (argCount < argc))
876 		{
877 			if (argCount < argc)
878 				global.synths->detune = atoi(argv[argCount + 1]);
879 			argCount++;
880 		}
881 
882 		if ((strcmp(argv[argCount], "-gain") == 0) && (argCount < argc))
883 		{
884 			if (argCount < argc)
885 				global.synths->gain = atoi(argv[argCount + 1]) * 128;
886 			argCount++;
887 		}
888 
889 		if ((strcmp(argv[argCount], "-pwd") == 0) && (argCount < argc))
890 		{
891 			if (argCount < argc)
892 				global.synths->pwd = atoi(argv[argCount + 1]);
893 			argCount++;
894 		}
895 /* Need to add in PitchWheel Depth (done), Find and Coarse tuning*/
896 
897 		if (strcmp(argv[argCount], "-neutral") == 0)
898 			global.synths->location = -1;
899 
900 		if ((strcmp(argv[argCount], "-load") == 0) && (argCount < argc))
901 		{
902 			if (argCount < argc)
903 				global.synths->location = atoi(argv[argCount + 1]);
904 
905 			global.synths->mbi = (global.synths->location / 1000) * 1000;
906 			global.synths->location = global.synths->location % 1000;
907 
908 			argCount++;
909 		}
910 
911 		/* SYSEX System ID */
912 		if ((strcmp(argv[argCount], "-sysid") == 0) && (argCount < argc))
913 		{
914 			unsigned int sysid = 0x534C6162, o = argCount + 1;
915 
916 			/*
917 			 * We will get 0x534C6162 for example
918 			 */
919 			if ((argv[o][0] == '0') || (argv[o][1] == 'x')
920 				|| (strlen(argv[o]) == 10))
921 			{
922 				sscanf(argv[o], "0x%x", &sysid);
923 				sysid &= 0x7f7f7f7f;
924 				bristolMidiOption(0, BRISTOL_NRP_SYSID_H, sysid >> 16);
925 				bristolMidiOption(0, BRISTOL_NRP_SYSID_L, sysid & 0x0000ffff);
926 				printf("fixing sysex system id at 0x%x\n", sysid);
927 			}
928 		}
929 
930 		if ((strcmp(argv[argCount], "-nrpcc") == 0) && (argCount < argc))
931 		{
932 			nrpcc = atoi(argv[argCount + 1]);
933 			printf("Reserving %i NRP controllers\n", nrpcc);
934 			argCount++;
935 		}
936 
937 		/* Master Bank Index */
938 		if ((strcmp(argv[argCount], "-mbi") == 0) && (argCount < argc))
939 		{
940 			int mbi;
941 
942 			if (argCount < argc)
943 				mbi = atoi(argv[argCount + 1]) * 1000;
944 
945 			if ((global.synths->mbi != 0) && (global.synths->mbi != mbi))
946 				printf("Master bank index and loaded memory conflict (%i/%i)\n",
947 					mbi/1000, global.synths->mbi/1000);
948 
949 			global.synths->mbi = mbi;
950 
951 			argCount++;
952 		}
953 
954 		if ((strcmp(argv[argCount], "-glide") == 0) && (argCount < argc))
955 		{
956 			if (argCount < argc)
957 				global.synths->glide = atoi(argv[argCount + 1]);
958 			if (global.synths->glide <= 0)
959 				global.synths->glide = 30;
960 			if (global.synths->glide > 30)
961 				global.synths->glide = 30;
962 			argCount++;
963 		}
964 
965 		if ((strcmp(argv[argCount], "-voices") == 0) && (argCount < argc))
966 		{
967 			if ((atoi(argv[argCount + 1]) > 0)
968 				&& ((global.synths->voices = atoi(argv[argCount + 1])) == 1)
969 				&& (global.synths->notepref == BRIGHTON_POLYPHONIC))
970 				global.synths->notepref = BRIGHTON_HNP;
971 			else if (atoi(argv[argCount + 1]) == 0)
972 				global.synths->voices = BRISTOL_VOICECOUNT;
973 			argCount++;
974 		}
975 
976 		if (strcmp(argv[argCount], "-mono") == 0)
977 		{
978 			global.synths->voices = 1;
979 			global.synths->notepref = BRIGHTON_HNP;
980 		}
981 
982 		if (strcmp(argv[argCount], "-localforward") == 0)
983 			global.synths->flags &= ~REQ_LOCAL_FORWARD;
984 		if (strcmp(argv[argCount], "-remoteforward") == 0)
985 			global.synths->flags &= ~REQ_REMOTE_FORWARD;
986 		if (strcmp(argv[argCount], "-forward") == 0)
987 			global.synths->flags
988 				&= ~(REQ_FORWARD|REQ_LOCAL_FORWARD|REQ_REMOTE_FORWARD);
989 
990 		if (strcmp(argv[argCount], "-mididbg2") == 0)
991 			global.synths->flags |= REQ_MIDI_DEBUG2;
992 		if ((strcmp(argv[argCount], "-mididbg") == 0)
993 			|| (strcmp(argv[argCount], "-mididbg1") == 0))
994 			global.synths->flags |= REQ_MIDI_DEBUG;
995 
996 		if (strcmp(argv[argCount], "-debug") == 0)
997 		{
998 			if ((argCount < argc) && (argv[argCount + 1][0] != '-'))
999 			{
1000 				int i;
1001 
1002 				if ((i = atoi(argv[argCount + 1])) > 15)
1003 					global.synths->flags |= REQ_DEBUG_MASK;
1004 				else {
1005 					global.synths->flags &= ~REQ_DEBUG_MASK;
1006 					global.synths->flags |= (i << 12);
1007 				}
1008 			} else {
1009 				/*
1010 				 * If we only have -debug and no value then increment the debug
1011 				 * level.
1012 				 */
1013 				global.synths->flags = (global.synths->flags & ~REQ_DEBUG_MASK)
1014 					| (((global.synths->flags & REQ_DEBUG_MASK) + REQ_DEBUG_1)
1015 						& REQ_DEBUG_MASK);
1016 			}
1017 
1018 			if (global.synths->flags & REQ_DEBUG_MASK)
1019 				printf("debuging level set to %i\n",
1020 					(global.synths->flags&REQ_DEBUG_MASK)>>12);
1021 		}
1022 
1023 		if (strcmp(argv[argCount], "-gnrp") == 0)
1024 			global.synths->flags ^= GUI_NRP;
1025 		if (strcmp(argv[argCount], "-enrp") == 0)
1026 			global.synths->flags ^= MIDI_NRP;
1027 		if (strcmp(argv[argCount], "-nrp") == 0)
1028 			global.synths->flags |= MIDI_NRP|GUI_NRP;
1029 
1030 		if ((strcmp(argv[argCount], "-channel") == 0) && (argCount < argc))
1031 		{
1032 			if (argCount < argc)
1033 				global.synths->midichannel = atoi(argv[argCount + 1]) - 1;
1034 			argCount++;
1035 		}
1036 
1037 		if (((strcmp(argv[argCount], "-velocity") == 0)
1038 			|| (strcmp(argv[argCount], "-curve") == 0)
1039 			|| (strcmp(argv[argCount], "-mvc") == 0))
1040 			&& (argCount < argc))
1041 		{
1042 			if (argCount < argc)
1043 				global.synths->velocity = atoi(argv[argCount + 1]);
1044 			argCount++;
1045 		}
1046 
1047 		if (strcmp(argv[argCount], "-tracking") == 0)
1048 		{
1049 			global.synths->flags |= NO_KEYTRACK;
1050 			argCount++;
1051 		}
1052 		if (strcmp(argv[argCount], "-keytoggle") == 0)
1053 			global.synths->flags &= ~NO_LATCHING_KEYS;
1054 
1055 		if (strcmp(argv[argCount], "-port") == 0)
1056 		{
1057 			if ((argCount < (argc - 1)) && (argv[argCount + 1] != NULL))
1058 				global.port = atoi(argv[argCount + 1]);
1059 			argCount++;
1060 		}
1061 
1062 		if (strcmp(argv[argCount], "-host") == 0)
1063 			snprintf(defaultcdev, 16, "%s", argv[++argCount]);
1064 
1065 		if (strcmp(argv[argCount], "-window") == 0)
1066 			synthesisers[global.synths->synthtype]->flags ^= BRIGHTON_WINDOW;
1067 
1068 		if (strcmp(argv[argCount], "-cli") == 0)
1069 		{
1070 			cli = 1;
1071 			brightonCLIinit(&global, cli_fd);
1072 			//synthesisers[global.synths->synthtype]->flags ^= BRIGHTON_WINDOW;
1073 		}
1074 
1075 		if (strcmp(argv[argCount], "-nwf") == 0)
1076 			global.synths->lwf = 0;
1077 		if (strcmp(argv[argCount], "-lwf") == 0)
1078 			global.synths->lwf = 1;
1079 		if (strcmp(argv[argCount], "-lwf2") == 0)
1080 			global.synths->lwf = 2;
1081 		if (strcmp(argv[argCount], "-wwf") == 0)
1082 			global.synths->lwf = 2;
1083 		if (strcmp(argv[argCount], "-hwf") == 0)
1084 			global.synths->lwf = 3;
1085 
1086 		if (strcmp(argv[argCount], "-lnp") == 0)
1087 			global.synths->notepref = BRIGHTON_LNP;
1088 		if (strcmp(argv[argCount], "-hnp") == 0)
1089 			global.synths->notepref = BRIGHTON_HNP;
1090 		if (strcmp(argv[argCount], "-nnp") == 0)
1091 			global.synths->notepref = BRIGHTON_POLYPHONIC;
1092 		if (strcmp(argv[argCount], "-retrig") == 0)
1093 			global.synths->notetrig = 1 - global.synths->notetrig;
1094 		if (strcmp(argv[argCount], "-lvel") == 0)
1095 			global.synths->legatovelocity = 1 - global.synths->legatovelocity;
1096 
1097 		/*
1098 		 * And finally all the different synths
1099 		 */
1100 		if ((strcmp(argv[argCount], "-mini") == 0)
1101 			||(strcmp(argv[argCount], "-minimoog") == 0))
1102 			global.synths->synthtype = BRISTOL_MINI;
1103 
1104 		if (strcmp(argv[argCount], "-hammond") == 0)
1105 			global.synths->synthtype = BRISTOL_HAMMONDB3;
1106 
1107 		if (strcmp(argv[argCount], "-prophet10") == 0)
1108 			global.synths->synthtype = BRISTOL_PROPHET10;
1109 
1110 		if ((strcmp(argv[argCount], "-pro1") == 0)
1111 			|| (strcmp(argv[argCount], "-proone") == 0)
1112 			|| (strcmp(argv[argCount], "-prophet1") == 0))
1113 		{
1114 			global.synths->synthtype = BRISTOL_PRO1;
1115 			opacity = 60;
1116 		}
1117 
1118 		if ((strcmp(argv[argCount], "-pro52") == 0)
1119 			|| (strcmp(argv[argCount], "-prophet52") == 0))
1120 			global.synths->synthtype = BRISTOL_PRO52;
1121 
1122 		if ((strcmp(argv[argCount], "-prophet") == 0)
1123 			|| (strcmp(argv[argCount], "-sequential") == 0)
1124 			|| (strcmp(argv[argCount], "-sequentialcircuits") == 0)
1125 			|| (strcmp(argv[argCount], "-prophet5") == 0))
1126 			global.synths->synthtype = BRISTOL_PROPHET;
1127 
1128 		if (strcmp(argv[argCount], "-prophet10") == 0)
1129 			global.synths->synthtype = BRISTOL_PROPHET10;
1130 
1131 		if (strcmp(argv[argCount], "-pro5") == 0)
1132 			global.synths->synthtype = BRISTOL_PROPHET;
1133 
1134 		if (strcmp(argv[argCount], "-pro10") == 0)
1135 		{
1136 			if (global.synths->detune == 0)
1137 				global.synths->detune = NON_DEF_DETUNE;
1138 			global.synths->synthtype = BRISTOL_PROPHET10;
1139 		}
1140 
1141 		if (strcmp(argv[argCount], "-dx") == 0)
1142 			global.synths->synthtype = BRISTOL_DX;
1143 
1144 		if (strcmp(argv[argCount], "-juno") == 0)
1145 			global.synths->synthtype = BRISTOL_JUNO;
1146 
1147 		if (strcmp(argv[argCount], "-cs80") == 0)
1148 		{
1149 			global.synths->synthtype = BRISTOL_CS80;
1150 			printf("The CS80 is not an operational emulator\n");
1151 			global.libtest = 1;
1152 		}
1153 
1154 		if ((strcmp(argv[argCount], "-jupiter8") == 0) ||
1155 			(strcmp(argv[argCount], "-uranus") == 0) ||
1156 			(strcmp(argv[argCount], "-jupiter") == 0))
1157 		{
1158 			if (global.synths->voices == BRISTOL_VOICECOUNT)
1159 				global.synths->voices = 8; /* Two 4 voice Jupiters */
1160 			if (global.synths->detune == 0)
1161 				global.synths->detune = NON_DEF_DETUNE;
1162 			global.synths->synthtype = BRISTOL_JUPITER8;
1163 			opacity = 40;
1164 		}
1165 
1166 		if (strcmp(argv[argCount], "-sampler") == 0)
1167 		{
1168 			global.synths->synthtype = BRISTOL_SAMPLER;
1169 			printf("The sampler is not an operational emulator\n");
1170 			global.libtest = 1;
1171 		}
1172 
1173 		if (strcmp(argv[argCount], "-bristol") == 0)
1174 			global.synths->synthtype = BRISTOL_BRISTOL;
1175 
1176 		if (strcmp(argv[argCount], "-voyager") == 0)
1177 			global.synths->synthtype = BRISTOL_EXPLORER;
1178 
1179 		if (strcmp(argv[argCount], "-sonic6") == 0)
1180 			global.synths->synthtype = BRISTOL_SONIC6;
1181 
1182 		if (strcmp(argv[argCount], "-explorer") == 0)
1183 			global.synths->synthtype = BRISTOL_EXPLORER;
1184 		if (strcmp(argv[argCount], "-voyager") == 0)
1185 			global.synths->synthtype = BRISTOL_VOYAGER;
1186 
1187 		if (strcmp(argv[argCount], "-mixer") == 0)
1188 		{
1189 			global.libtest = 1;
1190 			printf("The bristol mixer is not an operational emulator\n");
1191 			global.synths->synthtype = BRISTOL_MIXER;
1192 		}
1193 
1194 		if (strcmp(argv[argCount], "-rhodesbass") == 0)
1195 			global.synths->synthtype = BRISTOL_RHODES_BASS;
1196 		else if (strcmp(argv[argCount], "-rhodes") == 0)
1197 			global.synths->synthtype = BRISTOL_RHODES;
1198 
1199 		if (strcmp(argv[argCount], "-vox") == 0)
1200 			global.synths->synthtype = BRISTOL_VOX;
1201 
1202 		if ((strcmp(argv[argCount], "-voxm2") == 0)
1203 			|| (strcmp(argv[argCount], "-voxM2") == 0)
1204 			|| (strcmp(argv[argCount], "-vox300") == 0))
1205 			global.synths->synthtype = BRISTOL_VOXM2;
1206 
1207 		if (strcmp(argv[argCount], "-ddd") == 0)
1208 			global.synths->synthtype = BRISTOL_DDD;
1209 
1210 		if (strcmp(argv[argCount], "-b3") == 0)
1211 			global.synths->synthtype = BRISTOL_HAMMONDB3;
1212 
1213 		if (strcmp(argv[argCount], "-obxa") == 0)
1214 		{
1215 			if (global.synths->detune == 0)
1216 				global.synths->detune = NON_DEF_DETUNE;
1217 			global.synths->synthtype = BRISTOL_OBXA;
1218 			if (opacity == 40)
1219 				opacity = 60;
1220 		} else if (strcmp(argv[argCount], "-obx") == 0) {
1221 			if (global.synths->detune == 0)
1222 				global.synths->detune = NON_DEF_DETUNE;
1223 			global.synths->synthtype = BRISTOL_OBX;
1224 		}
1225 
1226 		if (strcmp(argv[argCount], "-moog") == 0)
1227 			global.synths->synthtype = BRISTOL_MINI;
1228 
1229 		if (strcmp(argv[argCount], "-arp") == 0)
1230 			global.synths->synthtype = BRISTOL_2600;
1231 
1232 		if (strcmp(argv[argCount], "-roland") == 0)
1233 			global.synths->synthtype = BRISTOL_JUNO;
1234 
1235 		if (strcmp(argv[argCount], "-oberheim") == 0)
1236 			global.synths->synthtype = BRISTOL_OBXA;
1237 
1238 		if ((strcmp(argv[argCount], "-polysix") == 0)
1239 			|| (strcmp(argv[argCount], "-korg") == 0)
1240 			|| (strcmp(argv[argCount], "-poly6") == 0)
1241 			|| (strcmp(argv[argCount], "-poly") == 0))
1242 			global.synths->synthtype = BRISTOL_POLY6;
1243 
1244 		if (strcmp(argv[argCount], "-monopoly") == 0)
1245 			global.synths->synthtype = BRISTOL_POLY;
1246 
1247 		if (strcmp(argv[argCount], "-poly800") == 0)
1248 		{
1249 			global.synths->synthtype = BRISTOL_POLY800;
1250 			global.synths->voices = 8;
1251 		}
1252 
1253 		if (strcmp(argv[argCount], "-ms20") == 0)
1254 		{
1255 			global.synths->synthtype = BRISTOL_MS20;
1256 			printf("The ms20 is not an operational emulator\n");
1257 			global.libtest = 1;
1258 		}
1259 
1260 		if (strcmp(argv[argCount], "-bme700") == 0)
1261 		{
1262 			global.synths->synthtype = BRISTOL_BME700;
1263 			global.synths->voices = 1;
1264 			global.synths->notepref = BRIGHTON_HNP;
1265 		}
1266 
1267 		if ((strcmp(argv[argCount], "-bassmaker") == 0)
1268 			|| (strcmp(argv[argCount], "-bm") == 0))
1269 		{
1270 			global.synths->synthtype = BRISTOL_BASSMAKER;
1271 			global.synths->voices = 1;
1272 		}
1273 
1274 		if ((strcmp(argv[argCount], "-sid") == 0)
1275 			|| (strcmp(argv[argCount], "-sidney") == 0))
1276 		{
1277 			global.synths->synthtype = BRISTOL_SID_M1;
1278 			global.synths->voices = 1;
1279 			global.synths->notepref = BRIGHTON_LNP;
1280 			global.synths->notetrig = 1;
1281 			antialias = 0.5;
1282 			aliastype = 1;
1283 			opacity = 50;
1284 		}
1285 
1286 		if ((strcmp(argv[argCount], "-sid2") == 0)
1287 			|| (strcmp(argv[argCount], "-melbourne") == 0)
1288 			|| (strcmp(argv[argCount], "-canberra") == 0)
1289 			|| (strcmp(argv[argCount], "-perth") == 0)
1290 			|| (strcmp(argv[argCount], "-resid") == 0)
1291 			|| (strcmp(argv[argCount], "-asid") == 0)
1292 			|| (strcmp(argv[argCount], "-acid") == 0))
1293 		{
1294 			global.synths->synthtype = BRISTOL_SID_M2;
1295 			global.synths->voices = 1;
1296 			global.synths->notepref = BRIGHTON_HNP;
1297 			global.synths->notetrig = 1;
1298 			antialias = 0.5;
1299 			aliastype = 1;
1300 			opacity = 50;
1301 		}
1302 
1303 		if (strcmp(argv[argCount], "-arp2600") == 0)
1304 			global.synths->synthtype = BRISTOL_2600;
1305 		if (strcmp(argv[argCount], "-2600") == 0)
1306 			global.synths->synthtype = BRISTOL_2600;
1307 
1308 		if (strcmp(argv[argCount], "-axxe") == 0)
1309 			global.synths->synthtype = BRISTOL_AXXE;
1310 
1311 		if (strcmp(argv[argCount], "-odyssey") == 0)
1312 			global.synths->synthtype = BRISTOL_ODYSSEY;
1313 
1314 		if (strcmp(argv[argCount], "-solina") == 0)
1315 			global.synths->synthtype = BRISTOL_SOLINA;
1316 
1317 		if (strcmp(argv[argCount], "-roadrunner") == 0)
1318 			global.synths->synthtype = BRISTOL_ROADRUNNER;
1319 
1320 		if ((strcmp(argv[argCount], "-memory") == 0)
1321 			|| (strcmp(argv[argCount], "-memmoog") == 0)
1322 			|| (strcmp(argv[argCount], "-memorymoog") == 0))
1323 			global.synths->synthtype = BRISTOL_MEMMOOG;
1324 
1325 		if ((strcmp(argv[argCount], "-mas") == 0)
1326 			|| (strcmp(argv[argCount], "-ems") == 0)
1327 			|| (strcmp(argv[argCount], "-aks") == 0))
1328 		{
1329 			global.synths->synthtype = BRISTOL_SAKS;
1330 			printf("AKS is not an operational emulator\n");
1331 			global.libtest = 1;
1332 		}
1333 
1334 		if ((strcmp(argv[argCount], "-granular") == 0)
1335 			|| (strcmp(argv[argCount], "-quantum") == 0))
1336 		{
1337 			global.synths->synthtype = BRISTOL_GRANULAR;
1338 			printf("The granular is not an operational emulator\n");
1339 			global.libtest = 1;
1340 		}
1341 
1342 		if ((strcmp(argv[argCount], "-realistic") == 0)
1343 			|| (strcmp(argv[argCount], "-mg1") == 0))
1344 			global.synths->synthtype = BRISTOL_REALISTIC;
1345 
1346 #define BIT1_ACTIVE 200
1347 		/*
1348 		 * Also add some hacks for a bit-99, same algorithm but different
1349 		 * GUI template
1350 		 */
1351 		if ((strcmp(argv[argCount], "-bitone") == 0)
1352 			|| (strcmp(argv[argCount], "-crumar") == 0)
1353 			|| (strcmp(argv[argCount], "-bit01") == 0)
1354 			|| (strcmp(argv[argCount], "-bit1") == 0))
1355 		{
1356 			int i;
1357 
1358 			if (global.synths->detune == 0)
1359 				global.synths->detune = NON_DEF_DETUNE;
1360 			global.synths->synthtype = BRISTOL_BIT_ONE;
1361 
1362 			for (i = 68; i < 77; i++)
1363 				bit99App.resources[0].devlocn[i].flags |= BRIGHTON_WITHDRAWN;
1364 
1365 			if (opacity == 40)
1366 				opacity = 60;
1367 
1368 			bit99App.resources[0].devlocn[48].flags |= BRIGHTON_WITHDRAWN;
1369 			/*
1370 			 * Hide the stereo button
1371 			 */
1372 			bit99App.resources[0].devlocn[BIT1_ACTIVE + 2].flags
1373 				|= BRIGHTON_WITHDRAWN;
1374 			bit99App.resources[0].devlocn[BIT1_ACTIVE + 2].x = 50;
1375 			bit99App.resources[0].devlocn[BIT1_ACTIVE + 2].y = 50;
1376 			/* And add the unison button */
1377 			bit99App.resources[0].devlocn[BIT1_ACTIVE + 38].flags
1378 				&= ~BRIGHTON_WITHDRAWN;
1379 		}
1380 
1381 		/*
1382 		 * The bit-99 hack, same algorithm but different GUI template
1383 		 */
1384 		if (strcmp(argv[argCount], "-bit99") == 0)
1385 		{
1386 			synthesisers[BRISTOL_BIT_ONE] = &bit99App;
1387 			global.synths->synthtype = BRISTOL_BIT_ONE;
1388 			if (global.synths->detune == 0)
1389 				global.synths->detune = NON_DEF_DETUNE;
1390 
1391 			if (opacity == 40)
1392 				opacity = 60;
1393 			/*
1394 			 * Enable a few extra parameters.
1395 			bit99App.resources[0].devlocn[77].flags &= ~BRIGHTON_WITHDRAWN;
1396 			bit99App.resources[0].devlocn[78].flags &= ~BRIGHTON_WITHDRAWN;
1397 			bit99App.resources[0].devlocn[79].flags &= ~BRIGHTON_WITHDRAWN;
1398 			bit99App.resources[0].devlocn[80].flags &= ~BRIGHTON_WITHDRAWN;
1399 			 */
1400 			bit99App.resources[0].devlocn[12].flags &= ~BRIGHTON_WITHDRAWN;
1401 			bit99App.resources[0].devlocn[BIT1_ACTIVE - 1].flags
1402 				&= ~BRIGHTON_WITHDRAWN;
1403 			/* Show the stereo button */
1404 			bit99App.resources[0].devlocn[BIT1_ACTIVE + 2].flags
1405 				&= ~BRIGHTON_WITHDRAWN;
1406 			/* And remove the unison button */
1407 			bit99App.resources[0].devlocn[BIT1_ACTIVE + 38].flags
1408 				|= BRIGHTON_WITHDRAWN;
1409 		}
1410 
1411 		/*
1412 		 * The bit-99 black hack, same algorithm but different GUI template
1413 		 */
1414 		if ((strcmp(argv[argCount], "-bit99m2") == 0)
1415 			|| (strcmp(argv[argCount], "-bit100") == 0))
1416 		{
1417 			synthesisers[BRISTOL_BIT_ONE] = &bit100App;
1418 			global.synths->synthtype = BRISTOL_BIT_ONE;
1419 			if (global.synths->detune == 0)
1420 				global.synths->detune = NON_DEF_DETUNE;
1421 
1422 			if (opacity == 40)
1423 				opacity = 60;
1424 			/*
1425 			 * Enable a few extra parameters.
1426 			 */
1427 			bit100App.resources[0].devlocn[88].flags &= ~BRIGHTON_WITHDRAWN;
1428 //			bit100App.resources[0].devlocn[74].flags |= BRIGHTON_WITHDRAWN;
1429 //			bit100App.resources[0].devlocn[75].flags |= BRIGHTON_WITHDRAWN;
1430 //			bit100App.resources[0].devlocn[76].flags |= BRIGHTON_WITHDRAWN;
1431 			bit100App.resources[0].devlocn[78].flags &= ~BRIGHTON_WITHDRAWN;
1432 			bit100App.resources[0].devlocn[79].flags &= ~BRIGHTON_WITHDRAWN;
1433 			bit100App.resources[0].devlocn[80].flags &= ~BRIGHTON_WITHDRAWN;
1434 			bit100App.resources[0].devlocn[12].flags &= ~BRIGHTON_WITHDRAWN;
1435 			bit100App.resources[0].devlocn[199].flags &= ~BRIGHTON_WITHDRAWN;
1436 			/* Show the stereo button */
1437 			bit100App.resources[0].devlocn[BIT1_ACTIVE + 2].flags
1438 				&= ~BRIGHTON_WITHDRAWN;
1439 			/* And remove the unison button */
1440 			bit100App.resources[0].devlocn[BIT1_ACTIVE + 38].flags
1441 				|= BRIGHTON_WITHDRAWN;
1442 			bit100App.resources[0].devlocn[BIT1_ACTIVE - 5].flags
1443 				|= BRIGHTON_CHECKBUTTON;
1444 		}
1445 
1446 		if (strcmp(argv[argCount], "-trilogy") == 0)
1447 		{
1448 			global.synths->synthtype = BRISTOL_TRILOGY;
1449 			global.synths->detune = 150;
1450 			opacity = 60;
1451 		}
1452 
1453 		if (strcmp(argv[argCount], "-stratus") == 0)
1454 		{
1455 			global.synths->synthtype = BRISTOL_STRATUS;
1456 			global.synths->detune = 150;
1457 			opacity = 60;
1458 		}
1459 
1460 		argCount++;
1461 	}
1462 
1463 	if (strncmp("unix:", defaultcdev, 5) == 0)
1464 	{
1465 		if (strlen(defaultcdev) == 5)
1466 			snprintf(defaultcdev, 16, "unix:%i", global.port);
1467 		else
1468 			global.port = atoi(&defaultcdev[5]);
1469 	}
1470 
1471 #ifndef BRIGHTON_HAS_X11
1472 	/* Reverse the window logic */
1473 	synthesisers[global.synths->synthtype]->flags ^= BRIGHTON_WINDOW;
1474 #endif
1475 
1476 	if (reqW)
1477 	{
1478 		/* Width is a scaler */
1479 		float scale;
1480 
1481 		scale = ((float) reqW) / synthesisers[global.synths->synthtype]->width;
1482 
1483 		/* Have been given some width value */
1484 		if (reqH)
1485 		{
1486 			nar = 1;
1487 			synthesisers[global.synths->synthtype]->width = reqW;
1488 			synthesisers[global.synths->synthtype]->height = reqH;
1489 		} else {
1490 			synthesisers[global.synths->synthtype]->width = reqW;
1491 			synthesisers[global.synths->synthtype]->height *= scale;
1492 		}
1493 
1494 		if ((scale > 1.1) || (scale < 0.9))
1495 			aliastype = 5;
1496 		else
1497 			aliastype = 0;
1498 	}
1499 
1500 	{
1501 		char statfile[1024];
1502 		struct stat statres;
1503 
1504 		sprintf(statfile, "%s/%s.gz", getenv("BRISTOL"),
1505 			synthesisers[global.synths->synthtype]->resources[0].image);
1506 
1507 		if ((synthesisers[global.synths->synthtype]->resources[0].image != 0) &&
1508 			(stat(statfile, &statres) != 0))
1509 		{
1510 			sprintf(statfile, "%s/%s", getenv("BRISTOL"),
1511 				synthesisers[global.synths->synthtype]->resources[0].image);
1512 
1513 			if (stat(statfile, &statres) != 0)
1514 			{
1515 				printf("unknown emulator\n");
1516 				sleep(1);
1517 				exit(-1);
1518 			}
1519 		}
1520 	}
1521 
1522 	if (readMe) {
1523 		printBrightonHelp(global.synths->synthtype);
1524 		exit(0);
1525 	}
1526 
1527 	printf("brighton version %s\n", VERSION);
1528 
1529 	sleep(1);
1530 
1531 	printf("  %s", argv[0]);
1532 	for (i = 1; i < argc; i++) {
1533 		if (argv[i][0] == '-')
1534 			printf("\n    %s", argv[i]);
1535 		else
1536 			printf(" %s", argv[i]);
1537 	}
1538 	printf("\n");
1539 
1540 	/*
1541 	 * Hm, this is a joke really. The Tandy, Realistic, whatever, is an old
1542 	 * synth and this mimics random slider changes. Should not really do it
1543 	 * but its fun: the original used to lose its white caps. Once the gui is
1544 	 * created its more work to change the image.
1545 	 */
1546 	if (global.synths->synthtype == BRISTOL_REALISTIC)
1547 	{
1548 		int cont, i;
1549 		struct timeval now;
1550 
1551 		gettimeofday(&now, NULL);
1552 
1553 		srand(now.tv_usec);
1554 
1555 		for (i = 0; i < 6; i++)
1556 		{
1557 			cont = rand() & 0x01f;
1558 			if (synthesisers[BRISTOL_REALISTIC]->resources[0].devlocn[cont].device
1559 				== 1)
1560 			{
1561 				synthesisers[BRISTOL_REALISTIC]->resources[0].devlocn[cont].image
1562 					= "bitmaps/knobs/knob8.xpm";
1563 			}
1564 		}
1565 	}
1566 
1567 	if (synthesisers[global.synths->synthtype] == 0)
1568 		exit(0);
1569 
1570 	global.synths->resources = synthesisers[global.synths->synthtype];
1571 
1572 	synthesisers[global.synths->synthtype]->width *= scale;
1573 	synthesisers[global.synths->synthtype]->height *= scale;
1574 
1575 	/*
1576 	 * Finally go and let the event manager handle our interface. Going to
1577 	 * create a separate GUI thread, which will allow us to handle things like
1578 	 * MIDI events from the engine, timed operations, etc, from there.
1579 	 */
1580 	if (pthread_create(&emgrThread, NULL, eventMgr, &global) != 0)
1581 		printf("Could not create GUI thread\n");
1582 
1583 	/*
1584 	 * We should not detach the thread, we should wait for it later before exit
1585 	if (pthread_detach(thread) != 0)
1586 		printf("Could not detach GUI thread\n");
1587 	 */
1588 
1589 	/*
1590 	 * win is actually set by the configuration routines, but we use it
1591 	 * here anyway. The configuration options are a structure, they were a
1592 	 * list of parameters however that became unwieldy.
1593 	 */
1594 	if ((global.synths->flags & REQ_DEBUG_MASK) >= (REQ_DEBUG_4|REQ_DEBUG_1))
1595 		aliastype |= BRIGHTON_LIB_DEBUG;
1596 	synthesisers[global.synths->synthtype]->flags |= bwflags;
1597 
1598 	/*
1599 	 * We play around with the names here so that the window title gets filled
1600 	 * with more information than just the emulator name. This enhancement was
1601 	 * added for JSM but could be any Jack installation. If multiple instances
1602 	 * of the same emulator are started then it is not clear which is which:
1603 	 * both have the same title bar but different names in Jack. What we do here
1604 	 * is add the Jack registration name to the title bar.
1605 	 */
1606 	snprintf(appname, 64, "%s (%s)",
1607 		synthesisers[global.synths->synthtype]->name, devname);
1608 	devname = synthesisers[global.synths->synthtype]->name;
1609 	synthesisers[global.synths->synthtype]->name = appname;
1610 	if ((global.synths->win =
1611 		brightonInterface(synthesisers[global.synths->synthtype],
1612 			quality, library, aliastype, antialias, gs, reqX, reqY)) == NULL)
1613 	{
1614 		printf("could not create window\n");
1615 		exit(-1);
1616 	}
1617 	synthesisers[global.synths->synthtype]->name = devname;
1618 	global.synths->resources->name = devname;
1619 
1620 	/*
1621 	 * We now need to decide which memory to load. There are a few choices.
1622 	 * If we had a LADI declaration it will have been copied to both ladimem
1623 	 * and to the emulator memory. If they are still the same then use it.
1624 	 *
1625 	 * If the emulator location has change then we should look and see if the
1626 	 * LADI memory actually exists, if so, use it (overwrite the emulator
1627 	 * memory location again). If it does not exist we will then continue to
1628 	 * access the emulator memory and it becomes the template for the eventual
1629 	 * LADI state information.
1630 	 */
1631 	if ((global.synths->flags & LADI_ENABLE) &&
1632 		(global.synths->ladimem
1633 			!= (global.synths->location + global.synths->mbi)))
1634 	{
1635 		int memHold = global.synths->location + global.synths->mbi;
1636 
1637 		global.synths->mbi = 0;
1638 		global.synths->location = global.synths->ladimem;
1639 
1640 		/* Location has changed. Stat the ladimem */
1641 		if (loadMemory(global.synths, global.synths->resources->name, 0,
1642 			global.synths->ladimem,
1643 			global.synths->mem.active, 0, BRISTOL_STAT) < 0)
1644 		{
1645 			/* No LADI mem */
1646 			global.synths->location = memHold;
1647 
1648 			global.synths->mbi = (global.synths->location / 1000) * 1000;
1649 			global.synths->location = global.synths->location % 1000;
1650 
1651 			printf("did not find LADI memory %i, using %i\n",
1652 				global.synths->ladimem, memHold);
1653 		} else
1654 			printf("using LADI state memory %i\n", global.synths->ladimem);
1655 	}
1656 
1657 	if (global.flags & REQ_EXIT)
1658 	{
1659 		printf("early termination logging thread (%i)\n", global.controlfd);
1660 
1661 		bristolOpenStdio(BRISTOL_LOG_TERMINATE);
1662 
1663 		if ((logthread != 0) && (pthread_join(logthread, NULL) != 0))
1664 			return(1);
1665 
1666 		exit(global.controlfd < 0? 1: 0);
1667 	}
1668 
1669 	global.synths->win->dcTimeout = dcTimeout;
1670 
1671 	global.synths->win->flags |= rlflags;
1672 
1673 	if (azoom) {
1674 		global.synths->win->flags |= BRIGHTON_AUTOZOOM;
1675 
1676 		if (deswidth >= 100)
1677 		{
1678 			global.synths->win->minw = deswidth;
1679 			global.synths->win->minh =
1680 				deswidth * global.synths->win->template->height
1681 				/ global.synths->win->template->width;
1682 			global.synths->win->maxw =
1683 				synthesisers[global.synths->synthtype]->width * scale;
1684 			global.synths->win->maxh =
1685 				synthesisers[global.synths->synthtype]->height * scale;
1686 		} else {
1687 			global.synths->win->minw
1688 				= global.synths->win->maxw
1689 				= global.synths->win->minh
1690 				= global.synths->win->maxh = 0;
1691 		}
1692 	}
1693 	if (nar)
1694 		global.synths->win->flags |= BRIGHTON_NO_ASPECT;
1695 
1696 	brightonOpacity(global.synths->win, ((float) opacity) / 100.0f);
1697 
1698 	/*
1699 	 * These should be synth specific?
1700 	 */
1701 	for (i = 0; i < 128; i++)
1702 	{
1703 		global.synths->win->midimap[i] = i;
1704 
1705 		for (j = 0; j < 128; j++)
1706 			global.synths->win->valuemap[i][j] = j;
1707 	}
1708 
1709 	printf("user r %i/%i, e %i/%i\n", getuid(), getgid(), geteuid(), getegid());
1710 
1711 	global.synths->win->nrpcount = nrpcc;
1712 	global.synths->win->nrpcontrol =
1713 		malloc(sizeof(brightonNRPcontrol) * nrpcc);
1714 	memset(global.synths->win->nrpcontrol, 0,
1715 		sizeof(brightonNRPcontrol) * nrpcc);
1716 
1717 	brightonReadConfiguration(global.synths->win,
1718 		synthesisers[global.synths->synthtype],
1719 		global.synths->midichannel,
1720 		synthesisers[global.synths->synthtype]->name,
1721 		NULL);
1722 
1723 	if (bristolMidiSendMsg(global.controlfd, global.synths->sid,
1724 		BRISTOL_ACTIVE_SENSE, 0, activeSense == 0? 0:16383) != 0)
1725 	{
1726 		printf("Active sense transmit failure\n");
1727 		sleep(1);
1728 		exit(1);
1729 	} if (global.synths->flags & REQ_MIDI_DEBUG)
1730 		printf("Sent Active sense\n");
1731 
1732 	if ((global.synths->sid2 > 0) &&
1733 		(bristolMidiSendMsg(global.manualfd, global.synths->sid2,
1734 			BRISTOL_ACTIVE_SENSE, 0, activeSense == 0? 0:16383) != 0))
1735 	{
1736 		printf("Active sense transmit failure\n");
1737 		sleep(1);
1738 		exit(1);
1739 	} if (global.synths->flags & REQ_MIDI_DEBUG)
1740 		printf("Sent Active sense on second channel\n");
1741 
1742 	emStart = 1;
1743 
1744 	if (global.libtest != 1)
1745 	{
1746 		if (global.synths->flags & REQ_FORWARD)
1747 			bristolMidiOption(0, BRISTOL_NRP_FORWARD, 1);
1748 
1749 		if (global.synths->flags & NO_KEYTRACK)
1750 			bristolMidiOption(0, BRISTOL_NRP_MIDI_GO, 0);
1751 		else
1752 			bristolMidiOption(0, BRISTOL_NRP_MIDI_GO, 1);
1753 
1754 		/*
1755 		 * The Hammond needs a note event on the upper manual to kick the
1756 		 * gearbox into action.
1757 		 */
1758 		if (global.synths->synthtype == BRISTOL_HAMMONDB3)
1759 		{
1760 			sleep(1);
1761 			bristolMidiSendMsg(global.controlfd, global.synths->midichannel,
1762 				BRISTOL_EVENT_KEYON, 0, 10 + global.synths->transpose);
1763 			usleep(50000);
1764 			bristolMidiSendMsg(global.controlfd, global.synths->midichannel,
1765 				BRISTOL_EVENT_KEYOFF, 0, 10 + global.synths->transpose);
1766 		}
1767 	}
1768 
1769 	/* if we are CLI, somebody needs to force this to happen */
1770 	if (synthesisers[global.synths->synthtype]->flags & BRIGHTON_WINDOW)
1771 		brightonWorldChanged(global.synths->win, 500, 500);
1772 
1773 	/*
1774 	if (cli == 0)
1775 	{
1776 		close(cli_fd[0]);
1777 		close(cli_fd[1]);
1778 	}
1779 	*/
1780 
1781 	while (~global.flags & REQ_EXIT)
1782 	{
1783 		/*
1784 		 * Do whatever we want. Will turn into a wait routine on the MIDI
1785 		 * channel. This could be merged with the UI heartbeat code.
1786 		 */
1787 		if (cli) {
1788 			if (brightonCLIcheck(&global) < 0)
1789 				cleanupBristol();
1790 		}
1791 		/*
1792 		 * This was never operational anyway:
1793 		if (vuInterval != 0) {
1794 			usleep(vuInterval);
1795 			if (global.synths->flags & OPERATIONAL)
1796 				doAlarm();
1797 		} else if (cli == 0)
1798 		 */
1799 		else
1800 			sleep(1);
1801 	}
1802 
1803 	if (pthread_join(emgrThread, NULL) != 0)
1804 		printf("brighton event thread exit error\n");
1805 	else
1806 		printf("brighton event thread exited\n");
1807 
1808 	/* Now that the event manager thread has exit, put key repeat back on */
1809 	BAutoRepeat(global.synths->win->display, 1);
1810 
1811 	printf("terminating logging thread (%i)\n", global.controlfd);
1812 
1813 	if (global.libtest == 0)
1814 		sleep(1);
1815 
1816 	bristolOpenStdio(BRISTOL_LOG_TERMINATE);
1817 
1818 	if ((logthread != 0) && (pthread_join(logthread, NULL) != 0))
1819 		return(1);
1820 
1821 	exit(global.controlfd < 0? 1: 0);
1822 }
1823 
1824 void *
eventMgr()1825 eventMgr()
1826 {
1827 	bristolMidiMsg msg;
1828 	int i = 50, r;
1829 	int midiFD, cFD;
1830 
1831 	/* This will send activesense as soon as the interface initialises */
1832 	asc = activeSense * 4;
1833 
1834 	printf("starting event management thread\n");
1835 
1836 	if (global.libtest == 0)
1837 	{
1838 		while (global.controlfd < 0)
1839 		{
1840 			usleep(100000);
1841 
1842 			if (i-- < 0)
1843 			{
1844 				global.flags |= REQ_EXIT;
1845 				pthread_exit(0);
1846 			}
1847 		}
1848 
1849 		/*
1850 		 * Here we should open an ALSA SEQ interface. We want to get an index
1851 		 * back and pass that to the event handler for selection. This should
1852 		 * not really be a SEQ interface, it should depend on the flags given
1853 		 * to the GUI.
1854 		 */
1855 		if (gmc)
1856 		{
1857 			if ((midiHandle = bristolMidiOpen("brighton",
1858 				BRISTOL_CONN_SEQ|BRISTOL_RDONLY,
1859 				-1, -1, brightonMidiInput, &global)) < 0)
1860 				printf("Error opening midi device %s\n", "0.0");
1861 		}
1862 	}
1863 
1864 	while (global.synths->win == NULL)
1865 	{
1866 		usleep(100000);
1867 		printf("waiting for window creation\n");
1868 	}
1869 
1870 	midiFD = bristolGetMidiFD(midiHandle);
1871 	cFD = bristolGetMidiFD(global.controlfd);
1872 
1873 	printf("opened GUI midi handles: %i, %i\n", midiFD, cFD);
1874 
1875 /*
1876 	if (global.libtest != 1)
1877 	{
1878 		if (global.synths->flags & REQ_FORWARD)
1879 			bristolMidiOption(0, BRISTOL_NRP_FORWARD, 1);
1880 
1881 		if (global.synths->flags & NO_KEYTRACK)
1882 			bristolMidiOption(0, BRISTOL_NRP_MIDI_GO, 0);
1883 		else
1884 			bristolMidiOption(0, BRISTOL_NRP_MIDI_GO, 1);
1885 
1886 		bristolMidiSendMsg(global.controlfd, global.synths->midichannel,
1887 			BRISTOL_EVENT_KEYON, 0, 10 + global.synths->transpose);
1888 		bristolMidiSendMsg(global.controlfd, global.synths->midichannel,
1889 			BRISTOL_EVENT_KEYOFF, 0, 10 + global.synths->transpose);
1890 	}
1891 */
1892 
1893 	while ((global.flags & REQ_EXIT) == 0) {
1894 		if (emStart)
1895 			i = brightonEventMgr();
1896 		else
1897 			i = 0;
1898 
1899 		/*
1900 		 * This will now become a select on the ALSA SEQ socket looking for
1901 		 * MIDI events. Not certain how they will be linked into the GUI at
1902 		 * the moment. For now this is just a sleep until the ALSA SEQ interface
1903 		 * registration code has been finalised.
1904 		 *
1905 		 * What we will be looking for are events on a MIDI channel, we will
1906 		 * look for that MIDI channel in our window lists. We want to respond
1907 		 * to key events and reflect that in the GUI optionally, but not send
1908 		 * the key events since the engine will handle all those. We also want
1909 		 * to look for controller values and have some configurable method to
1910 		 * link those to our controls. Now this linkage will be done via the
1911 		 * GUI, preferably, with the <Control><Middle Mouse><MIDI CC # motion>.
1912 		 * Since the GUI handles this then we can dispatch events to another
1913 		 * module that does the linkage. Need to be able to save and retrieve
1914 		 * configurations - <Control><Middle> will go to this module, and all
1915 		 * MIDI controller events as well, and it will make the linkage and
1916 		 * dispatch the events.
1917 		 *
1918 		 * We should try and have a vkeydb type X event keymap.
1919 		 *
1920 		 * With certain intense events the activeSensing can fail, most notably
1921 		 * with window resizing. Since 0.30.8 only a single window configure
1922 		 * event is handled in any one pass of the event list to reduce this
1923 		 * effect.
1924 		 *
1925 		 * This would perform better if X would give me its socket descriptors
1926 		 * for a select operation. We should look at some point in putting
1927 		 * this into a separate thread and using a semaphore since the 'busy'
1928 		 * waiting is ugly.
1929 		 *
1930 		 * We should also look into separating the MIDI and GUI threads more,
1931 		 * it would require a bit of internal signalling to prevent both wanting
1932 		 * X Server access at the same time.
1933 		 */
1934 		 /*
1935 		  * CHANGE TO READ ON EVERY OPENED HANDLE
1936 		bristolMidiDevRead(cFD, &msg);
1937 		bristolMidiDevRead(2, &msg);
1938 		  */
1939 		while ((r = bristolMidiDevRead(midiFD, &msg)) > 0)
1940 			;
1941 
1942 		if (r == BRISTOL_MIDI_CHANNEL)
1943 		{
1944 			if ((global.synths->flags & REQ_DEBUG_MASK) >= REQ_DEBUG_4)
1945 				printf("Read failed on Midi FD\n");
1946 			global.flags |= REQ_EXIT;
1947 
1948 			pthread_exit(0);
1949 		}
1950 
1951 		while ((r = bristolMidiTCPRead(&msg)) > 0)
1952 			;
1953 
1954 		if ((r < 0) && (global.libtest == 0))
1955 		{
1956 			if ((global.synths->flags & REQ_DEBUG_MASK) >= REQ_DEBUG_4)
1957 				printf("Read failed on TCP fd (no devices?)\n");
1958 			global.flags |= REQ_EXIT;
1959 
1960 			pthread_exit(0);
1961 		}
1962 
1963 		if (i == 0)
1964 			usleep(mwt);
1965 
1966 		/*
1967 		 * We should have some 'tack' in here where we call a routine in the
1968 		 * library that will execute any timed events that have been requested,
1969 		 * this will cover things like flashing lights, VU metering. It will
1970 		 * also be used to cover the midi sequencer.
1971 		 *
1972 		 * We should also attempt to recover lost time in graphical processing
1973 		 * by changing mwt into a target sleep period by getting the current
1974 		 * time and looking at the ms delta.
1975 		 */
1976 		brightonFastTimer(0, 0, 0, BRIGHTON_FT_CLOCK, mwt / 1000);
1977 
1978 		if ((activeSense > 0) && ((asc -= mwt / 1000) < 0) && (emStart))
1979 		{
1980 			asc = activeSense;
1981 
1982 			/*
1983 			 * Hm, this is wrong, we should scan the whole synths list but for
1984 			 * now we actually need to send one for each emulation, dual manual
1985 			 * and all that.
1986 			 * The check on send status is not really necessary, we will
1987 			 * probably end up seeing the SIGPIPE handler have us exit if the
1988 			 * socket closes at the remote end.
1989 			 */
1990 			if (bristolMidiSendMsg(global.controlfd, global.synths->sid,
1991 				BRISTOL_ACTIVE_SENSE, 0, activeSensePeriod) != 0)
1992 			{
1993 				printf("Active sense transmit failure\n");
1994 				sleep(1);
1995 				exit(1);
1996 			}
1997 			if ((global.synths->sid2 > 0) &&
1998 				(bristolMidiSendMsg(global.manualfd, global.synths->sid2,
1999 					BRISTOL_ACTIVE_SENSE, 0, activeSensePeriod) != 0))
2000 			{
2001 				printf("Active sense transmit failure\n");
2002 				sleep(1);
2003 				exit(1);
2004 			}
2005 
2006 			if ((ladiRequest == 1) && global.synths->flags & LADI_ENABLE) {
2007 				int memHold = global.synths->cmem;
2008 
2009 				ladiRequest = 0;
2010 
2011 				printf("LADI save state signalled\n");
2012 
2013 				global.synths->cmem = global.synths->ladimem;
2014 				brightonControlKeyInput(global.synths->win, 's', 0);
2015 
2016 				global.synths->cmem = memHold;
2017 			}
2018 
2019 			if ((ladiRequest == 2) && global.synths->flags & LADI_ENABLE) {
2020 				int memHold = global.synths->cmem;
2021 
2022 				ladiRequest = 0;
2023 
2024 				printf("LADI load state signalled\n");
2025 
2026 				global.synths->cmem = global.synths->ladimem;
2027 				brightonControlKeyInput(global.synths->win, 'l', 0);
2028 
2029 				global.synths->cmem = memHold;
2030 			}
2031 
2032 			/*
2033 			 * We are going to piggyback the slow event timer onto this code.
2034 			 * It means the slow events will be related to the activeSensing
2035 			 * but if anybody has issues due to changing AS or its timers we
2036 			 * can review it at that time.
2037 			 */
2038 			brightonSlowTimer(0, 0, BRIGHTON_ST_CLOCK);
2039 		}
2040 	}
2041 
2042 	printf("brighton event manager thread exiting\n");
2043 
2044 	global.flags |= REQ_EXIT;
2045 
2046 	pthread_exit(0);
2047 }
2048 
2049 void
cleanout(void * id)2050 cleanout(void *id)
2051 {
2052 	if (id)
2053 		brightonRemoveInterface(id);
2054 	cleanupBristol();
2055 	exit(4);
2056 }
2057 
2058 void
clearout(int result)2059 clearout(int result)
2060 {
2061 	/*
2062 	 * This is not the right way to do things. We should request an exit and
2063 	 * let all the processes do their work. The issue here is that this can
2064 	 * get called very early in the window creation process which causes other
2065 	 * issues if we try to close down nicely. A better option here would be
2066 	 * to assert the result is '0'. That way we get a nice core memory dump
2067 	 * to debug under other circumstances.
2068 	 */
2069 	printf("clearing out via early exit\n");
2070 	exit(result);
2071 }
2072 
2073 void
printBrightonHelp(int synth)2074 printBrightonHelp(int synth)
2075 {
2076 	if ((synth >= BRISTOL_SYNTHCOUNT) || (readme[synth] == NULL))
2077 		return;
2078 
2079 	printf("\n%s\n", readme[synth]);
2080 }
2081 
2082 void
printBrightonReadme()2083 printBrightonReadme()
2084 {
2085 	int i;
2086 
2087 	printf("\n%s\n\n\n", readmeheader);
2088 	for (i = 0; i < BRISTOL_SYNTHCOUNT; i++)
2089 	{
2090 		if ((synthesisers[i] != NULL) && (readme[i] != NULL))
2091 			printf("%s\n\n\n", readme[i]);
2092 	}
2093 	printf("\n%s\n", readmetrailer);
2094 	printf("%s", helptext);
2095 }
2096 
2097