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 🙂

Little things please little minds

I ran the register_service.py script at the same time as the following UDP listener:

#!/usr/bin/python
import socket
HOST='192.168.0.226'
PORT=5004
s = socket.socket( socket.AF_INET , socket.SOCK_DGRAM )
s.bind( (HOST, PORT ) )
buffer = s.recv(1024)
print buffer.encode('hex')

The service shows up in the Audio MIDI setup. When I connected to that server, the output was:

ffff494e00000002663348739ec3dbe341433700

which matched up with expectations !

I’m looking at DPKT ( http://code.google.com/p/dpkt/ ) to help me construct the data packets in Python seeing as I really don’t have the energy to play around with bytes.

I needed to create a parser for the initial Apple MIDI conversation.

import dpkt
class COMMAND(dpkt.Packet):
 __hdr__ = (
 ('signature', 'H', 0),
 ('command', '2s', 0),
 ('version', 'I', 2),
 ('initiator', 'I', 0),
 ('sender_ssrc', 'I', 0),
 ('name', '4s', ''),
 )

However, I need to look into the fact that name can be any length and is null-terminated. DPKT works on fixed lengths.

Hello, hello ?

More information is in the Wireshark dissector for Apple MIDI at http://anonsvn.wireshark.org/wireshark/trunk/epan/dissectors/packet-applemidi.c

Intial packet capture shows that the Audio Midi software makes the initial invitation:

Apple Network-MIDI Session Protocol
 Signature: 0xffff
 Command: Invitation (0x494e)
 Protocol Version: 2
 Initiator Token: 0x6b8b4567
 Sender SSRC: 0x1c037394
 Name: AC7

To which the application replies:

Apple Network-MIDI Session Protocol
 Signature: 0xffff
 Command: Invitation Accepted (0x4f4b)
 Protocol Version: 2
 Initiator Token: 0x6b8b4567
 Sender SSRC: 0xa3a202f2
 Name: Ravelox iPad

The commands are IN and OK.

The Initiator Token is a value that is randomly generated by the session initiator and is used throughout the conversation, the Sender SSRC is generated by each side and remains the same.

Playing with hardware

My original multimeter failed me. It wasn’t either the battery or the fuse so I revisited Radio Shack and $21 later, I got a new one.

The drum pad just houses a trigger.

IMG_0644

 

So I wired a drum pad and a drum pedal to a 9v battery and attempted to measure the voltage:

The pad seems to vary in voltage when it’s hit. It doesn’t fluctuate when it’s not hit.  I’m quite willing to accept that wiring up a 9v battery is less than ideal here but it’s indicative of the fact I *will* need the ADC.

The drum pedal really acts as a switch so an ADC isn’t required here.

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.

I’ve had this brilliant idea…

So, it’s like this you see….

I decided today that I needed a project to consolidate my time and give me a goal to achieve instead of aimlessly wandering around Azeroth beating people up.

I want a Raspberry Pi (http://www.raspberrypi.org) but I want to have a reason to get one and not leave it in a box somewhere doing nothing.

Today’s brilliant idea is to put together a midi interface for my ION Sound Sessions drum kit that’s gathering dust in the garage.