-
-
Notifications
You must be signed in to change notification settings - Fork 13
About RMIDI
SpessaSynth supports exporting to RMIDI, which is essentially MIDI + SF2 as a single file. As there's no specification on this type of RMIDI available, this page can serve as an "unofficial documentation" to this format.
This version of RMIDI does not use DLS and has been created (I think) by Falcosoft MidiPlayer6. I'm currently in contact with Falco and we're working on improving this format.
Below is a basic riff chunk structure. This applies to all chunks in the RMID file:
- 4 bytes representing the chunk header in ASCII (for example
RIFF
) - 4 bytes representing the chunk's size as a 32-bit little-endian number
- the chunk's data. Optionally the first 4 bytes form an ASCII string of the chunk's type (example
sfbk
)
Caution
The chunk's size MUST BE even. If the initial chunk data is odd, a pad byte of 0 must be added at the end. The chunk's length must not take the pad byte into account.
Important
The above constraint only applies to the RIFF chunks in the RMIDI file. This doesn't apply to the RIFF chunks in the soundfont chunk.
The following describes how is the RMID file formed:
RIFF
chunk (the main chunk)
-
RMID
ASCII string -
data
chunk -
- The complete MIDI file (MThd, MTrk, etc)
- Optional
LIST
chunk: metadata of the file. Very similar to SF2's chunk -
-
INFO
ASCII string
-
-
RIFF
chunk - the complete soundfont binary. Note that the first 4 bytes of the chunk should formsfbk
, like in a normal soundfont, to indicate that this is an SF2 soundfont and not a DLS one. SF3 compressed soundfonts are allowed.
If any other chunks are encountered, they should be ignored.
The info chunk describes the metadata of the file. Rules:
- If any other RIFF chunks are encountered within the INFO chunk, they should be ignored.
- The chunk size has to be even as described in the general riff structure.
It has the following fields:
- Optional
INAM
chunk: Song name. Preferably the same as the MIDI file, but doesn't have to be. - Optional
ICOP
chunk: Copyright. String of any length. - Optional
IART
chunk: Artist (MIDI creator). String of any length. - Optional
ICRD
chunk: Creation date. String of any length. - Optional
IPRD
chunk: Album name. String of any length. - Optional
IPIC
chunk: Attached picture (album cover for example). Binary picture data. A PNG or JPEG is recommended. - Optional
IGNR
chunk: song's genre. String of any length. - Optional
ICMT
chunk: comment/description. String of any length. - Optional
IENG
chunk: Engineer (the soundfont creator). String of any length. - Optional
ISFT
chunk: Software used to create the file. String of any length. - Optional
IENC
chunk: The encoding to use for other info chunks, string. (For exampleutf-8
). Not case sensitive, but lowercase is preffered. If not specified, ASCII is assumed. Note that this field MUST use ASCII encoding. - Optional
DBNK
chunk: The soundfont's bank offset. Sse this
It's up to the software to determine which is the name of the file (track name in MIDI or INAM chunk) although INAM chunk is preffered. The compatible software may ignore all chunks in the INFO chunk, except for the DBNK chunk.
The DBNK chunk is an optional RIFF chunk for the RMID INFO List. It always has a length of 2 and the 2 data bytes form a 16-bit little-endian offset for the soundfont banks.
Currently the boundaries are: min: 0 and max: 127. The other byte is reserved for future use.
All banks can be offset in the MIDI file and the soundfont. For example, offset of 1 means that every bank in the soundfont is incremented by 1. For drums the bank is 1. For XG, the behavior is not yet defined.
Note that the MIDI must use valid banks and presets as MP6 will fallback to the loaded soundfont instead of defaulting to preset 0 of the embedded soundfont. The behavior of missing preset requested in the MIDI sequence is undefined. Also the system cannot be GM since bank is ignored there. Either GS or XG are valid. This requires sanitizing the midi and putting either GS or XG on at the start.
If no DBNK is specified, offset of 1 is assumed by default.
Note that this should be reflected in the MIDI file itself:
- If DBNK is 1 and MIDI wants to use preset 001:080, it should call bank select of 2 instead of 1.
- If DBNK is 0, no offset is applied and the MIDI is unchanged.
If DBNK is 0, the system can be GM as the soundfont gets loaded at bank 0.
In MidiPlayer6, all banks seem to be offset by 1 by default. It can be set to 0 by altering the Real Time Loaded SF2 Default Bank
value to 0 in Device Settings
dialog.
In the future, it will also be affected by the DBNK chunk described above.
This means that to get bank 1, send bank select 2 in the embedded MIDI, etc.
Using bank 0 in MP6 leads to the loaded soundfont being used, not the embedded one. For drums the bank is 1 in XG.
The MIDI must use valid banks and presets as MP6 will fallback to the loaded soundfont instead of defaulting to preset 0 of the embedded soundfont. Also the system cannot be GM since bank is ignored there. Either GS or XG are valid. This requires sanitizing the midi and putting either GS or XG on at the start.
Tip
If you encounter any errors in this documentation, please open an issue!
Warning
Make sure you always update worklet_processor.min.js
along with the npm package!