Author Topic: Can I load a SoundFont from memory instead of from a file?  (Read 82 times)

ManlioMZ

  • Posts: 16
As far as I can tell, BASS_MIDI_FontInit only accepts files (e.g. GM.SF2) as input.

However I would very much like to be able to load the SF2 not from a file but from memory. The reasons for doing so include:

A) I use some small SF2 files that are embedded as resources in the Windows exe file. Normally one extracts such resources to memory streams (TMemoryStream or TResourceStream in Delphi/FPC) and uses them that way. But in the case of SF2 files it looks like I must first save those streams to an actual file somewhere, and then call BASS_MIDI_FontInit() with that file name.

B) I would not like my SF2 files to be easily copied by users. I'd like to keep my small SF2 files embedded in the exe and load them into BASS_MIDI_FontInit without having to use intermediate regular files, which are easily copied.

Is this possible at all?

Thank you!

Falcosoft

  • Posts: 65
There is an undocumented flag BASS_MIDI_FONT_MEM that is defined in Bassmidi's header file.
So you can use BASS_MIDI_FontInit(SoundfontBufferAddress, BASS_MIDI_FONT_MEM) call to load soundfont from memory.
Be aware that Bassmidi does not make a copy of the buffer so it has to be kept in memory while Bassmidi uses it. At least that is what I experienced. Contrary if you use compressed samples in SFPack soundfonts it seems the buffer can be freed right after font init is done since Bassmidi uses its own uncompressed image.
The above is just based on my own experiences so wait for Ian to confirm/refute my claims.

ManlioMZ

  • Posts: 16
So you can use BASS_MIDI_FontInit(SoundfontBufferAddress, BASS_MIDI_FONT_MEM) call to load soundfont from memory.

Thank you!! It worked perfectly on Windows.

Ian, can you kindly let us know if this may work on other systems as well?

And anything else we need to know -- limitations/dangers in using this method?

When I get the chance I'll test it on Mac and Android and will update this post accordingly.

Thanks again!

PS: For a moment I wondered how the method may work when you only pass the pointer to the buffer to it, but not its size. Then I realized that SF2 files are in RIFF format, and the size is written in the beginning of the buffer itself.

Ian @ un4seen

  • Administrator
  • Posts: 23743
The BASS_MIDI_FONT_MEM flag used to be a documented feature but it was deprecated when the BASS_MIDI_FontInitUser function was introduced, because the latter is safer. As you say, the main issue when using the BASS_MIDI_FONT_MEM flag is that it isn't possible to tell BASS_MIDI_FontInit how big the file is, so BASSMIDI just gets the length from the SF2 file's RIFF header. That's fine if you're sure the file is valid (eg. it's bundled with the app) but might not be safe if the user provides their own (it could be corrupt). If you would prefer to stick with the BASS_MIDI_FONT_MEM flag (rather than BASS_MIDI_FontInitUser) then you could precheck the file's header before passing it to BASS_MIDI_FontInit to be safe.

When using the BASS_MIDI_FONT_MEM flag, the provided memory should be kept valid until BASS_MIDI_FontFree is called to free the soundfont. That's generally true for compressed soundfonts (sf2pack) too, except perhaps if you preload all of the soundfont's samples (via BASS_MIDI_FontLoad).