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

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