00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef __jack_midi_unpack_h__
00020 #define __jack_midi_unpack_h__
00021
00022 enum {
00023 MIDI_UNPACK_MAX_MSG = 1024
00024 };
00025
00026 typedef struct {
00027 int pos, need, size;
00028 unsigned char data[MIDI_UNPACK_MAX_MSG];
00029 } midi_unpack_t;
00030
00031 static inline
00032 void midi_unpack_init(midi_unpack_t *u)
00033 {
00034 u->pos = 0;
00035 u->size = sizeof(u->data);
00036 u->need = u->size;
00037 }
00038
00039 static inline
00040 void midi_unpack_reset(midi_unpack_t *u)
00041 {
00042 u->pos = 0;
00043 u->need = u->size;
00044 }
00045
00046 static const unsigned char midi_voice_len[] = {
00047 3,
00048 3,
00049 3,
00050 3,
00051 2,
00052 2,
00053 3,
00054 1
00055 };
00056
00057 static const unsigned char midi_system_len[] = {
00058 0,
00059 2,
00060 3,
00061 2,
00062 0,
00063 0,
00064 1,
00065 1
00066 };
00067
00068 static
00069 int midi_unpack_buf(midi_unpack_t *buf, const unsigned char *data, int len, void *jack_port_buf, jack_nframes_t time)
00070 {
00071 int i;
00072 for (i=0; i<len; ++i)
00073 {
00074 const unsigned char byte = data[i];
00075 if (byte >= 0xF8)
00076 {
00077 jack_midi_event_write(jack_port_buf, time, &data[i], 1);
00078
00079
00080 }
00081 else if (byte < 0x80)
00082 {
00083 assert (buf->pos < buf->size);
00084 buf->data[buf->pos++] = byte;
00085 }
00086 else if (byte < 0xF0)
00087 {
00088 assert (byte >= 0x80 && byte < 0xF0);
00089
00090 buf->need = midi_voice_len[(byte-0x80)>>4];
00091 buf->data[0] = byte;
00092 buf->pos = 1;
00093 }
00094 else if (byte == 0xF7)
00095 {
00096 assert (buf->pos < buf->size);
00097 buf->data[buf->pos++] = byte;
00098 buf->need = buf->pos;
00099 }
00100 else
00101 {
00102 assert (byte >= 0xF0 && byte < 0xF8);
00103 buf->pos = 1;
00104 buf->data[0] = byte;
00105 buf->need = midi_system_len[byte - 0xF0];
00106 if (!buf->need)
00107 buf->need = buf->size;
00108 }
00109 if (buf->pos == buf->need)
00110 {
00111
00112 if (buf->data[0] >= 0x80 || (buf->data[0]==0xF0 && buf->data[buf->pos-1] == 0xF7)) {
00113
00114 if ((buf->data[0] & 0xF0) == 0x90 && buf->data[2] == 0) {
00115
00116 jack_midi_data_t temp[3] = { 0x80, 0, 0x40 };
00117 temp[0] |= buf->data[0] & 0x0F;
00118 temp[1] = buf->data[1];
00119 jack_midi_event_write(jack_port_buf, time, temp, 3);
00120 } else
00121 jack_midi_event_write(jack_port_buf, time, &buf->data[0], buf->pos);
00122
00123
00124 }
00125
00126 if (buf->data[0] >= 0x80 && buf->data[0] < 0xF0)
00127 buf->pos = 1;
00128 else
00129 {
00130 buf->pos = 0;
00131 buf->need = buf->size;
00132 }
00133 }
00134 }
00135 assert (i==len);
00136 return i;
00137 }
00138
00139 #endif