1 /* FluidSynth - A Software Synthesizer
2 *
3 * Copyright (C) 2003 Peter Hanappe and others.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public License
7 * as published by the Free Software Foundation; either version 2.1 of
8 * the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free
17 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 * 02110-1301, USA
19 */
20
21
22 /* fluid_jack.c
23 *
24 * Driver for the JACK
25 *
26 * This code is derived from the simple_client example in the JACK
27 * source distribution. Many thanks to Paul Davis.
28 *
29 */
30
31 #include "fluid_synth.h"
32 #include "fluid_adriver.h"
33 #include "fluid_mdriver.h"
34 #include "fluid_settings.h"
35
36 #if JACK_SUPPORT
37
38 #include <jack/jack.h>
39 #include <jack/midiport.h>
40
41 #include "fluid_lash.h"
42
43
44 typedef struct _fluid_jack_audio_driver_t fluid_jack_audio_driver_t;
45 typedef struct _fluid_jack_midi_driver_t fluid_jack_midi_driver_t;
46
47
48 /* Clients are shared for drivers using the same server. */
49 typedef struct
50 {
51 jack_client_t *client;
52 char *server; /* Jack server name used */
53 fluid_jack_audio_driver_t *audio_driver;
54 fluid_jack_midi_driver_t *midi_driver;
55 } fluid_jack_client_t;
56
57 /* Jack audio driver instance */
58 struct _fluid_jack_audio_driver_t
59 {
60 fluid_audio_driver_t driver;
61 fluid_jack_client_t *client_ref;
62
63 jack_port_t **output_ports;
64 int num_output_ports;
65 float **output_bufs;
66
67 jack_port_t **fx_ports;
68 int num_fx_ports;
69 float **fx_bufs;
70
71 fluid_audio_func_t callback;
72 void *data;
73 };
74
75 /* Jack MIDI driver instance */
76 struct _fluid_jack_midi_driver_t
77 {
78 fluid_midi_driver_t driver;
79 fluid_jack_client_t *client_ref;
80 int midi_port_count;
81 jack_port_t **midi_port; // array of midi port handles
82 fluid_midi_parser_t *parser;
83 int autoconnect_inputs;
84 fluid_atomic_int_t autoconnect_is_outdated;
85 };
86
87 static fluid_jack_client_t *new_fluid_jack_client(fluid_settings_t *settings,
88 int isaudio, void *driver);
89 static int fluid_jack_client_register_ports(void *driver, int isaudio,
90 jack_client_t *client,
91 fluid_settings_t *settings);
92
93 void fluid_jack_driver_shutdown(void *arg);
94 int fluid_jack_driver_srate(jack_nframes_t nframes, void *arg);
95 int fluid_jack_driver_bufsize(jack_nframes_t nframes, void *arg);
96 int fluid_jack_driver_process(jack_nframes_t nframes, void *arg);
97 void fluid_jack_port_registration(jack_port_id_t port, int is_registering, void *arg);
98
99 static fluid_mutex_t last_client_mutex = FLUID_MUTEX_INIT; /* Probably not necessary, but just in case drivers are created by multiple threads */
100 static fluid_jack_client_t *last_client = NULL; /* Last unpaired client. For audio/MIDI driver pairing. */
101
102
103 void
fluid_jack_audio_driver_settings(fluid_settings_t * settings)104 fluid_jack_audio_driver_settings(fluid_settings_t *settings)
105 {
106 fluid_settings_register_str(settings, "audio.jack.id", "fluidsynth", 0);
107 fluid_settings_register_int(settings, "audio.jack.multi", 0, 0, 1, FLUID_HINT_TOGGLED);
108 fluid_settings_register_int(settings, "audio.jack.autoconnect", 0, 0, 1, FLUID_HINT_TOGGLED);
109 fluid_settings_register_str(settings, "audio.jack.server", "", 0);
110 }
111
112 /*
113 * Connect all midi input ports to all terminal midi output ports
114 */
115 void
fluid_jack_midi_autoconnect(jack_client_t * client,fluid_jack_midi_driver_t * midi_driver)116 fluid_jack_midi_autoconnect(jack_client_t *client, fluid_jack_midi_driver_t *midi_driver)
117 {
118 int i, j;
119 const char **midi_source_ports;
120
121 midi_source_ports = jack_get_ports(client, NULL, JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput | JackPortIsTerminal);
122
123 if(midi_source_ports != NULL)
124 {
125 for(j = 0; midi_source_ports[j] != NULL; j++)
126 {
127 for(i = 0; i < midi_driver->midi_port_count; i++)
128 {
129 FLUID_LOG(FLUID_INFO, "jack midi autoconnect \"%s\" to \"%s\"", midi_source_ports[j], jack_port_name(midi_driver->midi_port[i]));
130 jack_connect(client, midi_source_ports[j], jack_port_name(midi_driver->midi_port[i]));
131 }
132 }
133
134 jack_free(midi_source_ports);
135 }
136
137 fluid_atomic_int_set(&midi_driver->autoconnect_is_outdated, FALSE);
138 }
139
140 /*
141 * Create Jack client as necessary, share clients of the same server.
142 * @param settings Settings object
143 * @param isaudio TRUE if audio driver, FALSE if MIDI
144 * @param driver fluid_jack_audio_driver_t or fluid_jack_midi_driver_t
145 * @param data The user data instance associated with the driver (fluid_synth_t for example)
146 * @return New or paired Audio/MIDI Jack client
147 */
148 static fluid_jack_client_t *
new_fluid_jack_client(fluid_settings_t * settings,int isaudio,void * driver)149 new_fluid_jack_client(fluid_settings_t *settings, int isaudio, void *driver)
150 {
151 fluid_jack_client_t *client_ref = NULL;
152 char *server = NULL;
153 char *client_name;
154 char name[64];
155
156 if(fluid_settings_dupstr(settings, isaudio ? "audio.jack.server" /* ++ alloc server name */
157 : "midi.jack.server", &server) != FLUID_OK)
158 {
159 return NULL;
160 }
161
162 fluid_mutex_lock(last_client_mutex); /* ++ lock last_client */
163
164 /* If the last client uses the same server and is not the same type (audio or MIDI),
165 * then re-use the client. */
166 if(last_client &&
167 (last_client->server != NULL && server != NULL && FLUID_STRCMP(last_client->server, server) == 0) &&
168 ((!isaudio && last_client->midi_driver == NULL) || (isaudio && last_client->audio_driver == NULL)))
169 {
170 client_ref = last_client;
171
172 /* Register ports */
173 if(fluid_jack_client_register_ports(driver, isaudio, client_ref->client, settings) == FLUID_OK)
174 {
175 last_client = NULL; /* No more pairing for this client */
176
177 if(isaudio)
178 {
179 fluid_atomic_pointer_set(&client_ref->audio_driver, driver);
180 }
181 else
182 {
183 fluid_atomic_pointer_set(&client_ref->midi_driver, driver);
184 }
185 }
186 else
187 {
188 // do not free client_ref and do not goto error_recovery
189 // client_ref is being used by another audio or midi driver. Freeing it here will lead to a double free.
190 client_ref = NULL;
191 }
192
193 fluid_mutex_unlock(last_client_mutex); /* -- unlock last_client */
194
195 if(server)
196 {
197 FLUID_FREE(server);
198 }
199
200 return client_ref;
201 }
202
203 /* No existing client for this Jack server */
204 client_ref = FLUID_NEW(fluid_jack_client_t);
205
206 if(!client_ref)
207 {
208 FLUID_LOG(FLUID_PANIC, "Out of memory");
209 goto error_recovery;
210 }
211
212 FLUID_MEMSET(client_ref, 0, sizeof(fluid_jack_client_t));
213
214 fluid_settings_dupstr(settings, isaudio ? "audio.jack.id" /* ++ alloc client name */
215 : "midi.jack.id", &client_name);
216
217 if(client_name != NULL && client_name[0] != 0)
218 {
219 FLUID_SNPRINTF(name, sizeof(name), "%s", client_name);
220 }
221 else
222 {
223 FLUID_STRNCPY(name, "fluidsynth", sizeof(name));
224 }
225
226 name[63] = '\0';
227
228 if(client_name)
229 {
230 FLUID_FREE(client_name); /* -- free client name */
231 }
232
233 /* Open a connection to the Jack server and use the server name if specified */
234 if(server && server[0] != '\0')
235 {
236 client_ref->client = jack_client_open(name, JackServerName, NULL, server);
237 }
238 else
239 {
240 client_ref->client = jack_client_open(name, JackNullOption, NULL);
241 }
242
243 if(!client_ref->client)
244 {
245 FLUID_LOG(FLUID_ERR, "Failed to connect to Jack server.");
246 goto error_recovery;
247 }
248
249 jack_set_port_registration_callback(client_ref->client, fluid_jack_port_registration, client_ref);
250 jack_set_process_callback(client_ref->client, fluid_jack_driver_process, client_ref);
251 jack_set_buffer_size_callback(client_ref->client, fluid_jack_driver_bufsize, client_ref);
252 jack_set_sample_rate_callback(client_ref->client, fluid_jack_driver_srate, client_ref);
253 jack_on_shutdown(client_ref->client, fluid_jack_driver_shutdown, client_ref);
254
255 /* Register ports */
256 if(fluid_jack_client_register_ports(driver, isaudio, client_ref->client, settings) != FLUID_OK)
257 {
258 goto error_recovery;
259 }
260
261 /* tell the JACK server that we are ready to roll */
262 if(jack_activate(client_ref->client))
263 {
264 FLUID_LOG(FLUID_ERR, "Failed to activate Jack client");
265 goto error_recovery;
266 }
267
268 /* tell the lash server our client name */
269 #ifdef HAVE_LASH
270 {
271 int enable_lash = 0;
272 fluid_settings_getint(settings, "lash.enable", &enable_lash);
273
274 if(enable_lash)
275 {
276 fluid_lash_jack_client_name(fluid_lash_client, name);
277 }
278 }
279 #endif /* HAVE_LASH */
280
281 client_ref->server = server; /* !! takes over allocation */
282 server = NULL; /* Set to NULL so it doesn't get freed below */
283
284 last_client = client_ref;
285
286 if(isaudio)
287 {
288 fluid_atomic_pointer_set(&client_ref->audio_driver, driver);
289 }
290 else
291 {
292 fluid_atomic_pointer_set(&client_ref->midi_driver, driver);
293 }
294
295 fluid_mutex_unlock(last_client_mutex); /* -- unlock last_client */
296
297 if(server)
298 {
299 FLUID_FREE(server);
300 }
301
302 return client_ref;
303
304 error_recovery:
305
306 fluid_mutex_unlock(last_client_mutex); /* -- unlock clients list */
307
308 if(server)
309 {
310 FLUID_FREE(server); /* -- free server name */
311 }
312
313 if(client_ref)
314 {
315 if(client_ref->client)
316 {
317 jack_client_close(client_ref->client);
318 }
319
320 FLUID_FREE(client_ref);
321 }
322
323 return NULL;
324 }
325
326 static int
fluid_jack_client_register_ports(void * driver,int isaudio,jack_client_t * client,fluid_settings_t * settings)327 fluid_jack_client_register_ports(void *driver, int isaudio, jack_client_t *client,
328 fluid_settings_t *settings)
329 {
330 fluid_jack_audio_driver_t *dev;
331 char name[64];
332 int multi;
333 int i;
334 unsigned long jack_srate;
335 double sample_rate;
336
337 if(!isaudio)
338 {
339 fluid_jack_midi_driver_t *dev = driver;
340 int midi_channels, ports;
341
342 fluid_settings_getint(settings, "synth.midi-channels", &midi_channels);
343 ports = midi_channels / 16;
344
345 if((dev->midi_port = FLUID_ARRAY(jack_port_t *, ports)) == NULL)
346 {
347 FLUID_LOG(FLUID_PANIC, "Out of memory");
348 return FLUID_FAILED;
349 }
350
351 for(i = 0; i < ports; i++)
352 {
353 FLUID_SNPRINTF(name, sizeof(name), "midi_%02d", i);
354 dev->midi_port[i] = jack_port_register(client, name, JACK_DEFAULT_MIDI_TYPE,
355 JackPortIsInput | JackPortIsTerminal, 0);
356
357 if(dev->midi_port[i] == NULL)
358 {
359 FLUID_LOG(FLUID_ERR, "Failed to create Jack MIDI port '%s'", name);
360 FLUID_FREE(dev->midi_port);
361 dev->midi_port = NULL;
362 return FLUID_FAILED;
363 }
364 }
365
366 dev->midi_port_count = ports;
367 return FLUID_OK;
368 }
369
370 dev = driver;
371
372 fluid_settings_getint(settings, "audio.jack.multi", &multi);
373
374 if(!multi)
375 {
376 /* create the two audio output ports */
377 dev->num_output_ports = 1;
378 dev->num_fx_ports = 0;
379
380 dev->output_ports = FLUID_ARRAY(jack_port_t *, 2 * dev->num_output_ports);
381
382 if(dev->output_ports == NULL)
383 {
384 FLUID_LOG(FLUID_PANIC, "Out of memory");
385 return FLUID_FAILED;
386 }
387
388 dev->output_bufs = FLUID_ARRAY(float *, 2 * dev->num_output_ports);
389 FLUID_MEMSET(dev->output_ports, 0, 2 * dev->num_output_ports * sizeof(jack_port_t *));
390
391 dev->output_ports[0]
392 = jack_port_register(client, "left", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
393
394 dev->output_ports[1]
395 = jack_port_register(client, "right", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
396
397 if(dev->output_ports[0] == NULL || dev->output_ports[1] == NULL)
398 {
399 FLUID_LOG(FLUID_ERR, "Failed to create Jack audio port '%s'",
400 (dev->output_ports[0] == NULL ? (dev->output_ports[1] == NULL ? "left & right" : "left") : "right"));
401 goto error_recovery;
402 }
403 }
404 else
405 {
406 fluid_settings_getint(settings, "synth.audio-channels", &dev->num_output_ports);
407
408 dev->output_ports = FLUID_ARRAY(jack_port_t *, 2 * dev->num_output_ports);
409
410 if(dev->output_ports == NULL)
411 {
412 FLUID_LOG(FLUID_PANIC, "Out of memory");
413 return FLUID_FAILED;
414 }
415
416 dev->output_bufs = FLUID_ARRAY(float *, 2 * dev->num_output_ports);
417
418 if(dev->output_bufs == NULL)
419 {
420 FLUID_LOG(FLUID_PANIC, "Out of memory");
421 goto error_recovery;
422 }
423
424 FLUID_MEMSET(dev->output_ports, 0, 2 * dev->num_output_ports * sizeof(jack_port_t *));
425
426 for(i = 0; i < dev->num_output_ports; i++)
427 {
428 sprintf(name, "l_%02d", i);
429
430 if((dev->output_ports[2 * i]
431 = jack_port_register(client, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)) == NULL)
432 {
433 FLUID_LOG(FLUID_ERR, "Failed to create Jack audio port '%s'", name);
434 goto error_recovery;
435 }
436
437 sprintf(name, "r_%02d", i);
438
439 if((dev->output_ports[2 * i + 1]
440 = jack_port_register(client, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)) == NULL)
441 {
442 FLUID_LOG(FLUID_ERR, "Failed to create Jack audio port '%s'", name);
443 goto error_recovery;
444 }
445 }
446
447 fluid_settings_getint(settings, "synth.effects-channels", &dev->num_fx_ports);
448 fluid_settings_getint(settings, "synth.effects-groups", &i);
449
450 dev->num_fx_ports *= i;
451 dev->fx_ports = FLUID_ARRAY(jack_port_t *, 2 * dev->num_fx_ports);
452
453 if(dev->fx_ports == NULL)
454 {
455 FLUID_LOG(FLUID_PANIC, "Out of memory");
456 goto error_recovery;
457 }
458
459 dev->fx_bufs = FLUID_ARRAY(float *, 2 * dev->num_fx_ports);
460
461 if(dev->fx_bufs == NULL)
462 {
463 FLUID_LOG(FLUID_PANIC, "Out of memory");
464 goto error_recovery;
465 }
466
467 FLUID_MEMSET(dev->fx_ports, 0, 2 * dev->num_fx_ports * sizeof(jack_port_t *));
468
469 for(i = 0; i < dev->num_fx_ports; i++)
470 {
471 sprintf(name, "fx_l_%02d", i);
472
473 if((dev->fx_ports[2 * i]
474 = jack_port_register(client, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)) == NULL)
475 {
476 FLUID_LOG(FLUID_ERR, "Failed to create Jack fx audio port '%s'", name);
477 goto error_recovery;
478 }
479
480 sprintf(name, "fx_r_%02d", i);
481
482 if((dev->fx_ports[2 * i + 1]
483 = jack_port_register(client, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)) == NULL)
484 {
485 FLUID_LOG(FLUID_ERR, "Failed to create Jack fx audio port '%s'", name);
486 goto error_recovery;
487 }
488 }
489 }
490
491 /* Adjust sample rate to match JACK's */
492 jack_srate = jack_get_sample_rate(client);
493 FLUID_LOG(FLUID_DBG, "Jack engine sample rate: %lu", jack_srate);
494
495 fluid_settings_getnum(settings, "synth.sample-rate", &sample_rate);
496
497 if((unsigned long)sample_rate != jack_srate)
498 {
499 fluid_synth_t* synth;
500 if(fluid_jack_obtain_synth(settings, &synth) == FLUID_OK)
501 {
502 FLUID_LOG(FLUID_INFO, "Jack sample rate mismatch, adjusting."
503 " (synth.sample-rate=%lu, jackd=%lu)", (unsigned long)sample_rate, jack_srate);
504 fluid_synth_set_sample_rate_immediately(synth, jack_srate);
505 }
506 else
507 {
508 FLUID_LOG(FLUID_WARN, "Jack sample rate mismatch (synth.sample-rate=%lu, jackd=%lu)"
509 " impossible to adjust, because the settings object provided to new_fluid_audio_driver2() was not used to create a synth."
510 , (unsigned long)sample_rate, jack_srate);
511 }
512 }
513
514 return FLUID_OK;
515
516 error_recovery:
517
518 FLUID_FREE(dev->output_ports);
519 dev->output_ports = NULL;
520 FLUID_FREE(dev->fx_ports);
521 dev->fx_ports = NULL;
522 FLUID_FREE(dev->output_bufs);
523 dev->output_bufs = NULL;
524 FLUID_FREE(dev->fx_bufs);
525 dev->fx_bufs = NULL;
526 return FLUID_FAILED;
527 }
528
529 static void
fluid_jack_client_close(fluid_jack_client_t * client_ref,void * driver)530 fluid_jack_client_close(fluid_jack_client_t *client_ref, void *driver)
531 {
532 if(client_ref->audio_driver == driver)
533 {
534 fluid_atomic_pointer_set(&client_ref->audio_driver, NULL);
535 }
536 else if(client_ref->midi_driver == driver)
537 {
538 fluid_atomic_pointer_set(&client_ref->midi_driver, NULL);
539 }
540
541 if(client_ref->audio_driver || client_ref->midi_driver)
542 {
543 fluid_msleep(100); /* FIXME - Hack to make sure that resources don't get freed while Jack callback is active */
544 return;
545 }
546
547 fluid_mutex_lock(last_client_mutex);
548
549 if(client_ref == last_client)
550 {
551 last_client = NULL;
552 }
553
554 fluid_mutex_unlock(last_client_mutex);
555
556 if(client_ref->client)
557 {
558 jack_client_close(client_ref->client);
559 }
560
561 if(client_ref->server)
562 {
563 FLUID_FREE(client_ref->server);
564 }
565
566 FLUID_FREE(client_ref);
567 }
568
569
570 fluid_audio_driver_t *
new_fluid_jack_audio_driver(fluid_settings_t * settings,fluid_synth_t * synth)571 new_fluid_jack_audio_driver(fluid_settings_t *settings, fluid_synth_t *synth)
572 {
573 return new_fluid_jack_audio_driver2(settings, NULL, synth);
574 }
575
576 fluid_audio_driver_t *
new_fluid_jack_audio_driver2(fluid_settings_t * settings,fluid_audio_func_t func,void * data)577 new_fluid_jack_audio_driver2(fluid_settings_t *settings, fluid_audio_func_t func, void *data)
578 {
579 fluid_jack_audio_driver_t *dev = NULL;
580 jack_client_t *client;
581 const char **jack_ports; /* for looking up ports */
582 int autoconnect = 0;
583 int i;
584
585 dev = FLUID_NEW(fluid_jack_audio_driver_t);
586
587 if(dev == NULL)
588 {
589 FLUID_LOG(FLUID_PANIC, "Out of memory");
590 return NULL;
591 }
592
593 FLUID_MEMSET(dev, 0, sizeof(fluid_jack_audio_driver_t));
594
595 dev->callback = func;
596 dev->data = data;
597
598 dev->client_ref = new_fluid_jack_client(settings, TRUE, dev);
599
600 if(!dev->client_ref)
601 {
602 FLUID_FREE(dev);
603 return NULL;
604 }
605
606 client = dev->client_ref->client;
607
608 /* connect the ports. */
609
610 /* find some physical ports and connect to them */
611 fluid_settings_getint(settings, "audio.jack.autoconnect", &autoconnect);
612
613 if(autoconnect)
614 {
615 jack_ports = jack_get_ports(client, NULL, NULL, JackPortIsInput | JackPortIsPhysical);
616
617 if(jack_ports && jack_ports[0])
618 {
619 int err, o = 0;
620 int connected = 0;
621
622 for(i = 0; i < 2 * dev->num_output_ports; ++i)
623 {
624 err = jack_connect(client, jack_port_name(dev->output_ports[i]), jack_ports[o++]);
625
626 if(err)
627 {
628 FLUID_LOG(FLUID_ERR, "Error connecting jack port");
629 }
630 else
631 {
632 connected++;
633 }
634
635 if(!jack_ports[o])
636 {
637 o = 0;
638 }
639 }
640
641 o = 0;
642 for(i = 0; i < 2 * dev->num_fx_ports; ++i)
643 {
644 err = jack_connect(client, jack_port_name(dev->fx_ports[i]), jack_ports[o++]);
645
646 if(err)
647 {
648 FLUID_LOG(FLUID_ERR, "Error connecting jack port");
649 }
650 else
651 {
652 connected++;
653 }
654
655 if(!jack_ports[o])
656 {
657 o = 0;
658 }
659 }
660
661 jack_free(jack_ports); /* free jack ports array (not the port values!) */
662 }
663 else
664 {
665 FLUID_LOG(FLUID_WARN, "Could not connect to any physical jack ports; fluidsynth is unconnected");
666 }
667 }
668
669 return (fluid_audio_driver_t *) dev;
670 }
671
672 /*
673 * delete_fluid_jack_audio_driver
674 */
675 void
delete_fluid_jack_audio_driver(fluid_audio_driver_t * p)676 delete_fluid_jack_audio_driver(fluid_audio_driver_t *p)
677 {
678 fluid_jack_audio_driver_t *dev = (fluid_jack_audio_driver_t *) p;
679 fluid_return_if_fail(dev != NULL);
680
681 if(dev->client_ref != NULL)
682 {
683 fluid_jack_client_close(dev->client_ref, dev);
684 }
685
686 FLUID_FREE(dev->output_bufs);
687 FLUID_FREE(dev->output_ports);
688 FLUID_FREE(dev->fx_bufs);
689 FLUID_FREE(dev->fx_ports);
690 FLUID_FREE(dev);
691 }
692
693 /* Process function for audio and MIDI Jack drivers */
694 int
fluid_jack_driver_process(jack_nframes_t nframes,void * arg)695 fluid_jack_driver_process(jack_nframes_t nframes, void *arg)
696 {
697 fluid_jack_client_t *client = (fluid_jack_client_t *)arg;
698 fluid_jack_audio_driver_t *audio_driver;
699 fluid_jack_midi_driver_t *midi_driver;
700 float *left, *right;
701 int i;
702
703 jack_midi_event_t midi_event;
704 fluid_midi_event_t *evt;
705 void *midi_buffer;
706 jack_nframes_t event_count;
707 jack_nframes_t event_index;
708 unsigned int u;
709
710 /* Process MIDI events first, so that they take effect before audio synthesis */
711 midi_driver = fluid_atomic_pointer_get(&client->midi_driver);
712
713 if(midi_driver)
714 {
715 if(fluid_atomic_int_get(&midi_driver->autoconnect_is_outdated))
716 {
717 fluid_jack_midi_autoconnect(client->client, midi_driver);
718 }
719
720 for(i = 0; i < midi_driver->midi_port_count; i++)
721 {
722 midi_buffer = jack_port_get_buffer(midi_driver->midi_port[i], 0);
723 event_count = jack_midi_get_event_count(midi_buffer);
724
725 for(event_index = 0; event_index < event_count; event_index++)
726 {
727 jack_midi_event_get(&midi_event, midi_buffer, event_index);
728
729 /* let the parser convert the data into events */
730 for(u = 0; u < midi_event.size; u++)
731 {
732 evt = fluid_midi_parser_parse(midi_driver->parser, midi_event.buffer[u]);
733
734 /* send the event to the next link in the chain */
735 if(evt != NULL)
736 {
737 fluid_midi_event_set_channel(evt, fluid_midi_event_get_channel(evt) + i * 16);
738 midi_driver->driver.handler(midi_driver->driver.data, evt);
739 }
740 }
741 }
742 }
743 }
744
745 audio_driver = fluid_atomic_pointer_get(&client->audio_driver);
746
747 if(audio_driver == NULL)
748 {
749 // shutting down
750 return FLUID_OK;
751 }
752
753 if(audio_driver->callback == NULL && audio_driver->num_output_ports == 1 && audio_driver->num_fx_ports == 0) /* i.e. audio.jack.multi=no */
754 {
755 left = (float *) jack_port_get_buffer(audio_driver->output_ports[0], nframes);
756 right = (float *) jack_port_get_buffer(audio_driver->output_ports[1], nframes);
757
758 return fluid_synth_write_float(audio_driver->data, nframes, left, 0, 1, right, 0, 1);
759 }
760 else
761 {
762 int res;
763 fluid_audio_func_t callback = (audio_driver->callback != NULL) ? audio_driver->callback : (fluid_audio_func_t) fluid_synth_process;
764
765 for(i = 0; i < audio_driver->num_output_ports; i++)
766 {
767 int k = i * 2;
768
769 audio_driver->output_bufs[k] = (float *)jack_port_get_buffer(audio_driver->output_ports[k], nframes);
770 FLUID_MEMSET(audio_driver->output_bufs[k], 0, nframes * sizeof(float));
771
772 k = 2 * i + 1;
773 audio_driver->output_bufs[k] = (float *)jack_port_get_buffer(audio_driver->output_ports[k], nframes);
774 FLUID_MEMSET(audio_driver->output_bufs[k], 0, nframes * sizeof(float));
775 }
776
777 for(i = 0; i < audio_driver->num_fx_ports; i++)
778 {
779 int k = i * 2;
780
781 audio_driver->fx_bufs[k] = (float *) jack_port_get_buffer(audio_driver->fx_ports[k], nframes);
782 FLUID_MEMSET(audio_driver->fx_bufs[k], 0, nframes * sizeof(float));
783
784 k = 2 * i + 1;
785 audio_driver->fx_bufs[k] = (float *) jack_port_get_buffer(audio_driver->fx_ports[k], nframes);
786 FLUID_MEMSET(audio_driver->fx_bufs[k], 0, nframes * sizeof(float));
787 }
788
789 res = callback(audio_driver->data,
790 nframes,
791 audio_driver->num_fx_ports * 2,
792 audio_driver->fx_bufs,
793 audio_driver->num_output_ports * 2,
794 audio_driver->output_bufs);
795 if(res != FLUID_OK)
796 {
797 const char *cb_func_name = (audio_driver->callback != NULL) ? "Custom audio callback function" : "fluid_synth_process()";
798 FLUID_LOG(FLUID_PANIC, "%s returned an error. As a consequence, fluidsynth will now be removed from Jack's processing loop.", cb_func_name);
799 }
800 return res;
801 }
802 }
803
804 int
fluid_jack_driver_bufsize(jack_nframes_t nframes,void * arg)805 fluid_jack_driver_bufsize(jack_nframes_t nframes, void *arg)
806 {
807 /* printf("the maximum buffer size is now %lu\n", nframes); */
808 return 0;
809 }
810
811 int
fluid_jack_driver_srate(jack_nframes_t nframes,void * arg)812 fluid_jack_driver_srate(jack_nframes_t nframes, void *arg)
813 {
814 /* printf("the sample rate is now %lu/sec\n", nframes); */
815 /* FIXME: change the sample rate of the synthesizer! */
816 return 0;
817 }
818
819 void
fluid_jack_driver_shutdown(void * arg)820 fluid_jack_driver_shutdown(void *arg)
821 {
822 // fluid_jack_audio_driver_t* dev = (fluid_jack_audio_driver_t*) arg;
823 FLUID_LOG(FLUID_ERR, "Help! Lost the connection to the JACK server");
824 /* exit (1); */
825 }
826
827 void
fluid_jack_port_registration(jack_port_id_t port,int is_registering,void * arg)828 fluid_jack_port_registration(jack_port_id_t port, int is_registering, void *arg)
829 {
830 fluid_jack_client_t *client_ref = (fluid_jack_client_t *)arg;
831
832 if(client_ref->midi_driver != NULL)
833 {
834 fluid_atomic_int_set(&client_ref->midi_driver->autoconnect_is_outdated, client_ref->midi_driver->autoconnect_inputs && is_registering != 0);
835 }
836 }
837
fluid_jack_midi_driver_settings(fluid_settings_t * settings)838 void fluid_jack_midi_driver_settings(fluid_settings_t *settings)
839 {
840 fluid_settings_register_str(settings, "midi.jack.id", "fluidsynth-midi", 0);
841 fluid_settings_register_str(settings, "midi.jack.server", "", 0);
842 }
843
844 /*
845 * new_fluid_jack_midi_driver
846 */
847 fluid_midi_driver_t *
new_fluid_jack_midi_driver(fluid_settings_t * settings,handle_midi_event_func_t handler,void * data)848 new_fluid_jack_midi_driver(fluid_settings_t *settings,
849 handle_midi_event_func_t handler, void *data)
850 {
851 fluid_jack_midi_driver_t *dev;
852
853 fluid_return_val_if_fail(handler != NULL, NULL);
854
855 /* allocate the device */
856 dev = FLUID_NEW(fluid_jack_midi_driver_t);
857
858 if(dev == NULL)
859 {
860 FLUID_LOG(FLUID_PANIC, "Out of memory");
861 return NULL;
862 }
863
864 FLUID_MEMSET(dev, 0, sizeof(fluid_jack_midi_driver_t));
865
866 dev->driver.handler = handler;
867 dev->driver.data = data;
868
869 /* allocate one event to store the input data */
870 dev->parser = new_fluid_midi_parser();
871
872 if(dev->parser == NULL)
873 {
874 FLUID_LOG(FLUID_PANIC, "Out of memory");
875 goto error_recovery;
876 }
877
878 fluid_settings_getint(settings, "midi.autoconnect", &dev->autoconnect_inputs);
879 fluid_atomic_int_set(&dev->autoconnect_is_outdated, dev->autoconnect_inputs);
880
881 dev->client_ref = new_fluid_jack_client(settings, FALSE, dev);
882
883 if(!dev->client_ref)
884 {
885 goto error_recovery;
886 }
887
888 return (fluid_midi_driver_t *)dev;
889
890 error_recovery:
891 delete_fluid_jack_midi_driver((fluid_midi_driver_t *)dev);
892 return NULL;
893 }
894
895 void
delete_fluid_jack_midi_driver(fluid_midi_driver_t * p)896 delete_fluid_jack_midi_driver(fluid_midi_driver_t *p)
897 {
898 fluid_jack_midi_driver_t *dev = (fluid_jack_midi_driver_t *)p;
899 fluid_return_if_fail(dev != NULL);
900
901 if(dev->client_ref != NULL)
902 {
903 fluid_jack_client_close(dev->client_ref, dev);
904 }
905
906 delete_fluid_midi_parser(dev->parser);
907 FLUID_FREE(dev->midi_port);
908 FLUID_FREE(dev);
909 }
910
fluid_jack_obtain_synth(fluid_settings_t * settings,fluid_synth_t ** synth)911 int fluid_jack_obtain_synth(fluid_settings_t *settings, fluid_synth_t **synth)
912 {
913 void *data;
914
915 if(!fluid_settings_is_realtime(settings, "synth.gain") ||
916 (data = fluid_settings_get_user_data(settings, "synth.gain")) == NULL)
917 {
918 return FLUID_FAILED;
919 }
920
921 *synth = data;
922 return FLUID_OK;
923 }
924
925 #endif /* JACK_SUPPORT */
926