:musical_keyboard: Making life easy to create a MIDI-app on the web. Includes a library to program synesthesia into your app for memory recognition or for creating trippy effects. Convert soundfonts for Guitar, Bass, Drums, ect. into code that can be read by the browser. Supports multiple simultaneous instruments and perfect timing.

Related tags


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 Pictures: Pictures of the 128 standard instruments on MIDI piano keyboards
  • MIDI Soundfonts: Pre-rendered General MIDI soundfonts that can be used immediately with MIDI.js

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.


MIDI.loadPlugin.js - Decides which framework is best to use

// interface to download soundfont, then execute callback;
// simple example to get started;
    instrument: "acoustic_grand_piano", // or the instrument code 1 (aka the default)
    instruments: [ "acoustic_grand_piano", "acoustic_guitar_nylon" ], // or multiple instruments
    onsuccess: function() { }

MIDI.Plugin.js - Controls MIDI output

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 MIDI stream

MIDI.Player.currentTime = integer; // time we are at now within the song.
MIDI.Player.endTime = integer; // time when song ends.
MIDI.Player.playing = boolean; // are we playing? yes or no.
MIDI.Player.loadFile(file, onsuccess); // load .MIDI from base64 or binary XML request.
MIDI.Player.start(); // start the MIDI track (you can put this in the loadFile callback)
MIDI.Player.resume(); // resume the MIDI track from pause.
MIDI.Player.pause(); // pause the MIDI track.
MIDI.Player.stop(); // stops all audio being played, and resets currentTime to 0.

Listener for when notes are played

