I've been using the MIDI library to 'map' certain notes to program changes and also send MIDI clock. But recently, I wanted to play MIDI files from an SD card, which is proving to be quite a challenge. I'm not sure why my code isn't working. Either the MIDI library functions work or the MIDIfile library functions work. But not both.

Note: the MIDIfile library is something I found that plays MIDI files from and SD card. It works, I know that. But not in my code with the MIDI library code:

/* this is the MIDIfile section that handles playing of the MIDI files on the SD card*/

void midiCallback(midi_event *pev)// Called by the MIDIFile library when a file event needs to be processed// thru the midi communications interface.// This callback is set up in the setup() function.{ if ((pev->data[0] >= 0x80) && (pev->data[0] <= 0xe0)) { Serial.write(pev->data[0] | pev->channel); Serial.write(&pev->data[1], pev->size-1); } else Serial.write(pev->data, pev->size); }

void sysexCallback(sysex_event *pev)// Called by the MIDIFile library when a system Exclusive (sysex) file event needs // to be processed thru the midi communications interface. MOst sysex events cannot // really be processed, so we just ignore it here.// This callback is set up in the setup() function{ DEBUG("\nS T"); DEBUG(pev->track); DEBUG(": Data "); for (uint8_t i=0; i<pev->size; i++) { DEBUGX(pev->data[i]);DEBUG(' '); }}

void midiSilence(void)// Turn everything off on every channel.// Some midi files are badly behaved and leave notes hanging, so between songs turn// off all the notes and sound{ midi_eventev;

// All sound off // When All Sound Off is received all oscillators will turn off, and their volume // envelopes are set to zero as soon as possible. ev.size = 0; ev.data[ev.size++] = 0xb0; ev.data[ev.size++] = 120; ev.data[ev.size++] = 0;

If the MIDI library uses the serial port, then you cannot have the MIDIFile library opening up the same serial port. I am not sure what the effect would be, but it is likely that the last 'open' is the one that works and the other is lost.

What you should probably be doing is calling the generic MIDI 'send a message' library call using the parameters from the MIDIFile callback rather than calling the serial routines (ie, all your MIDI messages are sent through the MIDI library).

this feels like a dumb question: I'm using the Ruggeduino MIDI shield, which allows you to change the MIDI IN/OUT to a variety of Digital in/outs. would that help me here? I think the MIDI library only supports Serial ...

typedef struct{uint8_ttrack;// the track this was onuint8_tchannel;// the midi channeluint8_tsize;// the number of data bytesuint8_tdata[4];// the data. Only 'size' bytes are valid} midi_event;

- The track you can ignore, as it is the track in the SMF being processed.- The channel should be mapped to the channel in the send() function above. Need to take care that whether the channel is zero or one based in MIDI. MIDIfile is zero based.- The rest of the data[] are KMIType, param1 and param2.

if I take the example MIDIfile sketch and simply add the MIDI.h reference, that sketch ceases to work. This somewhat confirms a conflict. The MIDI library is limited to using Serial as a comm method and changing the header file doesn't appear to work, but I'm not sure I'm doing it right either.

void midiCallback(midi_event *pev)// Called by the MIDIFile library when a file event needs to be processed// thru the midi communications interface.// This callback is set up in the setup() function.{if ((pev->data[0] >= 0x80) && (pev->data[0] <= 0xe0)){//SSerial.write(pev->data[0] | pev->channel);//SSerial.write(&pev->data[1], pev->size-1);