-
-
Notifications
You must be signed in to change notification settings - Fork 14
SoundFont2 Class
This module handles parsing and writing SoundFont2 (.sf2
and .sf3
) files.
It also contains support for .dls
files.
Tip
If you encounter any errors in this documentation, please open an issue!
// normal install
import { loadSoundFont } from "./spessasynth_lib/soundfont/load_soundfont.js";
// npm package
import { loadSoundFont } from "spessasynth_lib";
Tip
Using the npm package? Make sure you've read this
const soundFont = loadSoundFont(arrayBuffer);
-
arrayBuffer
- AnArrayBuffer
representing the binary file data either DLS level 1/2 or SoundFont2.
The returned value is the parsed BasicSoundFont
, described below.
Returns the matching Preset
class instance.
const preset = soundFont.getPreset(bankNr, presetNr);
-
bankNr
- MIDI bank number, typically set with theBank Select
controller. -
presetNr
- MIDI program number, usually set with theProgram Change
message.
If the matching preset is not found, the first preset will be returned. If the requested bank is 128, the first preset with bank 128 will be returned (drums).
Returns the matching Preset
class instance.
const preset = soundFont.getPresetByName(presetName);
-
presetName
- The name of the preset as a string. If not found, the first preset will be returned.
Write out an SF2 or SF3 file. The return value is an Uint8Array
- the binary of the file.
const binary = soundFont.write(options);
-
options
- An optional object:-
compress
- Aboolean
indicating if uncompressed samples should be compressed using the lossy Ogg Vorbis codec. This significantly reduces file size. -
compressionQuality
- Anumber
from -0.1 to 1, indicating compression quality. 1 is the best, -0.1 is the worst. -
compressionFunction
- See this for a detailed explanation
-
Important
If the SoundFont was already compressed, it will not be decompressed to avoid losing quality.
Warning
This method is memory and CPU intensive with large SoundFonts, especially if compression is enabled.
Writes out a DLS Level 2 sound bank. The return value is an Uint8Array
- the binary of the file.
Caution
This method is experimental and may produce corrupted files. See this for more info.
Warning
This method is memory and CPU intensive with large SoundFonts.
Merges multiple SoundFonts, adding (not replacing) presets on top of the previous ones, and returns a new SoundFont.
BasicSoundFont.mergeSoundfonts(soundfont1, soundfont2, soundfont3, /* more here... */);
-
soundfonts
-BasicSoundFont
instances, with any number of inputs. The first is used as a base, and the rest are added on top.
The return value is a new BasicSoundFont
.
Note
This method is static.
An array of all presets in the SoundFont, ordered by bank and preset number.
console.log(soundFont.presets);
Represents the SoundFont2's INFO
chunk data. Stored as an object like this:
const infoData = {
chunk: /* the read's 4-letter code, e.g. */ "INAM",
infoText: /* the read's data as text, e.g. */ "My cool SoundFont"
}
Check out this website for more information.
Important
ifil
and iver
are stored as strings like this: major.minor
.
For example, major 2 minor 1 will be 2.1
Trims the SoundFont in place to only include samples used in the MIDI sequence, down to the exact key-velocity combinations.
import { trimSoundfont } from './spessasynth_lib/soundfont/write/soundfont_trimmer.js'
trimSoundfont(soundfont, midi);
-
soundfont
-SoundFont2
- The SoundFont to trim. -
midi
-MIDI
- The MIDI file for which to trim the SoundFont.
Creates a fake soundfont with a single saw wave preset. Useful when a synthesizer initialization is needed but the proper soundfont isn't ready yet.
const sfBinary = BasicSoundFont.getDummySoundfontFile();
- the returned value is an
ArrayBuffer
- the binary represenation of a soundfont file.
Note
This method is static
The following describes the internal structure of a SoundFont and includes some methods not mentioned above. Useful for editing the SoundFont.
Legend:
-
Methods:
methodName (argumentName: type) -> description
-
Properties:
propertyName (type) -> description
Warning
Internal values not described here, such as modulatorZoneSize
, should not be tampered with.
-
soundFontInfo
(described above) -
deletePreset
(preset: Preset) -> Deletes a given preset. -
deleteInstrument
(instrument: Instrument) -> Deletes a given instrument. Cannot delete it if it's used. -
deleteSample
(sample: Sample) -> Deletes a given sample. Cannot delete it if it's used. -
instruments
(Instrument[]) -> All instruments. -
samples
(Sample[]) -> All samples. -
presets
(Preset[]) -> All presets. Note: Some methods are omitted. Click the link for the full description of thePreset
class.-
presetName
(string) -> The name of the preset. -
program
(number) -> The preset's MIDI program. -
bank
(number) -> The preset's MIDI bank. -
library
(number) -> Generally unused but preserved. -
genre
(number) -> Generally unused but preserved. -
morphology
(number) -> Generally unused but preserved. -
preload
(keyMin: number, keyMax: number) -> Preloads all samples for the given range. -
deleteZone
(index: number) -> Deletes a given preset zone and instrument if not used by anything else. -
presetZones
(PresetZone[]) -> All zones of the preset.-
keyRange
({min: number, max: number}) -> Key range of the zone. -
velRange
({min: number, max: number}) -> Velocity range of the zone. -
generators
(Generator[]) -> Generators of the zone. -
modulators
(Modulator[]) -> Modulators of the zone. -
isGlobal
(boolean) -> If true,instrument
is undefined. -
instrument
(Instrument) -> The zone's instrument. Undefined if global.-
instrumentName
(string) -> The name of the instrument. -
safeDeleteZone
(index: number) ->deleteZone
but only if the instrument's use count is 0. Useful to ensure the instrument is not deleted when used by other presets. -
deleteZone
(index: number) -> Deletes a given preset zone and instrument if not used by anything else. -
instrumentZones
(InstrumentZone[]) -> All zones of the instrument.-
keyRange
({min: number, max: number}) -> Key range of the zone. -
velRange
({min: number, max: number}) -> Velocity range of the zone. -
generators
(Generator[]) -> Generators of the zone. -
modulators
(Modulator) -> Modulators of the zone. -
isGlobal
(boolean) -> If true,sample
is undefined. -
sample
(Sample) -> The sample of the zone. Undefined if global.- See Sample class
-
-
-
-
spessasynth_lib used to provide this function, but it is rarely used, so it now has to be obtained separately.
Either copy this folder into your project, or you can write your own function. It must take the following arguments:
- audioData: an array of
Float32Array
. Always has length of 1. - channelCount: length of audioData (the array, not the
Float32Array
s inside. - sampleRate: in Hertz
- quality: -0.1 is the lowest, 1 is the highest
The function can’t be asynchronous.
It should return Uint8Array
containing the compressed bitstream.
Warning
Writing your own function is for advanced users only. Using the function linked above is recommended.
Note
Note that using a custom function allows for using any type of compression for the SF3 soundfont. This is allowed by the RFC describing SF3 spec , but SpessaSynth can only read Ogg Vorbis compression.
Import your function:
import { encodeVorbis } from './libvorbis/encode_vorbis.js'; // adjust the path if necessary
Then pass it to the write method:
const file = soundFont.write({
compress: true,
compressionQuality: 0.5,
compressionFunction: encodeVorbis
});
Why is it not bundled?
Importing it into the package would increase the size with the entire 1.1MB encoder, which would be unnecessary if the functionality is not used. This approach ensures that only software that uses this functionality can rely on this large file.
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!