Slight change of code

Well, the original intention was to use pybonjour and dpkt but it got a little complex when I actually read through the RTP-MIDI RFC ( http://tools.ietf.org/html/rfc4695 ) and got to the section on journals.

I’m hoping that the reference code at http://www.cs.berkeley.edu/~lazzaro/rtpmidi/ will achieve what I need. I’ve looked it over and can see that there is specific handling of SIP packets.

SIP is used by standard implementations but Apple ( in their infinite wisdom ) uses their own protocol. So, I’ve written some C code to handle pack and unpack of buffers into data structures and vice-versa. This will be a replacement for the SIP code in the reference. My test code works with each buffer I’ve taken from packet captures. It unpacks into a data structure and I can then pack that data structure into a new buffer that matches what I read originally. A quick valgrind leak check shows that I’m not leaking memory 🙂

Now that I’m switching to C, I needed to look at avahi (http://avahi.org/ ) to register the service instead of pybonjour. There is a simple client example at http://avahi.org/download/doxygen/client-publish-service_8c-example.html which I will modify to my own requirements.

The sample uses a polling loop which never returns control to the calling program so I either have to run it in a thread ( which I don’t really want to do ) or to poll at regular intervals. Regular intervals works better because I also need to check the inbound UDP ports for RTP and AppleMIDI events. It also means that I can create a listening socket of some kind to receive input events from any other code I write to read the GPIO data from the interface.

Good job I have a few days off this week 🙂

Initiating the connection

So, from what I can see, the connection is actually made by the Apple Audio MIDI setup rather than the other way around.

So I need to advertise the _apple-midi._udp service.

Step up pybonjour ( http://code.google.com/p/pybonjour/ ). Note that I missed this handy hint about a dependency, when I was headscratching about why it wouldn’t compile and install: “Under Ubuntu, the package to install is libavahi-compat-libdnssd1.”

I can run the register_service.py example script and see my service appear in the Audio MIDI setup.

Every journey begins with a single step !

Midi over a network

Midi over a network is actually defined in RFCs. See http://www.cs.berkeley.edu/~lazzaro/sa/pubs/txt/current-rtp-midi.txt for more information.

However, those definitions are only for transferring the MIDI data over RTP once the connection has been made. The next trick is to work out how to initiate the connection.

This is where wireshark comes in useful. I have AC-7 on my iPad which is a MIDI-based DAW interface so I’ve been able to capture the traffic between the iPad and my Mac. The fields used in the initial protocol have been identified are in the standard wireshark release. See http://www.wireshark.org/docs/dfref/a/applemidi.html for those fields.

There are a couple of steps involved here. The first part is to determine where to connect. Zeroconf comes into play here by searching for addresses offering _apple-midi._udp. Once the address has been identified, the connection can be made.

The second part is initiating the session.