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