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

Support Loading DLS Files #493

Merged
merged 26 commits into from
May 11, 2019
Merged

Support Loading DLS Files #493

merged 26 commits into from
May 11, 2019

Conversation

derselbst
Copy link
Member

@derselbst derselbst commented Dec 30, 2018

This is a RFC PR that attempts to support DLS as requested in #320 (perhaps also GigaSampler and SLI). I intend to bring this feature to the mailing list when it's ready, but for now, see this as alpha test.

DLS support is brought by libinstpatch, as suggested by the "Future" wiki page. CMake queries for it during compilation. If found, it adds a libinstpatch sfloader to the synth (fluid_instpatch.c).

fluid_instpatch.c basically works, but could be improved:

  • currently ignores synth.dynamic-sample-loading (IMO, this is the responsibility of libinstpatch)
  • allocates presets on-the-fly as needed, i.e. no preset pool
  • when loading a DLS file the defsfont loader complains that it's no SF2 file, which is a little annoying... one might need to rethink that

I've so far only tested this with a few DLS files. I'm not familiar with GigaSampler or SLI. It would be great if someone could give it a test. Ofc. general feedback is appreciated as well.


Why using libinstpatch?

Pro:

  • It's LGPL licensed (although the COPYING claims GPL)
  • It provides a C API
  • Most of the necessary implementation for this sfloader already exists in the fluidsynth-plugin for swami
  • It provides a converter that converts all its supported files to SF2 voice model, which makes it easy to use for fluidsynth (generators, modulators,... everything is there after a single convert)
  • Uses refcounting for every object, which makes it uncomplicated on cleanup

