A soundfont loader/player to use MIDI sounds in WebAudio API. The purpose of this project is to reduce as minimum the setup and code required to play MIDI sounds.
It is a much simpler and lightweight replacement for MIDI.js soundfont loader (MIDI.js is much bigger, capable of play midi files, for example)
Works out of the box with Benjamin Gleitzman's package of pre-rendered sound fonts. Just load the library and play. Try the demo
Load the library...
<script src="soundfont-player.js"></script>
... or require it using a npm package compatible environment (webpack, browserify):
var Soundfont = require('soundfont-player');
Create a Soundfont object:
var ctx = new AudioContext();
var soundfont = new Soundfont(ctx);
Then get the instrument and play:
var instrument = soundfont.instrument('acoustic_grand_piano');
instrument.onready(function() {
instrument.play('C4', 0);
}
Basically it fetches the instruments from https://github.com/gleitz/midi-js-soundfonts using https://rawgit.com, decode them and wrap in a simple buffer player.
It uses Promises and the Web Audio API.
## API
### Soundfont(audioContext)
Create a soundfont object. The soundfont object has two methods:
Returns an instrument with the given instrument name (take a look to all the names below).
All the instruments has a play method with the form: play(noteName, time, duration)
.
You can use the instrument.onready
method to know when the instrument is loaded.
If you play the instrument before its loaded, a simple sine oscillator is used
to generate the note:
var inst = soundfont.instrument('accordion');
inst.play('c4', 2, 0.2); // => a sine wave sound
inst.onready(function(accordion) {
inst.play('c4', 2, 0.2); // => a midi accordion sound
});
If you want to control the note release manually you can pass -1
as duration and call stop
:
note = inst.play('c4', 0, -1)
note.stop(1) // stops after 1 second
The instruments are cached, so call soundfont.instrument
twice with the same
name only loads the instrument once.
The valid options
are:
gain
: the gain value (by default 2.0)destination
: the instrument destination (by default the audio context destination)
You can pass null
to get the default sine oscillator instrument:
var inst = soundfont.instrument();
inst.play('c2', 1, 0.5);
The callback is fired when all the instruments are loaded:
var harmonics = soundfont.instrument('guitar_harmonics');
var sax = soundfont.instrument('soprano_sax');
soundfont.onready(function() {
console.log('Guitar harmonics and Sax ready.');
harmonics.play('c3', 1, 1);
sax.play('e2', 1, 1);
});
Returns a Promise with a buffers object. The buffers object map midi notes to audio buffers:
Soundfont.loadBuffers(ctx, 'acoustic_grand_piano').then(function(buffers) {
buffers[Soundfont.noteToMidi('C4')] // => audio buffer of C4
});
Returns the midi name of the note.
Overrinding Soundfont.nameToUrl
you can change the URL associated to a given instrument name:
Soundfont.nameToUrl= function(instName) { return '/' + instName + '-ogg.js'; }
## Run the tests, examples and build the library distribution file
To run the examples you need to install mocha first: npm i -g mocha
and then: npm run test
The dist
folder contains ready to use file for browser. You can use the dist file from the repo, but if you want to build you own you must install browserify and uglifyjs: npm i -g browserify uglifyjs
and then:
npm run dist
To run the html example start a local http server. For example:
npm install -g http-server
http-server
And open http://localhost:8080/examples
To run pure javascript examples npm install -g beefy
then beefy examples/piano.js
and navigate to http://localhost:9966/
You can grab a json file with all the instrument names, or require it:
var instrumentNames = require('soundfont-player/instruments.json');
The complete list is here
- SoundFont technical specification: http://freepats.zenvoid.org/sf2/sfspec24.pdf
MIT License