midicube
v0.6.2
Published
Library to assist in creating ES6 MIDI apps.
Downloads
250
Readme
midicube is a fork of Mudcube's great MIDI.js which adds ES6 modules and support.
To use in a javascript project:
$ npm install midicube
then in code (ES6 modules):
import * as MIDI from 'midicube';
MIDI.loadPlugin({
// this only has piano.
// for other sounds install the MIDI.js
// soundfonts somewhere.
soundfontUrl: "./examples/soundfont/",
onerror: console.warn,
onsuccess: () => {
MIDI.noteOn(0, 60, 0);
}
});
Or as a script tag:
<script src="releases/midicube.js"></script>
<script>
MIDI.loadPlugin({
// config as above...
});
</script>
Code examples - from the repo
- Basic - the most basic implementation.
- MIDIPlayer - how to parse MIDI files, and interact with the data stream.
- WhitneyMusicBox - a audio/visual experiment by Jim Bumgardner
Related repositories
- MIDI Soundfonts: Pre-rendered General MIDI soundfonts that can be used immediately with MIDI.js
- music21j: library for working with music scores; integrates midicube.
- MIDI Pictures: Pictures of the 128 standard instruments on MIDI piano keyboards
Demos based on the older MIDI.js library
- 3D Piano Player w/ Three.js by Borja Morales @reality3d
- Brite Lite by Daniel Christopher @uxmonk
- Color Piano by Michael Deal @mudcube
- Euphony 3D Piano by Xueqiao Xu @qiao
- Gbloink! by Phil Jones
- Piano Typewriter by Andrew Levine
- Ragamroll by Mani Balasubramanian
- Simon Says by Daniel Christopher @uxmonk
- Spiral Keyboard by Patrick Snels
- VexFlow by Mohit Muthanna @11111110b
Generating Base64 Soundfonts
There is two generators for MIDI.js soundfonts:
- NodeJS package for creating soundfonts from WAV files - by Patrick Wolleb
- Ruby package for creating soundsfonts from SF2 files - by Mohit Muthanna
To dive in quickly Benjamin Gleitzman has created a package of pre-rendered sound fonts.
API
MIDI - Decides which framework is best to use
// interface to connect, download soundfont, then execute callback;
MIDI.loadPlugin(onsuccess);
// simple example to get started;
MIDI.loadPlugin({
instrument: "acoustic_grand_piano", // or the instrument code 1 (aka the default)
instruments: [ "acoustic_grand_piano", "acoustic_guitar_nylon" ], // or multiple instruments
onsuccess: function() { }
});
// after loadPlugin succeeds these will work:
MIDI.noteOn(channel, note, velocity, delay);
MIDI.noteOff(channel, note, delay);
MIDI.chordOn(channel, [note, note, note], velocity, delay);
MIDI.chordOff(channel, [note, note, note], delay);
MIDI.keyToNote = object; // A0 => 21
MIDI.noteToKey = object; // 21 => A0
MIDI.Player.js - Plays encoded MIDI
Note that the ES6 interface requires new
before MIDI.Player()
but multiple MIDI.Player
instances can appear on the same page.
const Player = new MIDI.Player();
Player.currentTime = integer; // time we are at now within the song.
Player.endTime = integer; // time when song ends.
Player.playing = boolean; // are we playing? yes or no.
Player.loadFile(url_or_base64data, onsuccess); // load .MIDI from base64 or binary XML request.
Player.start(); // start the MIDI track (you can put this in the loadFile callback)
Player.resume(); // resume the MIDI track from pause.
Player.pause(); // pause the MIDI track.
Player.stop(); // stops all audio being played, and resets currentTime to 0.
Listener for when notes are played
const Player = new MIDI.Player();
Player.removeListener(); // removes current listener.
Player.addListener(function(data) { // set it to your own function!
const now = data.now; // where we are now
const end = data.end; // time when song ends
const channel = data.channel; // channel note is playing on
const message = data.message; // 128 is noteOff, 144 is noteOn
const note = data.note; // the note
const velocity = data.velocity; // the velocity of the note
// then do whatever you want with the information!
});
Smooth animation interpolating between onMidiEvent calls
const Player = new MIDI.Player();
Player.clearAnimation(); // clears current animation.
Player.setAnimation(function(data) {
const now = data.now; // where we are now
const end = data.end; // time when song ends
const events = data.events; // all the notes currently being processed
// then do what you want with the information!
});
Effects available for WebAudioContext via Tuna.js
MIDI.setEffects([
{
type: "MoogFilter",
bufferSize: 4096,
bypass: false,
cutoff: 0.065,
resonance: 3.5
},
{
type: "Bitcrusher",
bits: 4,
bufferSize: 4096,
bypass: false,
normfreq: 0.1
},
{
type: "Phaser",
rate: 1.2, // 0.01 to 8 is a decent range, but higher values are possible
depth: 0.3, // 0 to 1
feedback: 0.2, // 0 to 1+
stereoPhase: 30, // 0 to 180
baseModulationFrequency: 700, // 500 to 1500
bypass: 0
}, {
type: "Chorus",
rate: 1.5,
feedback: 0.2,
delay: 0.0045,
bypass: 0
}, {
type: "Delay",
feedback: 0.45, // 0 to 1+
delayTime: 150, // how many milliseconds should the wet signal be delayed?
wetLevel: 0.25, // 0 to 1+
dryLevel: 1, // 0 to 1+
cutoff: 20, // cutoff frequency of the built in highpass-filter. 20 to 22050
bypass: 0
}, {
type: "Overdrive",
outputGain: 0.5, // 0 to 1+
drive: 0.7, // 0 to 1
curveAmount: 1, // 0 to 1
algorithmIndex: 0, // 0 to 5, selects one of our drive algorithms
bypass: 0
}, {
type: "Compressor",
threshold: 0.5, // -100 to 0
makeupGain: 1, // 0 and up
attack: 1, // 0 to 1000
release: 0, // 0 to 3000
ratio: 4, // 1 to 20
knee: 5, // 0 to 40
automakeup: true, // true/false
bypass: 0
}, {
type: "Convolver",
highCut: 22050, // 20 to 22050
lowCut: 20, // 20 to 22050
dryLevel: 1, // 0 to 1+
wetLevel: 1, // 0 to 1+
level: 1, // 0 to 1+, adjusts total output of both wet and dry
impulse: "./inc/tuna/impulses/impulse_rev.wav", // the path to your impulse response
bypass: 0
}, {
type: "Filter",
frequency: 20, // 20 to 22050
Q: 1, // 0.001 to 100
gain: 0, // -40 to 40
bypass: 1, // 0 to 1+
filterType: 0 // 0 to 7, corresponds to the filter types in the native filter node: lowpass, highpass, bandpass, lowshelf, highshelf, peaking, notch, allpass in that order
}, {
type: "Cabinet",
makeupGain: 1, // 0 to 20
impulsePath: "./inc/tuna/impulses/impulse_guitar.wav", // path to your speaker impulse
bypass: 0
}, {
type: "Tremolo",
intensity: 0.3, // 0 to 1
rate: 0.1, // 0.001 to 8
stereoPhase: 0, // 0 to 180
bypass: 0
}, {
type: "WahWah",
automode: true, // true/false
baseFrequency: 0.5, // 0 to 1
excursionOctaves: 2, // 1 to 6
sweep: 0.2, // 0 to 1
resonance: 10, // 1 to 100
sensitivity: 0.5, // -1 to 1
bypass: 0
}
]);
synesthesia.js: Note-to-color mappings.
Used on the MIDIPlayer.html demo.
Libraries
- colorspace.js: Color conversions, music isn’t complete without!
Original URLs
The original version of MIDI.js was made by Mudcube.
- Original repo: where it began.
- His site: including Michael's work on Sketch.IO
The midi-js npm package is unrelated to this project, hence the rename to "midicube" in honor of Mudcube.
Many thanks to the authors of these libraries
- Web MIDI API: W3C proposal by Jussi Kalliokoski & Chris Wilson
- Web Audio API: W3C proposal by Chris Rogers
- <audio>: HTML5 specs
- Flash package: SoundManager2 by Scott Schiller
- jasmid: Reads MIDI file byte-code, and translats into a Javascript array.
- base642binary.js: Cleans up XML base64-requests for Web Audio API.
Similar projects
ES6 Conversion
ES6 Conversion by Michael Scott Asato Cuthbert:
Development
Build midicube with:
npm run watch
to publish a new version change the version tag in package.json and run
npm publish