From 276892f50f36c9c075722a973fa0faef5423f665 Mon Sep 17 00:00:00 2001 From: sletz Date: Thu, 10 Jan 2008 10:25:03 +0000 Subject: [PATCH] Add missing files git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@1761 0c269be4-1314-0410-8aa9-9f06e86f4224 --- linux/alsa/midi_pack.h | 46 +++++++++++++ linux/alsa/midi_unpack.h | 139 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 185 insertions(+) create mode 100644 linux/alsa/midi_pack.h create mode 100644 linux/alsa/midi_unpack.h diff --git a/linux/alsa/midi_pack.h b/linux/alsa/midi_pack.h new file mode 100644 index 00000000..c449eb7a --- /dev/null +++ b/linux/alsa/midi_pack.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2006,2007 Dmitry S. Baikov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __jack_midi_pack_h__ +#define __jack_midi_pack_h__ + +typedef struct { + int running_status; +} midi_pack_t; + +static inline +void midi_pack_reset(midi_pack_t *p) +{ + p->running_status = 0; +} + +static +void midi_pack_event(midi_pack_t *p, jack_midi_event_t *e) +{ + if (e->buffer[0] >= 0x80 && e->buffer[0] < 0xF0) { // Voice Message + if (e->buffer[0] == p->running_status) { + e->buffer++; + e->size--; + } else + p->running_status = e->buffer[0]; + } else if (e->buffer[0] < 0xF8) { // not System Realtime + p->running_status = 0; + } +} + +#endif /* __jack_midi_pack_h__ */ diff --git a/linux/alsa/midi_unpack.h b/linux/alsa/midi_unpack.h new file mode 100644 index 00000000..344b29ab --- /dev/null +++ b/linux/alsa/midi_unpack.h @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2006,2007 Dmitry S. Baikov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __jack_midi_unpack_h__ +#define __jack_midi_unpack_h__ + +enum { + MIDI_UNPACK_MAX_MSG = 1024 +}; + +typedef struct { + int pos, need, size; + unsigned char data[MIDI_UNPACK_MAX_MSG]; +} midi_unpack_t; + +static inline +void midi_unpack_init(midi_unpack_t *u) +{ + u->pos = 0; + u->size = sizeof(u->data); + u->need = u->size; +} + +static inline +void midi_unpack_reset(midi_unpack_t *u) +{ + u->pos = 0; + u->need = u->size; +} + +static const unsigned char midi_voice_len[] = { + 3, /*0x80 Note Off*/ + 3, /*0x90 Note On*/ + 3, /*0xA0 Aftertouch*/ + 3, /*0xB0 Control Change*/ + 2, /*0xC0 Program Change*/ + 2, /*0xD0 Channel Pressure*/ + 3, /*0xE0 Pitch Wheel*/ + 1 /*0xF0 System*/ +}; + +static const unsigned char midi_system_len[] = { + 0, /*0xF0 System Exclusive Start*/ + 2, /*0xF1 MTC Quarter Frame*/ + 3, /*0xF2 Song Postion*/ + 2, /*0xF3 Song Select*/ + 0, /*0xF4 undefined*/ + 0, /*0xF5 undefined*/ + 1, /*0xF6 Tune Request*/ + 1 /*0xF7 System Exlusive End*/ +}; + +static +int midi_unpack_buf(midi_unpack_t *buf, const unsigned char *data, int len, void *jack_port_buf, jack_nframes_t time) +{ + int i; + for (i=0; i= 0xF8) // system realtime + { + jack_midi_event_write(jack_port_buf, time, &data[i], 1, 0); + //printf("midi_unpack: written system relatime event\n"); + //midi_input_write(in, &data[i], 1); + } + else if (byte < 0x80) // data + { + assert (buf->pos < buf->size); + buf->data[buf->pos++] = byte; + } + else if (byte < 0xF0) // voice + { + assert (byte >= 0x80 && byte < 0xF0); + //buf->need = ((byte|0x0F) == 0xCF || (byte|0x0F)==0xDF) ? 2 : 3; + buf->need = midi_voice_len[(byte-0x80)>>4]; + buf->data[0] = byte; + buf->pos = 1; + } + else if (byte == 0xF7) // sysex end + { + assert (buf->pos < buf->size); + buf->data[buf->pos++] = byte; + buf->need = buf->pos; + } + else + { + assert (byte >= 0xF0 && byte < 0xF8); + buf->pos = 1; + buf->data[0] = byte; + buf->need = midi_system_len[byte - 0xF0]; + if (!buf->need) + buf->need = buf->size; + } + if (buf->pos == buf->need) + { + // TODO: deal with big sysex'es (they are silently dropped for now) + if (buf->data[0] >= 0x80 || (buf->data[0]==0xF0 && buf->data[buf->pos-1] == 0xF7)) { + /* convert Note On with velocity 0 to Note Off */ + if ((buf->data[0] & 0xF0) == 0x90 && buf->data[2] == 0) { + // we use temp array here to keep running status sync + jack_midi_data_t temp[3] = { 0x80, 0, 0x40 }; + temp[0] |= buf->data[0] & 0x0F; + temp[1] = buf->data[1]; + jack_midi_event_write(jack_port_buf, time, temp, 3, 0); + } else + jack_midi_event_write(jack_port_buf, time, &buf->data[0], buf->pos, 0); + //printf("midi_unpack: written %d-byte event\n", buf->pos); + //midi_input_write(in, &buf->data[0], buf->pos); + } + /* keep running status */ + if (buf->data[0] >= 0x80 && buf->data[0] < 0xF0) + buf->pos = 1; + else + { + buf->pos = 0; + buf->need = buf->size; + } + } + } + assert (i==len); + return i; +} + +#endif /* __jack_midi_unpack_h__ */