xnormidi

Originally called 'avr-midi', this C-language midi library has gone through several revisions and as proven to be quite useful for a variety of projects. I removed the 'avr' because, while my targets have still all been Atmel AVR microcontrollers, I have made an effort to remove the AVR dependencies from this project.

The library provides easy to use midi send functionality and callback based receive. The library itself does not actually implement the midi transport, instead it provides a method for parsing input and callback registration for sending output. This way it is relatively easy to send and receive midi over non-standard and standard transports alike. I have included a LUFA based USB midi implementation for USB AVRs, and intend to update the serial example for AVR soon.

License

This code is licensed with version 3 of the GPL license and is intended for use with in open source projects.

If you would you like to use this in a non 'GPL compatible', project please write me an email and we can discuss alternative licensing and compensation.

How to get it

I have created a github project where you can find the source code. There you can use git to download the code or use github's handy 'download' link.

Documentation

You can find the doxygen generated documentation here.

Example

Below is a very simple program taken from the LUFA example, which is included in the 'implementations' folder of the 'xnormidi' download. Here we set up the midi device, register some callbacks, send some midi messages, and run the midi process function.


#include "midi_usb.h" //see the lufa_midi implementation

//forward declarations of callbacks
void fallthrough_callback(MidiDevice * device,
      uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2);
void cc_callback(MidiDevice * device,
      uint8_t chan, uint8_t num, uint8_t val);

int main(void) {
   MidiDevice midi_device;

   //setup the device
   midi_usb_init(&midi_device);

   //register callbacks
   midi_register_fallthrough_callback(&midi_device, fallthrough_callback);
   midi_register_cc_callback(&midi_device, cc_callback);

   //send some messages
   midi_send_cc(&midi_device, 0, 1, 2);
   midi_send_noteon(&midi_device, 0, 64, 127);
   midi_send_noteoff(&midi_device, 0, 64, 127);

   while(1){
      //processes input from the midi device
      //and calls the appropriate callbacks
      midi_device_process(&midi_device);
   }

   return 0; //never happens
}

//echo data back
void fallthrough_callback(MidiDevice * device,
      uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2){
   //pass the data back to the device, using the general purpose send data
   //function, any bytes after cnt are ignored
   midi_send_data(device, cnt, byte0, byte1, byte2);
}

void cc_callback(MidiDevice * device,
      uint8_t chan, uint8_t num, uint8_t val) {
   //sending it back on the next channel
   midi_send_cc(device, (chan + 1) % 16, num, val);
}