Making Connections: MIDI in SuperCollider

Notes on acoustics

The previous post demonstrated the process of setting up SuperCollider and generating a tone. In this next post, I will be explaining how to set up MIDI input in SuperCollider.

MIDI is a standard protocol that dates back to the early 1980s. It supports up to sixteen channels and can be used to communicate pitch, velocity, and other information important for the operation of musical instruments. In the long term, I would like to be able to choose different timbres by mapping them to different MIDI channels. I would also like to be able to change parameters using control change messages.

First, however, I needed to set up SuperCollider to accept MIDI input.

Enabling MIDI in SuperCollider

Start the SuperCollider server if it is not already running.

s.boot;

From the Catia patchbay, it is clear that the SuperCollider instance does not currently accept MIDI input.

We can change this by running

MIDIClient.init;
MIDIIn.connectAll;

On my system, this created three MIDI input ports and one output port.

In this case, I was only interested in controlling the server from one source, so I only needed one MIDI input. The documentation for MIDIClient shows by default running MIDIClient.init “opens as many inports as there are MIDI sources”. To only have one inport, I reset the MIDIClient and reinitialized it with the correct number of ports specified.

MIDIClient.disposeClient;
MIDIClient.init(1, 1);

Now I had one input port and one output port.

Getting input

MIDIdef.noteOn allows us to run a function whenever a note is pressed. To test this out, I created a simple function that prints the associated MIDI information whenever a key is pressed.

MIDIdef.noteOn(\print, {arg val, num, chan, src; [src,chan, num, val].postln});

I then opened my DAW and created a simple MIDI pattern in the piano roll. I then configured the DAW to export any MIDI playback on that track to the program’s output. Connecting the DAW’s output to SuperCollider’s printed gave the following information:

[ 8454144, 0, 60, 127 ]
[ 8454144, 0, 63, 127 ]
[ 8454144, 0, 67, 127 ]
[ 8454144, 0, 65, 59 ]
[ 8454144, 0, 68, 59 ]
[ 8454144, 0, 72, 59 ]

This indicates that the source is identified by the integer 8454144 and that the MIDI notes were sent on the first channel (they are indexed starting with zero). The third number in the arrays represent notes and the last number represents the velocity of the note (ranging from zero to 127).

We can filter the notes such that the function is only called for a certain source or channel:

MIDIdef.noteOn(\test4, {arg val, num, chan, src; 
    [src,chan, num, val].postln;
}, chan: 1);

Down the road, this will give us the ability to set up multiple instruments that can be selected using the MIDI channel.


In this post, we have opened up SuperCollider to be able to interact with other programs and hardware using the MIDI standard. In the next post, we will use this MIDI control to control the sound generated by the server.