Con:

  • There are many issues in the code: Neither the stable 1.0.0 release nor recent git version is working
    • mostly due to incorrect GValue assignments and incorrect mutex (un-)locking
    • as a workaround I patched my own working version (you know that it works when you don't get any Glib - CRITICAL ** assertions on DLS loading)
  • Libinstpatch claims DLS and eps. GigaSampler support to be incomplete, but I don't know how severe this incompleteness is

Any alternative to libinstpatch? Yes: libgig

Pro:

  • Seems to be more complete and mature for DLS and GigaSampler

Con:

  • GPL licensed
  • Only provides a C++ API (haven't looked to close at it)

Both Cons are not too severe, but might restrain the number of users making use of it.

@derselbst derselbst added this to the 2.1 milestone Dec 30, 2018
@jjceresa
Copy link
Collaborator

jjceresa commented Jan 4, 2019

This is a RFC PR that attempts to support DLS as requested in #320 (perhaps also GigaSampler and SLI). I intend to bring this feature to the mailing list when it's ready, but for now, see this as alpha test.

This opens the door to other soundfont file formats by selecting at Cmake time the sfloader(s) need by the application. This is nice.

when loading a DLS file the defsfont loader complains that it's no SF2 file, which is a little annoying... one might need to rethink that

When fluid_synth_sfload() is called it uses all the fluid_sfloader_t loader (in the list) until loading is successful. Assuming the following loaders list: sfload1, dls loader, defsfont. When loading a file fails for sfload1, and dls loader this failure should be done silently. But when defsfont fails, as it is a sf2 loader and the last in the list it seems normal for a message to be displayed. Isn't it ?

@derselbst
Copy link
Member Author

But when defsfont fails, as it is a sf2 loader and the last in the list it seems normal for a message to be displayed. Isn't it ?

Nearly: The instpatch loader is the last one in the list. This is because libinstpatch would also accept sf2 files, which we want to be loaded by the defsfont loader though. Anyway, yes, a message should only be printed if all sfont loaders failed. However every loader keeps printing messages as soon as it encounters an "invalid" soundfont, which in fact is useful if an application only uses the API, but is annoying when using the fluidsynth executable.

@mawe42
Copy link
Member

mawe42 commented Jan 5, 2019

I really like the fact that adding libinstpatch loader support to Fluidsynth seems to be fairly non-intrusive to the rest of the codebase. I know that it's not complete and still has issues (which probably means more intrusive changes), but still... I think it's a sign that Fluidsynth has quite a good architecture.

What I'm not really sure about is if it's a good idea to add support for other sampler formats to Fluidsynth. If the foreign format is less expressive than Soundfont, it would be fine. Same if the foreign format is exactly like Soundfont, just with a different file structure.

Where I have problems is adding support for sampler formats that are more expressive or that rely on features that are difficult to reproduce in the Soundfont model. Where loading the foreign file would mean that Fluidsynth would perform worse than a synth native to that format. We would have to be very clear about what users should expect when loading these files. Otherwise I'm afraid that we will get lots of "X can play this much better than Fluidsynth" bug reports.

TLDR: I'm very fond of the fact that Fluidsynth is currently focussed on being an extremely good (if not the best) Soundfont synth. And I'm afraid that if we open up to other formats, we will loose some of that focus.

PS: At least the linuxsampler code is a strange form of GPL, because the authors forbid the use for commercial projects (even if those projects comply with the GPL). Not sure if that also applies to the libgig code.

@mawe42
Copy link
Member

mawe42 commented Jan 5, 2019

To clarify my thoughts: my opinion is that adding loaders for advanced formats like GigaSampler would only make sense if we would also change and extend the synthesis model at the same time. In other words: if we were to move more into the direction of LinuxSampler and implement different synthesis engines for the different formats. Otherwise we would simply add code that would make Fluidsynth a bad GigaSampler synth. And there is already a very good GigaSampler synth out there: LinuxSampler.

@derselbst
Copy link
Member Author

And I'm afraid that if we open up to other formats, we will loose some of that focus.

Sure, I understand this. I think that's a matter of documentation. We could claim smth. like limited or partial DLS support. Similar to like it's said in the sfont loader API:

This API allows for virtual SoundFont files to be loaded and synthesized, which may not actually be SoundFont files, as long as they can be represented by the SoundFont synthesis model.

We can keep this limited to DLS support for now, as this was the intention of #320. Citing ElementGreen, DLS and SF2 are very similar, except that DLS is "more" expressive because it supports 32 bit parameters, rather than 16 bit as SF2 does.

The idea of GigaSampler only came up because libinstpatch supports them as well by loading DLS files and then recognizing those as GigaSampler files. But I can't tell anything about the relation between GigaSampler and DLS.

In other words: if we were to move more into the direction of LinuxSampler and implement different synthesis engines for the different formats.

You're right. And I'm not intending to shift our focus. Fluidsynth should stay a SF2 synth. Supporting DLS just seems to be a nice idea as much/most/all (?) of DLS can be represented by the SoundFont synthesis model. And if there are any incorrect envelopes or attenuation calculations for DLS, keep in mind that there is limited / partial support.

As next steps I suggest:

  1. Test more DLS files to figure out the current state of support (I have not been very successful in finding them on the web, if you have any it would be nice to submit them)
  2. Test a very few GigaSampler files just to see how it works (well/barely/not at all ?) and how to treat them
  3. Decide whether to go with libinstpatch or not (I'm confident though)
  4. Fix libinstpatch upstream + new release

PS: At least the linuxsampler code is a strange form of GPL, because the authors forbid the use for commercial projects (even if those projects comply with the GPL). Not sure if that also applies to the libgig code.

No, it doesn't.

@mawe42
Copy link
Member

mawe42 commented Jan 6, 2019

Fluidsynth should stay a SF2 synth. Supporting DLS just seems to be a nice idea as much/most/all (?) of DLS can be represented by the SoundFont synthesis model.

I agree, if DLS really is like "high-resolution Soundfont", then it seems like a very good fit and adding support is a good idea, especially as there is actual user demand for this feature.

I have not been very successful in finding (DLS files) on the web, if you have any it would be nice to submit them

To be honest, I had never even heard of DLS before reading the ticket. Maybe @frabert (the original reporter of the ticket) could supply some?

Your proposed way forward sounds good. And going with libinstpatch instead of libgig feels better to me (regardless of code quality / maturity) as libgig looks to be a GigaSampler library first and foremost. And using such a lib when we can't completely support that format would send the wrong message, I think. Granted, a message that not many people will hear or understand... :-)

@jjceresa
Copy link
Collaborator

jjceresa commented Jan 6, 2019

Make use of libinstpatch to add sfloader seems a good choice. This should helps later to propose a virtual soundfont loader optional component (or at least documentation to do that). This kind of sfloader should simplify the integration of fluidsynth lib into soundfont editor application. Actually free soundfont SF2 editor aren't massive. Also there is few or none free SF2 editor integrating a full SF 2.0 synthesizer engine with modulators capabilities. Probably the reason is that data edition and synthesis are two jobs so different that coupling a synthesizer inside an SF editor is really a hard task for most SF editor developer. Thanks to this PR, libinstpath lib and author(s).

@frabert
Copy link

frabert commented Jan 6, 2019

@mawe42 Unfortunately I do not have any freely redistributable DLS file, but every Windows copy ships with c:\windows\system32\gm.dls, which is used for General MIDI patches by the system's softsynth.

@derselbst derselbst changed the title [RFC] Support Loading DLS Files Support Loading DLS Files Mar 17, 2019
@derselbst
Copy link
Member Author

Meanwhile, I've tested a bunch of DLS files and they all play fine. Gig files are problematic though, because they currently cause lots of crashes in libinstpatch due to a nasty int to pointer cast.

@derselbst
Copy link
Member Author

derselbst commented Apr 20, 2019

As this seems to be a very popular feature, open TODOs right now:

  • implement IO callbacks (postponed until really needed, only workaround possible, instpatch loader isn't currently public anyway)
  • make sure it doesn't crash when dls font is unloaded while its samples are still used for rendering
  • check for memory leaks (samples unloaded correctly)

@derselbst
Copy link
Member Author

Considering this ready for squashing.

@mawe42, @carlo-bramini Any of you available for a review?

@derselbst derselbst requested review from mawe42 and carlo-bramini and removed request for mawe42 May 5, 2019 12:01
Copy link
Member

@mawe42 mawe42 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks very good, thanks a lot! I haven't compiled or tested it yet, so this review is based on a quick read through the code. All very nice and clean, just a few minor nit-picky formatting, style and wording comments. Will have more time for testing next week, if required.

src/sfloader/fluid_instpatch.c Show resolved Hide resolved
src/fluidsynth.c Outdated Show resolved Hide resolved
src/fluidsynth.c Outdated Show resolved Hide resolved
src/sfloader/fluid_sffile.c Outdated Show resolved Hide resolved
src/synth/fluid_synth.c Outdated Show resolved Hide resolved
src/sfloader/fluid_instpatch.c Outdated Show resolved Hide resolved
src/sfloader/fluid_instpatch.c Outdated Show resolved Hide resolved
src/sfloader/fluid_instpatch.c Outdated Show resolved Hide resolved
src/sfloader/fluid_instpatch.c Outdated Show resolved Hide resolved
src/sfloader/fluid_instpatch.c Outdated Show resolved Hide resolved
@derselbst
Copy link
Member Author

Thanks for the quick review Marcus! Hope I've addresses all issues. (I should have executed make format earlier)

Will keep this open for another 3 or 4 days. Anybody, feel free to test or give feedback.

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

Successfully merging this pull request may close these issues.

4 participants