1 #include <stdlib.h>
2 #include <string.h>
3 #include <errno.h>
4 #include <regex.h>
5 #include "test.h"
6
7 /*
8 * Checks whether the regular expression matches the entire MIDI data, printed
9 * as hex.
10 */
midi_matches_regex(unsigned char * midi,int count,const char * regex)11 static int midi_matches_regex(unsigned char *midi, int count, const char *regex)
12 {
13 char *text;
14 regex_t re;
15 regmatch_t match;
16 int i;
17
18 text = malloc(2 * count + 1);
19 if (!text)
20 return 0;
21 for (i = 0; i < count; ++i)
22 sprintf(text + 2 * i, "%02x", midi[i]);
23 if (regcomp(&re, regex, REG_EXTENDED) != 0) {
24 free(text);
25 return 0;
26 }
27 i = regexec(&re, text, 1, &match, 0);
28 i = i == 0 && match.rm_so == 0 && match.rm_eo == strlen(text);
29 regfree(&re);
30 free(text);
31 return i;
32 }
33
test_decode(void)34 static void test_decode(void)
35 {
36 snd_midi_event_t *midi_event;
37 snd_seq_event_t ev;
38 unsigned char buf[50];
39 int count;
40
41 if (ALSA_CHECK(snd_midi_event_new(256 /* ? */, &midi_event)) < 0)
42 return;
43
44 #define DECODE() snd_midi_event_decode(midi_event, buf, sizeof(buf), &ev)
45 #define BUF_MATCHES(str) midi_matches_regex(buf, count, str)
46 #define DECODES_TO(str) ((count = DECODE()), BUF_MATCHES(str))
47
48 snd_seq_ev_clear(&ev);
49
50 snd_seq_ev_set_fixed(&ev);
51 ev.type = SND_SEQ_EVENT_NONE;
52 TEST_CHECK(DECODE() == -ENOENT);
53
54 snd_seq_ev_set_noteoff(&ev, 1, 2, 3);
55 TEST_CHECK(DECODES_TO("810203"));
56
57 snd_seq_ev_set_noteon(&ev, 4, 5, 6);
58 TEST_CHECK(DECODES_TO("940506"));
59
60 snd_seq_ev_set_keypress(&ev, 7, 8, 9);
61 TEST_CHECK(DECODES_TO("a70809"));
62
63 snd_seq_ev_set_controller(&ev, 10, 11, 12);
64 TEST_CHECK(DECODES_TO("ba0b0c"));
65
66 snd_seq_ev_set_pgmchange(&ev, 13, 14);
67 TEST_CHECK(DECODES_TO("cd0e"));
68
69 snd_seq_ev_set_chanpress(&ev, 15, 16);
70 TEST_CHECK(DECODES_TO("df10"));
71
72 snd_seq_ev_set_pitchbend(&ev, 1, 0x222);
73 TEST_CHECK(DECODES_TO("e12244"));
74
75 snd_seq_ev_set_sysex(&ev, 6, "\xf0\x7e\x7f\x06\x01\xf7");
76 TEST_CHECK(DECODES_TO("f07e7f0601f7"));
77
78 snd_seq_ev_set_fixed(&ev);
79 ev.type = SND_SEQ_EVENT_QFRAME;
80 ev.data.control.value = 3;
81 TEST_CHECK(DECODES_TO("f103"));
82
83 ev.type = SND_SEQ_EVENT_SONGPOS;
84 ev.data.control.value = 0x444;
85 TEST_CHECK(DECODES_TO("f24408"));
86
87 ev.type = SND_SEQ_EVENT_SONGSEL;
88 ev.data.control.value = 5;
89 TEST_CHECK(DECODES_TO("f305"));
90
91 ev.type = SND_SEQ_EVENT_TUNE_REQUEST;
92 TEST_CHECK(DECODES_TO("f6"));
93
94 ev.type = SND_SEQ_EVENT_CLOCK;
95 TEST_CHECK(DECODES_TO("f8"));
96
97 ev.type = SND_SEQ_EVENT_START;
98 TEST_CHECK(DECODES_TO("fa"));
99
100 ev.type = SND_SEQ_EVENT_CONTINUE;
101 TEST_CHECK(DECODES_TO("fb"));
102
103 ev.type = SND_SEQ_EVENT_STOP;
104 TEST_CHECK(DECODES_TO("fc"));
105
106 ev.type = SND_SEQ_EVENT_SENSING;
107 TEST_CHECK(DECODES_TO("fe"));
108
109 ev.type = SND_SEQ_EVENT_RESET;
110 TEST_CHECK(DECODES_TO("ff"));
111
112 ev.type = SND_SEQ_EVENT_CONTROL14;
113 ev.data.control.channel = 6;
114 ev.data.control.param = 7;
115 ev.data.control.value = 0x888;
116 /*
117 * This regular expression catches all allowed combinations of LSB/MSB
118 * order and running status.
119 */
120 TEST_CHECK(DECODES_TO("b6(0711(b6)?2708|2708(b6)?0711)"));
121
122 ev.type = SND_SEQ_EVENT_NONREGPARAM;
123 ev.data.control.channel = 9;
124 ev.data.control.param = 0xaaa;
125 ev.data.control.value = 0xbbb;
126 TEST_CHECK(DECODES_TO("b9(622a(b9)?6315|6315(b9)?622a)(b9)?(0617(b9)?263b|263b(b9)?0617)"));
127
128 ev.type = SND_SEQ_EVENT_REGPARAM;
129 ev.data.control.channel = 12;
130 ev.data.control.param = 0xddd;
131 ev.data.control.value = 0xeee;
132 TEST_CHECK(DECODES_TO("bc(645d(bc)?651b|651b(bc)?645d)(bc)?(061d(bc)?266e|266e(bc)?061d)"));
133
134 /* no running status after SysEx */
135 snd_seq_ev_set_pgmchange(&ev, 0, 0x11);
136 TEST_CHECK(DECODES_TO("c011"));
137 snd_seq_ev_set_sysex(&ev, 6, "\xf0\x7e\x7f\x09\x02\xf7");
138 TEST_CHECK(DECODES_TO("f07e7f0902f7"));
139 snd_seq_ev_set_pgmchange(&ev, 0, 0x11);
140 TEST_CHECK(DECODES_TO("c011"));
141
142 /* no running status for non-realtime common messages */
143 ev.type = SND_SEQ_EVENT_QFRAME;
144 ev.data.control.value = 0x11;
145 TEST_CHECK(DECODES_TO("f111"));
146 TEST_CHECK(DECODES_TO("f111"));
147
148 /* buffer overflow */
149 TEST_CHECK(snd_midi_event_decode(midi_event, buf, 1, &ev) == -ENOMEM);
150
151 snd_midi_event_free(midi_event);
152 }
153
test_reset_decode(void)154 static void test_reset_decode(void)
155 {
156 snd_midi_event_t *midi_event;
157 snd_seq_event_t ev;
158 unsigned char buf[50];
159 int count;
160
161 if (ALSA_CHECK(snd_midi_event_new(256 /* ? */, &midi_event)) < 0)
162 return;
163
164 snd_seq_ev_clear(&ev);
165
166 snd_seq_ev_set_noteon(&ev, 1, 2, 3);
167 TEST_CHECK(DECODES_TO("910203"));
168
169 snd_midi_event_reset_decode(midi_event);
170
171 TEST_CHECK(DECODES_TO("910203"));
172
173 snd_midi_event_free(midi_event);
174 }
175
test_encode(void)176 static void test_encode(void)
177 {
178 snd_midi_event_t *midi_event;
179 snd_seq_event_t ev;
180
181 if (ALSA_CHECK(snd_midi_event_new(256, &midi_event)) < 0)
182 return;
183
184 #define ENCODE(str) snd_midi_event_encode(midi_event, \
185 (const unsigned char *)str, \
186 sizeof(str) - 1, &ev)
187 TEST_CHECK(ENCODE("\x81\x02\x03") == 3);
188 TEST_CHECK(ev.type == SND_SEQ_EVENT_NOTEOFF);
189 TEST_CHECK((ev.flags & SND_SEQ_EVENT_LENGTH_MASK) == SND_SEQ_EVENT_LENGTH_FIXED);
190 TEST_CHECK(ev.data.note.channel == 1);
191 TEST_CHECK(ev.data.note.note == 2);
192 TEST_CHECK(ev.data.note.velocity == 3);
193
194 TEST_CHECK(ENCODE("\x94\x05\x06") == 3);
195 TEST_CHECK(ev.type == SND_SEQ_EVENT_NOTEON);
196 TEST_CHECK(ev.data.note.channel == 4);
197 TEST_CHECK(ev.data.note.note == 5);
198 TEST_CHECK(ev.data.note.velocity == 6);
199
200 TEST_CHECK(ENCODE("\xa7\x08\x09") == 3);
201 TEST_CHECK(ev.type == SND_SEQ_EVENT_KEYPRESS);
202 TEST_CHECK(ev.data.note.channel == 7);
203 TEST_CHECK(ev.data.note.note == 8);
204 TEST_CHECK(ev.data.note.velocity == 9);
205
206 TEST_CHECK(ENCODE("\xba\x0b\x0c") == 3);
207 TEST_CHECK(ev.type == SND_SEQ_EVENT_CONTROLLER);
208 TEST_CHECK(ev.data.control.channel == 10);
209 TEST_CHECK(ev.data.control.param == 11);
210 TEST_CHECK(ev.data.control.value == 12);
211
212 TEST_CHECK(ENCODE("\xcd\x0e") == 2);
213 TEST_CHECK(ev.type == SND_SEQ_EVENT_PGMCHANGE);
214 TEST_CHECK(ev.data.control.channel == 13);
215 TEST_CHECK(ev.data.control.value == 14);
216
217 TEST_CHECK(ENCODE("\xdf\x10") == 2);
218 TEST_CHECK(ev.type == SND_SEQ_EVENT_CHANPRESS);
219 TEST_CHECK(ev.data.control.channel == 15);
220 TEST_CHECK(ev.data.control.value == 16);
221
222 TEST_CHECK(ENCODE("\xe1\x22\x33") == 3);
223 TEST_CHECK(ev.type == SND_SEQ_EVENT_PITCHBEND);
224 TEST_CHECK(ev.data.control.channel == 1);
225 TEST_CHECK(ev.data.control.value == -1630);
226
227 TEST_CHECK(ENCODE("\xf0\x7f\x7f\x04\x01\x7f\x7f\xf7") == 8);
228 TEST_CHECK(ev.type == SND_SEQ_EVENT_SYSEX);
229 TEST_CHECK((ev.flags & SND_SEQ_EVENT_LENGTH_MASK) == SND_SEQ_EVENT_LENGTH_VARIABLE);
230 TEST_CHECK(ev.data.ext.len == 8);
231 TEST_CHECK(!memcmp(ev.data.ext.ptr, "\xf0\x7f\x7f\x04\x01\x7f\x7f\xf7", 8));
232
233 TEST_CHECK(ENCODE("\xf1\x04") == 2);
234 TEST_CHECK(ev.type == SND_SEQ_EVENT_QFRAME);
235 TEST_CHECK(ev.data.control.value == 4);
236
237 TEST_CHECK(ENCODE("\xf2\x55\x66") == 3);
238 TEST_CHECK(ev.type == SND_SEQ_EVENT_SONGPOS);
239 TEST_CHECK(ev.data.control.value == 13141);
240
241 TEST_CHECK(ENCODE("\xf3\x07") == 2);
242 TEST_CHECK(ev.type == SND_SEQ_EVENT_SONGSEL);
243 TEST_CHECK(ev.data.control.value == 7);
244
245 TEST_CHECK(ENCODE("\xf6") == 1);
246 TEST_CHECK(ev.type == SND_SEQ_EVENT_TUNE_REQUEST);
247
248 TEST_CHECK(ENCODE("\xf8") == 1);
249 TEST_CHECK(ev.type == SND_SEQ_EVENT_CLOCK);
250
251 TEST_CHECK(ENCODE("\xfa") == 1);
252 TEST_CHECK(ev.type == SND_SEQ_EVENT_START);
253
254 TEST_CHECK(ENCODE("\xfb") == 1);
255 TEST_CHECK(ev.type == SND_SEQ_EVENT_CONTINUE);
256
257 TEST_CHECK(ENCODE("\xfc") == 1);
258 TEST_CHECK(ev.type == SND_SEQ_EVENT_STOP);
259
260 TEST_CHECK(ENCODE("\xfe") == 1);
261 TEST_CHECK(ev.type == SND_SEQ_EVENT_SENSING);
262
263 TEST_CHECK(ENCODE("\xff") == 1);
264 TEST_CHECK(ev.type == SND_SEQ_EVENT_RESET);
265
266 TEST_CHECK(ENCODE("\xc1\xf8") == 2);
267 TEST_CHECK(ev.type == SND_SEQ_EVENT_CLOCK);
268 TEST_CHECK(ENCODE("\x22") == 1);
269 TEST_CHECK(ev.type == SND_SEQ_EVENT_PGMCHANGE);
270 TEST_CHECK(ev.data.control.channel == 1);
271 TEST_CHECK(ev.data.control.value == 0x22);
272 TEST_CHECK(ENCODE("\xf8") == 1);
273 TEST_CHECK(ev.type == SND_SEQ_EVENT_CLOCK);
274 TEST_CHECK(ENCODE("\x33") == 1);
275 TEST_CHECK(ev.type == SND_SEQ_EVENT_PGMCHANGE);
276 TEST_CHECK(ev.data.control.channel == 1);
277 TEST_CHECK(ev.data.control.value == 0x33);
278
279 TEST_CHECK(ENCODE("\xc1\xf6") == 2);
280 TEST_CHECK(ev.type == SND_SEQ_EVENT_TUNE_REQUEST);
281 TEST_CHECK(ENCODE("\x44\x44") == 2);
282 TEST_CHECK(ev.type == SND_SEQ_EVENT_NONE);
283
284 snd_midi_event_free(midi_event);
285 }
286
test_reset_encode(void)287 static void test_reset_encode(void)
288 {
289 snd_midi_event_t *midi_event;
290 snd_seq_event_t ev;
291
292 if (ALSA_CHECK(snd_midi_event_new(256, &midi_event)) < 0)
293 return;
294
295 TEST_CHECK(ENCODE("\x91\x02") == 2);
296 TEST_CHECK(ev.type == SND_SEQ_EVENT_NONE);
297
298 snd_midi_event_reset_encode(midi_event);
299
300 TEST_CHECK(ENCODE("\x03") == 1);
301 TEST_CHECK(ev.type == SND_SEQ_EVENT_NONE);
302
303 snd_midi_event_free(midi_event);
304 }
305
test_init(void)306 static void test_init(void)
307 {
308 snd_midi_event_t *midi_event;
309 snd_seq_event_t ev;
310 unsigned char buf[50];
311 int count;
312
313 if (ALSA_CHECK(snd_midi_event_new(256, &midi_event)) < 0)
314 return;
315
316 snd_seq_ev_set_noteon(&ev, 1, 2, 3);
317 TEST_CHECK(DECODES_TO("910203"));
318
319 TEST_CHECK(ENCODE("\x94\x05") == 2);
320 TEST_CHECK(ev.type == SND_SEQ_EVENT_NONE);
321
322 snd_midi_event_init(midi_event);
323
324 snd_seq_ev_set_noteon(&ev, 1, 2, 3);
325 TEST_CHECK(DECODES_TO("910203"));
326
327 TEST_CHECK(ENCODE("\x06") == 1);
328 TEST_CHECK(ev.type == SND_SEQ_EVENT_NONE);
329
330 snd_midi_event_free(midi_event);
331 }
332
test_encode_byte(void)333 static void test_encode_byte(void)
334 {
335 snd_midi_event_t *midi_event;
336 snd_seq_event_t ev;
337
338 if (ALSA_CHECK(snd_midi_event_new(256, &midi_event)) < 0)
339 return;
340
341 #define ENCODE_BYTE(c) snd_midi_event_encode_byte(midi_event, c, &ev)
342 TEST_CHECK(ENCODE_BYTE(0x81) == 0);
343 TEST_CHECK(ENCODE_BYTE(0x02) == 0);
344 TEST_CHECK(ENCODE_BYTE(0x03) == 1);
345 TEST_CHECK(ev.type == SND_SEQ_EVENT_NOTEOFF);
346 TEST_CHECK((ev.flags & SND_SEQ_EVENT_LENGTH_MASK) == SND_SEQ_EVENT_LENGTH_FIXED);
347 TEST_CHECK(ev.data.note.channel == 1);
348 TEST_CHECK(ev.data.note.note == 2);
349 TEST_CHECK(ev.data.note.velocity == 3);
350 TEST_CHECK(ENCODE_BYTE(0x04) == 0);
351 TEST_CHECK(ENCODE_BYTE(0xf8) == 1);
352 TEST_CHECK(ev.type == SND_SEQ_EVENT_CLOCK);
353 TEST_CHECK(ENCODE_BYTE(0x05) == 1);
354 TEST_CHECK(ev.type == SND_SEQ_EVENT_NOTEOFF);
355 TEST_CHECK(ev.data.note.channel == 1);
356 TEST_CHECK(ev.data.note.note == 4);
357 TEST_CHECK(ev.data.note.velocity == 5);
358
359 snd_midi_event_free(midi_event);
360 }
361
main(void)362 int main(void)
363 {
364 test_decode();
365 test_reset_decode();
366 test_encode();
367 test_reset_encode();
368 test_encode_byte();
369 test_init();
370 return TEST_EXIT_CODE();
371 }
372