jsm makes a system's MIDI ports accessible to node applications. It uses the portmidi cross-platform media library, so it should work on MacOS, Windows and Linux.
jsm is designed to make it easy for node applications to send and receive MIDI messages. It was initially developed to implement flexible interfaces between control surfaces and synthesizers. Efficiency is a concern, too, but at this stage, there is no provision to make strict timing promises. This means that while it is possible to generate note messages, jitter and latency cannot be controlled tightly yet.
This is an example of a program that sends a few MIDI control messages:
var MIDI = require('MIDI');
var midiOutput = new MIDI.MIDIOutput();
console.log("opened MIDI output port", midiOutput.portName);
midiOutput.channel(3); // Set output channel 3
midiOutput.controlChange(0, 10); // Select bank 10 (CC0)
midiOutput.channel(4); // Set output channel 4
midiOutput.controlChange(7, 80); // Set volume to 80 (CC7)
This is an example of a program that receives MIDI noteOn messages and prints them to the console:
var MIDI = require('MIDI');
var midiInput = new MIDI.MIDIInput();
console.log("opened MIDI input port", midiOutput.portName);
midiInput.on('noteOn',
function (pitch, velocity, channel) {
console.log('note', MIDI.pitchToNote(pitch),
'velocity', velocity,
'channel', channel);
});
Return the available MIDI input port and output port names, as arrays of strings.
Convert the given integer MIDI pitch
to a note name string.
Convert the given noteName
string to a MIDI integer pitch.
Convert the given binary message
, an array containing integer
values, to a string of hex bytes separated by spaces.
Returns the current time in terms of milliseconds since program start. This is the time base used for sending delayed messages and timestamps of incoming messages.
Establishes a callback function to be called synchronously to the MIDI
clock. time
is specified in absolute time as returned by the
currentTime()
function, passed to the application from callbacks and
specified in message sending functions.
The MIDIInput
objects represents a handle to a MIDI input port.
Its constructor function accepts a port name as argument.
Applications are notified by incoming messages by the way of events that are delivered to callbacks, using the standard node event handling idiom.
All event handlers are called with the message timestamp as last argument. The message timestamp indicates the point in time when the message was received, measured in milliseconds since the start of the program.
Return a MIDIInput
object opened to the port with the given
portName
. portName
can be specified as undefined
. If so, the
port named by the MIDI_INPUT environment variable, or, if that
variable is not set, the first MIDI input port available in the system
will be opened.
function (parameterNumber, value, channel, time) { }
Emitted when an NRPN control change has been received. NRPNs are a sort of extended parameters that allow for a larger number of parameters with a wider value range to be submitted. The parameter number is represented by 14 bits sent in two controlChange message for controller 0x63 (MSB) and 0x62 (LSB), the value is either 7 bits sent as controlChange for controller 0x06, or 14 bits sent in two controlChange messages for controller 0x06 (MSB) and 0x26 (LSB). To change the value of an NRPN controller, the sender first sends the parameter number as two controlChange messages for controller 0x63 (MSB) and 0x62 (LSB) followed by the value, either as one message for controller 0x06 or as two messages for controller 0x06 (MSB) and controller 0x26.
When the NRPN controller number has been selected, the sender can also send incremental changes using the controller number 0x60 (increment) or 0x61 (decrement).
The sender does not need to re-select the NRPN controller for each value change. Rather, the NRPN controller is kept selected until overwritten. For NRPN controllers in 14 bit mode, it is possible to send only the LSB after the controller number and the MSB have been sent.
The 'nrpn7' and 'nrpn14' events are emitted to the application whenever a new value has been completely received, either through an incremental or an absolute change message.
Applications can listen for any of the standard MIDI messages as listed below. Event handlers are called with the message argument(s) parsed as integer values.
function (pitch, velocity, channel, time) { }
function (pitch, velocity, channel, time) { }
function (pitch, velocity, channel, time) { }
function (controllerNumber, controllerValue, channel, time) { }
function (programNumber, channel, time) { }
function (pressureValue, channel, time) { }
function (valueLsb, valueMsb, channel, time) { }
function (message, time) { }
Emitted when a system exclusive message has been received. The message is passed as an array of numbers, including the 0xf0 and 0xf7 message delimiters.
function (argument, time) { }
function (positionLsb, positionMsb, time) { }
function (songNumber, time) { }
function (time) { }
function (time) { }
function (time) { }
function (time) { }
function (time) { }
function (time) { }
function (time) { }
function (time) { }
Returns the port name that this MIDIInput
object has been opened on.
Establish the channel mask for received messages. By default, messages for all channels are received.
The argument
may be either a single channel number or an array of
channel numbers to listen to. Channel numbers are one-based. Channel
number zero indicates that messages for all channels should be
listened for.
## MIDIOutput
The MIDIOutput
object represents a handle to a MIDI output port.
Its constructor function accepts a port name as argument. It has a
send()
function for sending arbitary MIDI messages as well as
convenience functions for each defined MIDI message.
Return a MIDIOutput
object opened to the port with the given
portName
. portName
can be specified as undefined
. If so, the
port named by the MIDI_OUTPUT environment variable, or, if that
variable is not set, the first MIDI output port available in the
system will be opened.
If a latency
is supplied, it determines the portmidi latency of the
port and enables deferred sending of messages.
The time
argument that can be supplied to all the message sending
functions below specifies the absolute time at which the message will
be sent. The current absolute time may be determined by the
'MIDI.currentTime()' function. Note that it is an error to specify a
sending time that has already passed. Also, message sending
timestamps must be monotonically increasing, i.e. once a message has
been enqueued for a certain point in time, it is not possible to
enqueue another message to be sent earlier than that. Such a
condition will be detected and signalled as an error to the
application.
Returns the port name that this MIDIOutput
object has been opened on.
The channel number to use for sending messages (1 to 16). When using
the send()
function directly, the channel number is not used. By
default, the MIDIOutput object sends on MIDI channel 1.
Send a raw MIDI message. message
is either a string with space
separated hexadecimal values or an array of numbers.
Send a MIDI Note On
or Note Off
event on the current channel.
pitch
is the pitch of the note, which may be specified either as
integer MIDI note number or as note name string (e.g. 'C0', 'F#4' or
'B-2').
Send a MIDI pitchWheelChange message with the given value
as
argument. value
must be passed as a number between -8192 and 8191.
Send the given MIDI sysex message. The message must be either a string with space separated hexadecimal values or an array of numbers. The start sysex (0xf0) and end sysex (0xf7) bytes must be included in the message. Nested messages are not allowed.
Send a NRPN message consisting of a 14 bit NRPN parameter
and a 7
(nrpn7
) or 14 (nrpn14
) bit value
. No previous selection of the
NRPN controller number in the target device is assumed, i.e. nrpn7
results in three controlChange messages and nrpn14
results in four
controlChange message to be sent to the target device.
Send the respective standard MIDI message with the arguments supplied on the current channel. No further translation of the arguments is performed for these messages.