~ubuntu-branches/ubuntu/trusty/jack-audio-connection-kit/trusty

« back to all changes in this revision

Viewing changes to drivers/alsa-midi/midi_unpack.h

  • Committer: Bazaar Package Importer
  • Author(s): Luca Falavigna
  • Date: 2008-12-06 11:05:15 UTC
  • mfrom: (4.1.3 sid)
  • Revision ID: james.westby@ubuntu.com-20081206110515-xa9v9pajr9jqvfvg
Tags: 0.115.6-1ubuntu1
* Merge from Debian unstable, remaining Ubuntu changes:
  - Redirect stderr in bash completion (Debian #504488).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2006,2007 Dmitry S. Baikov
 
3
 *
 
4
 *  This program is free software; you can redistribute it and/or modify
 
5
 *  it under the terms of the GNU General Public License as published by
 
6
 *  the Free Software Foundation; either version 2 of the License, or
 
7
 *  (at your option) any later version.
 
8
 *
 
9
 *  This program is distributed in the hope that it will be useful,
 
10
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
 *  GNU General Public License for more details.
 
13
 *
 
14
 *  You should have received a copy of the GNU General Public License
 
15
 *  along with this program; if not, write to the Free Software
 
16
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 
17
 */
 
18
 
 
19
#ifndef __jack_midi_unpack_h__
 
20
#define __jack_midi_unpack_h__
 
21
 
 
22
#include <jack/midiport.h>
 
23
#include <jack/engine.h>
 
24
 
 
25
enum {
 
26
        MIDI_UNPACK_MAX_MSG = 1024
 
27
};
 
28
 
 
29
typedef struct {
 
30
        int pos, need, size;
 
31
        unsigned char data[MIDI_UNPACK_MAX_MSG];
 
32
} midi_unpack_t;
 
33
 
 
34
static inline
 
35
void midi_unpack_init(midi_unpack_t *u)
 
36
{
 
37
        u->pos = 0;
 
38
        u->size = sizeof(u->data);
 
39
        u->need = u->size;
 
40
}
 
41
 
 
42
static inline
 
43
void midi_unpack_reset(midi_unpack_t *u)
 
44
{
 
45
        u->pos = 0;
 
46
        u->need = u->size;
 
47
}
 
48
 
 
49
static const unsigned char midi_voice_len[] = {
 
50
        3, /*0x80 Note Off*/
 
51
        3, /*0x90 Note On*/
 
52
        3, /*0xA0 Aftertouch*/
 
53
        3, /*0xB0 Control Change*/
 
54
        2, /*0xC0 Program Change*/
 
55
        2, /*0xD0 Channel Pressure*/
 
56
        3, /*0xE0 Pitch Wheel*/
 
57
        1  /*0xF0 System*/
 
58
};
 
59
 
 
60
static const unsigned char midi_system_len[] = {
 
61
        0, /*0xF0 System Exclusive Start*/
 
62
        2, /*0xF1 MTC Quarter Frame*/
 
63
        3, /*0xF2 Song Postion*/
 
64
        2, /*0xF3 Song Select*/
 
65
        0, /*0xF4 undefined*/
 
66
        0, /*0xF5 undefined*/
 
67
        1, /*0xF6 Tune Request*/
 
68
        1  /*0xF7 System Exlusive End*/
 
69
};
 
70
 
 
71
static
 
72
int midi_unpack_buf(midi_unpack_t *buf, const unsigned char *data, int len, void *jack_port_buf, jack_nframes_t time)
 
73
{
 
74
        int i;
 
75
        for (i=0; i<len; ++i)
 
76
        {
 
77
                const unsigned char byte = data[i];
 
78
                if (byte >= 0xF8) // system realtime
 
79
                {
 
80
                        jack_midi_event_write(jack_port_buf, time, &data[i], 1);
 
81
                        //jack_error("midi_unpack: written system relatime event\n");
 
82
                        //midi_input_write(in, &data[i], 1);
 
83
                }
 
84
                else if (byte < 0x80) // data
 
85
                {
 
86
                        assert (buf->pos < buf->size);
 
87
                        buf->data[buf->pos++] = byte;
 
88
                }
 
89
                else if (byte < 0xF0) // voice
 
90
                {
 
91
                        assert (byte >= 0x80 && byte < 0xF0);
 
92
                        //buf->need = ((byte|0x0F) == 0xCF || (byte|0x0F)==0xDF) ? 2 : 3;
 
93
                        buf->need = midi_voice_len[(byte-0x80)>>4];
 
94
                        buf->data[0] = byte;
 
95
                        buf->pos = 1;
 
96
                }
 
97
                else if (byte == 0xF7) // sysex end
 
98
                {
 
99
                        assert (buf->pos < buf->size);
 
100
                        buf->data[buf->pos++] = byte;
 
101
                        buf->need = buf->pos;
 
102
                }
 
103
                else
 
104
                {
 
105
                        assert (byte >= 0xF0 && byte < 0xF8);
 
106
                        buf->pos = 1;
 
107
                        buf->data[0] = byte;
 
108
                        buf->need = midi_system_len[byte - 0xF0];
 
109
                        if (!buf->need)
 
110
                                buf->need = buf->size;
 
111
                }
 
112
                if (buf->pos == buf->need)
 
113
                {
 
114
                        // TODO: deal with big sysex'es (they are silently dropped for now)
 
115
                        if (buf->data[0] >= 0x80 || (buf->data[0]==0xF0 && buf->data[buf->pos-1] == 0xF7)) {
 
116
                                /* convert Note On with velocity 0 to Note Off */
 
117
                                if ((buf->data[0] & 0xF0) == 0x90 && buf->data[2] == 0) {
 
118
                                        // we use temp array here to keep running status in sync
 
119
                                        jack_midi_data_t temp[3] = { 0x80, 0, 0x40 };
 
120
                                        temp[0] |= buf->data[0] & 0x0F;
 
121
                                        temp[1] = buf->data[1];
 
122
                                        jack_midi_event_write(jack_port_buf, time, temp, 3);
 
123
                                } else
 
124
                                        jack_midi_event_write(jack_port_buf, time, &buf->data[0], buf->pos);
 
125
                                //jack_error("midi_unpack: written %d-byte event\n", buf->pos);
 
126
                                //midi_input_write(in, &buf->data[0], buf->pos);
 
127
                        }
 
128
                        /* keep running status */
 
129
                        if (buf->data[0] >= 0x80 && buf->data[0] < 0xF0)
 
130
                                buf->pos = 1;
 
131
                        else
 
132
                        {
 
133
                                buf->pos = 0;
 
134
                                buf->need = buf->size;
 
135
                        }
 
136
                }
 
137
        }
 
138
        assert (i==len);
 
139
        return i;
 
140
}
 
141
 
 
142
#endif /* __jack_midi_unpack_h__ */