🎹 noon-io
Easy io for the Web MIDI API
🚨 Disclaimer
Development has just started and until v1.0.0 has been released, noon-io should be considered unstable.
🗒️ API Documentation
A more detailed documentation of noon-io can be found here.
🚀 Getting started
📦 Install
npm i noon-io
📤 Send MIDI messages
Send a A4 NOTE ON
message on all available MIDI outputs
import * as NIO from 'noon-io';
// Gain access to the Web MIDI API
const midiAccess = await navigator.requestMIDIAccess();
// Send a Note On message over all available outputs on channel 2
for (const output of midiAccess.outputs.values()) {
const noteOnMessage = {
status: NIO.MidiStatus.NOTE_ON,
channel: 2,
data: {
value: 69, // A4
velocity: 127
}
};
output.send(NIO.write(noteOnMessage));
}
🔨 Using channel message factory functions
For one dedicated channel, noon-io offers a more concise way of writing messages using factory functions.
// send a CC of 80 for control 71
output.send(NIO.channel(2).controlChange(71, 80));
// send a A4 note on message with a velocity of 120
output.send(NIO.channel(2).noteOn(69, 120));
// send the subsequent note off message for our A4 note
output.send(NIO.channel(2).noteOff(69));
For more information about noon-io factories, you can checkout this documentation
📥 Read MIDI messages
import * as NIO from 'noon-io';
// Gain access to the Web MIDI API
const midiAccess = await navigator.requestMIDIAccess();
// Bind NIO reader to all midi inputs
for (const input of midiAccess.inputs.values()) {
input.onmidimessage = NIO.read;
}
🕒 Subscribing to the messages stream
Once read, messages are exposed through the stream
rx Subject.
import * as NIO from 'noon-io';
NIO.stream.subscribe(message => {
console.log(message);
});
// Gain access to the Web MIDI API
const midiAccess = await navigator.requestMIDIAccess();
// Bind NIO reader to all midi inputs
for (const input of midiAccess.inputs.values()) {
input.onmidimessage = NIO.read; // message is handle by the subscriber
}
🕒 Filtering messages
In addition to the message stream, NIO provides a convenient observe
function,
which will return a observable of MIDI messages matching the given MIDI status.
import * as NIO from 'noon-io';
const { MidiStatus, observe } = NIO;
observe(MidiStatus.CONTROL_CHANGE)
.subscribe(message => {
// handle control change message
});
⚗️ Bank Select / Program Change
Sending a bank select followed by a program change can be achieved by sending two consecutive control change messages before sending the actual program change.
(The following has been tested on a Dave Smith Instruments Mopho device)
import * as NIO from 'noon-io';
/*
* Start Bank Select message
* Selects banks 2 (bank 1 is 0) for channel 2
*/
output.send(
NIO.writeMidiMessage({
status: NIO.MidiStatus.CONTROL_CHANGE,
channel: 2,
data: {
control: 0, // bank select MSB (always 0)
value: 1, // MSB multiplier
}
})
);
output.send(
NIO.writeMidiMessage({
status: NIO.MidiStatus.CONTROL_CHANGE,
channel: 2,
data: {
control: 0, // bank select LSB (always 32)
value: 1, // LSB multiplier
}
})
); // Ends bank select message
/*
* Now that we have selected bank 2,
* let's select a random program
*/
output.send(
NIO.writeMidiMessage({
status: NIO.MidiStatus.PROGRAM_CHANGE,
channel: 2,
data: {
value: Math.ceil(Math.random() * 127),
}
})
);
Or using the bankSelectMSB
and bankSelectLSB
factories provided by noon-io
// Select bank 1
output.send(NIO.channel(2).bankSelectMSB(0));
output.send(NIO.channel(2).bankSelectLSB(0));
// Select program 109 from bank 1
output.send(NIO.channel(2).programChange(Math.ceil(Math.random() * 127)));
🚧 Supported Messages
🎶 Channel Messages
Type | Reader | Writer | Status |
---|---|---|---|
NOTE ON | Read and write have been tested on a MIDI port | ||
NOTE OFF | Read and write have been tested on a MIDI port | ||
PITCH BEND | Read and write have been tested on a MIDI port | ||
CONTROL CHANGE | Read and write have been tested on a MIDI port | ||
PROGRAM CHANGE | Read and write have been tested on a MIDI port | ||
NOTE AFTER TOUCH | ✅ | Both read and write have not been tested | |
CHANNEL AFTER TOUCH | ✅ | Both read and write have not been tested |
🎛️ System Messages
Type | Reader | Writer | Status |
---|---|---|---|
TIMING CLOCK | ✅ | Only Read has been tester on a MIDI port | |
START | ✅ | Both read and write have not been tested | |
STOP | Both read and write have not been tested | ||
CONTINUE | Both read and write have not been tested | ||
SYSTEM RESET | Both read and write have not been tested | ||
ACTIVE SENDING | Both read and write have not been tested | ||
SYSTEM EXCLUSIVE | ❌ | Reader has not been tested, writer is not implemented | |
MIDI TIME CODE | Not Implemented | ||
SONG POSITION | ❌ | Not Implemented | |
SONG SELECT | Not Implemented | ||
TUNE REQUEST | Not Implemented |