• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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