npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

simple-midi-input

v1.2.1

Published

Abstraction over the MIDI input. Does all the byte crunching and exposes a straightforward event API with MIDI learn capability.

Downloads

3

Readme

SimpleMidiInput.js

Build Status

Abstraction over the MIDI input. Does all the byte crunching and exposes a straightforward event API.

Installing and testing

With npm do npm install simple-midi-input.

Or download the build/SimpleMidiInput.js file and include it in your html page.

To run the test suite clone the repository, install the dev dependencies with npm install and then run the following command: npm test

Usage

var SimpleMidiInput = require('simple-midi-input'),
    smi = new SimpleMidiInput();

navigator.requestMIDIAccess().then( onsuccesscallback, onerrorcallback );

var onsuccesscallback = function(midi) {
    smi.attach(midi);
};

var onerrorcallback = function(err) {
    console.log('ERROR : ' + err.code);
};

Here we instanciate SimpleMidiInput and attach it to all the MIDI inputs.

smi.on('noteOn', function(data) {
  console.log(data.event, data.key, data.velocity);
});

smi.on('noteOff', function(data) {
  console.log(data.event, data.key);
});

Here we log the noteOn and noteOff events with their relative parameters.

smi.on('noteOn', 2, function(data) {
  console.log(data.event, data.key, data.velocity);
}).on('noteOff', 2, function(data) {
  console.log(data.event, data.key);
});

We do exactly the same thing, but only for the second channel while taking advantage of the method chaining.

smi.on('cc7', 1, function(data) {
  console.log(data.event, 'usually this is the volume knob, here is its value : ', data.value);
});

Here we catch the control change #7 (which is commonly used to set the volume) on the first channel.

smi.on('polyphonicAftertouch', 1, function(data) {
  console.log(data.event, data.key, data.pressure);
}).on('channelAftertouch', 1, function(data) {
  console.log(data.event, data.pressure);
}).on('programChange', 1, function(data) {
  console.log(data.event, data.program);
});

We can also catch the polyphonicAftertouch, channelAftertouch and programChange events.

smi.on('global', function(data) {
  if(data.event !== 'clock') {
    console.log(data);
  }
});

You can always catch all the events and log them for debugging. Filtering the MIDI clock events is probably a good idea though.

MIDI learn

MIDI Learn is a simple system used by many DAW and plugins to simplify the use of MIDI controllers. For web apps, the main advantage is that the MIDI binding doesn't have to be hardcoded. The users can effectively bind the parameters to the CC of their choice.

Check this specific documentation.

API reference

new SimpleMidiInput([midiInput]);

Instaciation of the class.

Options :

  • midiInput : A single instance of MIDIInput, MIDIInputMap, MIDIInputAccess or an array of MIDIInput.

smi.attach(midiInput);

Attach the instance to one or several MIDIInput.

Options :

  • midiInput : A single instance of MIDIInput, MIDIInputMap, MIDIInputAccess or an array of MIDIInput.

smi.detach(midiInput);

Detach the instance from one or several MIDIInput.

Options :

  • midiInput : A single instance of MIDIInput, MIDIInputMap, MIDIInputAccess or an array of MIDIInput.

smi.detachAll();

Detach the instance from all MIDIInputs.

smi.on(event, channel, handler);

smi.on(event, handler);

Subscribe to an event.

Options :

  • event : Name of the event to listen to (ie: noteOn, noteOff, ...)
  • channel : Number of the midi channel to listen to (from 1 to 16)
  • handler : Handler function

Example:

var func = function(event) {
    console.log(event);
};

smi.on('noteOn', func); // add an event on noteOn for the all channels
smi.on('noteOn', 1, func); // add an event on noteOn for the first channel

smi.off(event, channel, [handler]);

smi.off(event, [handler]);

Unsubscribe to an event.

Options :

  • event : Name of the event to listen to (ie: noteOn, noteOff, ...)
  • channel : Number of the midi channel to listen to (from 1 to 16)
  • handler : Handler function

Example :

smi.off('noteOff'); // remove any events on noteOff from all channels
smi.off('noteOff', 1); // remove any events on noteOff from the first channel
smi.off('noteOff', func); // remove a specific event on noteOff from all channels
smi.off('noteOff', 1, func); // remove a specific event on noteOff from the first channel

smi.trigger(event, args);

Artificially triggers one of the event.

Options :

  • event : Name of the event to listen to (ie: noteOn, noteOff, ...)
  • args : Arguments to pass to the handler function

Example :

smi.trigger('noteOff', {
    channel: 1,
    key: 69,
    velocity: 127
});

smi.setFilter(filter);

Set a function to filter the midi event, the function will get the event as argument and must return false to filter it out. There can only be one filter function at a time, passing null removes the current function.

Options :

  • filter : Filtering function.

Example :

smi.setFilter(function(event) {
    // we don't want any of the noteOn / noteOff events for notes above E4
    if((event.event === 'noteOn' || event.event === 'noteOff') && event.key > 64) {
        return false;
    }
});
smi.setFilter(null); //remove the current function

Event names with their relative values

  • noteOn (channel, key, velocity)
  • noteOff (channel, key, velocity)
  • cc(x) (channel, cc, value)
  • channelAftertouch (channel, pressure)
  • polyphonicAftertouch (channel, key, pressure)
  • pitchWheel (channel, value)
  • programChange (channel, program)
  • clock (command)
  • songPosition
  • songSelect
  • tuneRequest
  • activeSensing
  • reset
  • global (catches everything)

History

1.2.1 (2023/02/15) :

  • Update the detection of iterator which caused an issue when initialising SMI on current browsers.
  • Remove any mention of bower.
  • General dev deps cleaning.

1.2.0 (2015/05/30) :

  • Fix an issue where the midi events were not handled in latest Chrome.
  • Fix error in doc for setFilter.
  • Refactor to CommonJs and publish on npm as simple-midi-input.
  • Provide a browserified bundle for bower.

1.1.1 (2015/01/25) :

  • attach() and detach() now receive a instance of MIDIInputMap or MIDIAccess.
  • Fix detach() not working correctly when used with an array.

1.1.0 (2014/08/10) :

  • Add experimental MIDI learn capability (doc).

1.0.2 (2014/07/19) :

  • A single instance can now be bound to many MIDI Inputs.
  • Add attach(), detach() and detachAll() methods to change the MIDI inputs bound to the instance.
  • Add proper API reference to the readme.

1.0.1 (2014/04/15) :

  • Add missing channel information to pitchWheel event.
  • Make the script AMD and CommonJS compliant.
  • Add a few mocha tests on the parsing of midi message.

1.0.0 (2014/04/14) :

  • Add pitchWheel, songPosition, songSelect, tuneRequest and activeSensing support.
  • Publish on bower.
  • Declares the public API stable.

0.1.0 (~ 2014/02/23)

Notes

  • Some controllers and MIDI apps send a noteOn events with a velocity of 0 instead of noteOff events. SMI automatically translates them to noteOff events.
  • Tested with MPK Mini, HotHand USB and half a dozen iOS apps with rtpMIDI / CoreMIDI.
  • No Sysex support yet.