MIDI.Player.removeListener(); // removes current listener.
MIDI.Player.addListener(function(data) { // set it to your own function!
    var now = data.now; // where we are now
    var end = data.end; // time when song ends
    var channel = data.channel; // channel note is playing on
    var message = data.message; // 128 is noteOff, 144 is noteOn
    var note = data.note; // the note
    var velocity = data.velocity; // the velocity of the note
    // then do whatever you want with the information!

Smooth animation interpolating between onMidiEvent calls

MIDI.Player.clearAnimation(); // clears current animation.
MIDI.Player.setAnimation(function(data) {
    var now = data.now; // where we are now
    var end = data.end; // time when song ends
    var events = data.events; // all the notes currently being processed
    // then do what you want with the information!

Effects available for WebAudioContext via Tuna.js

 		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


  • colorspace.js: Color conversions, music isn’t complete without!
Color.Space(0xff0000, "HEX>RGB>HSL");
DOMLoader.script.add(src, onsuccess);
DOMLoader.sendRequest(src, onsuccess);

Many thanks to the authors of these libraries

Similar projects

  • The demo files are not playing from the zip download

    The demo files are not playing from the zip download


    This is a really amazing library but I facing some challenges in getting it to work.

    I am really new to this stuff and have downloaded the source zip files twice.

    The last time I downloaded the code zip, the demo files were playing when opened in chrome but they are not playing now. The colorful circles keeps going around and the soundfonts are never downloaded. The only message displayed is "Web Audio API...".

    I happen to have the old zip and opening the the demo's from the old zip still works - the events and b64 midi plays when the demo files are opened in chrome.

    In both cases the files are on my local machine and are not hosted on any server

    So, do I need to make some changes that will get the latest version of demos playing?

    Thanks for the help in advance.


    opened by Shantanu-Daithankar 24
  • Web Audio API on Firefox

    Web Audio API on Firefox

    Mozilla has recently introduced the Web Audio API to Firefox: https://blog.mozilla.org/blog/2013/10/29/listen-up-web-audio-api-now-in-firefox-completes-web-as-a-platform-for-gaming/

    I have tried to hard code Firefox to use Web Audio in MIDI.loadPlugin, but in the console I'm seeing this error: TypeError: ctx.createGainNode is not a function TypeError: source.gain is undefined

    How do I get Firefox to use it's new Web Audio API with midi.js?

    opened by etayluz 24
  • No more maintained ?

    No more maintained ?

    2 years of inactivity, 16 PR and 86 issues that's sad...

    opened by Adrion 21
  • Use with NPM + Browserify?

    Use with NPM + Browserify?


    This is an impressive thing here, but I find it to be confusing almost completely unportable.

    Please consider using NPM, and perhaps browserify, to make it truly modular and portable. It much easier to manage and organize code with those tools (which are becoming industry standards in Javascript).

    Many thanks,

    opened by NHQ 18
  • Can't load instruments from external sites.

    Can't load instruments from external sites.

    Instrument files are pretty big and better served via CDNs.

    This is currently not possible because they are loaded via XMLHttpRequest which disallows cross-domain requests. Can this be changed to use the "script" tag?


    opened by 0xfe 12
  • Play MIDI with multiple instruments

    Play MIDI with multiple instruments

    Is it possible to bind different instruments to each channel in multichannel MIDI? For example if I've got a midi file with guitar and drums and soundfonts for each instrument. How could I play this midi in this way? Should i hack jasmid or MIDI.js and add instruments support for each midi channel?


    opened by mbektimirov 10
  • New Chrome will have

    New Chrome will have "Failed to execute 'stop' on 'OscillatorNode': cannot call stop more than once." problem.

    It seems the spec has changed. Now when I try to load a new midi file to play. It shows "Failed to execute 'stop' on 'OscillatorNode': cannot call stop more than once." error.

    Does anyone know how to avoid this?

    Thanks a lot

    opened by wzchou 8
  • How to automate startRecording and stopRecording

    How to automate startRecording and stopRecording

    Please refer this issue https://github.com/mudcube/MIDI.js/issues/169 I want to record the sound made by MIDI.js as soon as it starts making sound

    I am partially successful to achieve this. Means I have buttons to start and stop recording when MIDI.js is making sound please refer below gist


    But I want it to be automatic i.e. recording should start automatically as soon as MIDI.js starts making sound and it should stop automatically when it stops. It should not require manual buttons to control recording.

    Please guide to achieve this

    opened by shivrajsa 7
  • Suggestion for how to add reverb?

    Suggestion for how to add reverb?

    Does anyone have a suggestion for a way to add reverb to the output? Is there a reverb.js hiding somewhere? I don't know if its too processor intensive to do in a browser, seems like it should be possible for simple reverb.

    opened by kittles 7
  • chrome:

    chrome: "audio resources unavailable for AudioContext construction"

    using the basic demo and playing a note over and over again, Chrome throws this error: "Uncaught SyntaxError: audio resources unavailable for AudioContext construction"

    as seen on here: http://stanford.edu/~c0chran/cgi-bin/midi-default/

    if I put a try block around the new audio context that is generated in plugin.js, it doesn't throw the error: try { MIDI.Player.ctx = ctx = new AudioContext(); } catch(err) {}

    however, the rendering of the audio is much slower on chrome than on Firefox, such that you could only play a note about once every 2 seconds.when the try block is removed, the audio can play more rapidly but then the error is thrown after 5-6 plays.

    is there no having one without the other?

    opened by dannycochran 7
  • Updated URL (line 09)

    Updated URL (line 09)

    opened by kant 0
  • Color piano not found in chrome web store

    Color piano not found in chrome web store

    Hi I am new to GitHub but I am following Sir Michael Deal (mudcube) 's project Color piano theory, from around 2013 when I first got a computer. It has been about 8 years and still I use Color piano frequently. The app is not appearing on the Chrome Web Store. Please do the needful so that the app appears again on chrome web store.

    Ps. 1. I want to contact Sir Michel Deal (mudcube). How to contact him?

    Ps. 2. I am looking for mobile app version for Color Piano app. Is thete any way I can install colour piano in my android mobile phone? Many Thanks and regards.

    opened by FanFollower 0
  • can i use midi.js to create a online piano and guitar?

    can i use midi.js to create a online piano and guitar?

    if so, where can i learn how to use it? I'm a beginner, so it would be nice if I had documentation to use! Thank you!

    opened by stubbornYang1706 0
  • How to play file.mid

    How to play file.mid

    hello, how can I play recorded mid files on my pc. like file.mid

    - This is working online and offline.

    How can I use it on my local folder as here: Why is it not working. Thank you :)

    opened by josanta 4
  • Improve Soundfont generation

    Improve Soundfont generation

    This PR performs two main goals:

    1. Parallelize Soundfont generation. Generally reduces the time to create a Soundfont by a factor of #cores.
    2. Fix a long standing compatibility issue between MIDI.js naming schemes and MIDI Association / midilib naming schemes.

    For example, midilib uses "SynthBrass 1" -> https://github.com/jimm/midilib/blob/6c8e481ae72cd9f00a38eb3700ddfca6b549f153/lib/midilib/consts.rb#L280

    and the MIDI association uses "SynthBrass 1" -> https://www.midi.org/specifications-old/item/gm-level-1-sound-set

    but the MIDI.js calls this "Synth Brass 1" -> https://github.com/mudcube/MIDI.js/blob/a8a84257afa70721ae462448048a87301fc1554a/js/midi/gm.js#L44

    There are others like "Bag pipe" vs "Bagpipe" that cause issues with generation.

    Now we use the MIDI.js definitions because that is how most users will interact with the generated soundfonts.

    opened by gleitz 0
  • Midi files with multi channels doesn't work using MIDI.Player.Loadfile

    Midi files with multi channels doesn't work using MIDI.Player.Loadfile

    I have a midi file with three channels(both acoustic_grand_piano), when calling MIDI.Player.Loadfile, it only plays one track. Another problem is that the player dropped the very first note of the midi file, and the note is at time 0:00. After I move the first note 2 seconds later then it sounds good. And also I checkout to a branch called "abcjs", and I change the code to the newest commit, the two problems are resolved. Since there're too many commits(29commits ahead of HEAD), so I can't figure out which important part has been changed. But that commit has a problem with pause function, which will play one or two unexpected notes after 3 or 4 seconds after resume.

    What's more is another project Color Piano (https://galactic.ink/piano/), which is awesome and it doesn't have any of issues described above. But it seems not open source. So @mudcube , would you mind creating a repo of that project? Much thanks!

    opened by KomeijiSatori 3
  • Question, Piano Layout

    Question, Piano Layout


    It is possible to change the piano layout to a thumb piano? https://galactic.ink/piano/

    I would like to teach this instrument and give the students a place so they can see the classes without having to buy the program. I am willing to work on the code although I am not an expert, I know a little programming, or pay if necessary.

    opened by animetals 1
  • How to disable sound in Player.js?

    How to disable sound in Player.js?

    I want to output midi using only event of player.js.

    opened by Zel9278 0
  • Is it impossible to pause when using noteon noteoff instead of player

    Is it impossible to pause when using noteon noteoff instead of player

    Is it impossible to pause when using noteon noteoff instead of player?or it can pause only when using player.load(xxx.midi)?

    opened by ysfgmissbless 3
  • k


    opened by ShadowHunter21 0
A music composition library for Clojure and Clojurescript.

Leipzig A composition library for Clojure and Clojurescript by @ctford. Use Include it as a dependency in your project.clj, along with Overtone: [over

Chris Ford 428 Aug 15, 2021
Typographic Beat-Oriented Notation for music

tbon Typographic Beat-Oriented Notation for music Tbon aims to be the fastest way to enter pitches, rhythms, meter and dynamic levels from a computer

null 11 Jan 23, 2020
Esoteric Programming Language

ORCΛ Orca is an esoteric programming language designed to quickly create procedural sequencers, in which every letter of the alphabet is an operation,

Hundredrabbits 3.4k Sep 14, 2021
A language for music notation

Lydown is a language and compiler for creating music scores, parts and snippets. The lydown code is compiled to lilypond code and then compiled to PDF

Sharon Rosner 21 Apr 8, 2021
Lilypond music preprocessor

Ripple - DRY for Lilypond Ripple is a small program that helps you generate scores and parts without repeating yourself, performing complex includes o

Sharon Rosner 21 Mar 24, 2020
Music typeset with the Lilypond system

Intro (from long ago) This repo contains sheet music typeset with the Lilypond typesetter. The music chosen is in favour of cello music (mostly chambe

Enthusiastic about  the Cello 95 Sep 24, 2021
Limiter, compressor, reverberation, equalizer and auto volume effects for Pulseaudio applications

PulseEffects Audio effects for PipeWire applications. Effects available Applications output Auto gain Bass enhancer Compressor Convolver Crossfeed Cry

Wellington Wallace 2.7k Sep 17, 2021
The git repository of the advanced drum machine

Hydrogen drum machine Hydrogen is an advanced drum machine for GNU/Linux, Mac and Windows. It's main goal is to bring professional yet simple and intu

Hydrogen 702 Sep 15, 2021
A music programming language for musicians. :notes:

Installation | Docs | Changelog | Contributing composers chatting Alda is a text-based programming language for music composition. It allows you to co

Alda 4.7k Sep 25, 2021
Frescobaldi LilyPond Editor

README for Frescobaldi Homepage: http://www.frescobaldi.org/ Main author: Wilbert Berendsen Frescobaldi is a LilyPond sheet music text editor. It aims

Frescobaldi 501 Sep 21, 2021
Cross-platform music production software

LMMS A soft PR-Freeze is currently underway to prepare for refactoring (#5592). Please do not open non-essential PRs at this time. What is LMMS? LMMS

LMMS 5.3k Sep 15, 2021
Collaborative Programmable Music

888 888 _ooooooooo._ 888 ,o888PP""""PP88

Overtone 5.2k Sep 24, 2021
Javascript audio library for the modern web.

Description howler.js is an audio library for the modern web. It defaults to Web Audio API and falls back to HTML5 Audio. This makes working with audi

James Simpson 19k Sep 25, 2021
An Internet radio player for Linux

Radiotray-NG: An Internet radio player for Linux It became clear as one of the early contributors to the RadioTray project that it was not getting the

Ed Bruck 187 Aug 21, 2021
Python CD-DA ripper preferring accuracy over speed

Whipper Whipper is a Python 3 (3.6+) CD-DA ripper based on the morituri project (CDDA ripper for *nix systems aiming for accuracy over speed). It star

null 554 Sep 19, 2021
Compose music and write score easily in your browser!

inknote Compose music easily in your browser! http://www.michalpaszkiewicz.co.uk/inknote/ Store multiple files, tag them with colours. Made using Type

Michal Paszkiewicz 145 Aug 18, 2021
OpenSheetMusicDisplay renders sheet music in MusicXML format in your web browser based on VexFlow. OSMD is brought to you by PhonicScore.com.

OpenSheetMusicDisplay (OSMD) A MusicXML renderer for the Browser opensheetmusicdisplay.org About OSMD • Demo • Key Features • Limitations • How to Use

Open Sheet Music Display 806 Sep 24, 2021
Baroque music scores, typeset with GNU LilyPond

nénuvar - baroque music scores typeset with GNU LilyPond Available scores: J.B. Lully * La Revente des habits (ballet, LWV05) * Amour malade (ballet

Nicolas Sceaux 36 Aug 29, 2021
A JavaScript library for rendering music notation and guitar tablature.

VexFlow 3 A JavaScript library for rendering music notation. Copyright (c) 2010 Mohit Muthanna Cheppudira Sponsor this Project If you use VexFlow in y

Mohit Cheppudira 3.1k Sep 25, 2021