I love the idea of grid based controllers like the Monome… much more than I actually use them in music oddly.
So on and off I’ve had a play around with PadKontrols, Launchpads, Lemur on Ipad, TouchOSC etc. and in particular the monome emulations.
However, when you start out it is a bit of a nightmare of different technologies to get your head around until you piece it all together.. and when things don’t ‘just work’ it is a frustrating brick wall. So I started learning some of this stuff to make my own utilities and get some of this working for me (e.g. a SerialOSC Monome emu for Lemur), and thought it would be useful to jot it down as a primer for anyone else who wants to clear some fog around this stuff.
The result is below:
This is a primer for open sound control, and in particular monome emulation
Ok, starting from first principles:
Machines on a network (Computers, Ipads, printers etc) have an address so they can be located. It is called an IP address and generally looks like this:
127.0.0.1 or 192.168.0.1
The idea is that this is a unique number that refers to only that machine, and the network ensures that if you send a packet of data into the network it will end up at the machine with the right address.
Now, since computers can run more than one program at a time but only have one address we need a way to distinguish between messages intended for one program, and messages intended for another. The mechanism for this is the ‘Port’. Each piece of software opens up one or more ports on the network to listen for messages. These ports are just named with numbers (although there are some standards ones, for example for email services etc).
So to send messages to a particular piece of software on a machine, you specify the IP address of the machine and the port that piece of software is listening to, which may look like this:
Now you may also see UDP and TCP referred to. These are just different technologies for passing the messages over a network. In general, it is not that useful to know the differences if you are just using some networking software rather than writing some so there is no need to dig deeper here (but feel free to Google “TCP vs UDP” if interested).
OSC – Open Sound Control
So open sound control is a protocol. If you’re not a techy person that word just means it is a format for some messages.
Here is a protocol: When a spy wants to identify another spy he says a code, which will be a special word followed the current day of the week. In response a friendly spy must say another special word and touch his nose. Note that the actual special words are not specified, that would vary by department, but the general format for the conversation is outlined.
It is similar with OSC. The message contents are not being specified, only the general format of how they look. It is up to the individual pieces of software that support OSC to specify what their specific messages will contain.
So, OSC says common messages will look something like this:
Here “App” will generally identify the software, e.g. it will be the name of a DAW or synth. Then “Area” will be an area within this, like FilterSection and finally ControlName will be a specific control, perhaps “Cutoff”. Then the data will be in this case most likely be a new setting for this control.
OSC specifies that it looks like /Something/Something data similar to the URL system for webpages. The number of somethings is not specified and is again up to the piece of software that is using OSC.
Software supporting OSC
So putting all this together, software that wants to support OSC generally does the following:
1) Open a UDP network port on the machine
2) Receives messages on this port and interprets them as OSC messages above
1) Connects to a UDP network port on another machine
2) Sends messages constructed as OSC messages to that port
So a practical example, connecting the Lemur app to an OSC supporting app on your machine should make sense now:
Open the app on the computer, maybe some MAX music application. And configure the port setting in it to some arbitrary number for the port you want it to listen on.
You open the Lemur app on your Ipad and, in the OSC section, enter an IP address (of the machine running the MAX app) and the port you told the MAX app to listen to , so that Lemur knows where to send the messages.
Now the Lemur app will send messages to the IP and port specified, and the application will receive them and process them and act accordingly.
That is all there is to that really.
The complications come in where firewalls (read as “Message blockers”) get in the way, or networking code is badly written and can’t open the port you asked for (maybe because something else opened it already) but doesn’t tell you. Those kind of scenarios make it hard to debug issues and obscure the relative simplicity of what is happening underneath, and of course are all a bit too specific to your particular system to get into here.
Ok so what we have above is the basics of networking and the OSC protocol and how it allows connecting various bits of software.
Now I want to describe how this relates to the Monome. This is also not complex (once you get it), but trying to pick this up from snippets of information on forums can be no fun at all.
Firstly the Monome needs some software on the computer that will talk to the Monome. This software acts as the middle man:
1) It takes messages from the monome (e.g. the user just pressed this button), and converts them to OSC messages.
2) It takes OSC messages from an application (e.g. light up this button) and converts them to messages the Monome understands.
Not so complicated so far.
Now both of these apps talk directly to the Monome (in its native serial language that we don’t care about) and convert this language to OSC messages.
However, there are two important differences:
1) Monomeserial made connections by specifying the port in the monome app (e.g. mlr), in the way described above. SerialOSC hides this away with a more user friendly system (see below).
2) Monomeserial converts the messages into a particular set of OSC messages, and SerialOSC converts these into another.
There are bridging apps that help manage this conversion (as seen lower down on that link), so that SerialOSC users can connect to legacy apps.
However, of course for a newcomer, you now have the monome itself, the messaging service (e.g. SerialOSC), the bridge (a MAX app), and the receiving application (probably another MAX app) all running at the same time – which can be a tad daunting for a non technical musician (and there must be some of these left?).
Ok, so finally before getting to Monome emulation lets look at this.
I said that SerialOSC hides the details of ports away to make a more user friendly system.
This is the detail:
The technology it uses is ZeroConf, and you can think of it as a registry of pieces of software that lists what port numbers they are listening to.
When a Monome is connected, the SerialOSC software opens a port that it will use for messages going to that Monome, and announces to the ZeroConf system a name and port number – which is recorded by ZeroConf into its registry.
When a SerialOSC Monome app is opened it queries this registry and (via a certain naming convention) gets all the registry entries that refer to Monomes. This is generally then displayed in the app as a drop down, allowing the user to select one.
When this selection happens the Monome app opens its own port for receiving messages and sends some setup OSC messages to the Monome port it got fom ZeroConf. These messages arrive at the SerialOSC service and tell it the port that the monome app wants to receive its messages on.
At this point the Monome app has got the port number for when it needs to send messages to the selected Monome. And SerialOSC has the port number from the Monome app for sending messages from the Monome to.
From the users point of view, they just selected a Monome that magically appeared in the Monome apps drop down. So better than messing with port numbers really (when it all works!).
The version of ZeroConf a lot of people use is within the Bonjour service created by Apple.
So finally, Monome emulation.
What tends to happen is that for some other piece of hardware, someone will write an equivalent of the MonomeSerial software. That is, a service that talks to that piece of hardware (e.g. a Launchpad) and does all the work of converting its messages to OSC messages that follow the convention of MonomeSerial.
This will generally be supplied in the form of a MAX application that you run, and then have to configure to connect to your hardware and also to your Monome app.
Currently very few of these support the SerialOSC versions of apps. I.e. they do not register with zeroconf, and they use the old version of the Monome OSC message format.
It is not actually particularly hard to convert these though.
You can add a few patchers to your MAX install that allow interaction with ZeroConf. The ones I’m currently using are in a file called zeroconf_20110226_win32.zip, with some help and an example here.
MAX based SerialOSC monome apps tend to use the “serialosc.maxpat” MAX patch to handle the ZeroConf stuff, which if you open up you will see is based on these osctools too.
Using these tools you can register a port with ZeroConf, and it will show up in the SerialOSC Monome app. Follow the help example in the file above, and change the service name to “@Type _monome-osc._udp” (which is the naming convention I mentioned earlier). When selected the Monome app will send some system messages informing you of the port it is listening on, and if you send SerialOSC style messages to this port you can simulate Monome keypresses.
A project I started to get Lemur to work via SerialOSC (still WIP as of writing) follows this approach and I have enough working that I’m fairly confident the framework is there. I’m still new to both MAX and Lemur though so scaling the thing up to a full Momome emu is going to take a bit of time.
Maybe when I can get it working reliably I can make the Monome app that will scratch my itch about working easily with grid based controllers !