Skip to content

About RMIDI

spessasus edited this page Aug 6, 2024 · 23 revisions

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.

RIFF chunk

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.

File structure

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 form sfbk, 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

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 example utf-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

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.

Bank offset

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.

Program and bank Correction

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.