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 for SF2 RMIDI files with embedded soundfonts #1356

Open
spessasus opened this issue Jul 21, 2024 · 9 comments
Open

Support for SF2 RMIDI files with embedded soundfonts #1356

spessasus opened this issue Jul 21, 2024 · 9 comments

Comments

@spessasus
Copy link
Contributor

spessasus commented Jul 21, 2024

FluidSynth version

Execute fluidsynth --version and provide the output.

FluidSynth runtime version 2.3.5
Copyright (C) 2000-2024 Peter Hanappe and others.
Distributed under the LGPL license.
SoundFont(R) is a registered trademark of Creative Technology Ltd.

FluidSynth executable version 2.3.5
Sample type=double

SF2 RMIDI specification

The feature request

Fluidsynth would be able to open RIFF midi (.rmi) files.
Bonus points for also reading the embedded sf2 file and using it.

Simple solution

  1. check if the file starts with RIFF instead of MThd
  2. check if the data chunk starts with RMID
  3. The first chunk is called data. The data of the chunk is the MIDI file (complete with MThd, etc).
  4. Loop through the following chunks (there may be a metadata INFO chunk. Read the DBNK chunk which is the soundfont's bank offset, others can be ignored)
  5. Find the chunk with header RIFF and the data that starts with 'RIFF' or 'DLS '. This is the embedded soundfont or dls. The provided file has an sf2 embedded, not dls.

Steps to reproduce

Please explain the steps required to duplicate the issue, esp. if you are able to provide a sample application. E.g. how to start fluidsynth, what shell commands to enter, what midi events to send, etc.

  1. get an .rmi file Example files
  2. fluidsynth soundfont.sf2 the_file.rmi
@spessasus spessasus added the bug label Jul 21, 2024
@spessasus spessasus changed the title Cannot onen RMID files Cannot open RMID files Jul 21, 2024
@derselbst derselbst added enhancement and removed bug labels Jul 21, 2024
@derselbst
Copy link
Member

RMID is a different file format than MIDI, which is currently not supported. Hence, this is a feature request, not a bug. And to be frank, my personal motivation to support this is nearly non-existent. Fluidsynth's builtin MIDI player is very basic. Yet, I would probably accept a PR for this.

@spessasus spessasus changed the title Cannot open RMID files Support for .rmi files with embedded soundfonts Jul 28, 2024
@spessasus
Copy link
Contributor Author

I wrote a complete and precise version of the SF2 RMIDI standard and I've updated the link in the issue.

Also, here's another test file:
Field.rmi

@spessasus spessasus changed the title Support for .rmi files with embedded soundfonts Support for SF2 RMIDI files with embedded soundfonts Aug 8, 2024
@derselbst
Copy link
Member

I didn't look up any official RMID spec. But pls. keep in mind that RIFF usually has a 16-bit alignment requirement. The embedded SF probably fulfills this requirement. I'm not sure if the MID has to, but if is has, it won't be a simple "read MIDI from memory" operation. One would first has to get rid of the padding bytes.

@spessasus
Copy link
Contributor Author

I didn't look up any official RMID spec. But pls. keep in mind that RIFF usually has a 16-bit alignment requirement. The embedded SF probably fulfills this requirement. I'm not sure if the MID has to, but if is has, it won't be a simple "read MIDI from memory" operation. One would first has to get rid of the padding bytes.

The pad bytes aren't taken into account within the RIFF chunks. That's how the specification describes it and that's how Microsoft's RMIDIs are made as well.

image
As you can see, the chunk size is odd, while the actual chunk has bytes ad the end.

MIDI file i used

@spessasus
Copy link
Contributor Author

Also I've linked the specification for the SF2 RMIDI format, which is backwards compatible with the DLS version, so simply using that would work.

@derselbst
Copy link
Member

Ok. So then my preference of implementing this would be to teach both, the MIDI player and the soundfont loader to handle and accept rmid files (rather than memory mapping the file and loading from memory).

@spessasus
Copy link
Contributor Author

Ok. So then my preference of implementing this would be to teach both, the MIDI player and the soundfont loader to handle and accept rmid files (rather than memory mapping the file and loading from memory).

Yes, but the soundfont loader also has to load the DBNK chunk from the INFO chunk to set the bank offset correctly.

@spessasus
Copy link
Contributor Author

Okay, I think I need to clear things up:

So, here's the official doc from MMA (via internet archive):
https://web.archive.org/web/20110610135604/http://www.midi.org/about-midi/rp29spec(rmid).pdf

This (official) version only supports DLS and poses a few issues:

  1. DLS is not used anymore, like at all, where soundfonts still are, and some are really, really high quality.
  2. This stash of the DLS RMIDIS shows me a few issues:
    • Some of the files assume a GM soundbank at bank 0 and DLS at bank 1 (see AWEBLOWN.rmi)
    • Some however, assume DLS loaded at bank 0. (see PMDawn.rmi)
    • My program currently gets around this by searching for all bank selects and if it finds one that isn't 0 or 127, then the bank offset is 1, otherwise 0. But this solution isn't ideal.
  3. See Incorrect DLS Support #1373. This does not apply to sf2 in fluidsynth.

This is why I propose to add the new SF2 Version that I created with help of Zoltán Bacskó from Falcosoft. This version solves all of the problems mentioned above:

  1. It uses soundfonts instead of DLS. It also allows SF3 compression which further reduces the file size.
  2. It explicitly states the bank offset the soundfont shall get loaded at.
  3. It also allows for more metadata than the old RMI files.

Getting it supported in fluidsynth would help a lot in it getting more popular as fluid is a very well known sf2 synth.
I also think that implementing it is rather easy as it's just:

  1. Load the RIFF LIST.
  2. load the data chunk as SMF.
  3. Load the inner RIFF chunk as a soundfont bitstream.
  4. Check for INFO chunk and DBNK chunk within.
  5. If present, load the soundfont at a given bank, otherwise at bank 1.

Bonus: this logic should also work for DLS files as they too have RIFF but with DLS instead of sfbk. The thing about DLS is having to either assume one of the offsets or detect it like my program does.

@spessasus
Copy link
Contributor Author

Any updates on this?

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

No branches or pull requests

2 participants