1 /**
2 * \file seq/seq_midi_event.c
3 * \brief MIDI byte <-> sequencer event coder
4 * \author Takashi Iwai <tiwai@suse.de>
5 * \author Jaroslav Kysela <perex@perex.cz>
6 * \date 2000-2001
7 */
8
9 /*
10 * MIDI byte <-> sequencer event coder
11 *
12 * Copyright (C) 1998,99,2000 Takashi Iwai <tiwai@suse.de>,
13 * Jaroslav Kysela <perex@perex.cz>
14 *
15 *
16 * This library is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU Lesser General Public License as
18 * published by the Free Software Foundation; either version 2.1 of
19 * the License, or (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU Lesser General Public License for more details.
25 *
26 * You should have received a copy of the GNU Lesser General Public
27 * License along with this library; if not, write to the Free Software
28 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29 */
30
31 #include "local.h"
32 #if HAVE_MALLOC_H
33 #include <malloc.h>
34 #endif
35
36 #ifndef DOC_HIDDEN
37
38 /* midi status */
39 struct snd_midi_event {
40 ssize_t qlen; /* queue length */
41 size_t read; /* chars read */
42 int type; /* current event type */
43 unsigned char lastcmd;
44 unsigned char nostat;
45 size_t bufsize;
46 unsigned char *buf; /* input buffer */
47 };
48
49
50 /* event type, index into status_event[] */
51 /* from 0 to 6 are normal commands (note off, on, etc.) for 0x8?-0xe? */
52 #define ST_INVALID 7
53 #define ST_SPECIAL 8
54 #define ST_SYSEX ST_SPECIAL
55 /* from 8 to 15 are events for 0xf0-0xf7 */
56
57
58 /* status event types */
59 typedef void (*event_encode_t)(snd_midi_event_t *dev, snd_seq_event_t *ev);
60 typedef void (*event_decode_t)(const snd_seq_event_t *ev, unsigned char *buf);
61
62 #endif /* DOC_HIDDEN */
63
64 /*
65 * prototypes
66 */
67 static void note_event(snd_midi_event_t *dev, snd_seq_event_t *ev);
68 static void one_param_ctrl_event(snd_midi_event_t *dev, snd_seq_event_t *ev);
69 static void pitchbend_ctrl_event(snd_midi_event_t *dev, snd_seq_event_t *ev);
70 static void two_param_ctrl_event(snd_midi_event_t *dev, snd_seq_event_t *ev);
71 static void one_param_event(snd_midi_event_t *dev, snd_seq_event_t *ev);
72 static void songpos_event(snd_midi_event_t *dev, snd_seq_event_t *ev);
73 static void note_decode(const snd_seq_event_t *ev, unsigned char *buf);
74 static void one_param_decode(const snd_seq_event_t *ev, unsigned char *buf);
75 static void pitchbend_decode(const snd_seq_event_t *ev, unsigned char *buf);
76 static void two_param_decode(const snd_seq_event_t *ev, unsigned char *buf);
77 static void songpos_decode(const snd_seq_event_t *ev, unsigned char *buf);
78
79 /*
80 * event list
81 */
82 #ifndef DOC_HIDDEN
83 static const struct status_event_list_t {
84 int event;
85 int qlen;
86 event_encode_t encode;
87 event_decode_t decode;
88 } status_event[] = {
89 /* 0x80 - 0xef */
90 {SND_SEQ_EVENT_NOTEOFF, 2, note_event, note_decode},
91 {SND_SEQ_EVENT_NOTEON, 2, note_event, note_decode},
92 {SND_SEQ_EVENT_KEYPRESS, 2, note_event, note_decode},
93 {SND_SEQ_EVENT_CONTROLLER, 2, two_param_ctrl_event, two_param_decode},
94 {SND_SEQ_EVENT_PGMCHANGE, 1, one_param_ctrl_event, one_param_decode},
95 {SND_SEQ_EVENT_CHANPRESS, 1, one_param_ctrl_event, one_param_decode},
96 {SND_SEQ_EVENT_PITCHBEND, 2, pitchbend_ctrl_event, pitchbend_decode},
97 /* invalid */
98 {SND_SEQ_EVENT_NONE, -1, NULL, NULL},
99 /* 0xf0 - 0xff */
100 {SND_SEQ_EVENT_SYSEX, 1, NULL, NULL}, /* sysex: 0xf0 */
101 {SND_SEQ_EVENT_QFRAME, 1, one_param_event, one_param_decode}, /* 0xf1 */
102 {SND_SEQ_EVENT_SONGPOS, 2, songpos_event, songpos_decode}, /* 0xf2 */
103 {SND_SEQ_EVENT_SONGSEL, 1, one_param_event, one_param_decode}, /* 0xf3 */
104 {SND_SEQ_EVENT_NONE, -1, NULL, NULL}, /* 0xf4 */
105 {SND_SEQ_EVENT_NONE, -1, NULL, NULL}, /* 0xf5 */
106 {SND_SEQ_EVENT_TUNE_REQUEST, 0, NULL, NULL}, /* 0xf6 */
107 {SND_SEQ_EVENT_NONE, -1, NULL, NULL}, /* 0xf7 */
108 {SND_SEQ_EVENT_CLOCK, 0, NULL, NULL}, /* 0xf8 */
109 {SND_SEQ_EVENT_NONE, -1, NULL, NULL}, /* 0xf9 */
110 {SND_SEQ_EVENT_START, 0, NULL, NULL}, /* 0xfa */
111 {SND_SEQ_EVENT_CONTINUE, 0, NULL, NULL}, /* 0xfb */
112 {SND_SEQ_EVENT_STOP, 0, NULL, NULL}, /* 0xfc */
113 {SND_SEQ_EVENT_NONE, -1, NULL, NULL}, /* 0xfd */
114 {SND_SEQ_EVENT_SENSING, 0, NULL, NULL}, /* 0xfe */
115 {SND_SEQ_EVENT_RESET, 0, NULL, NULL}, /* 0xff */
116 };
117
118 static int extra_decode_ctrl14(snd_midi_event_t *dev, unsigned char *buf, int len, const snd_seq_event_t *ev);
119 static int extra_decode_xrpn(snd_midi_event_t *dev, unsigned char *buf, int count, const snd_seq_event_t *ev);
120
121 static const struct extra_event_list_t {
122 int event;
123 int (*decode)(snd_midi_event_t *dev, unsigned char *buf, int len, const snd_seq_event_t *ev);
124 } extra_event[] = {
125 {SND_SEQ_EVENT_CONTROL14, extra_decode_ctrl14},
126 {SND_SEQ_EVENT_NONREGPARAM, extra_decode_xrpn},
127 {SND_SEQ_EVENT_REGPARAM, extra_decode_xrpn},
128 };
129
130 #define numberof(ary) (sizeof(ary)/sizeof(ary[0]))
131 #endif /* DOC_HIDDEN */
132
133 /**
134 * \brief Creates a MIDI event parser.
135 * \param[in] bufsize Size of the buffer used for encoding; this should be
136 * large enough to hold the largest MIDI message to be
137 * encoded.
138 * \param[out] rdev The new MIDI event parser.
139 * \return Zero on success, otherwise a negative error code.
140 *
141 * This function creates and initializes a MIDI parser object that can be used
142 * to convert a MIDI byte stream to sequencer events (encoding) and/or to
143 * convert sequencer events to a MIDI byte stream (decoding).
144 *
145 * \par Errors:
146 * <dl>
147 * <dt>-ENOMEM<dd>Out of memory.
148 *
149 * \par Conforming to:
150 * LSB 3.2
151 */
snd_midi_event_new(size_t bufsize, snd_midi_event_t **rdev)152 int snd_midi_event_new(size_t bufsize, snd_midi_event_t **rdev)
153 {
154 snd_midi_event_t *dev;
155
156 *rdev = NULL;
157 dev = (snd_midi_event_t *)calloc(1, sizeof(snd_midi_event_t));
158 if (dev == NULL)
159 return -ENOMEM;
160 if (bufsize > 0) {
161 dev->buf = malloc(bufsize);
162 if (dev->buf == NULL) {
163 free(dev);
164 return -ENOMEM;
165 }
166 }
167 dev->bufsize = bufsize;
168 dev->lastcmd = 0xff;
169 dev->type = ST_INVALID;
170 *rdev = dev;
171 return 0;
172 }
173
174 /**
175 * \brief Frees a MIDI event parser.
176 * \param dev MIDI event parser.
177 *
178 * Frees a MIDI event parser.
179 *
180 * \par Conforming to:
181 * LSB 3.2
182 */
snd_midi_event_free(snd_midi_event_t *dev)183 void snd_midi_event_free(snd_midi_event_t *dev)
184 {
185 if (dev != NULL) {
186 free(dev->buf);
187 free(dev);
188 }
189 }
190
191 /**
192 * \brief Enables/disables MIDI command merging.
193 * \param dev MIDI event parser.
194 * \param on 0 to enable MIDI command merging,
195 * 1 to always write the command byte.
196 *
197 * This function enables or disables MIDI command merging (running status).
198 *
199 * When MIDI command merging is not disabled, #snd_midi_event_decode is allowed
200 * to omit any status byte that is identical to the previous status byte.
201 */
snd_midi_event_no_status(snd_midi_event_t *dev, int on)202 void snd_midi_event_no_status(snd_midi_event_t *dev, int on)
203 {
204 dev->nostat = on ? 1 : 0;
205 }
206
207 /*
208 * initialize record
209 */
reset_encode(snd_midi_event_t *dev)210 inline static void reset_encode(snd_midi_event_t *dev)
211 {
212 dev->read = 0;
213 dev->qlen = 0;
214 dev->type = ST_INVALID;
215 }
216
217 /**
218 * \brief Resets MIDI encode parser.
219 * \param dev MIDI event parser.
220 *
221 * This function resets the MIDI encoder of the parser \a dev.
222 * Any partially encoded MIDI message is dropped,
223 * and running status state is cleared.
224 *
225 * \par Conforming to:
226 * LSB 3.2
227 */
snd_midi_event_reset_encode(snd_midi_event_t *dev)228 void snd_midi_event_reset_encode(snd_midi_event_t *dev)
229 {
230 reset_encode(dev);
231 }
232
233 /**
234 * \brief Resets MIDI decode parser.
235 * \param dev MIDI event parser.
236 *
237 * This function resets the MIDI decoder of the parser \a dev.
238 * The next decoded message does not use running status from before the call to
239 * \a snd_midi_event_reset_decode.
240 *
241 * \par Conforming to:
242 * LSB 3.2
243 */
snd_midi_event_reset_decode(snd_midi_event_t *dev)244 void snd_midi_event_reset_decode(snd_midi_event_t *dev)
245 {
246 dev->lastcmd = 0xff;
247 }
248
249 /**
250 * \brief Resets MIDI encode/decode parsers.
251 * \param dev MIDI event parser.
252 *
253 * This function resets both encoder and decoder of the MIDI event parser.
254 * \sa snd_midi_event_reset_encode, snd_midi_event_reset_decode
255 *
256 * \par Conforming to:
257 * LSB 3.2
258 */
snd_midi_event_init(snd_midi_event_t *dev)259 void snd_midi_event_init(snd_midi_event_t *dev)
260 {
261 snd_midi_event_reset_encode(dev);
262 snd_midi_event_reset_decode(dev);
263 }
264
265 /**
266 * \brief Resizes the MIDI message encoding buffer.
267 * \param dev MIDI event parser.
268 * \param bufsize The new buffer size.
269 * \return Zero on success, otherwise a negative error code.
270 *
271 * This function resizes the buffer that is used to hold partially encoded MIDI
272 * messages.
273 *
274 * If there is a partially encoded message in the buffer, it is dropped.
275 *
276 * \par Errors:
277 * <dl>
278 * <dt>-ENOMEM<dd>Out of memory.
279 *
280 * \sa snd_midi_event_encode, snd_midi_event_reset_encode
281 */
snd_midi_event_resize_buffer(snd_midi_event_t *dev, size_t bufsize)282 int snd_midi_event_resize_buffer(snd_midi_event_t *dev, size_t bufsize)
283 {
284 unsigned char *new_buf, *old_buf;
285
286 if (bufsize == dev->bufsize)
287 return 0;
288 new_buf = malloc(bufsize);
289 if (new_buf == NULL)
290 return -ENOMEM;
291 old_buf = dev->buf;
292 dev->buf = new_buf;
293 dev->bufsize = bufsize;
294 reset_encode(dev);
295 free(old_buf);
296 return 0;
297 }
298
299 /**
300 * \brief Encodes bytes to sequencer event.
301 * \param[in] dev MIDI event parser.
302 * \param[in] buf Buffer containing bytes of a raw MIDI stream.
303 * \param[in] count Number of bytes in \a buf.
304 * \param[out] ev Sequencer event.
305 * \return The number of bytes consumed, or a negative error code.
306 *
307 * This function tries to use up to \a count bytes from the beginning of the
308 * buffer to encode a sequencer event. If a complete MIDI message has been
309 * encoded, the sequencer event is written to \a ev; otherwise, \a ev->type is
310 * set to #SND_SEQ_EVENT_NONE, and further bytes are required to complete
311 * a message.
312 *
313 * The buffer in \a dev is used to hold any bytes of a not-yet-complete MIDI
314 * message. If a System Exclusive message is larger than the buffer, the
315 * message is split into multiple parts, and a sequencer event is returned at
316 * the end of each part.
317 *
318 * Any bytes that are not part of a valid MIDI message are silently ignored,
319 * i.e., they are consumed without signaling an error.
320 *
321 * When this function returns a system exclusive sequencer event (\a ev->type
322 * is #SND_SEQ_EVENT_SYSEX), the data pointer (\a ev->data.ext.ptr) points into
323 * the MIDI event parser's buffer. Therefore, the sequencer event can only be
324 * used as long as that buffer remains valid, i.e., until the next call to
325 * #snd_midi_event_encode, #snd_midi_event_encode_byte,
326 * #snd_midi_event_resize_buffer, #snd_midi_event_init,
327 * #snd_midi_event_reset_encode, or #snd_midi_event_free for that MIDI event
328 * parser.
329 *
330 * This function can generate any sequencer event that corresponds to a MIDI
331 * message, i.e.:
332 * - #SND_SEQ_EVENT_NOTEOFF
333 * - #SND_SEQ_EVENT_NOTEON
334 * - #SND_SEQ_EVENT_KEYPRESS
335 * - #SND_SEQ_EVENT_CONTROLLER
336 * - #SND_SEQ_EVENT_PGMCHANGE
337 * - #SND_SEQ_EVENT_CHANPRESS
338 * - #SND_SEQ_EVENT_PITCHBEND
339 * - #SND_SEQ_EVENT_SYSEX
340 * - #SND_SEQ_EVENT_QFRAME
341 * - #SND_SEQ_EVENT_SONGPOS
342 * - #SND_SEQ_EVENT_SONGSEL
343 * - #SND_SEQ_EVENT_TUNE_REQUEST
344 * - #SND_SEQ_EVENT_CLOCK
345 * - #SND_SEQ_EVENT_START
346 * - #SND_SEQ_EVENT_CONTINUE
347 * - #SND_SEQ_EVENT_STOP
348 * - #SND_SEQ_EVENT_SENSING
349 * - #SND_SEQ_EVENT_RESET
350 * .
351 * Some implementations may also be able to generate the following events
352 * for a sequence of controller change messages:
353 * - #SND_SEQ_EVENT_CONTROL14
354 * - #SND_SEQ_EVENT_NONREGPARAM
355 * - #SND_SEQ_EVENT_REGPARAM
356 *
357 * \par Conforming to:
358 * LSB 3.2
359 *
360 * \sa snd_midi_event_new, snd_midi_event_reset_encode, snd_midi_event_encode_byte
361 */
snd_midi_event_encode(snd_midi_event_t *dev, const unsigned char *buf, long count, snd_seq_event_t *ev)362 long snd_midi_event_encode(snd_midi_event_t *dev, const unsigned char *buf, long count, snd_seq_event_t *ev)
363 {
364 long result = 0;
365 int rc;
366
367 ev->type = SND_SEQ_EVENT_NONE;
368
369 while (count-- > 0) {
370 rc = snd_midi_event_encode_byte(dev, *buf++, ev);
371 result++;
372 if (rc < 0)
373 return rc;
374 else if (rc > 0)
375 return result;
376 }
377
378 return result;
379 }
380
381 /**
382 * \brief Encodes byte to sequencer event.
383 * \param[in] dev MIDI event parser.
384 * \param[in] c A byte of a raw MIDI stream.
385 * \param[out] ev Sequencer event.
386 * \return 1 if a sequenver event has been completed, 0 if more bytes are
387 * required to complete an event, or a negative error code.
388 *
389 * This function tries to use the byte \a c to encode a sequencer event. If
390 * a complete MIDI message has been encoded, the sequencer event is written to
391 * \a ev; otherwise, further bytes are required to complete a message.
392 *
393 * See also the description of #snd_midi_event_encode.
394 *
395 * \par Conforming to:
396 * LSB 3.2
397 *
398 * \sa snd_midi_event_new, snd_midi_event_reset_encode, snd_midi_event_encode
399 */
snd_midi_event_encode_byte(snd_midi_event_t *dev, int c, snd_seq_event_t *ev)400 int snd_midi_event_encode_byte(snd_midi_event_t *dev, int c, snd_seq_event_t *ev)
401 {
402 int rc = 0;
403
404 c &= 0xff;
405
406 if (c >= MIDI_CMD_COMMON_CLOCK) {
407 /* real-time event */
408 ev->type = status_event[ST_SPECIAL + c - 0xf0].event;
409 ev->flags &= ~SND_SEQ_EVENT_LENGTH_MASK;
410 ev->flags |= SND_SEQ_EVENT_LENGTH_FIXED;
411 return ev->type != SND_SEQ_EVENT_NONE;
412 }
413
414 if ((c & 0x80) &&
415 (c != MIDI_CMD_COMMON_SYSEX_END || dev->type != ST_SYSEX)) {
416 /* new command */
417 dev->buf[0] = c;
418 if ((c & 0xf0) == 0xf0) /* system message */
419 dev->type = (c & 0x0f) + ST_SPECIAL;
420 else
421 dev->type = (c >> 4) & 0x07;
422 dev->read = 1;
423 dev->qlen = status_event[dev->type].qlen;
424 } else {
425 if (dev->qlen > 0) {
426 /* rest of command */
427 dev->buf[dev->read++] = c;
428 if (dev->type != ST_SYSEX)
429 dev->qlen--;
430 } else {
431 /* running status */
432 dev->buf[1] = c;
433 dev->qlen = status_event[dev->type].qlen - 1;
434 dev->read = 2;
435 }
436 }
437 if (dev->qlen == 0) {
438 ev->type = status_event[dev->type].event;
439 ev->flags &= ~SND_SEQ_EVENT_LENGTH_MASK;
440 ev->flags |= SND_SEQ_EVENT_LENGTH_FIXED;
441 if (status_event[dev->type].encode) /* set data values */
442 status_event[dev->type].encode(dev, ev);
443 if (dev->type >= ST_SPECIAL)
444 dev->type = ST_INVALID;
445 rc = 1;
446 } else if (dev->type == ST_SYSEX) {
447 if (c == MIDI_CMD_COMMON_SYSEX_END ||
448 dev->read >= dev->bufsize) {
449 ev->flags &= ~SND_SEQ_EVENT_LENGTH_MASK;
450 ev->flags |= SND_SEQ_EVENT_LENGTH_VARIABLE;
451 ev->type = SND_SEQ_EVENT_SYSEX;
452 ev->data.ext.len = dev->read;
453 ev->data.ext.ptr = dev->buf;
454 if (c != MIDI_CMD_COMMON_SYSEX_END)
455 dev->read = 0; /* continue to parse */
456 else
457 reset_encode(dev); /* all parsed */
458 rc = 1;
459 }
460 }
461
462 return rc;
463 }
464
465 /* encode note event */
note_event(snd_midi_event_t *dev, snd_seq_event_t *ev)466 static void note_event(snd_midi_event_t *dev, snd_seq_event_t *ev)
467 {
468 ev->data.note.channel = dev->buf[0] & 0x0f;
469 ev->data.note.note = dev->buf[1];
470 ev->data.note.velocity = dev->buf[2];
471 }
472
473 /* encode one parameter controls */
one_param_ctrl_event(snd_midi_event_t *dev, snd_seq_event_t *ev)474 static void one_param_ctrl_event(snd_midi_event_t *dev, snd_seq_event_t *ev)
475 {
476 ev->data.control.channel = dev->buf[0] & 0x0f;
477 ev->data.control.value = dev->buf[1];
478 }
479
480 /* encode pitch wheel change */
pitchbend_ctrl_event(snd_midi_event_t *dev, snd_seq_event_t *ev)481 static void pitchbend_ctrl_event(snd_midi_event_t *dev, snd_seq_event_t *ev)
482 {
483 ev->data.control.channel = dev->buf[0] & 0x0f;
484 ev->data.control.value = (int)dev->buf[2] * 128 + (int)dev->buf[1] - 8192;
485 }
486
487 /* encode midi control change */
two_param_ctrl_event(snd_midi_event_t *dev, snd_seq_event_t *ev)488 static void two_param_ctrl_event(snd_midi_event_t *dev, snd_seq_event_t *ev)
489 {
490 ev->data.control.channel = dev->buf[0] & 0x0f;
491 ev->data.control.param = dev->buf[1];
492 ev->data.control.value = dev->buf[2];
493 }
494
495 /* encode one parameter value*/
one_param_event(snd_midi_event_t *dev, snd_seq_event_t *ev)496 static void one_param_event(snd_midi_event_t *dev, snd_seq_event_t *ev)
497 {
498 ev->data.control.value = dev->buf[1];
499 }
500
501 /* encode song position */
songpos_event(snd_midi_event_t *dev, snd_seq_event_t *ev)502 static void songpos_event(snd_midi_event_t *dev, snd_seq_event_t *ev)
503 {
504 ev->data.control.value = (int)dev->buf[2] * 128 + (int)dev->buf[1];
505 }
506
507 /**
508 * \brief Decodes sequencer event to MIDI byte stream.
509 * \param[in] dev MIDI event parser.
510 * \param[out] buf Buffer for the resulting MIDI byte stream.
511 * \param[in] count Number of bytes in \a buf.
512 * \param[in] ev The sequencer event to decode.
513 * \return The number of bytes written to \a buf, or a negative error code.
514 *
515 * This function tries to decode the sequencer event into one or more MIDI
516 * messages, and writes the raw MIDI byte(s) into \a buf.
517 *
518 * The generated MIDI messages may use running status, unless disabled with
519 * #snd_midi_event_no_status.
520 *
521 * The required buffer size for a sequencer event it as most 12 bytes, except
522 * for System Exclusive events (\a ev->type == #SND_SEQ_EVENT_SYSEX) which can
523 * have any length (as specified by \a ev->data.ext.len).
524 *
525 * The following sequencer events correspond to MIDI messages:
526 * - #SND_SEQ_EVENT_NOTEOFF
527 * - #SND_SEQ_EVENT_NOTEON
528 * - #SND_SEQ_EVENT_KEYPRESS
529 * - #SND_SEQ_EVENT_CONTROLLER
530 * - #SND_SEQ_EVENT_PGMCHANGE
531 * - #SND_SEQ_EVENT_CHANPRESS
532 * - #SND_SEQ_EVENT_PITCHBEND
533 * - #SND_SEQ_EVENT_SYSEX
534 * - #SND_SEQ_EVENT_QFRAME
535 * - #SND_SEQ_EVENT_SONGPOS
536 * - #SND_SEQ_EVENT_SONGSEL
537 * - #SND_SEQ_EVENT_TUNE_REQUEST
538 * - #SND_SEQ_EVENT_CLOCK
539 * - #SND_SEQ_EVENT_START
540 * - #SND_SEQ_EVENT_CONTINUE
541 * - #SND_SEQ_EVENT_STOP
542 * - #SND_SEQ_EVENT_SENSING
543 * - #SND_SEQ_EVENT_RESET
544 * - #SND_SEQ_EVENT_CONTROL14
545 * - #SND_SEQ_EVENT_NONREGPARAM
546 * - #SND_SEQ_EVENT_REGPARAM
547 *
548 * \par Errors:
549 * <dl>
550 * <dt>-EINVAL<dd>\a ev is not a valid sequencer event.
551 * <dt>-ENOENT<dd>The sequencer event does not correspond to one or more MIDI messages.
552 * <dt>-ENOMEM<dd>The MIDI message(s) would not fit into \a count bytes.
553 *
554 * \par Conforming to:
555 * LSB 3.2
556 *
557 * \sa snd_midi_event_reset_decode, snd_midi_event_no_status
558 */
snd_midi_event_decode(snd_midi_event_t *dev, unsigned char *buf, long count, const snd_seq_event_t *ev)559 long snd_midi_event_decode(snd_midi_event_t *dev, unsigned char *buf, long count, const snd_seq_event_t *ev)
560 {
561 int cmd;
562 long qlen;
563 unsigned int type;
564
565 if (ev->type == SND_SEQ_EVENT_NONE)
566 return -ENOENT;
567
568 for (type = 0; type < numberof(status_event); type++) {
569 if (ev->type == status_event[type].event)
570 goto __found;
571 }
572 for (type = 0; type < numberof(extra_event); type++) {
573 if (ev->type == extra_event[type].event)
574 return extra_event[type].decode(dev, buf, count, ev);
575 }
576 return -ENOENT;
577
578 __found:
579 if (type >= ST_SPECIAL)
580 cmd = 0xf0 + (type - ST_SPECIAL);
581 else
582 /* data.note.channel and data.control.channel is identical */
583 cmd = 0x80 | (type << 4) | (ev->data.note.channel & 0x0f);
584
585
586 if (cmd == MIDI_CMD_COMMON_SYSEX) {
587 snd_midi_event_reset_decode(dev);
588 qlen = ev->data.ext.len;
589 if (count < qlen)
590 return -ENOMEM;
591 switch (ev->flags & SND_SEQ_EVENT_LENGTH_MASK) {
592 case SND_SEQ_EVENT_LENGTH_FIXED:
593 return -EINVAL; /* invalid event */
594 }
595 memcpy(buf, ev->data.ext.ptr, qlen);
596 return qlen;
597 } else {
598 unsigned char xbuf[4];
599
600 if ((cmd & 0xf0) == 0xf0 || dev->lastcmd != cmd || dev->nostat) {
601 dev->lastcmd = cmd;
602 xbuf[0] = cmd;
603 if (status_event[type].decode)
604 status_event[type].decode(ev, xbuf + 1);
605 qlen = status_event[type].qlen + 1;
606 } else {
607 if (status_event[type].decode)
608 status_event[type].decode(ev, xbuf + 0);
609 qlen = status_event[type].qlen;
610 }
611 if (qlen <= 0)
612 return 0;
613 if (count < qlen)
614 return -ENOMEM;
615 memcpy(buf, xbuf, qlen);
616 return qlen;
617 }
618 }
619
620
621 /* decode note event */
note_decode(const snd_seq_event_t *ev, unsigned char *buf)622 static void note_decode(const snd_seq_event_t *ev, unsigned char *buf)
623 {
624 buf[0] = ev->data.note.note & 0x7f;
625 buf[1] = ev->data.note.velocity & 0x7f;
626 }
627
628 /* decode one parameter controls */
one_param_decode(const snd_seq_event_t *ev, unsigned char *buf)629 static void one_param_decode(const snd_seq_event_t *ev, unsigned char *buf)
630 {
631 buf[0] = ev->data.control.value & 0x7f;
632 }
633
634 /* decode pitch wheel change */
pitchbend_decode(const snd_seq_event_t *ev, unsigned char *buf)635 static void pitchbend_decode(const snd_seq_event_t *ev, unsigned char *buf)
636 {
637 int value = ev->data.control.value + 8192;
638 buf[0] = value & 0x7f;
639 buf[1] = (value >> 7) & 0x7f;
640 }
641
642 /* decode midi control change */
two_param_decode(const snd_seq_event_t *ev, unsigned char *buf)643 static void two_param_decode(const snd_seq_event_t *ev, unsigned char *buf)
644 {
645 buf[0] = ev->data.control.param & 0x7f;
646 buf[1] = ev->data.control.value & 0x7f;
647 }
648
649 /* decode song position */
songpos_decode(const snd_seq_event_t *ev, unsigned char *buf)650 static void songpos_decode(const snd_seq_event_t *ev, unsigned char *buf)
651 {
652 buf[0] = ev->data.control.value & 0x7f;
653 buf[1] = (ev->data.control.value >> 7) & 0x7f;
654 }
655
656 /* decode 14bit control */
extra_decode_ctrl14(snd_midi_event_t *dev, unsigned char *buf, int count, const snd_seq_event_t *ev)657 static int extra_decode_ctrl14(snd_midi_event_t *dev, unsigned char *buf, int count, const snd_seq_event_t *ev)
658 {
659 unsigned char cmd;
660 int idx = 0;
661
662 cmd = MIDI_CMD_CONTROL|(ev->data.control.channel & 0x0f);
663 if (ev->data.control.param < 32) {
664 if (count < 4)
665 return -ENOMEM;
666 if (dev->nostat && count < 6)
667 return -ENOMEM;
668 if (cmd != dev->lastcmd || dev->nostat) {
669 if (count < 5)
670 return -ENOMEM;
671 buf[idx++] = dev->lastcmd = cmd;
672 }
673 buf[idx++] = ev->data.control.param;
674 buf[idx++] = (ev->data.control.value >> 7) & 0x7f;
675 if (dev->nostat)
676 buf[idx++] = cmd;
677 buf[idx++] = ev->data.control.param + 32;
678 buf[idx++] = ev->data.control.value & 0x7f;
679 } else {
680 if (count < 2)
681 return -ENOMEM;
682 if (cmd != dev->lastcmd || dev->nostat) {
683 if (count < 3)
684 return -ENOMEM;
685 buf[idx++] = dev->lastcmd = cmd;
686 }
687 buf[idx++] = ev->data.control.param & 0x7f;
688 buf[idx++] = ev->data.control.value & 0x7f;
689 }
690 return idx;
691 }
692
693 /* decode reg/nonreg param */
extra_decode_xrpn(snd_midi_event_t *dev, unsigned char *buf, int count, const snd_seq_event_t *ev)694 static int extra_decode_xrpn(snd_midi_event_t *dev, unsigned char *buf, int count, const snd_seq_event_t *ev)
695 {
696 unsigned char cmd;
697 const char *cbytes;
698 static const char cbytes_nrpn[4] = { MIDI_CTL_NONREG_PARM_NUM_MSB,
699 MIDI_CTL_NONREG_PARM_NUM_LSB,
700 MIDI_CTL_MSB_DATA_ENTRY,
701 MIDI_CTL_LSB_DATA_ENTRY };
702 static const char cbytes_rpn[4] = { MIDI_CTL_REGIST_PARM_NUM_MSB,
703 MIDI_CTL_REGIST_PARM_NUM_LSB,
704 MIDI_CTL_MSB_DATA_ENTRY,
705 MIDI_CTL_LSB_DATA_ENTRY };
706 unsigned char bytes[4];
707 int idx = 0, i;
708
709 if (count < 8)
710 return -ENOMEM;
711 if (dev->nostat && count < 12)
712 return -ENOMEM;
713 cmd = MIDI_CMD_CONTROL|(ev->data.control.channel & 0x0f);
714 bytes[0] = (ev->data.control.param & 0x3f80) >> 7;
715 bytes[1] = ev->data.control.param & 0x007f;
716 bytes[2] = (ev->data.control.value & 0x3f80) >> 7;
717 bytes[3] = ev->data.control.value & 0x007f;
718 if (cmd != dev->lastcmd && !dev->nostat) {
719 if (count < 9)
720 return -ENOMEM;
721 buf[idx++] = dev->lastcmd = cmd;
722 }
723 cbytes = ev->type == SND_SEQ_EVENT_NONREGPARAM ? cbytes_nrpn : cbytes_rpn;
724 for (i = 0; i < 4; i++) {
725 if (dev->nostat)
726 buf[idx++] = dev->lastcmd = cmd;
727 buf[idx++] = cbytes[i];
728 buf[idx++] = bytes[i];
729 }
730 return idx;
731 }
732