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