Radio Junk Box
/
KAMUI_USBHOST_MIDI-CV_Example
KAMUI USB HOST MIDI-CV Example based on Peter Barrett's BlueUSB
Diff: midi_parser.c
- Revision:
- 0:3b4e3e2ec6a5
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/midi_parser.c Fri May 11 15:31:59 2012 +0000 @@ -0,0 +1,258 @@ +//------------------------------------------------------------- +// file : midi_parser.c +// Copyright (C) 2012 RJB RadioJunkBox +// Released under the MIT License: http://mbed.org/license/mit +//------------------------------------------------------------- + +#include "mbed.h" +#include "midi_parser.h" + +//------------------------------------------------------------- +// MIDI Parser + +void MIDI_Parser(unsigned char mididata) +{ + RxByte = mididata; + + if(MIDI_SystemMessage()) { + MIDI_ChannelMessage(); + } +} + +//------------------------------------------------------------- +// MIDI System Meassage + +int MIDI_SystemMessage(void) +{ + if(SysEx){ + if(RxByte == MIDI_EndSysEx){ + SysEx = FALSE; + } + } + else{ + if(RxByte < 0xF8){ + if(RxByte > 0x7F){ + if(RxByte == MIDI_StartSysEx){ + SysEx = TRUE; + } + else{ + MidiCh = RxByte & 0x0F; + } + PC = 0; + } + else{ + MByte[PC & 0x01] = RxByte; + } + return TRUE; + } + else { + MIDI_SystemRealtimeMessage(); + } + } + return FALSE; +} + +//------------------------------------------------------------- +// MIDI System Realtime Message + +void MIDI_SystemRealtimeMessage(void) +{ + switch(RxByte) { + case MIDI_TimingClock: + gMIDISYNC_CLK |= 0x01; + break; + case MIDI_Start: + gMIDISYNC_RUN = 0x01; + break; + case MIDI_Continue: + gMIDISYNC_RUN = 0x01; + break; + case MIDI_Stop: + gMIDISYNC_RUN = 0x00; + break; + case MIDI_ActiveSensing: + break; + case MIDI_SystemReset: + break; + } +} + +//------------------------------------------------------------- +// MIDI Channel Message + +void MIDI_ChannelMessage(void) +{ + switch(PC){ + case 0: + switch(RxByte & 0xF0){ + case MIDI_NoteOff: + PC = 2; + break; + case MIDI_NoteOn: + PC = 4; + break; + case MIDI_PolykeyPressure: + PC = 6; + break; + case MIDI_ProgramChange: + PC = 8; + break; + case MIDI_ControlChange: + PC = 10; + break; + case MIDI_ChannelPressure: + PC = 12; + break; + case MIDI_PitchBend: + PC = 14; + break; + } break; + + // Note OFF + case 2: + PC = 3; + break; + case 3: + PC = 2; + NoteOFF(); + break; + + // Note ON + case 4: + PC = 5; + break; + case 5: + PC = 4; + if( MByte[1] == 0){ + NoteOFF(); + } + else{ + NoteON(); + } + break; + + // Polyphonic Key Pressure + case 6: + PC = 7; + break; + case 7: + PC = 6; + break; + + // Program Change + case 8: + break; + + // Control Change + case 10: PC = 11; break; + case 11: + switch(MByte[0]) { + case MIDI_CC_Moduration: + gModWheelBuf[MidiCh] = MByte[1] >> 2; + break; + case MIDI_CC_DataEntry: + break; + case MIDI_CC_RPN_LSB: + break; + case MIDI_CC_RPN_MSB: + break; + case MIDI_MM_AllSoundOff: + break; + case MIDI_MM_ResetAllControl: + break; + case MIDI_MM_AllNoteOff: + break; + } + break; + + // Channel Pressure + case 12: + break; + + // Pitch Bend + case 14: + PC = 15; + break; + + case 15: + PC = 14; + gPitchBendBuf[MidiCh] = (MByte[1] << 1) | (MByte[0] >> 6); + break; + + default: + break; + } +} + +//------------------------------------------------------------- +// Note ON Message Processing + +void NoteON(void) +{ + unsigned char i; + unsigned char h = 0; // higheest note + + // ignore note if registed buffer + for(i = 0; i < NoteCnt[MidiCh]; i++) { + if(NoteBuf[MidiCh][i] == MByte[0]) { + return; + } + } + + // full note buffer? + if(NoteCnt[MidiCh] == MAX_NOTE_CNT) { + for(i = 0; i < (MAX_NOTE_CNT - 1); i++) { + NoteBuf[MidiCh][i] = NoteBuf[MidiCh][i+1]; + } + NoteBuf[MidiCh][MAX_NOTE_CNT - 1] = MByte[0]; + } + else { + NoteBuf[MidiCh][NoteCnt[MidiCh]] = MByte[0]; + NoteCnt[MidiCh]++; + } + + // set highest note + for(i = 0; i < NoteCnt[MidiCh]; i++) { + if(h < NoteBuf[MidiCh][i]) { + h = NoteBuf[MidiCh][i]; + } + } + gPlayNoteBuf[MidiCh] = h; + gGateBuf[MidiCh] = ON; +} + +//------------------------------------------------------------- +// Note OFF Message Processing + +void NoteOFF(void) +{ + unsigned char i; + unsigned char h = 0; // highest note + int flg = FALSE; + + // Delete Note If Registed Buffer + for(i = 0; i < NoteCnt[MidiCh]; i++) { + if(flg) { + NoteBuf[MidiCh][i-1] = NoteBuf[MidiCh][i]; + } + if(NoteBuf[MidiCh][i] == MByte[0]) { + flg = TRUE; + } + } + if(flg) NoteCnt[MidiCh]--; + + if(NoteCnt[MidiCh] == 0) { + // Empty Buffer then Gate OFF + gGateBuf[MidiCh] = OFF; + } + else { + // Highest Note + for(i = 0; i < NoteCnt[MidiCh]; i++) { + if( h < NoteBuf[MidiCh][i]) { + h = NoteBuf[MidiCh][i]; + } + } + gPlayNoteBuf[MidiCh] = h; + } +} +