forked from michaelforney/oscmix
-
Notifications
You must be signed in to change notification settings - Fork 0
/
sysex.c
124 lines (117 loc) · 1.89 KB
/
sysex.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include <string.h>
#include "sysex.h"
#include "intpack.h"
size_t
sysexenc(struct sysex *p, unsigned char *dst, int flags)
{
size_t len;
len = 2 + p->datalen;
if (flags & SYSEX_MFRID)
len += p->mfrid > 0x7f ? 3 : 1;
if (flags & SYSEX_DEVID)
++len;
if (flags & SYSEX_SUBID)
++len;
if (!dst)
return len;
*dst++ = 0xf0;
if (flags & SYSEX_MFRID) {
if (p->mfrid > 0x7f) {
*dst++ = 0x00;
dst = putbe16(dst, p->mfrid);
} else {
*dst++ = p->mfrid;
}
}
if (flags & SYSEX_DEVID)
*dst++ = p->devid;
if (flags & SYSEX_SUBID)
*dst++ = p->subid;
if (p->data)
memcpy(dst, p->data, p->datalen);
else
p->data = dst;
dst += p->datalen;
*dst++ = 0xf7;
return len;
}
int
sysexdec(struct sysex *p, const unsigned char *src, size_t len, int flags)
{
if (len < 2 || src[0] != 0xf0 || src[len - 1] != 0xf7)
return -1;
++src;
len -= 2;
if (flags & SYSEX_MFRID) {
if (len < 1)
return -1;
p->mfrid = *src++;
--len;
if (!p->mfrid) {
if (len < 2)
return -1;
p->mfrid = getbe16(src);
src += 2;
len -= 2;
}
}
if (flags & SYSEX_DEVID) {
if (len < 1)
return -1;
p->devid = *src++;
--len;
}
if (flags & SYSEX_SUBID) {
if (len < 1)
return -1;
p->subid = *src++;
--len;
}
p->data = (unsigned char *)src;
p->datalen = len;
return 0;
}
void
base128enc(unsigned char *dst, const unsigned char *src, size_t len)
{
unsigned b;
int i;
b = 0;
i = 0;
while (len-- > 0) {
b = *src++ << i | b;
*dst++ = b & 0x7f;
b >>= 7;
if (++i == 7) {
*dst++ = b;
b = 0;
i = 0;
}
}
if (i > 0)
*dst++ = b;
}
int
base128dec(unsigned char *dst, const unsigned char *src, size_t len)
{
const unsigned char *end;
unsigned b, c;
int i;
end = src + len;
b = 0;
i = 0;
while (src != end) {
c = *src++;
if (c & ~0x7f)
return -1;
b |= c << i;
if (i == 0) {
i = 7;
} else {
*dst++ = b & 0xff;
b >>= 8;
--i;
}
}
return 0;
}