1 
2 /*
3  *  Diverse Bristol audio routines.
4  *  Copyright (c) by Nick Copeland <nickycopeland@hotmail.com> 1996,2012
5  *
6  *
7  *   This program is free software; you can redistribute it and/or modify
8  *   it under the terms of the GNU General Public License as published by
9  *   the Free Software Foundation; either version 3 of the License, or
10  *   (at your option) any later version.
11  *
12  *   This program is distributed in the hope that it will be useful,
13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *   GNU General Public License for more details.
16  *
17  *   You should have received a copy of the GNU General Public License
18  *   along with this program; if not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 /*
23  * This file was taken out of the engine and moved to the audio library where
24  * it correctly lies however it incorporates a few flags from bristol.h header
25  * file that should really be removed to keep them independent. That is for
26  * later study.
27  */
28 
29 /*#define DEBUG */
30 
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <unistd.h>
34 #include <fcntl.h>
35 #include <signal.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 
40 #ifdef _BRISTOL_JACK
41 #if (BRISTOL_HAS_ALSA == 1)
42 #include <alsa/iatomic.h>
43 #endif
44 
45 /*
46  * Drop this atomic stuff, it comes from the ALSA library and it not present on
47  * a lot of systems. It is failing the Debian hurdles on some pretty wild host
48  * architectures admittedly. Now the benefits of a real atomic access here are
49  * small: there is one writer changing a value from 1 to zero. There is one
50  * reader waiting for it to be zero, even as a non-atomic operation the worst
51  * this can do is delay detection by a period.
52  */
53 #ifdef DONT_USE_THIS //IATOMIC_DEFINED // Not very portable
54 atomic_t closedown = ATOMIC_INIT(1);
55 #else
56 int closedown = 1;
57 #endif
58 
59 #include "bristol.h"
60 #include "bristoljack.h"
61 
62 #ifdef _BRISTOL_JACK_SESSION
63 #include <jack/session.h>
64 char sessionfile[1024];
65 char commandline[1024];
66 #endif
67 
68 extern int dupfd;
69 static char defreg[8] = "bristol";
70 static char *regname = defreg;
71 
72 static jackDev jackdev;
73 static float *outbuf, *inbuf;
74 
75 static int fsize = sizeof(jack_default_audio_sample_t);
76 
77 #ifdef _BRISTOL_JACK_MIDI
78 extern void bristolJackSetMidiHandle(jack_client_t *);
79 extern int jackMidiRoutine(jack_nframes_t, void *);
80 #endif
81 
82 static void
jack_shutdown(void * jackdev)83 jack_shutdown(void *jackdev)
84 {
85 	((jackDev *) jackdev)->audiomain->atReq = BRISTOL_REQSTOP;
86 }
87 
88 #ifdef _BRISTOL_JACK_SESSION
89 /*
90  * This is polled by the GUI to see if any session events need handling. It is
91  * called fromm the idle loop of the engine parent thread.
92  */
93 int
bristolJackSessionCheck(audioMain * audiomain)94 bristolJackSessionCheck(audioMain *audiomain)
95 {
96 	int rval = 0;
97 
98 	if ((jackdev.sEvent == NULL) || (jack_set_session_callback == NULL))
99 		return(0);
100 
101 	snprintf(sessionfile, 1024, "%s%s", jackdev.sEvent->session_dir, regname);
102 	audiomain->sessionfile = sessionfile;
103 
104 	snprintf(commandline, 1024, "%s -jsmfile \"${SESSION_DIR}%s\" -jsmuuid %s",
105 		audiomain->cmdline, regname, jackdev.sEvent->client_uuid);
106 
107 	jackdev.sEvent->command_line = bristolmalloc(strlen(commandline) + 1);
108 	sprintf(jackdev.sEvent->command_line, "%s", commandline);
109 
110 	/*
111 	 * Need to flag the event for outside handling
112 	 */
113 	if (audiomain->debuglevel > 1)
114 	{
115 		if (jackdev.audiomain->jackUUID[0] != '\0')
116 			printf("jack session callback: %s %s\n",
117 				jackdev.sEvent->client_uuid,
118 				jackdev.audiomain->jackUUID);
119 		else
120 			printf("jack session callback: %s\n", jackdev.sEvent->client_uuid);
121 
122 		printf("session file is %s\n", audiomain->sessionfile);
123 
124 		printf("command line is %s\n", jackdev.sEvent->command_line);
125 	}
126 
127 	rval = jackdev.sEvent->type;
128 
129 	jack_session_reply(jackdev.handle, jackdev.sEvent);
130 
131 	/* This was not malloc'ed do does not belong to jack session manager */
132 	jack_session_event_free(jackdev.sEvent);
133 	jackdev.sEvent = NULL;
134 
135 	return(rval);
136 }
137 
138 void
jack_session_callback(jack_session_event_t * event,void * arg)139 jack_session_callback(jack_session_event_t *event, void *arg)
140 {
141 	if (jack_set_session_callback == NULL)
142 		return;
143 
144 	if (jackdev.sEvent != NULL)
145 		jack_session_event_free(jackdev.sEvent);
146 
147 	/* This is not a very good signaling method, it has race conditions */
148 	jackdev.sEvent = event;
149 }
150 #endif
151 
152 static void
bufstats(float * buf,int nframes,int stage)153 bufstats(float *buf, int nframes, int stage)
154 {
155 	float max = 0.0f, min = 1.0f;
156 
157 	if (buf == NULL)
158 		return;
159 
160 	for (; nframes > 0; nframes-= 8)
161 	{
162 		max = *buf > max? *buf:max; min = *buf < min? *buf:min; buf++;
163 		max = *buf > max? *buf:max; min = *buf < min? *buf:min; buf++;
164 		max = *buf > max? *buf:max; min = *buf < min? *buf:min; buf++;
165 		max = *buf > max? *buf:max; min = *buf < min? *buf:min; buf++;
166 		max = *buf > max? *buf:max; min = *buf < min? *buf:min; buf++;
167 		max = *buf > max? *buf:max; min = *buf < min? *buf:min; buf++;
168 		max = *buf > max? *buf:max; min = *buf < min? *buf:min; buf++;
169 		max = *buf > max? *buf:max; min = *buf < min? *buf:min; buf++;
170 	}
171 	printf("%i %p: min %f, max %f\n", stage, buf, min, max);
172 }
173 
174 static int
audioShim(jack_nframes_t nframes,void * jd)175 audioShim(jack_nframes_t nframes, void *jd)
176 {
177 	jackDev *jackdev = (jackDev *) jd;
178 	register float *outL, *outR, *toutbuf = outbuf, gain;
179 	register int i, nint;
180 
181 #ifdef _BRISTOL_JACK_MIDI
182 	if (~jackdev->audiomain->flags & BRISTOL_JACK_DUAL)
183 		jackMidiRoutine(nframes, NULL);
184 #endif
185 
186 	/*
187 	 * We may need to consider jack changing its nframes on the fly. Whilst
188 	 * decreasing frames is not an issue, increasing them could be painful.
189 	 *
190 	 * I think I would prefer to reap all synths rather than code such an
191 	 * operation, or alternatively add in a shim to do some reframing.
192 	 * #warning need to consider jackd changes to nframes?
193 	 */
194 	if (jackdev->jack_in[BRISTOL_JACK_STDINL])
195 		jackdev->inbuf[BRISTOL_JACK_STDINL]
196 			= jack_port_get_buffer(jackdev->jack_in[BRISTOL_JACK_STDINL],
197 				nframes);
198 	if (jackdev->jack_in[BRISTOL_JACK_STDINR])
199 		jackdev->inbuf[BRISTOL_JACK_STDINR]
200 			= jack_port_get_buffer(jackdev->jack_in[BRISTOL_JACK_STDINR],
201 				nframes);
202 
203 	if (jackdev->iocount > 0)
204 	{
205 		int j;
206 		float *buf;
207 
208 		if ((gain = jackdev->audiomain->m_io_igc) <= 0)
209 			gain = 1.0;
210 
211 		for (i = 0; i < jackdev->iocount; i++)
212 		{
213 			jackdev->inbuf[i] = buf =
214 				jackdev->audiomain->io_i[i] =
215 				jack_port_get_buffer(jackdev->jack_in[i], nframes);
216 
217 			for (j = 0; j < nframes; j+=8)
218 			{
219 				*buf++ *= gain;
220 				*buf++ *= gain;
221 				*buf++ *= gain;
222 				*buf++ *= gain;
223 				*buf++ *= gain;
224 				*buf++ *= gain;
225 				*buf++ *= gain;
226 				*buf++ *= gain;
227 			}
228 
229 			jackdev->outbuf[i] =
230 				jackdev->audiomain->io_o[i] =
231 				jack_port_get_buffer(jackdev->jack_out[i], nframes);
232 
233 			memset(jackdev->outbuf[i], 0.0f, nframes * sizeof(float));
234 		}
235 	}
236 
237 	toutbuf = inbuf;
238 	gain = 12.0f;
239 
240 	for (i = 0; i < nframes; i+=8)
241 	{
242 		*toutbuf++ = jackdev->inbuf[BRISTOL_JACK_STDINL][i] * gain;
243 		*toutbuf++ = jackdev->inbuf[BRISTOL_JACK_STDINL][i] * gain;
244 		*toutbuf++ = jackdev->inbuf[BRISTOL_JACK_STDINL][i] * gain;
245 		*toutbuf++ = jackdev->inbuf[BRISTOL_JACK_STDINL][i] * gain;
246 		*toutbuf++ = jackdev->inbuf[BRISTOL_JACK_STDINL][i] * gain;
247 		*toutbuf++ = jackdev->inbuf[BRISTOL_JACK_STDINL][i] * gain;
248 		*toutbuf++ = jackdev->inbuf[BRISTOL_JACK_STDINL][i] * gain;
249 		*toutbuf++ = jackdev->inbuf[BRISTOL_JACK_STDINL][i] * gain;
250 	}
251 
252 	/*
253 	 * For now we are not going to be too picky about inbuf.
254 	 *
255 	 * The buffers are however mono, which is a bit of a bummer as now I have
256 	 * to do the interleaving and deinterleaving. This could be changed but
257 	 * it would have to apply to the native audio drivers as well.
258 	 *
259 	 * This doAudioOps is the same one used for the last few years by bristol
260 	 * as its own dispatch routine. However, there are additional features
261 	 * possible with Jack such that each synth could requisition its own
262 	 * ports dynamically, one or two depending on the synth stereo status.
263 	 *
264 	 * That should be an option, probably, but either way, if it were done
265 	 * then we would need to rework this dispatcher. That is not a bad thing
266 	 * since we could have the audioEngine write directly to the jack buffer
267 	 * rather than use the stereo interleaved outbuf.
268 	 *
269 	 * The reworked dispatcher should be placed in here, it is currently in
270 	 * audioEngine.c
271 	 */
272 	doAudioOps(jackdev->audiomain, outbuf, inbuf);
273 
274 	/*
275 	 * The bristol audio does this with zero suppression. Hm. Saved data is
276 	 * the output from the algo, it does not have outgain applied.
277 	 */
278 	if (dupfd > 0)
279 		nint = write(dupfd, outbuf, jackdev->audiomain->segmentsize * 2);
280 
281 	/*
282 	 * We have an issue with sample formats. These are normalised to 0/1
283 	 * whilst we have been working on full range values. No problem.
284 	 */
285 	if ((gain = jackdev->audiomain->outgain) < 1)
286 		gain = 1.0f;
287 	gain /= 32768.0;
288 
289 	outL = (float *)
290 		jack_port_get_buffer(jackdev->jack_out[BRISTOL_JACK_STDOUTL], nframes);
291 	outR = (float *)
292 		jack_port_get_buffer(jackdev->jack_out[BRISTOL_JACK_STDOUTR], nframes);
293 
294 	/*
295 	 * Deinterleave our output through to the jack buffers.
296 	 */
297 	toutbuf = outbuf;
298 	for (i = nframes; i > 0; i--)
299 	{
300 		*outL++ = *toutbuf++ * gain;
301 		*outR++ = *toutbuf++ * gain;
302 	}
303 
304 	if (jackdev->iocount > 0)
305 	{
306 		register int j;
307 		register float *buf, gain;
308 
309 		if ((gain = jackdev->audiomain->m_io_ogc) <= 0)
310 			gain = 1.0;
311 
312 		for (i = 0; i < jackdev->iocount; i++)
313 		{
314 			buf = jackdev->outbuf[i];
315 
316 			for (j = 0; j < nframes; j+=8)
317 			{
318 				*buf++ *= gain;
319 				*buf++ *= gain;
320 				*buf++ *= gain;
321 				*buf++ *= gain;
322 				*buf++ *= gain;
323 				*buf++ *= gain;
324 				*buf++ *= gain;
325 				*buf++ *= gain;
326 			}
327 
328 			memset(jackdev->inbuf[i], 0.0f, nframes * sizeof(float));
329 		}
330 	}
331 
332 	if (jackdev->audiomain->debuglevel > 9)
333 	{
334 		bufstats(jackdev->outbuf[0], nframes, 1);
335 		bufstats(jackdev->outbuf[2], nframes, 2);
336 	}
337 
338 	return(0);
339 }
340 
341 static void
bristolIntJackClose()342 bristolIntJackClose()
343 {
344 	int i;
345 
346 	--closedown;
347 
348 	printf("closedown on interrupt\n");
349 
350 	jack_deactivate(jackdev.handle);
351 
352 	jack_port_unregister(jackdev.handle,
353 		jackdev.jack_out[BRISTOL_JACK_STDOUTL]);
354 	jack_port_unregister(jackdev.handle,
355 		jackdev.jack_out[BRISTOL_JACK_STDOUTR]);
356 	jack_port_unregister(jackdev.handle,
357 		jackdev.jack_in[BRISTOL_JACK_STDINL]);
358 	jack_port_unregister(jackdev.handle,
359 		jackdev.jack_in[BRISTOL_JACK_STDINR]);
360 
361 	for (i = 0; i < jackdev.iocount; i++)
362 	{
363 		jack_port_unregister(jackdev.handle, jackdev.jack_in[i]);
364 		jack_port_unregister(jackdev.handle, jackdev.jack_out[i]);
365 	}
366 
367 	jack_client_close(jackdev.handle);
368 
369 	_exit(0);
370 }
371 
372 static int
bristolJackClose(jackDev * jackdev)373 bristolJackClose(jackDev *jackdev)
374 {
375 	int i;
376 
377 	if ((jackdev->handle == NULL) || (jackdev->jack_out[BRISTOL_JACK_STDOUTL] == NULL))
378 		return(-1);
379 
380 	/*
381 	 * So, if we don't have the ALSA atomic headers then just run it on ints,
382 	 * this bit of code is far from critical but collisions cause some gory
383 	 * shutdown sequences. The code used to call this shutdown from two
384 	 * different threads, removed on of them instead to prevent the possibility
385 	 * of them battering each other.
386 	 */
387 #ifdef DONT_USE_THIS //IATOMIC_DEFINED // Not very portable
388 	if (atomic_dec_and_test(&closedown))
389 #else
390 	if (--closedown == 0)
391 #endif
392 		printf("unregistering jack interface: %p->%p\n",
393 			jackdev, jackdev->handle);
394 	else {
395 		printf("interface unregistered\n");
396 		return(0);
397 	}
398 
399 	jack_deactivate(jackdev->handle);
400 
401 	usleep(100000);
402 
403 	jack_port_unregister(jackdev->handle,
404 		jackdev->jack_out[BRISTOL_JACK_STDOUTL]);
405 	jack_port_unregister(jackdev->handle,
406 		jackdev->jack_out[BRISTOL_JACK_STDOUTR]);
407 	jack_port_unregister(jackdev->handle,
408 		jackdev->jack_in[BRISTOL_JACK_STDINL]);
409 	jack_port_unregister(jackdev->handle,
410 		jackdev->jack_in[BRISTOL_JACK_STDINR]);
411 
412 	for (i = 0; i < jackdev->iocount; i++)
413 	{
414 		jack_port_unregister(jackdev->handle, jackdev->jack_in[i]);
415 		jack_port_unregister(jackdev->handle, jackdev->jack_out[i]);
416 	}
417 
418 	jackdev->jack_out[BRISTOL_JACK_STDOUTL] = NULL;
419 
420 	jack_client_close(jackdev->handle);
421 
422 	/*
423 	 * The API does not seem to be clear on who owns this however since we
424 	 * are exiting.....
425 	jackdev->handle = NULL;
426 	 */
427 
428 	jackdev->audiomain->atReq |= BRISTOL_REQSTOP;
429 	jackdev->audiomain->mtReq |= BRISTOL_REQSTOP;
430 
431 	return(0);
432 }
433 
434 /*
435  * This builds us our port list for connections. Per default we will connect
436  * to the first capture port and the first two playback ports, but that
437  * should also be optional. We should have some fixed starting ports though,
438  * even if we are going to pass parameters, since when each synth starts
439  * registering its own set of ports then they have to be linked somewhere
440  * by default.
441  */
442 static void
jackPortStats(jackDev * jackdev,int dir)443 jackPortStats(jackDev *jackdev, int dir)
444 {
445 	int i;
446 
447 	bristolfree(jackdev->ports);
448 
449 	if ((jackdev->ports = jack_get_ports(jackdev->handle, NULL, NULL,
450 		JackPortIsPhysical|dir)) == NULL)
451 	{
452 		printf("Empty jack_get_ports()\n");
453 		return;
454 	}
455 
456 	for (i = 0; jackdev->ports[i] != NULL; i++)
457 		printf("Found port %s\n", jackdev->ports[i]);
458 }
459 
460 static int
bristolJackOpen(jackDev * jackdev,audioMain * audiomain,JackProcessCallback shim)461 bristolJackOpen(jackDev *jackdev, audioMain *audiomain,
462 JackProcessCallback shim)
463 {
464 	int waitc = 10, sr;
465 
466 	if (audiomain->audiodev != NULL)
467 		regname = audiomain->audiodev;
468 
469 #ifdef _BRISTOL_JACK_SESSION
470 	if (audiomain->jackUUID[0] == '\0')
471 	{
472 		printf("registering jack interface: %s\n", regname);
473 		jackdev->handle = jack_client_open(regname, JackNullOption, NULL);
474 	} else {
475 		printf("reregistering jack interface: %s, UUDI %s\n",
476 			regname, &audiomain->jackUUID[0]);
477 		jackdev->handle = jack_client_open(regname, JackSessionID, NULL,
478 			&audiomain->jackUUID[0]);
479 	}
480 #else
481 	printf("registering jack interface: %s\n", regname);
482 	jackdev->handle = jack_client_open(regname, JackNullOption, NULL);
483 #endif
484 
485 	if (jackdev->handle == 0)
486 	{
487 		char process_indexed[32];
488 
489 		/*
490 		 * This had to be changed as the process ID is variable between
491 		 * invocations. The port number is not, it has to be provided to build
492 		 * a connection and is unique.
493 		 */
494 		snprintf(process_indexed, 32, "%s_%i", regname, audiomain->port);
495 
496 #ifdef _BRISTOL_JACK_SESSION
497 		if (audiomain->jackUUID[0] == '\0')
498 			jackdev->handle = jack_client_open(regname, JackNullOption, NULL);
499 		else
500 			jackdev->handle = jack_client_open(regname, JackSessionID, NULL,
501 				&audiomain->jackUUID[0]);
502 #else
503 		jackdev->handle = jack_client_open(regname, JackNullOption, NULL);
504 #endif
505 
506 		if (jackdev->handle == 0)
507 		{
508 			printf("Cannot connect to jack\n");
509 			audiomain->atStatus = BRISTOL_REQSTOP;
510 			return(-1);
511 		}
512 	}
513 
514 #ifdef _BRISTOL_JACK_MIDI
515 	if (~audiomain->flags & BRISTOL_JACK_DUAL)
516 		bristolJackSetMidiHandle(jackdev->handle);
517 #endif
518 
519 	signal(SIGINT, bristolIntJackClose);
520 	signal(SIGTERM, bristolIntJackClose);
521 	signal(SIGHUP, bristolIntJackClose);
522 	signal(SIGQUIT, bristolIntJackClose);
523 	/*
524 	 * This is (was) perhaps not wise....
525 	 * Thanks to Hagen.
526 	signal(SIGSEGV, bristolIntJackClose);
527 	 */
528 
529 	/* Samplerate mismatches should be reported however they are not critical */
530 	if (audiomain->samplerate != (sr = jack_get_sample_rate(jackdev->handle)))
531 		printf("\nJack SAMPLERATE MISMATCH: startBristol -jack -rate %i\n", sr);
532 
533 	/*
534 	 * This value can change, and we should register a callback for such an
535 	 * event. The values are used internally and are already configured for
536 	 * some parts of the system, hence, for now, if this does not match we
537 	 * are going to exit as this is critical.
538 	 */
539 	if (audiomain->samplecount != (sr = jack_get_buffer_size(jackdev->handle)))
540 	{
541 		printf("\nJack PERIOD COUNT MISMATCH: `startBristol -jack -count %i`\n",
542 			sr);
543 		printf("\nYou need to ensure that bristol uses the same period size\n");
544 
545 		/*
546 		 * This did call bristolJackClose(jackdev), however as we have not
547 		 * yet done much of the registration then the following is correct:
548 		 */
549 		jack_client_close(jackdev->handle);
550 
551 		audiomain->atStatus = BRISTOL_REQSTOP;
552 		return(-1);
553 	}
554 
555 	audiomain->samplecount = sr;
556 	audiomain->segmentsize = audiomain->samplecount * sizeof(float);
557 
558 	/*
559 	 * We double this value since I am going to be using interleaved samples
560 	 * for some buffering. I should change this, just let the audio library
561 	 * do interleave if it is writing to physical devices.
562 	 */
563 	outbuf = (float *) bristolmalloc(audiomain->samplecount * fsize * 2);
564 	inbuf = (float *) bristolmalloc(audiomain->samplecount * fsize * 2);
565 
566 	audiomain->atStatus = BRISTOL_OK;
567 	audiomain->flags |= BRISTOL_AUDIOWAIT;
568 
569 	initAudioThread(audiomain);
570 
571 	jackdev->audiomain = audiomain;
572 
573 	jack_set_process_callback(jackdev->handle, shim, (void *) jackdev);
574 
575 	jack_on_shutdown(jackdev->handle, jack_shutdown, (void *) jackdev);
576 
577 #ifdef _BRISTOL_JACK_SESSION
578 	if (jack_set_session_callback)
579 		jack_set_session_callback(jackdev->handle, jack_session_callback,
580 			(void *) jackdev);
581 #endif
582 
583 	if ((jackdev->jack_out[BRISTOL_JACK_STDOUTL] = jack_port_register(jackdev->handle,
584 		"out_left", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)) == NULL)
585 	{
586 		printf("Cannot register jack port\n");
587 		audiomain->atStatus = BRISTOL_REQSTOP;
588 		return(-1);
589 	}
590 	if ((jackdev->jack_out[BRISTOL_JACK_STDOUTR] = jack_port_register(jackdev->handle,
591 		"out_right", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)) == NULL)
592 	{
593 		printf("Cannot register jack port\n");
594 		audiomain->atStatus = BRISTOL_REQSTOP;
595 		return(-1);
596 	}
597 
598 	/*
599 	 * We only use the input for a couple of the synths (Mini/Explorer) and
600 	 * even that had limited use. It was also employed historically for sync
601 	 * - read/modify/write sequences. We could drop this registration, but it
602 	 * can stay in for now, it will be used in the future.
603 	 */
604 	if ((jackdev->jack_in[BRISTOL_JACK_STDINL] = jack_port_register(jackdev->handle,
605 		"in_left", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0)) == NULL)
606 	{
607 		printf("Cannot register jack port\n");
608 		audiomain->atStatus = BRISTOL_REQSTOP;
609 		return(-1);
610 	}
611 	if ((jackdev->jack_in[BRISTOL_JACK_STDINR] = jack_port_register(jackdev->handle,
612 		"in_right", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0)) == NULL)
613 	{
614 		printf("Cannot register jack port\n");
615 		audiomain->atStatus = BRISTOL_REQSTOP;
616 		return(-1);
617 	}
618 
619 	/*
620 	 * Our engine is going have to wait for the GUI to inform us what synth
621 	 * we are going to be running. It is wiser not to request callbacks until
622 	 * at least the first synth is active. If the priorities are correct this
623 	 * should not be an issue, but 'dropping' a synth costs a few cycles in
624 	 * the midi thread.
625 	 */
626 	while (audiomain->flags & BRISTOL_AUDIOWAIT)
627 	{
628 		sleep(1);
629 		if (--waitc <= 0)
630 		{
631 			printf("Did not receive request from GUI, exiting.\n");
632 			/*
633 			 * We should really unregister here.....
634 			 */
635 			return(-1);
636 		}
637 	}
638 
639 	if (jack_activate(jackdev->handle) != 0)
640 	{
641 		printf("Cannot activate jack\n");
642 		audiomain->atStatus = BRISTOL_REQSTOP;
643 		return(-1);
644 	}
645 
646 	jackPortStats(jackdev, JackPortIsInput);
647 
648 	if ((audiomain->flags & BRISTOL_AUTO_CONN) && (jackdev->ports != NULL))
649 	{
650 		int jport = 0;
651 		char *lport, *rport;
652 
653 		lport = getenv("BRISTOL_AUTO_LEFT");
654 		rport = getenv("BRISTOL_AUTO_RIGHT");
655 
656 		if ((lport != NULL) && (rport != NULL))
657 		{
658 			/*
659 			 * We should scan through the list looking for our ports
660 			 */
661 			for (jport = 0; jackdev->ports[jport] != NULL; jport++) {
662 				if (strcmp(lport, jackdev->ports[jport]) == 0)
663 				{
664 					if (jack_connect(jackdev->handle,
665 						jack_port_name(jackdev->jack_out[BRISTOL_JACK_STDOUTL]),
666 							jackdev->ports[jport]) != 0)
667 					{
668 						printf("Bristol Failed Conn: %s to %s failed\n",
669 							jack_port_name(jackdev->jack_out[BRISTOL_JACK_STDOUTL]),
670 							jackdev->ports[jport]);
671 					} else
672 						printf("Bristol Env AutoConn: %s to %s\n",
673 							jack_port_name(jackdev->jack_out[BRISTOL_JACK_STDOUTL]),
674 							jackdev->ports[jport]);
675 				}
676 				if (strcmp(rport, jackdev->ports[jport]) == 0)
677 				{
678 					if (jack_connect(jackdev->handle,
679 						jack_port_name(jackdev->jack_out[BRISTOL_JACK_STDOUTR]),
680 							jackdev->ports[jport]) != 0)
681 					{
682 						printf("Bristol Failed Conn: %s to %s failed\n",
683 							jack_port_name(jackdev->jack_out[BRISTOL_JACK_STDOUTR]),
684 							jackdev->ports[jport]);
685 					} else
686 						printf("Bristol Env AutoConn: %s to %s\n",
687 							jack_port_name(jackdev->jack_out[BRISTOL_JACK_STDOUTL]),
688 							jackdev->ports[jport]);
689 				}
690 			}
691 		} else for (jport = 0; jackdev->ports[jport] != NULL; jport++) {
692 			/*
693 			 * I don't like this code but I cannot find a way to ask jack if
694 			 * this port is audio or midi. Without this scan then it is possible
695 			 * that the engine will default a connection from audio to midi.
696 			 *
697 			 * It is okay here to attempt the connection but continue through
698 			 * the list in the event of failure but that is sloppy. All we
699 			 * actually want is to find the first two available ports to return
700 			 * audio to and one to receive from the daemon.
701 			 */
702 			if (strstr(jackdev->ports[jport], "midi") != 0)
703 			{
704 				printf("Skipping Jack Conn: %s\n", jackdev->ports[jport]);
705 				continue;
706 			}
707 
708 			if (jack_connect(jackdev->handle,
709 				jack_port_name(jackdev->jack_out[BRISTOL_JACK_STDOUTL]),
710 					jackdev->ports[jport]) != 0)
711 			{
712 				printf("Bristol Defaulted Conn: %s to %s failed\n",
713 					jack_port_name(jackdev->jack_out[BRISTOL_JACK_STDOUTL]),
714 					jackdev->ports[jport]);
715 				continue;
716 			} else
717 				printf("Bristol Defaulted Conn: %s to %s\n",
718 					jack_port_name(jackdev->jack_out[BRISTOL_JACK_STDOUTL]),
719 					jackdev->ports[jport]);
720 
721 			for (jport++; jackdev->ports[jport] != 0; jport++)
722 			{
723 				if (strstr(jackdev->ports[jport], "midi") != 0)
724 				{
725 					printf("Skipping Jack Conn: %s\n", jackdev->ports[jport]);
726 					continue;
727 				}
728 
729 				if (jack_connect(jackdev->handle,
730 					jack_port_name(jackdev->jack_out[BRISTOL_JACK_STDOUTR]),
731 						jackdev->ports[jport]) != 0)
732 				{
733 					printf("Bristol Defaulted Conn: %s to %s failed\n",
734 						jack_port_name(jackdev->jack_out[BRISTOL_JACK_STDOUTR]),
735 						jackdev->ports[jport]);
736 					continue;
737 				} else
738 					printf("Bristol Defaulted Conn: %s to %s\n",
739 						jack_port_name(jackdev->jack_out[BRISTOL_JACK_STDOUTR]),
740 						jackdev->ports[jport]);
741 				break;
742 			}
743 
744 			break;
745 		}
746 	}
747 
748 	/*
749 	 * We now need to connect the ports together. For now this will be fixed
750 	 * but actually needs to be a set of options.
751 	 */
752 	jackPortStats(jackdev, JackPortIsOutput);
753 
754 	if ((audiomain->flags & BRISTOL_AUTO_CONN) && (jackdev->ports != NULL))
755 	{
756 		int jport = 0;
757 		char *iport;
758 
759 		iport = getenv("BRISTOL_AUTO_IN");
760 
761 		if (iport != NULL)
762 		{
763 			/*
764 			 * We should scan through the list looking for our ports
765 			 */
766 			for (jport = 0; jackdev->ports[jport] != NULL; jport++)
767 			{
768 				if (strcmp(iport, jackdev->ports[jport]) == 0)
769 				{
770 					if (jack_connect(jackdev->handle, jackdev->ports[jport],
771 						jack_port_name(jackdev->jack_in[BRISTOL_JACK_STDINL])) != 0)
772 					{
773 						/*
774 						 * We don't actually need to fail any of these, it just
775 						 * means we have no defaults.
776 						 */
777 						printf("Bristol Env AutoConn: %s to %s failed\n",
778 							jackdev->ports[jport],
779 							jack_port_name(jackdev->jack_in[BRISTOL_JACK_STDINL]));
780 						continue;
781 					} else
782 						printf("Bristol Env AutoConn: %s to %s\n",
783 							jackdev->ports[jport],
784 							jack_port_name(jackdev->jack_in[BRISTOL_JACK_STDINL]));
785 				}
786 			}
787 		} else for (jport = 0; jackdev->ports[jport] != 0; jport++)
788 		{
789 			if (strstr(jackdev->ports[jport], "midi") != 0)
790 			{
791 				printf("Skipping Jack Conn: %s\n", jackdev->ports[jport]);
792 				continue;
793 			}
794 
795 			if (jack_connect(jackdev->handle, jackdev->ports[jport],
796 				jack_port_name(jackdev->jack_in[BRISTOL_JACK_STDINL])) != 0)
797 			{
798 				/*
799 				 * We don't actually need to fail any of these, it just means
800 				 * we have no defaults.
801 				 */
802 				printf("Bristol Defaulted Conn: %s to %s failed\n",
803 					jackdev->ports[jport], jack_port_name(jackdev->jack_in[BRISTOL_JACK_STDINL]));
804 				continue;
805 			} else
806 				printf("Bristol Defaulted Conn: %s to %s\n",
807 					jackdev->ports[jport], jack_port_name(jackdev->jack_in[BRISTOL_JACK_STDINL]));
808 
809 			break;
810 		}
811 	}
812 
813 	/*
814 	 * So now see if we were requested to register more ports.
815 	 */
816 	if ((jackdev->iocount = audiomain->iocount) > 0)
817 	{
818 		int i;
819 		char pn[256];
820 
821 		for (i = 0; i < jackdev->iocount; i++)
822 		{
823 			sprintf(pn, "out_%i", i + 1);
824 			if ((jackdev->jack_out[i] = jack_port_register(jackdev->handle,
825 				pn, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)) == NULL)
826 			{
827 				printf("Cannot register jack port\n");
828 				audiomain->atStatus = BRISTOL_REQSTOP;
829 				return(-1);
830 			}
831 			sprintf(pn, "in_%i", i + 1);
832 			if ((jackdev->jack_in[i] = jack_port_register(jackdev->handle,
833 				pn, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0)) == NULL)
834 			{
835 				printf("Cannot register jack port\n");
836 				audiomain->atStatus = BRISTOL_REQSTOP;
837 				return(-1);
838 			}
839 		}
840 	}
841 
842 	return(0);
843 }
844 
845 /*
846  * Test dynamic disconnect and reconnects. Eventually each synth will
847  * potentially register its own set of ports. Want to do this with a
848  * reasonably large number of iterations. Correctly speaking we should
849  * probably take a copy of the jack_in port, null the jackdev entry
850  * and then unregister it.
851 static void
852 jackPortBounce(jackDev *jackdev)
853 {
854 	jack_disconnect(jackdev->handle,
855 		jackdev->ports[0], jack_port_name(jackdev->jack_in[BRISTOL_JACK_STDINL]));
856 
857 	if (jack_port_unregister(jackdev->handle, jackdev->jack_in[BRISTOL_JACK_STDINL]) == 0)
858 	{
859 		printf("Unregistered port\n");
860 		jackdev->jack_in[BRISTOL_JACK_STDINL] = 0;
861 
862 		sleep(5);
863 
864 		if ((jackdev->jack_in[BRISTOL_JACK_STDINL] = jack_port_register(jackdev->handle,
865 			"in", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0)) != NULL)
866 			printf("Registered port\n");
867 	} else
868 		sleep(5);
869 
870 	jack_connect(jackdev->handle,
871 		jackdev->ports[0], jack_port_name(jackdev->jack_in[BRISTOL_JACK_STDINL]));
872 }
873 
874 jack_client_t *
875 bristolJackGetAudioHandle()
876 {
877 	if (jackdev.audiomain == NULL)
878 		sleep(1);
879 	if (jackdev.audiomain->flags & BRISTOL_JACK_DUAL)
880 		return(NULL);
881 	sleep(1);
882 	return(jackdev.handle);
883 }
884  */
885 
886 int
bristolJackInterface(audioMain * audiomain)887 bristolJackInterface(audioMain *audiomain)
888 {
889 	/*
890 	 * This was added into 0.40.3 to prevent subgraph timeouts on exit. The
891 	 * call is made from the midi thread once the audio thread has done the
892 	 * necessary cleanup work.
893 	 */
894 	if ((audiomain == NULL) || (audiomain->audiolist == 0))
895 		/*
896 		 * If the audiolist is empty (or we are called with a null pointer)
897 		 * then assume we are being requested to close down the interface.
898 		 */
899 		return(bristolJackClose(&jackdev));
900 
901 	if (bristolJackOpen(&jackdev, audiomain, audioShim) != 0)
902 		return(-1);
903 
904 	while (audiomain->atReq != BRISTOL_REQSTOP)
905 		sleep(1);
906 
907 	return(0);
908 }
909 #endif /* _BRISTOL_JACK */
910 
911