KAMUI MIDI-CV Example

Dependencies:   TextLCD mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers midi_parser.c Source File

midi_parser.c

00001 //-------------------------------------------------------------
00002 // KAMUI MIDI-CV Exapmle
00003 // file : midi_parser.c
00004 // Copyright (C) 2012 RJB RadioJunkBox
00005 // Released under the MIT License: http://mbed.org/license/mit
00006 //-------------------------------------------------------------
00007 
00008 #include "mbed.h"
00009 #include "midi_parser.h"
00010 
00011 //-------------------------------------------------------------
00012 // MIDI Parser
00013 
00014 void MIDI_Parser(unsigned char mididata)
00015 {
00016     RxByte = mididata;
00017 
00018     if(MIDI_SystemMessage()) {
00019         MIDI_ChannelMessage();
00020     }
00021 }
00022 
00023 //-------------------------------------------------------------
00024 // MIDI System Meassage
00025 
00026 int MIDI_SystemMessage(void)
00027 {
00028     if(SysEx){
00029         if(RxByte == MIDI_EndSysEx){
00030             SysEx = FALSE;
00031         }
00032     }
00033     else{
00034         if(RxByte < 0xF8){
00035             if(RxByte > 0x7F){
00036                 if(RxByte == MIDI_StartSysEx){
00037                     SysEx = TRUE;
00038                 }
00039                 else{
00040                     MidiCh = RxByte & 0x0F;
00041                 }
00042                 PC = 0;
00043              }
00044             else{
00045                 MByte[PC & 0x01] = RxByte;
00046             }
00047             return TRUE;
00048         }
00049         else {
00050             MIDI_SystemRealtimeMessage();
00051         }
00052     }
00053     return FALSE;
00054 }
00055 
00056 //-------------------------------------------------------------
00057 // MIDI System Realtime Message
00058 
00059 void MIDI_SystemRealtimeMessage(void)
00060 {
00061     switch(RxByte) {
00062         case MIDI_TimingClock:
00063             gMIDISYNC_CLK |= 0x01;
00064             break;
00065         case MIDI_Start:
00066             gMIDISYNC_RUN = 0x01;
00067             break;
00068         case MIDI_Continue:
00069             gMIDISYNC_RUN = 0x01;
00070             break;
00071         case MIDI_Stop:
00072             gMIDISYNC_RUN = 0x00;
00073             break;
00074         case MIDI_ActiveSensing:
00075             break;
00076         case MIDI_SystemReset:
00077             break;
00078     }
00079 }
00080 
00081 //-------------------------------------------------------------
00082 // MIDI Channel Message
00083 
00084 void MIDI_ChannelMessage(void)
00085 {
00086     switch(PC){
00087         case 0:
00088             switch(RxByte & 0xF0){
00089             case MIDI_NoteOff:
00090                 PC = 2;
00091                 break;
00092             case MIDI_NoteOn:
00093                 PC = 4;
00094                 break;
00095             case MIDI_PolykeyPressure:
00096                 PC = 6;
00097                 break;
00098             case MIDI_ProgramChange:
00099                 PC = 8;
00100                 break;
00101             case MIDI_ControlChange:
00102                 PC = 10;
00103                 break;
00104             case MIDI_ChannelPressure:
00105                 PC = 12;
00106                 break;
00107             case MIDI_PitchBend:
00108                 PC = 14;
00109                 break;
00110             } break;
00111 
00112         // Note OFF
00113         case 2:
00114             PC = 3;
00115             break;
00116         case 3:
00117             PC = 2;
00118             NoteOFF();
00119             break;
00120 
00121         // Note ON
00122         case 4:
00123             PC = 5;
00124             break;
00125         case 5:
00126             PC = 4;
00127             if( MByte[1] == 0){
00128                 NoteOFF();
00129             }
00130             else{
00131                 NoteON();
00132             }
00133             break;
00134 
00135         // Polyphonic Key Pressure
00136         case 6:
00137             PC = 7;
00138             break;
00139         case 7:
00140             PC = 6;
00141             break;
00142 
00143         // Program Change
00144         case 8:
00145             break;
00146 
00147         // Control Change
00148         case 10: PC = 11; break;
00149         case 11:
00150             switch(MByte[0]) {
00151                 case MIDI_CC_Moduration:
00152                     gModWheelBuf[MidiCh] = MByte[1] >> 2;
00153                     break;
00154                 case MIDI_CC_DataEntry:
00155                     break;
00156                 case MIDI_CC_RPN_LSB:
00157                     break;
00158                 case MIDI_CC_RPN_MSB:
00159                     break;
00160                 case MIDI_MM_AllSoundOff:
00161                     break;
00162                 case MIDI_MM_ResetAllControl:
00163                     break;
00164                 case MIDI_MM_AllNoteOff:
00165                     break;
00166             }
00167             break;
00168 
00169         // Channel Pressure
00170         case 12:
00171             break;
00172 
00173         // Pitch Bend
00174         case 14:
00175             PC = 15;
00176             break;
00177             
00178         case 15:
00179             PC = 14;
00180             gPitchBendBuf[MidiCh] = (MByte[1] << 1) | (MByte[0] >> 6);
00181             break;
00182 
00183         default:
00184             break;
00185     }
00186 }
00187 
00188 //-------------------------------------------------------------
00189 // Note ON Message Processing
00190 
00191 void NoteON(void)
00192 {
00193     unsigned char i;
00194     unsigned char h = 0; // higheest note
00195 
00196     // ignore note if registed buffer
00197     for(i = 0; i < NoteCnt[MidiCh]; i++) {
00198         if(NoteBuf[MidiCh][i] == MByte[0]) {
00199             return;
00200         }
00201     }
00202 
00203     // full note buffer?
00204     if(NoteCnt[MidiCh] == MAX_NOTE_CNT) {
00205         for(i = 0; i < (MAX_NOTE_CNT - 1); i++) {
00206             NoteBuf[MidiCh][i] = NoteBuf[MidiCh][i+1];
00207         }
00208         NoteBuf[MidiCh][MAX_NOTE_CNT - 1] = MByte[0];
00209     }
00210     else {
00211         NoteBuf[MidiCh][NoteCnt[MidiCh]] = MByte[0];
00212         NoteCnt[MidiCh]++;
00213     }
00214 
00215     // set highest note
00216     for(i = 0; i < NoteCnt[MidiCh]; i++) {
00217         if(h < NoteBuf[MidiCh][i]) {
00218             h = NoteBuf[MidiCh][i];
00219         }
00220     }
00221     gPlayNoteBuf[MidiCh] = h;
00222     gGateBuf[MidiCh] = ON;
00223 }
00224 
00225 //-------------------------------------------------------------
00226 // Note OFF Message Processing
00227 
00228 void NoteOFF(void)
00229 {
00230     unsigned char i;
00231     unsigned char h = 0; // highest note
00232     int flg = FALSE;
00233 
00234     // Delete Note If Registed Buffer
00235     for(i = 0; i < NoteCnt[MidiCh]; i++) {
00236         if(flg) {
00237             NoteBuf[MidiCh][i-1] = NoteBuf[MidiCh][i];
00238         }
00239         if(NoteBuf[MidiCh][i] == MByte[0]) {
00240             flg = TRUE;
00241         }
00242     }
00243     if(flg) NoteCnt[MidiCh]--;
00244 
00245     if(NoteCnt[MidiCh] == 0) {
00246         // Empty Buffer then Gate OFF
00247         gGateBuf[MidiCh] = OFF;
00248     }
00249     else {
00250         // Highest Note
00251         for(i = 0; i < NoteCnt[MidiCh]; i++) {
00252             if( h < NoteBuf[MidiCh][i]) {
00253                 h = NoteBuf[MidiCh][i];
00254             }
00255         }
00256         gPlayNoteBuf[MidiCh] = h;
00257     }
00258 }
00259