## MIDI in object for Propeller

The MidiIn object is a Propeller object which reads a MIDI data stream, parses the MIDI commands, and returns the MIDI events to the user for further processing. The code is based on my understanding of the MIDI spec as documented by the very useful web site The MIDI Spec. Although I have tried very hard to make sure that I'm handling the MIDI data correctly, it is quite possible that there are still errors. If you find any, please let me know so that I can fix them!

### Limitations

- SYSEX messages are not handled well (actually they are barely handled at all) in this version. I'm open to suggestions as to the best way to handle SYSEX data.
- MTC (Midi Time Code) Messages are just passed along in their raw form. If you'd like to see me parsing them and passing back more refined data, talk to me. My project does not need MTC, so I'm not sure what would be useful.
- I only have a 16 slot event buffer, with no provision for handling buffer overflow. You'll need to make sure you are retrieving the events fast enough to prevent overflow.

### Overview

The MidiIn object runs in its own cog, passing desired MIDI events back through a simple SPIN interface. When you start the MidiIn object (using the start method) you pass two parameters, the I/O pin that the MIDI in stream will be connected to, and a word containing bit flags indicating what MIDI events you want to see. You then use the evtCheck, evtTime, and/or evt methods to retrieve MIDI events. These three methods all do the same thing - return one word containing a MIDI event. evtCheck will always return immediately, returning -1 if there is no MIDI event available. evtTime will wait for a user specified time for a MIDI event, and evt will wait with no limit for a MIDI event.

Although the code may appear rather voluminous, the actual code paths are very short, and there is no problem keeping up with a standard MIDI input stream. I have commented the code - probably to excess - so that it should be fairly easy to follow aand modify if you want to.

### MIDI Event Flags

When you start up the MidiIn object, you pass a word containing bit flags indicating what events you would like to see. Here is a fragment of spin code to put in your CON section defining the available flags:

      doNoteOn            = $00000001
      doNoteOff           = $00000002
      doAftertouch        = $00000004
      doController        = $00000008
      doProgramChange     = $00000010
      doChannelPressure   = $00000020
      doPitchWheel        = $00000040
      doSysex             = $00000100
      doMTC               = $00000200
      doSongPosPtr        = $00000400
      doSongSelect        = $00000800
      doTuneRequest       = $00001000
      doMidiClock         = $00002000
      doMidiTick          = $00004000
      doMidiStart         = $00008000
      doMidiContinue      = $00010000
      doMidiStop          = $00020000
      doActiveSense       = $00040000
      doReset             = $00080000

Since these are bit flags, you can just add them together to get the word to be passed to MidiIn. So if you only want to see the Note On and Note Off events, you would start up the MidiIn object with:

      midiIn.start(midiPin, doNoteOn+doNoteOff)

### MIDI Events

Each MIDI event is returned as one word, according to the layouts in the table below. The values for Pitch Wheel and Song Position MIDI events are sent in a MIDI stream as two bytes, each containing 7 bits. MidiIn combines these correctly and returns the value as a halfword.

| Byte 3 | Byte 2 | Byte 1 | Byte 0
--- | --- | --- | --- | ---
Note On | $00 | channel | note | velocity
Note Off | $01 | channel | note | velocity
Aftertouch | $02 | channel | note | velocity
Controller | $03 | channel | controller number | controller value
Program Change | $04 | channel | $00 | program number
Channel Pressure | $05 | channel | $00 | channel pressure
Pitch Wheel | $06 | channel | pitch wheel value
SysEx | $07 | sysex length | sysex buffer address
Midi Time Code (MTC) | $08 | $00 | $00 | MTC value
Song Position | $09 | $00 | song position value
Song Select | $0A | $00 | $00 | song select value
Tune Request | $0B | $00 | $00 | $00
Midi Clock | $0C | $00 | $00 | $00
Midi Tick | $0D | $00 | $00 | $00
Midi Start | $0E | $00 | $00 | $00
Midi Continue | $0F | $00 | $00 | $00
Midi Stop | $10 | $00 | $00 | $00
Active Sense | $11 | $00 | $00 | $00
Reset | $12 | $00 | $00 | $00

### Hardware

Interfacing MIDI to the Propeller is quite easy, requiring only three resistors, one diode, and an opto-isolator. My implementation is shown in the circuit below, which is in turn based on this circuit. I'm pretty sure that you could reduce the 5v connection to the opto-isolator to 3.3v and eliminate the 1K resistor, but I have not tried that.

### About My Project

This object was created as part of my project to equip my Austin Pipe Organ to play from a MIDI stream. I acquired the organ about twenty years ago, when the church that owned it decided to replace it with an electronic organ after the pipe organ was damaged in a flood. I worked with a close friend to build a MIDI controller for it based on the 8051 micro-computer. I etched my own circuit boards and we actually got it all working - one of the first MIDI capable pipe organs in the world. But the system did not age well, and was difficult to impossible to modify. Several years ago the organ stopped playing. I had been looking at several possibilities for building a new controller - the Javelin chip from Parallax looked very promising (I was a Java programmer at work), until I found that it could not deal with the 31.25KB baud rate of MIDI. The SX processors could have done the job, and I was starting to look into them when the Propeller chip was announced. The organ now plays from my breadboard implementation, and I should have my ProtoBoard version up and running very soon.

Tom Dimock
tad1@cornell.edu
6/4/2007