Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revise jack driver #416

Closed
derselbst opened this issue Jul 11, 2018 · 15 comments
Closed

Revise jack driver #416

derselbst opened this issue Jul 11, 2018 · 15 comments
Milestone

Comments

@derselbst
Copy link
Member

The implementation of fluid_jack.c has many open TODOs and needs to be revised. Potentially also taking #79 into account.

@derselbst derselbst added this to the 2.0-post milestone Jul 11, 2018
@derselbst
Copy link
Member Author

It seems that the current implementation is not able to start two audio jack drivers: A first jack client is created, but the second client simply reuses the first client. The output_ports of the first client have already been setup, but they will be set up again by the second call, which is not possible as they already exist, thus jack_port_register() returns NULL, essentially overwriting the correctly set up ports. This will then cause the jack_port_get_buffer() to return a NULL buffer, which will be passed to fluid_synth_write_float(). Crash.

@rncbc
Copy link
Contributor

rncbc commented Sep 17, 2018

I can confirm that the current implementation (as of released V2.0.0) is not able to start or run more than one audio jack driver; for instance Qsynth crashes/segfaults when trying to create a second engine.

This issue is currently a qsynth-git (on libfluidsynth2) showstopper, at least for the folks that have more than one qsynth engine working fine for ages (on libfluidsynth1).

@derselbst
Copy link
Member Author

But I cant think of any significant change to the jack driver that explains why it worked in fluidsynth1. And it seems not that trivial to fix either :/

@mawe42
Copy link
Member

mawe42 commented Sep 17, 2018

I just tried to recreate the problem and also got the core dumps. Compiled qsynth from github master, with fluidsynth from github master. Ran qsynth with jack as audio driver (I had already two synths from a previous configuration) => core dump.

Finally I deleted my ./config/Qsynth.conf file, started Qsynth with jack, added three different synths and had no crashes. Even after quitting and starting (with all three synths being created succesfully), no crashes. Sadly I didn't keep a copy of the old config to see whats different.

@mawe42
Copy link
Member

mawe42 commented Sep 17, 2018

I could recreate the crashes again, but only when I choose a fairly large SF3 soundfont for one of the synths, like the MuseScore_General.sf3. Smaller SF3 files don't seem to trigger the crash. And even very large SF2 files don't trigger it, but they load quite quickly anyway. Could it be a timing/locking issue?

@rncbc
Copy link
Contributor

rncbc commented Sep 17, 2018

seems that having Options > Output peak level meters turned on makes all the difference...

on ~/.config/rncbc.org/Qsynth.conf:

[Options]
OutputMeters=false

when set to true it crashes on sight of a second engine.

@mawe42
Copy link
Member

mawe42 commented Sep 17, 2018

I'm not sure it's even Qsynth related. I can reproduce the crash with fluidsynth, a Jack server running and loading an SF3 file on the command line. It crashes here:

client_ref->client = jack_client_open(name, JackNullOption, NULL);

When specifying a new server name with audio.jack.server it uses the jack_client_open above that and everything works fine:

client_ref->client = jack_client_open(name, JackServerName, NULL, server);

@mawe42
Copy link
Member

mawe42 commented Sep 17, 2018

I've got the feeling it's connected to the new sample loading mechanism. It crashes with SF2 and dynamic-sample-loading enabled, and with SF3 regardless of dynamic-sample-loading. Just not with a very small SF3 file. This is really strange...

@rncbc
Copy link
Contributor

rncbc commented Sep 18, 2018

i can confirm the finding in #416 (comment), a second JACK client is not created at least with the given client name and no new JACK client/ports are registered, whenever a second Qsynth engine is setup to "jack" audio driver, even thought output peak level meters option is turned off--if turned on, it crashes, most probably on the second bogus client's fluid_jack_driver_process() ... just sayin' :)

@mawe42
Copy link
Member

mawe42 commented Sep 18, 2018

As @derselbst has noticed, there's a bug in jack2 where failed mlock calls are not properly handled, leading to segfaults. I can confirm that setting the memlock limits on my machine to unlimited, I can start jackd, qsynth from current master, create 4 synth instances all using jack as output, assign sf3 and/or sf2 soundfonts and play them all using jack-keyboard.

edit: and enabling output meters works fine as well

@rncbc
Copy link
Contributor

rncbc commented Sep 18, 2018

i can confirm also, the weird finding in #416 (comment), when starting with qsynth -o audio.jack.server=default, a second JACK client engine gets created and ports registered alright and having OutputMeters=true won't crash Qsynth either.

this is specially weird as this JACK server name is/was considered a terrible mistake on JACK design to start with (Paul Davis words, not mine:)).

@mawe42
Copy link
Member

mawe42 commented Sep 18, 2018

As I wrote in #431, it seems to all come down to who get's first grabs on the limited amount of mlock'able memory. If jack succeeds, then it's all fine. If someone else (e.g. fluidsynth) gets it and there's non left for jack, it crashes with a segfault.

@rncbc
Copy link
Contributor

rncbc commented Sep 18, 2018

As @derselbst has noticed, there's a bug in jack2 where failed mlock calls are not properly handled,

FWIW: i've tested on jack2 (1.9.12) and jack1 (0.125.0) with either "No memory lock" option on and off (-m): no difference.

however, the qsynth -o audio.jack.server=default seems to work out which is still weird and a pointer to fluid_jack implementation fault, somewhere :)

@mawe42
Copy link
Member

mawe42 commented Sep 18, 2018

FWIW: i've tested on jack2 (1.9.12) and jack1 (0.125.0) with either "No memory lock" option on and off (-m): no difference.

The "No memory lock" option doesn't seem to disable the memory lock in the place that is triggering the bug. It's a memlock attempted in an mmap call, for a mutex:
jackaudio/jack2@cc8576a

@derselbst
Copy link
Member Author

After I've patched jack to correctly check for mmap(), I started qsynth again, attempting to run >10 instances.

when starting with qsynth -o audio.jack.server=default, a second JACK client engine gets created and ports registered alright

Doesnt work for me. Only the first qsynth instance is able to create a driver. Subsequent instances fail to create the audio driver: fluidsynth: error: Failed to connect to Jack server.

Weird issue indeed. Necessitates some serious investigation, which I'm currently lacking time for.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants