Radio Junk Box
/
KAMUI_MIDI-CV_Example
KAMUI MIDI-CV Example
Embed:
(wiki syntax)
Show/hide line numbers
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
Generated on Wed Jul 13 2022 04:53:02 by 1.7.2