Soundfont SF2 runtime loader

manicksan

Well-known member
I have recently been working on a SF2 reader written in c++
to work together with AudioSynthWavetable
+ a C# testing software

While I have learned about the SF2 file format
I have fixed some export bugs in SoundFontDecoder
Written a similar tool in c# which also shows the "raw" contents of SF2 files
(the export function only prints the cpp+h exports in the tool)

The recent sf2reader
works by lazy loading the sf2 for minimal ram usage
and check for errors while also getting all
important pointers for the chunks

I have been testing it a little and it works ok, but think there is more cleanup to be made
specially when creating the final data structure that can be used with AudioSynthWavetable

I have noticed some crashes, so there is some more work to be done.

load times is visible in the screenshot for the C# test software
the time is measured in microseconds

my final goal is to try it with PSRAM for bigger and/or more instruments can be loaded at the same time
 
I have now fixed the problems that I had.

I also encapsulated it into a class to facilitate the simultaneous loading of multiple files.
This enables faster switching between instruments within a single loaded file.

I've successfully tested PSRAM integration.
PSRAM usage is automatic when PSRAM is available, but it can be directed to utilize internal RAM for specific requirements.
To achieve this, ensure the function ReadSampleDataFromFile is called with the second optional argument set to true.

Currently, the internal RAM allocation is capped at 400,000 bytes, which is modifiable using
the define SF22ASWT_SAMPLES_MAX_INTERNAL_RAM_USAGE in sf22aswt_reader_base.h.
However, as of this writing, I intend to convert this to a local variable for dynamic adjustment at runtime, planned for version 0.1.4.
This forthcoming version will allow setting it with:
SF22ASWT::Samples_Max_Internal_RAM_Cap = 200,000.

It's important to note that the code still handles RAM allocation failures appropriately.
The Samples_Max_Internal_RAM_Cap/SF22ASWT_SAMPLES_MAX_INTERNAL_RAM_USAGE
serves as an early check before attempting any RAM allocation.

Additionally when using external PSRAM the early check assumes full availability of external RAM.
(see future plans at the end of this post for some additional info)

I have made it into a official Arduino Library which can be found with the name: sf22aswt

the current versions that soon will be availabe should be:

* 0.1.4 which i mentioned about above
* 0.1.3 which have hidden certain functions that should not be public,
and make some functions use Print &printStream instead of hardcoding them.
the current version:
* 0.1.2 is otherwise the same as 0.1.3 and 0.1.4

changed the github names as well and here is the new links

* Library: https://github.com/manicken/sf22aswt
* Test GUI: https://github.com/manicken/sf22aswtTester

Examples are available at:

https://github.com/manicken/sf22aswt/tree/main/examples/advanced
https://github.com/manicken/sf22aswt/tree/main/examples/simple

note the sf22aswt.h contains the following:
Code:
#pragma once

#define USE_LAZY_READER

#ifndef USE_LAZY_READER
// using SF22ASWT::reader is currently not fully implemented
// as both List_instruments and Load_instrument is missing from
// sf22asw_reader.h, and is only included for future use
// when more ram is available or for specific demands
#include <sf22aswt_reader.h>
#define SF22ASWTreader SF22ASWT::Reader
#else
#include <sf22aswt_reader_lazy.h>
#define SF22ASWTreader SF22ASWT::ReaderLazy
#endif
and as you can see you can instance the lazy reader directly with
SF22ASWT::ReaderLazy nameOfInstance;
or the shorter version:
SF22ASWTreader nameOfInstance;


Future plans

I'm considering several enhancements for future versions:

* Implementing a memory pool for sample data to minimize memory allocation overhead.

* Enabling loading multiple instruments within the same instance of the reader class.
current implementaion need to have different instances to allow that functionality

* Preset reading - mostly so MIDI files can be played with soundfonts that have complete GM instrument sets
otherwise to also make it possible for different presets that uses the same instruments

* Enabling playback of overlapping key ranges and presets featuring multiple instruments simultaneously.

* Dynamic mixer that somehow allow playing of multiple samples together without loosing any quality


I'm thinking of implementing the polyphonic playback using different instances of AudioSynthWavetable that is then feeded into a mixer object
in that way there is no need to change the code of AudioSynthWavetable

edit. I will also publish the library to PlatformIO (which is my main development platform)
 
Last edited:
Back
Top