render MIDIs to PCM with custom soundfonts via tinysoundfont in WASM.
import TinyMidiPCM from 'tinymidipcm';
(async () => {
const midiRes = await fetch('/e1m1.mid');
const midiBuffer = new Uint8Array(await midiRes.arrayBuffer());
const channels = 2;
const sampleRate = 44100;
let renderEndSeconds = 0;
const tinyMidiPCM = new TinyMidiPCM({
channels,
sampleRate,
renderInterval: 1000,
onPCMData: (pcm) => player.feed(pcm),
onRenderEnd: (ms) => {
console.log('midi finished rendering.');
renderEndSeconds = Math.floor(ms / 1000);
console.log(renderEndSeconds, 'seconds');
}
});
const pcmPlayerOptions = {
inputCodec: 'Float32',
channels,
sampleRate,
onended: async () => {
const timeSeconds = Math.floor(
player.audioCtx.currentTime
);
if (
renderEndSeconds > 0 &&
Math.abs(timeSeconds - renderEndSeconds) <= 2
) {
console.log('midi finished playing.');
renderEndSeconds = 0;
}
},
flushTime: 1000
};
// https://www.npmjs.com/package/pcm-player
const player = new PCMPlayer(pcmPlayerOptions);
tinyMidiPCM.setBufferDuration(2);
await tinyMidiPCM.init();
const soundfontRes = await fetch('/scc1t2.sf2');
const soundfontBuffer = new Uint8Array(
await soundfontRes.arrayBuffer()
);
tinyMidiPCM.setSoundfont(soundfontBuffer);
window.onclick = async () => {
await player.pause();
player.destroy();
player.init(pcmPlayerOptions);
player.volume(1);
tinyMidiPCM.render(midiBuffer);
};
})();
create a new rendering instance. options include:
bufferSize
PCM chunk size to render perrenderInterval
. default to 1 second worth of data.renderInterval
how often in ms to generate a newbufferSize
PCM data event. default30
.sampleRate
default44100
.channels
stereo or mono. default2
.gain
volume gain in decibels (>0 means higher, <0 means lower).onPCMData
function callback wich emits aUint8Array
of PCM data atrenderInterval
rate. encoded as 32 bit floats.onRenderEnd
function callback when the entire MIDI is processed, providing millseconds rendered argument.
fetch and load the wasm. required for following methods.
start emitting onPCMData
callbacks. midiBuffer
is a Uint8Array
of a MIDI
file.
TinySoundFont is available under the MIT license.