• Home
  • History
  • Annotate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/ap/gpl/iserver/alsa-lib-1.0.26/src/seq/

Lines Matching defs:*

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
10 * MIDI byte <-> sequencer event coder
12 * Copyright (C) 1998,99,2000 Takashi Iwai <tiwai@suse.de>,
13 * Jaroslav Kysela <perex@perex.cz>
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 #include <malloc.h>
32 #include "local.h"
34 #ifndef DOC_HIDDEN
36 /* midi status */
37 struct snd_midi_event {
38 size_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 */
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 */
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);
60 #endif /* DOC_HIDDEN */
63 * prototypes
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);
78 * event list
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 */
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);
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},
128 #define numberof(ary) (sizeof(ary)/sizeof(ary[0]))
129 #endif /* DOC_HIDDEN */
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.
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).
143 * \par Errors:
144 * <dl>
145 * <dt>-ENOMEM<dd>Out of memory.
147 * \par Conforming to:
148 * LSB 3.2
150 int snd_midi_event_new(size_t bufsize, snd_midi_event_t **rdev)
152 snd_midi_event_t *dev;
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;
165 dev->bufsize = bufsize;
166 dev->lastcmd = 0xff;
167 dev->type = ST_INVALID;
168 *rdev = dev;
169 return 0;
173 * \brief Frees a MIDI event parser.
174 * \param dev MIDI event parser.
176 * Frees a MIDI event parser.
178 * \par Conforming to:
179 * LSB 3.2
181 void snd_midi_event_free(snd_midi_event_t *dev)
183 if (dev != NULL) {
184 free(dev->buf);
185 free(dev);
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.
195 * This function enables or disables MIDI command merging (running status).
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.
200 void snd_midi_event_no_status(snd_midi_event_t *dev, int on)
202 dev->nostat = on ? 1 : 0;
206 * initialize record
208 inline static void reset_encode(snd_midi_event_t *dev)
210 dev->read = 0;
211 dev->qlen = 0;
212 dev->type = ST_INVALID;
216 * \brief Resets MIDI encode parser.
217 * \param dev MIDI event parser.
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.
223 * \par Conforming to:
224 * LSB 3.2
226 void snd_midi_event_reset_encode(snd_midi_event_t *dev)
228 reset_encode(dev);
232 * \brief Resets MIDI decode parser.
233 * \param dev MIDI event parser.
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.
239 * \par Conforming to:
240 * LSB 3.2
242 void snd_midi_event_reset_decode(snd_midi_event_t *dev)
244 dev->lastcmd = 0xff;
248 * \brief Resets MIDI encode/decode parsers.
249 * \param dev MIDI event parser.
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
254 * \par Conforming to:
255 * LSB 3.2
257 void snd_midi_event_init(snd_midi_event_t *dev)
259 snd_midi_event_reset_encode(dev);
260 snd_midi_event_reset_decode(dev);
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.
269 * This function resizes the buffer that is used to hold partially encoded MIDI
270 * messages.
272 * If there is a partially encoded message in the buffer, it is dropped.
274 * \par Errors:
275 * <dl>
276 * <dt>-ENOMEM<dd>Out of memory.
278 * \sa snd_midi_event_encode, snd_midi_event_reset_encode
280 int snd_midi_event_resize_buffer(snd_midi_event_t *dev, size_t bufsize)
282 unsigned char *new_buf, *old_buf;
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;
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.
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.
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.
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.
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.
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
355 * \par Conforming to:
356 * LSB 3.2
358 * \sa snd_midi_event_new, snd_midi_event_reset_encode, snd_midi_event_encode_byte
360 long snd_midi_event_encode(snd_midi_event_t *dev, const unsigned char *buf, long count, snd_seq_event_t *ev)
362 long result = 0;
363 int rc;
365 ev->type = SND_SEQ_EVENT_NONE;
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;
376 return result;
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.
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.
391 * See also the description of #snd_midi_event_encode.
393 * \par Conforming to:
394 * LSB 3.2
396 * \sa snd_midi_event_new, snd_midi_event_reset_encode, snd_midi_event_encode
398 int snd_midi_event_encode_byte(snd_midi_event_t *dev, int c, snd_seq_event_t *ev)
400 int rc = 0;
402 c &= 0xff;
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;
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;
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;
460 return rc;
463 /* encode note event */
464 static void note_event(snd_midi_event_t *dev, snd_seq_event_t *ev)
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];
471 /* encode one parameter controls */
472 static void one_param_ctrl_event(snd_midi_event_t *dev, snd_seq_event_t *ev)
474 ev->data.control.channel = dev->buf[0] & 0x0f;
475 ev->data.control.value = dev->buf[1];
478 /* encode pitch wheel change */
479 static void pitchbend_ctrl_event(snd_midi_event_t *dev, snd_seq_event_t *ev)
481 ev->data.control.channel = dev->buf[0] & 0x0f;
482 ev->data.control.value = (int)dev->buf[2] * 128 + (int)dev->buf[1] - 8192;
485 /* encode midi control change */
486 static void two_param_ctrl_event(snd_midi_event_t *dev, snd_seq_event_t *ev)
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];
493 /* encode one parameter value*/
494 static void one_param_event(snd_midi_event_t *dev, snd_seq_event_t *ev)
496 ev->data.control.value = dev->buf[1];
499 /* encode song position */
500 static void songpos_event(snd_midi_event_t *dev, snd_seq_event_t *ev)
502 ev->data.control.value = (int)dev->buf[2] * 128 + (int)dev->buf[1];
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.
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.
516 * The generated MIDI messages may use running status, unless disabled with
517 * #snd_midi_event_no_status.
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).
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
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.
552 * \par Conforming to:
553 * LSB 3.2
555 * \sa snd_midi_event_reset_decode, snd_midi_event_no_status
557 long snd_midi_event_decode(snd_midi_event_t *dev, unsigned char *buf, long count, const snd_seq_event_t *ev)
559 int cmd;
560 long qlen;
561 unsigned int type;
563 if (ev->type == SND_SEQ_EVENT_NONE)
564 return -ENOENT;
566 for (type = 0; type < numberof(status_event); type++) {
567 if (ev->type == status_event[type].event)
568 goto __found;
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);
574 return -ENOENT;
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);
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 */
593 memcpy(buf, ev->data.ext.ptr, qlen);
594 return qlen;
595 } else {
596 unsigned char xbuf[4];
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;
609 if (count < qlen)
610 return -ENOMEM;
611 memcpy(buf, xbuf, qlen);
612 return qlen;
617 /* decode note event */
618 static void note_decode(const snd_seq_event_t *ev, unsigned char *buf)
620 buf[0] = ev->data.note.note & 0x7f;
621 buf[1] = ev->data.note.velocity & 0x7f;
624 /* decode one parameter controls */
625 static void one_param_decode(const snd_seq_event_t *ev, unsigned char *buf)
627 buf[0] = ev->data.control.value & 0x7f;
630 /* decode pitch wheel change */
631 static void pitchbend_decode(const snd_seq_event_t *ev, unsigned char *buf)
633 int value = ev->data.control.value + 8192;
634 buf[0] = value & 0x7f;
635 buf[1] = (value >> 7) & 0x7f;
638 /* decode midi control change */
639 static void two_param_decode(const snd_seq_event_t *ev, unsigned char *buf)
641 buf[0] = ev->data.control.param & 0x7f;
642 buf[1] = ev->data.control.value & 0x7f;
645 /* decode song position */
646 static void songpos_decode(const snd_seq_event_t *ev, unsigned char *buf)
648 buf[0] = ev->data.control.value & 0x7f;
649 buf[1] = (ev->data.control.value >> 7) & 0x7f;
652 /* decode 14bit control */
653 static int extra_decode_ctrl14(snd_midi_event_t *dev, unsigned char *buf, int count, const snd_seq_event_t *ev)
655 unsigned char cmd;
656 int idx = 0;
658 cmd = MIDI_CMD_CONTROL|(ev->data.control.channel & 0x0f);
659 if (ev->data.control.param < 32) {
660 if (count < 4)
661 return -ENOMEM;
662 if (dev->nostat && count < 6)
663 return -ENOMEM;
664 if (cmd != dev->lastcmd || dev->nostat) {
665 if (count < 5)
666 return -ENOMEM;
667 buf[idx++] = dev->lastcmd = cmd;
669 buf[idx++] = ev->data.control.param;
670 buf[idx++] = (ev->data.control.value >> 7) & 0x7f;
671 if (dev->nostat)
672 buf[idx++] = cmd;
673 buf[idx++] = ev->data.control.param + 32;
674 buf[idx++] = ev->data.control.value & 0x7f;
675 } else {
676 if (count < 2)
677 return -ENOMEM;
678 if (cmd != dev->lastcmd || dev->nostat) {
679 if (count < 3)
680 return -ENOMEM;
681 buf[idx++] = dev->lastcmd = cmd;
683 buf[idx++] = ev->data.control.param & 0x7f;
684 buf[idx++] = ev->data.control.value & 0x7f;
686 return idx;
689 /* decode reg/nonreg param */
690 static int extra_decode_xrpn(snd_midi_event_t *dev, unsigned char *buf, int count, const snd_seq_event_t *ev)
692 unsigned char cmd;
693 const char *cbytes;
694 static const char cbytes_nrpn[4] = { MIDI_CTL_NONREG_PARM_NUM_MSB,
695 MIDI_CTL_NONREG_PARM_NUM_LSB,
696 MIDI_CTL_MSB_DATA_ENTRY,
697 MIDI_CTL_LSB_DATA_ENTRY };
698 static const char cbytes_rpn[4] = { MIDI_CTL_REGIST_PARM_NUM_MSB,
699 MIDI_CTL_REGIST_PARM_NUM_LSB,
700 MIDI_CTL_MSB_DATA_ENTRY,
701 MIDI_CTL_LSB_DATA_ENTRY };
702 unsigned char bytes[4];
703 int idx = 0, i;
705 if (count < 8)
706 return -ENOMEM;
707 if (dev->nostat && count < 12)
708 return -ENOMEM;
709 cmd = MIDI_CMD_CONTROL|(ev->data.control.channel & 0x0f);
710 bytes[0] = (ev->data.control.param & 0x3f80) >> 7;
711 bytes[1] = ev->data.control.param & 0x007f;
712 bytes[2] = (ev->data.control.value & 0x3f80) >> 7;
713 bytes[3] = ev->data.control.value & 0x007f;
714 if (cmd != dev->lastcmd && !dev->nostat) {
715 if (count < 9)
716 return -ENOMEM;
717 buf[idx++] = dev->lastcmd = cmd;
719 cbytes = ev->type == SND_SEQ_EVENT_NONREGPARAM ? cbytes_nrpn : cbytes_rpn;
720 for (i = 0; i < 4; i++) {
721 if (dev->nostat)
722 buf[idx++] = dev->lastcmd = cmd;
723 buf[idx++] = cbytes[i];
724 buf[idx++] = bytes[i];
726 return idx;