https://github.com/misterhat/tinymidipcm
render MIDIs to PCM with custom soundfonts via tinysoundfont in WASM
https://github.com/misterhat/tinymidipcm
midi pcm sf2 soundfont wasm
Last synced: 11 months ago
JSON representation
render MIDIs to PCM with custom soundfonts via tinysoundfont in WASM
- Host: GitHub
- URL: https://github.com/misterhat/tinymidipcm
- Owner: misterhat
- License: mit
- Created: 2023-01-30T09:16:43.000Z (over 3 years ago)
- Default Branch: master
- Last Pushed: 2023-02-02T06:48:56.000Z (over 3 years ago)
- Last Synced: 2025-07-13T01:21:41.538Z (11 months ago)
- Topics: midi, pcm, sf2, soundfont, wasm
- Language: C
- Homepage:
- Size: 5.78 MB
- Stars: 7
- Watchers: 2
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: COPYING
Awesome Lists containing this project
README
# tinymidipcm
render MIDIs to PCM with custom soundfonts via tinysoundfont in WASM.
## example
```javascript
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);
};
})();
```
## api
### tinyMidiPCM = new TinyMidiPCM(options = {})
create a new rendering instance. options include:
* `bufferSize` PCM chunk size to render per `renderInterval`. default
to 1 second worth of data.
* `renderInterval` how often in ms to generate a new `bufferSize` PCM data
event. default `30`.
* `sampleRate` default `44100`.
* `channels` stereo or mono. default `2`.
* `gain` volume gain in decibels (>0 means higher, <0 means lower).
* `onPCMData` function callback wich emits a `Uint8Array` of PCM data at
`renderInterval` rate. encoded as 32 bit floats.
* `onRenderEnd` function callback when the entire MIDI is processed, providing
millseconds rendered argument.
### async tinyMidiPCM.init()
fetch and load the wasm. required for following methods.
### tinyMidiPCM.render(midiBuffer)
start emitting `onPCMData` callbacks. `midiBuffer` is a `Uint8Array` of a MIDI
file.
## license
> [TinySoundFont](https://github.com/schellingb/TinySoundFont) is available
> under the [MIT license](https://choosealicense.com/licenses/mit/).