/* MIDI Input Driver by Sebastian Tomczak August 2009 */ // Definitions byte dataIn; // general working byte for serially-received data byte channel; byte pitch; byte velocity; byte ccnumber; byte ccvalue; byte bendLSB; byte bendMSB; byte rstat; int flag_previous = 0; // keeps track of the previus MIDI byte type received /* flag_previous meanings: -1 = note off status -2 = note off pitch 0 = no action / waiting 1 = note on status 2 = pitch 3 = cc status 4 = cc number */ // Setup void setup() { Serial.begin(31250); } // Main Program void loop() { // start main loop if(Serial.available() > 0) { dataIn = Serial.read(); if(dataIn < 0x80 && flag_previous == 0) { doMidiIn(rstat); } doMidiIn(dataIn); } // end main loop } void doMidiIn(byte data) { // running status set if((data >= 0x80) && (data < 0xf0) && (flag_previous == 0)) { rstat = data; } // deal with note on if((data >= 0x90) && (data < 0xa0) && (flag_previous == 0)) { channel = data & B00001111; flag_previous = 1; } else if((data < 0x80) && (flag_previous == 1)) { pitch = data; flag_previous = 2; } else if((data < 0x80) && (flag_previous == 2)) { velocity = data; doNote(channel, pitch, velocity); flag_previous = 0; } // done with note on // deal with note off (as discrete status byte) else if((data >= 0x80) && (data < 0x90) && (flag_previous == 0)) { channel = data & B00001111; flag_previous = -1; } else if((data < 0x80) && (flag_previous == -1)) { pitch = data; flag_previous = -2; } else if((data < 0x80) && (flag_previous == -2)) { velocity = data; doNoteOff(channel, pitch, velocity); flag_previous = 0; } // done with note off (as discrete status byte) // deal with cc data else if((data >= 0xb0) && (data < 0xc0) && (flag_previous == 0)) { channel = data & B00001111; flag_previous = 3; } else if((data < 0x80) && (flag_previous == 3)) { ccnumber = data; flag_previous = 4; } else if((data < 0x80) && (flag_previous == 4)) { ccvalue = data; doCC(channel, ccnumber, ccvalue); flag_previous = 0; } // done with cc data // deal with bend data else if((data >= 0xe0) && (data < 0xf0) && (flag_previous == 0)) { channel = data & B00001111; flag_previous = 5; } else if((data < 0x80) && (flag_previous == 5)) { bendLSB = data; flag_previous = 6; } else if((data < 0x80) && (flag_previous == 6)) { bendMSB = data; doBend(channel, bendLSB, bendMSB); flag_previous = 0; } // done with bend data // deal with real time messages else if((data >= 0xf8) && (data <= 0xff)) { switch(data) { case 0xf8: doRtClock(); break; case 0xfa: doRtStart(); break; case 0xfb: doRtContinue(); break; case 0xfc: doRtStop(); break; case 0xff: doRtReset(); break; } } // done with real time messages } // Functions void doNote(byte channel, byte pitch, byte velocity) { // do something with the note off data //... // nothing yet! } void doNoteOff(byte channel, byte pitch, byte velocity) { // do something with the note off data // ... // nothing yet! } void doCC(byte channel, byte ccnumber, byte ccvalue) { // do something with the cc data // ... // nothing yet! } void doBend(byte channel, byte bendLSB, byte bendMSB) { // do something with the bend data // ... // nothing yet! } void doRtClock() { // do something with timing // ... // nothing yet! } void doRtStart() { // do something with timing // ... // nothing yet! } void doRtContinue() { // do something with timing // ... // nothing yet! } void doRtStop() { // do something with timing // ... // nothing yet! } void doRtReset() { // do something with timing // ... // nothing yet! }