//midi for embedded chips, //Copyright 2010 Alex Norman // //This file is part of avr-midi. // //avr-midi is free software: you can redistribute it and/or modify //it under the terms of the GNU General Public License as published by //the Free Software Foundation, either version 3 of the License, or //(at your option) any later version. // //avr-midi is distributed in the hope that it will be useful, //but WITHOUT ANY WARRANTY; without even the implied warranty of //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //GNU General Public License for more details. // //You should have received a copy of the GNU General Public License //along with avr-midi. If not, see . #include "midi_device.h" #include "midi.h" #include #include #include "bytequeue.h" #define Q_BUFLEN 8 uint8_t buf[Q_BUFLEN]; byteQueue_t queue; MidiDevice test_device; uint8_t sent[3]; uint8_t got[16]; bool cc_called; bool noteon_called; bool noteoff_called; bool aftertouch_called; bool pitchbend_called; bool songposition_called; bool progchange_called; bool chanpressure_called; bool songselect_called; bool tc_quarterframe_called; bool realtime_called; bool tunerequest_called; bool fallthrough_called; void send_func(MidiDevice * device, uint8_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2) { sent[0] = byte0; sent[1] = byte1; sent[2] = byte0; printf("sent: "); uint8_t i; for (i = 0; i < cnt; i++) { printf("%02x ", sent[i]); } printf("\n"); } void cc_callback(MidiDevice * device, uint8_t byte0, uint8_t byte1, uint8_t byte2){ cc_called = true; got[0] = byte0; got[1] = byte1; got[2] = byte2; } void noteon_callback(MidiDevice * device, uint8_t byte0, uint8_t byte1, uint8_t byte2){ noteon_called = true; got[0] = byte0; got[1] = byte1; got[2] = byte2; } void noteoff_callback(MidiDevice * device, uint8_t byte0, uint8_t byte1, uint8_t byte2){ noteoff_called = true; got[0] = byte0; got[1] = byte1; got[2] = byte2; } void aftertouch_callback(MidiDevice * device, uint8_t byte0, uint8_t byte1, uint8_t byte2){ aftertouch_called = true; got[0] = byte0; got[1] = byte1; got[2] = byte2; } void pitchbend_callback(MidiDevice * device, uint8_t byte0, uint8_t byte1, uint8_t byte2){ pitchbend_called = true; got[0] = byte0; got[1] = byte1; got[2] = byte2; } void songposition_callback(MidiDevice * device, uint8_t byte0, uint8_t byte1, uint8_t byte2){ songposition_called = true; got[0] = byte0; got[1] = byte1; got[2] = byte2; } void progchange_callback(MidiDevice * device, uint8_t byte0, uint8_t byte1){ progchange_called = true; got[0] = byte0; got[1] = byte1; } void chanpressure_callback(MidiDevice * device, uint8_t byte0, uint8_t byte1){ chanpressure_called = true; got[0] = byte0; got[1] = byte1; } void songselect_callback(MidiDevice * device, uint8_t byte0, uint8_t byte1){ songselect_called = true; got[0] = byte0; got[1] = byte1; } void tc_quarterframe_callback(MidiDevice * device, uint8_t byte0, uint8_t byte1){ tc_quarterframe_called = true; got[0] = byte0; got[1] = byte1; } void realtime_callback(MidiDevice * device, uint8_t byte){ realtime_called = true; got[0] = byte; } void tunerequest_callback(MidiDevice * device, uint8_t byte){ tunerequest_called = true; got[0] = byte; } void fallthrough_callback(MidiDevice * device, uint8_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2){ fallthrough_called = true; got[0] = byte0; got[1] = byte1; got[2] = byte2; } void sysex_callback(MidiDevice * device, uint8_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2){ fallthrough_called = true; static int index = 0; fallthrough_called = true; switch (cnt) { case 3 : got[index+2] = byte2; case 2: got[index+1] = byte1; case 1: got[index+0] = byte0; } index += cnt; } void reset() { uint8_t i; for(i = 0; i < 3; i++) got[i] = sent[i] = 0; cc_called = false; noteon_called = false; noteoff_called = false; aftertouch_called = false; pitchbend_called = false; songposition_called = false; progchange_called = false; chanpressure_called = false; songselect_called = false; tc_quarterframe_called = false; realtime_called = false; tunerequest_called = false; fallthrough_called = false; } bool anything_called() { return cc_called || noteon_called || noteoff_called || aftertouch_called || pitchbend_called || songposition_called || progchange_called || chanpressure_called || songselect_called || tc_quarterframe_called || realtime_called || tunerequest_called || fallthrough_called; } int main(void) { bytequeue_init(&queue, buf, Q_BUFLEN); uint8_t i; for (i = 0; i < Q_BUFLEN - 1; i++) { assert(bytequeue_enqueue(&queue, i)); assert(bytequeue_length(&queue) == i+1); } assert(!bytequeue_enqueue(&queue, 0)); bytequeue_remove(&queue, bytequeue_length(&queue)); assert(bytequeue_length(&queue) == 0); for (i = 0; i < Q_BUFLEN - 1; i++) { assert(bytequeue_enqueue(&queue, i)); assert(bytequeue_length(&queue) == i+1); } for (i = 0; i < Q_BUFLEN - 1; i++) { bytequeue_remove(&queue, 1); } assert(bytequeue_length(&queue) == 0); midi_device_init(&test_device); midi_device_set_send_func(&test_device, send_func); midi_send_cc(&test_device, 0, 0, 1); midi_send_cc(&test_device, 15, 1, 1); midi_register_fallthrough_callback(&test_device, fallthrough_callback); midi_register_realtime_callback(&test_device, realtime_callback); assert(!fallthrough_called); assert(!realtime_called); midi_device_input(&test_device, 3, 0xB0, 0, 1); midi_device_input(&test_device, 1, MIDI_CLOCK, 0, 0); midi_device_process(&test_device); assert(fallthrough_called); assert(realtime_called); reset(); assert(!fallthrough_called); assert(!realtime_called); //interspersed midi_device_input(&test_device, 1, 0xB0, 0, 0); midi_device_input(&test_device, 1, MIDI_CLOCK, 0, 0); midi_device_input(&test_device, 1, 0, 0, 0); midi_device_input(&test_device, 1, MIDI_START, 0, 0); midi_device_input(&test_device, 1, 1, 0, 0); midi_device_process(&test_device); assert(fallthrough_called); assert(realtime_called); midi_register_cc_callback(&test_device, cc_callback); assert(!cc_called); midi_device_input(&test_device, 3, 0xB0, 0, 1); midi_device_process(&test_device); assert(cc_called); reset(); assert(!cc_called); assert(!realtime_called); midi_device_input(&test_device, 1, 0xB0, 0, 0); midi_device_input(&test_device, 1, MIDI_CLOCK, 0, 0); midi_device_input(&test_device, 1, 0, 0, 0); midi_device_input(&test_device, 1, MIDI_START, 0, 0); midi_device_input(&test_device, 1, 1, 0, 0); midi_device_process(&test_device); assert(cc_called); assert(realtime_called); reset(); assert(!anything_called()); midi_device_input(&test_device, 1, 0xB0, 0, 0); midi_device_input(&test_device, 1, 0, 0, 0); midi_device_process(&test_device); assert(!anything_called()); midi_register_fallthrough_callback(&test_device, sysex_callback); midi_device_input(&test_device, 3, SYSEX_BEGIN, 0, 1); midi_device_input(&test_device, 3, 2, 3, 4); midi_device_input(&test_device, 2, 5, 6, 0); midi_device_input(&test_device, 1, 7, 0, 0); midi_device_input(&test_device, 1, SYSEX_END, 0, 0); midi_device_process(&test_device); assert(fallthrough_called); assert(got[0] == SYSEX_BEGIN); // uint8_t i; for (i = 0; i < 8; i++) assert(got[i+1] == i); assert(got[9] == SYSEX_END); assert(midi_packet_length(MIDI_NOTEON) == 3); assert(midi_packet_length(MIDI_CLOCK) == 1); printf("\n\nTEST PASSED!\n\n"); return 0; }