Information burst

More reading, more changes of mind.

As my requirements for this MIDI interface are limited only to sending notes, I came to the realisation that I don’t need to handle journals inbound to me and the only journal I need to create outbound is a Chapter N for NOTE ON/OFF events. After playing with reference implementation and copying most of the sample code from the RFC, I’ve taken it all out again and I’m starting from scratch. The RFC code isn’t the best example of a Chapter N journal so I need to go over the details again and translate the concept. I’m sure it’s relatively simple, I just need to wrap my head around it (I’m a bear of little brain).

I have 2 binaries right now. The first is a simple Avahi registration app that publishes host and port 5004 and the name of the service (_apple-midi._udp). The second listens on the ports for events. The listener app is correctly unpacking the Apple MIDI events. I did clean up some segfaults when the OS X MIDI app ends the session ( by sending a BY event ). I’m debating whether I want to handle just 1 session or multiple.

On the hardware side, having got a little bored of starting at C code, I spent some money at Radio Shack and other places to get capacitors, resistors, diodes and also some 3.5mm audio inputs that are breadboard combatible.

I did some reading up on how to handle the drum pad inputs. As the teardown showed, it’s a piezo trigger and, according to the internet, that requires some special handling.

The following pages are useful information: http://petervieth.com/projects/midi-drum-pad/ and http://leucos.lstilde.org/wp/2009/06/piezo-transducer-signal-conditioning/

They show the circuits needed to handle a piezo input.

Here’s my problem right now. I built the circuit using the info from Peter Vieth’s page and, if I connect up my multimeter, I can see there is a change in voltage when I hit a pad but it’s very small. Some of the many questions I have is whether I’m supposed to be seeing such a small voltage change ( which I saw when I first tested the pad a couple of months ago ). In some cases, with light hits, I don’t see a change at all.

I connected the drum pads back up to the controller they came with and they play fine. Light hits are registering so I know I haven’t broken anything ( hard to do seeing as it’s a piezo trigger ). The controller uses a 9v DC input and I’ve hooked my circuit to a 9v battery but see little change.

The other question I have is whether I’m actually using my multimeter correctly or if I should even be seeing anything register with a multimeter. The info on the Leucos site shows some good data using an oscilloscope but I don’t want to get into that at my stage of life ( $$$ ).

 

I guess more reading is in order. I have some work colleagues that are part of Noisebridge (www.noisebridge.net) and they have sessions on a Monday  which helps members learn about circuits’n’stuff so I may check them out.

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.