MIDIVal just got a big version bump with exciting new functionality! You can now use the MIDIVal library to send and receive MIDI Polyphonic Expression messages. It is the only high level JavaScript library to add support for this protocol. Thanks to portability of MIDIVal, you can use it in your web, node and react native projects!
What is MPE?
MPE is an extension of the MIDI 1 protocol. MPE, or MIDI Polyphonic Expression, adds the ability to vary pressure, pitch and timbre for each note independently (or in fact any 3 dimensions of your sound). It allows for way more expression in your performances.
The specification describes a low-level protocol for communication but fortunately, with the new version of MIDIVal you can use might more user-friendly interface and not care about low-level implementation details.
Getting started with MPE in MIDIVal
To install the new MIDIVal version, run npm
or yarn
targeting version 0.1:
npm install @midival/core@0.1
# Or using YARN
yarn add @midival/core@0.1
To start communicating with MPE you need to select which MIDI device you want to use. To do so, you can list all input and output devices (same as before in earlier versions of the library):
import { MIDIVal } from "@midival/core"
MIDIVal.connect()
.then(access => {
const { inputs, outputs } = access
// Select which input or output you want to use.
})
Sending MPE messages
To send MPE messages you need to instantiate MPEMIDIValOutput
and pass the device you want to use. MPE documentation allows you to define both the lower and upper zone for your device which can be used to split the channel into 2 separately addressable keyboards.
Instantiating MPEInputOutput
will send all necessary setup messages.
import { MPEMidivalOutput } from "@midival/core/dist/mpe"
const mpeOutput = new MPEMidivalOutput(output,
{ lowerZoneSize: 7, upperZoneSize: 3 }
)
Once the object is set up, you can start sending notes. MIDIVal library will take care of proper routing for your message to corresponding channels.
const note: ActiveNote = mpeOutput.lowerZone.sendNoteOn(64, 120); // [note, velocity]
Using ActiveNote
object you can modify the note during its lifetime and also send noteOff signal:
note.changeBend(-0.2);
note.changeTimbre(20);
note.changePressure(50);
// Or if you prefer using coordinates system x,y,z
note.x = -0.2;
note.y = 20;
note.z = 50;
// when you want to send note off
note.noteOff()
Receiving MPE messages
const input = new MPEMidivalInput(new MIDIValInput(input));
input.onLowerZoneUpdate(lowerZone => {
if (!lowerZone) {
console.log("Lower Zone was disabled");
return;
}
lowerZone.onNoteOn(note => {
// React to note being pressed.
})
lowerZone.onNoteOff(note => {
// React to note being depressed
})
lowerZone.onMemberPitchBend(bend => {
// React to note being bent
})
lowerZone.onMemberTimbre(tim => {
// React to notes timbre being changed
})
lowerZone.onMemberPressure(pres => {
// React to notes pressure being changed
})
})
Similarly, you can react to pitch, timbre and pressure change for the whole zone using onMasterPitchBend
, onMasterTimbre
, onMasterPressure
.
Test it now
If you have DAW with MPE support you can use the MIDIVal Demo page to send sample MPE messages to it. The website uses the latest version of MIDIVal to send messages. You can enable LFO modulation for each of the notes independently.
If you have an MPE input device, you can use the same website to check notes received, their corresponding channels and modulations.
API Docs
For full API documentation of the MPE functionality, visit @midival/core MPE documentation page.
Join the community
With the release of MIDIVal 0.1.0, I have also launched a Discord channel for anyone interested in the library. If you have questions about the library, want to contribute or even just have a casual chat about MIDI or anything music related, join and drop the message there!
For more information about MIDIVal, Web MIDI, Web Audio and TypeScript articles, remember to follow me here on Medium!