-
Notifications
You must be signed in to change notification settings - Fork 258
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
Workaround for jack sample rate mismatch #607
Conversation
How about Also, what about jack changing it's sample rate on the fly? We currently register a callback with |
Alternatively, solve the sample rate problem. Maybe by introducing a "rendering suspended" state into the synth. When going into suspend mode, the audio rendering APIs are still callable, but don't do any real work with the internal structures. They simply return silence. After suspending the rendering, we are free to do any non-realtime stuff and can even access structures in the rendering thread without risk of conflicts. No need for events to be passed to the rendering thread to do stuff, which gives us the ability to return proper error codes etc. As soon as the work is done, we unsuspend the rendering and audio resumes. We could even add a volume ramp up duing the unsuspend, to get rid of any artifacts introduced due to resetting of internal structures. Quite a large job, though :-/ |
Ok, so basically you're voting for 1. :)
I have no clue how to trigger this callback.
Jack's current implementation is not really interested in whether a callback is registered or not. And if we return an error from that callback, Jack only prints an error message: But in any case, I agree.
Just to clarify: Currently, the problem is not how to solve the sample-rate problem. The problem is how or where to get the [...Although you're pointing in the right direction with your proposed solution. I would simplify things: I would not expose the sample-rate change via public API. Instead, when we get a sample-rate change callback, we know that no rendering takes place and we can change the sample-rate via an internal function call. If the synth is used outside the audio driver concurrently, the behavior is undefined. Ofc, that would need to be documented...] The last resort I see without changing the API is to read the e.g. |
If I understand well, your main fear is to ensure that jack driver will work as before for jack user. |
Yes.
Not sure if an on-the-fly adaption is needed via the sample-rate change callback. But an adaption is definitely needed during the creation of the driver. This is because, for all other drivers, fluidsynth can dictate at which sample-rate audio is being written to the hardware. In case of jack however, jack dictates the sample-rate that we must use. If fluidsynth doesn't respect the sample-rate of jack, the audio is being played at a different pitch. |
I wasn't aware of this unilateral behaviour (because I am not a jack user). Thanks for this useful information. |
Ah... yes, I think I am :-)
Ok, that's interesting. Then ignore my comment about the sample rate callback returning an error. We could print a warning here, though. But that's probably off topic here.
And then document that the data pointer for callbacks registered for the sample rate change setting needs to be null or a synth instance? Would also be a solution, I think. But thinking about the original question of this issue again... if I understand correctly then we have introduced a regression that cause both jack audio drivers not to adjust their sample rate to the jack server anymore. And the reason is the deprecation of a function and removal of code calling that function. One way to solve this could be to simply roll back that change completely and restore the previous behaviour. Then think about a proper solution so the sample rate change problem, possibly deprecating the function again. |
Ok, I'll update the PR accordingly later this week.
With the workaround described earlier, I think we have a quite good working solution for now. How we change the sample rate internally can be solved later, I'll file a bug for this. This "internal" solution will be a simple, non-realtime solution, as I've described previously. I want leave the public API call deprecated because I see no way for a better implementation of a real-time sample-rate change. Doing it via |
Ofc, we could also export this "internal" solution via the API, but this would be a breaking change behavior for |
f93fe50
to
3181d67
Compare
During creation of a jack audio driver, it is checked whether the sample-rate of the settings object matches jack's rate. If not, it was adjusted previously via fluid_synth_set_sample_rate(). Due to the deprecation of that function and removal of real-time capability of synth.sample-rate setting, a regression was introduced in 5fbddce causing the synth's sample-rate to be not updated. This workaround obtains the synth via the settings instance and for now calls the deprecated sample-rate set function.
3181d67
to
3ae29e7
Compare
Updated. Now obtaining the synth pointer via the settings. Added a unit test to make sure that this works. And elaborated API doc of |
Do not exit with error if no synth object could be obtained.
During the creation of a jack audio driver, it is checked whether the sample-rate of the settings object matches jack's rate. If not, it was adjusted previously via
fluid_synth_set_sample_rate()
. Due to thedeprecation of that function and removal of the real-time capability of the
synth.sample-rate
setting, a regression was introduced in 5fbddce causing the synth's sample-rate to be not updated. For such a case, a workaround has been added, which restores the previous behavior by causing the sample-rate to be corrected by using the now deprecated functionfluid_synth_set_sample_rate()
(to be improved in the future). Unfortunately, this only works when the driver was created withnew_fluid_audio_driver()
. In case ofnew_fluid_audio_driver2()
we don't have afluid_synth_t
object, so we cannot change the sample-rate.With this change, an annoying deprecation compiler warning will arise during compilation.
Any feedback, how to handle such a sample-rate mismatch is welcome. (@mawe42, @jjceresa??)
I see the following solutions:
synth
pointer), return with an error.new_fluid_audio_driver3 (fluid_synth_t *synth, fluid_audio_func_t func, void *data)
and use thesettings
object that the synth was created with.