Skip to main content

MIDIVal 0.0.16: now with MIDI Clock support

· 3 min read
Kacper Kula

MIDIVal Cover

The new version of MIDIVal just landed bringing an easier way to use MIDI Clock in your app.

If you didn’t come across MIDIVal before, it is a library that simplifies communication with MIDI devices from your JavaScript / TypeScript code by providing a high-level interface. It allows you to communicate with synthesizers (or any other MIDI devices) in an idiomatic way. You can read more about library itself in my initial post here.

// CARD LINK

Listening to MIDI Clock Messages

Now you can listen to all MIDI Clock messages like Clock Start, Stop and Continue as well as to individual pulse messages (sent 24 times every quarter note). This allows you to synchronize your Web-based music with an external clock from your synthesizer (or your DAW), create real-time applications based on the clock, or even send it over the web (or whatever else you can imagine).

midivalInputObject.onClockStart(() => {
console.log('MIDI Clock Started');
});

midivalInputObject.onClockStop(() => {
console.log('MIDI Clock Stoped');
});

midivalInputObject.onClockContinue(() => {
console.log('MIDI Clock Continued');
});

midivalInputObject.onClockPulse(() => {
console.log('Pulse');
});

Moreover, if you want to compute and use tempo (beats per minute) in which your MIDI device is sending those messages, you can use MIDIVal to automatically compute that for you. Then you can access it anytime:

const midivalInputObject = new MIDIValInput(input, {
computeClockTempo: true, // needs to be set on initialisation to make sure MIDIVal computes it.
});

// Whenever you want to use it
console.log(`Current Tempo is ${midivalInputObject.tempo}BPM`);

If you forget to set computeClockTempo option, getting tempo will throw MIDIValConfigurationError on access attempt.

Sending MIDI Clock Messages

You can also send MIDI Messages to your MIDI Output device now. The following new methods are available:

  • sendClockStart()
  • sendClockStop()
  • sendClockContinue()
  • sendClockPulse()

These allow you to manually control the clock. This can be a great tool when you don’t have any physical MIDI device with a built-in clock/sequencer or when you want to have full control over the clock from your JavaScript / TypeScript code. Remember that you have to send pulse messages manually 24 times every quarter note, for example like the following:

let clockHandle = null;
const BPM = 120;

midiStartButton.addEventListener("click", () => {
console.log("START");
midiOut.sendClockStart();
clockHandle = setInterval(() => {
midiOut.sendClockPulse();
}, 60 * 1000 / (BPM * 24));
});

midiStopButton.addEventListener("click", () => {
console.log("STOP");
midiOut.sendClockStop();
clearInterval(clockHandle);
});

Other Changes

Besides adding MIDI Clock messages extended support, new versions of MIDIVal have been reworked from the ground up to incorporate my other project, Omnibus — a simple implementation of platform-agnostic Event Bus. The initial implementation of the event bus in MIDIVal was a direct inspiration for this library and I decided to make it reusable in different projects.

// OMNI LINK

In addition, MIDI Callbacks are not much nicely typed and Note On/Off, CC and Program Change messages get the parameters nicely mapped to logical names:

// before
midiInput.onNoteOn(message => {
console.log("Note", message.data1);
console.log("Velocity", message.data2);
});

// now
midiInput.onNoteon(message => {
console.log("Note", message.note);
console.log("Velocity", message.velocity);
});

This can allow for tidier code without having to bother about MIDI message internals even more.