@marmooo/midy
v0.3.8
Published
A MIDI player/synthesizer written in JavaScript that supports GM-Lite/GM1 and SF2/SF3.
Readme
Midy
A MIDI player/synthesizer written in JavaScript that supports GM-Lite/GM1/GM2 and SF2/SF3.
This library provides several files depending on the implementation level.
- midy-GMLite.js: support minimal GM-Lite (ref: en, ja)
- midy-GM1.js: support minimal GM1 (ref: en, en full, ja)
- midy-GM2.js: support minimal GM2 (ref: en v1.2a, en v1.0, ja v1.0)
- midy.js: full implementation (in progress)
Demo
- @marmooo/midi-player - GUI library
- Humidy - GM2 MIDI mixer app
Support Status
All implementations follow the specification.
| Message | Support | Notes | | :----------------------- | :-----: | :------- | | Note Off | ✔️ | | | Note On | ✔️ | | | Polyphonic Key Pressure | ✔️ | full GM2 | | Controller Change | ✔️ | full GM2 | | Program Change | ✔️ | full GM2 | | Channel Pressure | ✔️ | full GM2 | | Pitch Bend | ✔️ | | | System Exclusive Message | ✔️ | full GM2 | | System Common Message | ❌ | | | System Real Time Message | ✔️ | full GM2 | | MIDI Time Code | ❌ | | | MIDI Show Control | ❌ | | | MIDI Machine Control | ❌ | |
Usage
Initialization
// import { MidyGMLite as Midy } from "midy-GMLite.js";
// import { MidyGM1 as Midy } from "midy-GM1.js";
// import { MidyGM2 as Midy } from "midy-GM2.js";
import { Midy } from "midy.js";
const audioContext = new AudioContext();
await audioContext.suspend();
const midy = new Midy(audioContext);
await midy.loadMIDI("test.mid");
await midy.loadSoundFont("test.sf3");
await midy.start();Playback
await midy.start();
await midy.stop();
await midy.pause();
await midy.resume();
midy.seekTo(second);MIDI Message
There are functions that handle MIDI messages as they are, as well as simplified functions.
midy.handleMessage(data, scheduleTime);
midy.noteOn(channelNumber, noteNumber, velocity);
midy.setProgramChange(channelNumber, programNumber);Control Change
There are functions that handle control changes as they are, as well as simplified functions.
midy.setControlChange(
channelNumber,
controller,
value,
scheduleTime,
); // [0-127] value
midy.setModulation(channelNumber, modulation); // [0-127] modulation
midy.setVolume(channelNumber, volume); // [0-127] volumeSystem Exclusive Message
There are functions that handle SysEx data as is, as well as simplified functions.
midy.handleSysEx(data, scheduleTime); // [F0 F6 04 01 xx xx F7] data
midy.handleMasterVolumeSysEx(data, scheduleTime); // [F0 F6 04 01 xx xx F7] data
midy.setMasterVolume(volume); // [0-1] volumeMultiple Soundfonts
This library supports SF2 and SF3. In addition, it supports multiple soundfonts and splitted soundfonts that are optimized for playback on the web. The following example loads only the minimum presets required for playback.
const soundFontURL = "https://soundfonts.pages.dev/GeneralUser_GS_v1.471";
function getSoundFontPaths() {
const paths = [];
for (const instrument of midy.instruments) {
const [bank, program] = instrument.split(":");
const bankNumber = Number(bank);
const programNumber = Number(program);
const index = midy.soundFontTable[programNumber][bankNumber];
if (index !== undefined) continue;
const baseName = bankNumber === 128 ? "128" : program;
paths.push(`${soundFontURL}/${baseName}.sf3`);
}
return paths;
}
const paths = getSoundFontPaths();
await midy.loadSoundFont(paths);Build
deno task buildLicense
Apache-2.0
