midi.c (1765B)
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <stdint.h> 4 #include <sndio.h> 5 #include <assert.h> 6 #include "midi.h" 7 8 uint8_t mmessage[4]; 9 uint8_t mlen; 10 uint8_t mi; 11 struct mio_hdl *mh; 12 uint8_t mbuf[32]; 13 Mvector m_vector; 14 15 enum { 16 NOTE_OFF = 0x80, 17 NOTE_ON = 0x90, 18 KEY_PRESSURE = 0xa0, 19 CTL_CHANGE = 0xb0, 20 PROG_CHANGE = 0xc0, 21 CHAN_PRESSURE = 0xd0, 22 PITCH_WHEEL = 0xe0, 23 SYS_MESSAGE = 0xf0, 24 }; 25 26 void m_exec(void); 27 void m_fillmess(uint8_t); 28 29 void 30 m_fillmess(uint8_t b) 31 { 32 if (b >= 0x80){ /* status byte */ 33 mmessage[0] = b & 0xf0; 34 mmessage[1] = b & 0x0f; 35 mlen = 0; 36 switch (mmessage[0]){ 37 case NOTE_OFF: 38 case NOTE_ON: 39 case KEY_PRESSURE: 40 case CTL_CHANGE: 41 case PITCH_WHEEL: 42 mlen = 4; 43 break; 44 case PROG_CHANGE: 45 case CHAN_PRESSURE: 46 mlen = 3; 47 break; 48 case SYS_MESSAGE: 49 mlen = 2; 50 break; 51 } 52 mi = 2; 53 } else if (mi < mlen){ 54 mmessage[mi] = b; 55 mi++; 56 } 57 if (mi == mlen) m_exec(); 58 } 59 60 void 61 m_exec(void) 62 { 63 void (*f)(uint8_t*); 64 switch(mmessage[0]&0xf0){ 65 case NOTE_OFF: 66 f = m_vector.note_off; 67 break; 68 case NOTE_ON: 69 f = m_vector.note_on; 70 assert(f != NULL); 71 break; 72 case KEY_PRESSURE: 73 f = m_vector.key_pressure; 74 break; 75 case CTL_CHANGE: 76 f = m_vector.ctl_change; 77 break; 78 case PROG_CHANGE: 79 f = m_vector.prog_change; 80 break; 81 case CHAN_PRESSURE: 82 f = m_vector.chan_pressure; 83 break; 84 case PITCH_WHEEL: 85 f = m_vector.pitch_wheel; 86 break; 87 case SYS_MESSAGE: 88 f = m_vector.sys_message; 89 break; 90 } 91 if (f != NULL) f(mmessage); 92 } 93 94 void 95 m_init(char *mdev) 96 { 97 mh = mio_open(mdev, MIO_IN, 1); 98 if (mh == 0){ 99 fprintf(stderr, "error: couldn't open midi device %s\n", mdev); 100 exit(-1); 101 } 102 mlen = 0; 103 mi = 0; 104 } 105 106 void 107 m_read(void) 108 { 109 size_t i, n; 110 n = mio_read(mh, mbuf, 32); 111 for (i=0; i<n; i++) m_fillmess(mbuf[i]); 112 }