VL: Event based MIDI

April 12, 2017 posted by: tonfilm

Midi was released in 1982 and is one of the most successful hardware communication protocols in the world. The simple nature of the protocol makes it easy to implement and even more important, easy to understand for humans.

This makes it a perfect example for the first event based library in VL using the MIDI-Toolkit developed by Leslie Sanford.

Modularity

Instead of having all settings on one node, functionality is now separate to allow arbitrary combinations.

Devices

Device nodes have an enum input for the input/output device driver you want to use. You can have many of them, even for the same driver. Under the hood they will share the actual device driver resource. The driver is opened only if it is necessary, for example if there is an event sink listening to it.

The dynamic device enum will update as soon as a midi device is connected or disconnected to the machine. So no restart required on configuration change:

Driver list updating on connect/disconnect of a device

MidiIn has one observable output for all midi messages received on the given device. MidiOut has one input that accepts an observable to send midi messages to the given device.

Route all messages from in to out

Message Filtering

Following the midi message structure, there are filters that allow you to select only the messages you are interested in. For example only midi clock messages, or messages on a specific midi channel:

Only let messages on midi channel 0 thru

Message Handling

For all midi message types there are specific nodes to read the message content or construct new messages. These are mostly the native methods of the MidiToolkit library.

Create a channel message and read its content

Event Based Processing

You can process a midi message (in fact any event) directly as it occurs. The new ForEach region in the Reactive category executes it’s patch for each event that is passed in and can transform the event into a different message type and decide whether to pass the current event on via the Keep output.

Handling midi messages in a custom patch as they occur

This is part of a bigger programming paradigm that was also polished for the new midi nodes. Definitely check out for the blog post on Reactive Programming.

Events vs. Mainloop

To Mainloop

At some point all async input event handling in the background will be over and you want to leave the observable world and have the processed values in the main loop. For that there are several options:

For supereasy controller value input there is ControllerState or NoteState:

Getting the value of midi controller 7 directly

For more advanced scenarios refer to the Reactive nodes HoldLatest, S+H or Sampler which provide ways to pass event values safely to the mainloop.

From Mainloop

If you want to generate midi messages in the mainloop you also have a simple node that generates controller message events:

Sending controller 7 on channel 0 on value change

For other messages use the Reactive nodes ToObservable which create an event source that you can use to send events from the mainloop.

Spreading

Since VL makes a difference between a single value and a spread of values, some nodes come in ‘plural’ version to allow listening for example for multiple channels at one.

Filter messages of channel 0 or channels 0, 3 and 5


Comments:

Comments are no longer accepted for this post.

sebescudie
12.04.2017 - 19:19
wow that’s massive! thanks!
sebl
12.04.2017 - 20:40
wohoo, thrilled about reactive announcement
tonfilm
19.05.2018 - 18:25
hello @ddf upcoming alpha will have MidiClock in/out nodes. just wait a few days… if you want to handle the messages yourself, use the MessageSplitter and check the RealtimeMessages with a ForEach reactive for MessageType Clock…
ddf
19.05.2018 - 23:39
Thanks @tonfilm !
ddf
30.05.2018 - 00:53
Something like this @tonfilm ? thanks Is that correct?
Vadoe
17.09.2018 - 10:16
Sending tones of midicontroller to a Device needs tones of cpu timings. I was wondering if i can do the midioutput as a asynctask or async loop. Maybe someone know how to build a midi out that runs async
tonfilm
17.09.2018 - 16:51

more like this @ddf

sunep
13.04.2017 - 10:17

looks cool! One question, shouldn’t ControllerState also have a channel input?

EDIT: aaaaahh, ChannelFilter

tonfilm
13.04.2017 - 12:43
@sunep yes, we had that at first but then decided against it because of more modularity and less complex nodes. Since most midi nodes are patched you can easily copy the Controller node and add the channel pin on your own if you need that often in a project.
sunep
13.04.2017 - 12:46
makes sense
featherfurl
14.04.2017 - 03:40
:D
ddf
29.03.2018 - 01:53
..But how can I get a midi clock in?
tonfilm
02.04.2018 - 21:47
hello @ddf seems i overlooked this. midi clock messages are called SystemRealtimeMessages. in latest alpha you also have the driver timestamp per message, this makes calculating the midi clock quite precise. i’ve planned to add an example to the midi lib on how to do this, i’ll let you know.
ddf
03.04.2018 - 00:44

Hi @tonfilm,

I am pretty new into VL For Controller and notes is quite clear, not for the clock for me.. probably the answer is obvious: How should I connect the nodes in order to get a value into the mainloop? thanks a lot for now ddf

ddf
19.05.2018 - 17:52
No one?

Contact


Imprint

vvvv - Dießl & Gregor GbR
Oranienstrasse 10
10997 Berlin/Germany
VAT: DE275566955

groupӘvvvv.org

Follow us

Mastodon.social
Pixelfed.social
Github
Vimeo
Youtube

Sign up for our Newsletter

Your subscription could not be saved. Please try again.
Your subscription has been successful.