root/sound/core/seq/seq_midi_event.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. snd_midi_event_new
  2. snd_midi_event_free
  3. reset_encode
  4. snd_midi_event_reset_encode
  5. snd_midi_event_reset_decode
  6. snd_midi_event_no_status
  7. snd_midi_event_encode_byte
  8. note_event
  9. one_param_ctrl_event
  10. pitchbend_ctrl_event
  11. two_param_ctrl_event
  12. one_param_event
  13. songpos_event
  14. snd_midi_event_decode
  15. note_decode
  16. one_param_decode
  17. pitchbend_decode
  18. two_param_decode
  19. songpos_decode
  20. extra_decode_ctrl14
  21. extra_decode_xrpn

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  *  MIDI byte <-> sequencer event coder
   4  *
   5  *  Copyright (C) 1998,99 Takashi Iwai <tiwai@suse.de>,
   6  *                        Jaroslav Kysela <perex@perex.cz>
   7  */
   8 
   9 #include <linux/slab.h>
  10 #include <linux/errno.h>
  11 #include <linux/string.h>
  12 #include <linux/module.h>
  13 #include <sound/core.h>
  14 #include <sound/seq_kernel.h>
  15 #include <sound/seq_midi_event.h>
  16 #include <sound/asoundef.h>
  17 
  18 MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>, Jaroslav Kysela <perex@perex.cz>");
  19 MODULE_DESCRIPTION("MIDI byte <-> sequencer event coder");
  20 MODULE_LICENSE("GPL");
  21 
  22 /* event type, index into status_event[] */
  23 /* from 0 to 6 are normal commands (note off, on, etc.) for 0x9?-0xe? */
  24 #define ST_INVALID      7
  25 #define ST_SPECIAL      8
  26 #define ST_SYSEX        ST_SPECIAL
  27 /* from 8 to 15 are events for 0xf0-0xf7 */
  28 
  29 
  30 /*
  31  * prototypes
  32  */
  33 static void note_event(struct snd_midi_event *dev, struct snd_seq_event *ev);
  34 static void one_param_ctrl_event(struct snd_midi_event *dev, struct snd_seq_event *ev);
  35 static void pitchbend_ctrl_event(struct snd_midi_event *dev, struct snd_seq_event *ev);
  36 static void two_param_ctrl_event(struct snd_midi_event *dev, struct snd_seq_event *ev);
  37 static void one_param_event(struct snd_midi_event *dev, struct snd_seq_event *ev);
  38 static void songpos_event(struct snd_midi_event *dev, struct snd_seq_event *ev);
  39 static void note_decode(struct snd_seq_event *ev, unsigned char *buf);
  40 static void one_param_decode(struct snd_seq_event *ev, unsigned char *buf);
  41 static void pitchbend_decode(struct snd_seq_event *ev, unsigned char *buf);
  42 static void two_param_decode(struct snd_seq_event *ev, unsigned char *buf);
  43 static void songpos_decode(struct snd_seq_event *ev, unsigned char *buf);
  44 
  45 /*
  46  * event list
  47  */
  48 static struct status_event_list {
  49         int event;
  50         int qlen;
  51         void (*encode)(struct snd_midi_event *dev, struct snd_seq_event *ev);
  52         void (*decode)(struct snd_seq_event *ev, unsigned char *buf);
  53 } status_event[] = {
  54         /* 0x80 - 0xef */
  55         {SNDRV_SEQ_EVENT_NOTEOFF,        2, note_event, note_decode},
  56         {SNDRV_SEQ_EVENT_NOTEON,         2, note_event, note_decode},
  57         {SNDRV_SEQ_EVENT_KEYPRESS,       2, note_event, note_decode},
  58         {SNDRV_SEQ_EVENT_CONTROLLER,     2, two_param_ctrl_event, two_param_decode},
  59         {SNDRV_SEQ_EVENT_PGMCHANGE,      1, one_param_ctrl_event, one_param_decode},
  60         {SNDRV_SEQ_EVENT_CHANPRESS,      1, one_param_ctrl_event, one_param_decode},
  61         {SNDRV_SEQ_EVENT_PITCHBEND,      2, pitchbend_ctrl_event, pitchbend_decode},
  62         /* invalid */
  63         {SNDRV_SEQ_EVENT_NONE,          -1, NULL, NULL},
  64         /* 0xf0 - 0xff */
  65         {SNDRV_SEQ_EVENT_SYSEX,          1, NULL, NULL}, /* sysex: 0xf0 */
  66         {SNDRV_SEQ_EVENT_QFRAME,         1, one_param_event, one_param_decode}, /* 0xf1 */
  67         {SNDRV_SEQ_EVENT_SONGPOS,        2, songpos_event, songpos_decode}, /* 0xf2 */
  68         {SNDRV_SEQ_EVENT_SONGSEL,        1, one_param_event, one_param_decode}, /* 0xf3 */
  69         {SNDRV_SEQ_EVENT_NONE,          -1, NULL, NULL}, /* 0xf4 */
  70         {SNDRV_SEQ_EVENT_NONE,          -1, NULL, NULL}, /* 0xf5 */
  71         {SNDRV_SEQ_EVENT_TUNE_REQUEST,   0, NULL, NULL}, /* 0xf6 */
  72         {SNDRV_SEQ_EVENT_NONE,          -1, NULL, NULL}, /* 0xf7 */
  73         {SNDRV_SEQ_EVENT_CLOCK,          0, NULL, NULL}, /* 0xf8 */
  74         {SNDRV_SEQ_EVENT_NONE,          -1, NULL, NULL}, /* 0xf9 */
  75         {SNDRV_SEQ_EVENT_START,          0, NULL, NULL}, /* 0xfa */
  76         {SNDRV_SEQ_EVENT_CONTINUE,       0, NULL, NULL}, /* 0xfb */
  77         {SNDRV_SEQ_EVENT_STOP,           0, NULL, NULL}, /* 0xfc */
  78         {SNDRV_SEQ_EVENT_NONE,          -1, NULL, NULL}, /* 0xfd */
  79         {SNDRV_SEQ_EVENT_SENSING,        0, NULL, NULL}, /* 0xfe */
  80         {SNDRV_SEQ_EVENT_RESET,          0, NULL, NULL}, /* 0xff */
  81 };
  82 
  83 static int extra_decode_ctrl14(struct snd_midi_event *dev, unsigned char *buf, int len,
  84                                struct snd_seq_event *ev);
  85 static int extra_decode_xrpn(struct snd_midi_event *dev, unsigned char *buf, int count,
  86                              struct snd_seq_event *ev);
  87 
  88 static struct extra_event_list {
  89         int event;
  90         int (*decode)(struct snd_midi_event *dev, unsigned char *buf, int len,
  91                       struct snd_seq_event *ev);
  92 } extra_event[] = {
  93         {SNDRV_SEQ_EVENT_CONTROL14, extra_decode_ctrl14},
  94         {SNDRV_SEQ_EVENT_NONREGPARAM, extra_decode_xrpn},
  95         {SNDRV_SEQ_EVENT_REGPARAM, extra_decode_xrpn},
  96 };
  97 
  98 /*
  99  *  new/delete record
 100  */
 101 
 102 int snd_midi_event_new(int bufsize, struct snd_midi_event **rdev)
 103 {
 104         struct snd_midi_event *dev;
 105 
 106         *rdev = NULL;
 107         dev = kzalloc(sizeof(*dev), GFP_KERNEL);
 108         if (dev == NULL)
 109                 return -ENOMEM;
 110         if (bufsize > 0) {
 111                 dev->buf = kmalloc(bufsize, GFP_KERNEL);
 112                 if (dev->buf == NULL) {
 113                         kfree(dev);
 114                         return -ENOMEM;
 115                 }
 116         }
 117         dev->bufsize = bufsize;
 118         dev->lastcmd = 0xff;
 119         dev->type = ST_INVALID;
 120         spin_lock_init(&dev->lock);
 121         *rdev = dev;
 122         return 0;
 123 }
 124 EXPORT_SYMBOL(snd_midi_event_new);
 125 
 126 void snd_midi_event_free(struct snd_midi_event *dev)
 127 {
 128         if (dev != NULL) {
 129                 kfree(dev->buf);
 130                 kfree(dev);
 131         }
 132 }
 133 EXPORT_SYMBOL(snd_midi_event_free);
 134 
 135 /*
 136  * initialize record
 137  */
 138 static inline void reset_encode(struct snd_midi_event *dev)
 139 {
 140         dev->read = 0;
 141         dev->qlen = 0;
 142         dev->type = ST_INVALID;
 143 }
 144 
 145 void snd_midi_event_reset_encode(struct snd_midi_event *dev)
 146 {
 147         unsigned long flags;
 148 
 149         spin_lock_irqsave(&dev->lock, flags);
 150         reset_encode(dev);
 151         spin_unlock_irqrestore(&dev->lock, flags);
 152 }
 153 EXPORT_SYMBOL(snd_midi_event_reset_encode);
 154 
 155 void snd_midi_event_reset_decode(struct snd_midi_event *dev)
 156 {
 157         unsigned long flags;
 158 
 159         spin_lock_irqsave(&dev->lock, flags);
 160         dev->lastcmd = 0xff;
 161         spin_unlock_irqrestore(&dev->lock, flags);
 162 }
 163 EXPORT_SYMBOL(snd_midi_event_reset_decode);
 164 
 165 void snd_midi_event_no_status(struct snd_midi_event *dev, int on)
 166 {
 167         dev->nostat = on ? 1 : 0;
 168 }
 169 EXPORT_SYMBOL(snd_midi_event_no_status);
 170 
 171 /*
 172  *  read one byte and encode to sequencer event:
 173  *  return true if MIDI bytes are encoded to an event
 174  *         false data is not finished
 175  */
 176 bool snd_midi_event_encode_byte(struct snd_midi_event *dev, unsigned char c,
 177                                 struct snd_seq_event *ev)
 178 {
 179         bool rc = false;
 180         unsigned long flags;
 181 
 182         if (c >= MIDI_CMD_COMMON_CLOCK) {
 183                 /* real-time event */
 184                 ev->type = status_event[ST_SPECIAL + c - 0xf0].event;
 185                 ev->flags &= ~SNDRV_SEQ_EVENT_LENGTH_MASK;
 186                 ev->flags |= SNDRV_SEQ_EVENT_LENGTH_FIXED;
 187                 return ev->type != SNDRV_SEQ_EVENT_NONE;
 188         }
 189 
 190         spin_lock_irqsave(&dev->lock, flags);
 191         if ((c & 0x80) &&
 192             (c != MIDI_CMD_COMMON_SYSEX_END || dev->type != ST_SYSEX)) {
 193                 /* new command */
 194                 dev->buf[0] = c;
 195                 if ((c & 0xf0) == 0xf0) /* system messages */
 196                         dev->type = (c & 0x0f) + ST_SPECIAL;
 197                 else
 198                         dev->type = (c >> 4) & 0x07;
 199                 dev->read = 1;
 200                 dev->qlen = status_event[dev->type].qlen;
 201         } else {
 202                 if (dev->qlen > 0) {
 203                         /* rest of command */
 204                         dev->buf[dev->read++] = c;
 205                         if (dev->type != ST_SYSEX)
 206                                 dev->qlen--;
 207                 } else {
 208                         /* running status */
 209                         dev->buf[1] = c;
 210                         dev->qlen = status_event[dev->type].qlen - 1;
 211                         dev->read = 2;
 212                 }
 213         }
 214         if (dev->qlen == 0) {
 215                 ev->type = status_event[dev->type].event;
 216                 ev->flags &= ~SNDRV_SEQ_EVENT_LENGTH_MASK;
 217                 ev->flags |= SNDRV_SEQ_EVENT_LENGTH_FIXED;
 218                 if (status_event[dev->type].encode) /* set data values */
 219                         status_event[dev->type].encode(dev, ev);
 220                 if (dev->type >= ST_SPECIAL)
 221                         dev->type = ST_INVALID;
 222                 rc = true;
 223         } else  if (dev->type == ST_SYSEX) {
 224                 if (c == MIDI_CMD_COMMON_SYSEX_END ||
 225                     dev->read >= dev->bufsize) {
 226                         ev->flags &= ~SNDRV_SEQ_EVENT_LENGTH_MASK;
 227                         ev->flags |= SNDRV_SEQ_EVENT_LENGTH_VARIABLE;
 228                         ev->type = SNDRV_SEQ_EVENT_SYSEX;
 229                         ev->data.ext.len = dev->read;
 230                         ev->data.ext.ptr = dev->buf;
 231                         if (c != MIDI_CMD_COMMON_SYSEX_END)
 232                                 dev->read = 0; /* continue to parse */
 233                         else
 234                                 reset_encode(dev); /* all parsed */
 235                         rc = true;
 236                 }
 237         }
 238 
 239         spin_unlock_irqrestore(&dev->lock, flags);
 240         return rc;
 241 }
 242 EXPORT_SYMBOL(snd_midi_event_encode_byte);
 243 
 244 /* encode note event */
 245 static void note_event(struct snd_midi_event *dev, struct snd_seq_event *ev)
 246 {
 247         ev->data.note.channel = dev->buf[0] & 0x0f;
 248         ev->data.note.note = dev->buf[1];
 249         ev->data.note.velocity = dev->buf[2];
 250 }
 251 
 252 /* encode one parameter controls */
 253 static void one_param_ctrl_event(struct snd_midi_event *dev, struct snd_seq_event *ev)
 254 {
 255         ev->data.control.channel = dev->buf[0] & 0x0f;
 256         ev->data.control.value = dev->buf[1];
 257 }
 258 
 259 /* encode pitch wheel change */
 260 static void pitchbend_ctrl_event(struct snd_midi_event *dev, struct snd_seq_event *ev)
 261 {
 262         ev->data.control.channel = dev->buf[0] & 0x0f;
 263         ev->data.control.value = (int)dev->buf[2] * 128 + (int)dev->buf[1] - 8192;
 264 }
 265 
 266 /* encode midi control change */
 267 static void two_param_ctrl_event(struct snd_midi_event *dev, struct snd_seq_event *ev)
 268 {
 269         ev->data.control.channel = dev->buf[0] & 0x0f;
 270         ev->data.control.param = dev->buf[1];
 271         ev->data.control.value = dev->buf[2];
 272 }
 273 
 274 /* encode one parameter value*/
 275 static void one_param_event(struct snd_midi_event *dev, struct snd_seq_event *ev)
 276 {
 277         ev->data.control.value = dev->buf[1];
 278 }
 279 
 280 /* encode song position */
 281 static void songpos_event(struct snd_midi_event *dev, struct snd_seq_event *ev)
 282 {
 283         ev->data.control.value = (int)dev->buf[2] * 128 + (int)dev->buf[1];
 284 }
 285 
 286 /*
 287  * decode from a sequencer event to midi bytes
 288  * return the size of decoded midi events
 289  */
 290 long snd_midi_event_decode(struct snd_midi_event *dev, unsigned char *buf, long count,
 291                            struct snd_seq_event *ev)
 292 {
 293         unsigned int cmd, type;
 294 
 295         if (ev->type == SNDRV_SEQ_EVENT_NONE)
 296                 return -ENOENT;
 297 
 298         for (type = 0; type < ARRAY_SIZE(status_event); type++) {
 299                 if (ev->type == status_event[type].event)
 300                         goto __found;
 301         }
 302         for (type = 0; type < ARRAY_SIZE(extra_event); type++) {
 303                 if (ev->type == extra_event[type].event)
 304                         return extra_event[type].decode(dev, buf, count, ev);
 305         }
 306         return -ENOENT;
 307 
 308       __found:
 309         if (type >= ST_SPECIAL)
 310                 cmd = 0xf0 + (type - ST_SPECIAL);
 311         else
 312                 /* data.note.channel and data.control.channel is identical */
 313                 cmd = 0x80 | (type << 4) | (ev->data.note.channel & 0x0f);
 314 
 315 
 316         if (cmd == MIDI_CMD_COMMON_SYSEX) {
 317                 snd_midi_event_reset_decode(dev);
 318                 return snd_seq_expand_var_event(ev, count, buf, 1, 0);
 319         } else {
 320                 int qlen;
 321                 unsigned char xbuf[4];
 322                 unsigned long flags;
 323 
 324                 spin_lock_irqsave(&dev->lock, flags);
 325                 if ((cmd & 0xf0) == 0xf0 || dev->lastcmd != cmd || dev->nostat) {
 326                         dev->lastcmd = cmd;
 327                         spin_unlock_irqrestore(&dev->lock, flags);
 328                         xbuf[0] = cmd;
 329                         if (status_event[type].decode)
 330                                 status_event[type].decode(ev, xbuf + 1);
 331                         qlen = status_event[type].qlen + 1;
 332                 } else {
 333                         spin_unlock_irqrestore(&dev->lock, flags);
 334                         if (status_event[type].decode)
 335                                 status_event[type].decode(ev, xbuf + 0);
 336                         qlen = status_event[type].qlen;
 337                 }
 338                 if (count < qlen)
 339                         return -ENOMEM;
 340                 memcpy(buf, xbuf, qlen);
 341                 return qlen;
 342         }
 343 }
 344 EXPORT_SYMBOL(snd_midi_event_decode);
 345 
 346 
 347 /* decode note event */
 348 static void note_decode(struct snd_seq_event *ev, unsigned char *buf)
 349 {
 350         buf[0] = ev->data.note.note & 0x7f;
 351         buf[1] = ev->data.note.velocity & 0x7f;
 352 }
 353 
 354 /* decode one parameter controls */
 355 static void one_param_decode(struct snd_seq_event *ev, unsigned char *buf)
 356 {
 357         buf[0] = ev->data.control.value & 0x7f;
 358 }
 359 
 360 /* decode pitch wheel change */
 361 static void pitchbend_decode(struct snd_seq_event *ev, unsigned char *buf)
 362 {
 363         int value = ev->data.control.value + 8192;
 364         buf[0] = value & 0x7f;
 365         buf[1] = (value >> 7) & 0x7f;
 366 }
 367 
 368 /* decode midi control change */
 369 static void two_param_decode(struct snd_seq_event *ev, unsigned char *buf)
 370 {
 371         buf[0] = ev->data.control.param & 0x7f;
 372         buf[1] = ev->data.control.value & 0x7f;
 373 }
 374 
 375 /* decode song position */
 376 static void songpos_decode(struct snd_seq_event *ev, unsigned char *buf)
 377 {
 378         buf[0] = ev->data.control.value & 0x7f;
 379         buf[1] = (ev->data.control.value >> 7) & 0x7f;
 380 }
 381 
 382 /* decode 14bit control */
 383 static int extra_decode_ctrl14(struct snd_midi_event *dev, unsigned char *buf,
 384                                int count, struct snd_seq_event *ev)
 385 {
 386         unsigned char cmd;
 387         int idx = 0;
 388 
 389         cmd = MIDI_CMD_CONTROL|(ev->data.control.channel & 0x0f);
 390         if (ev->data.control.param < 0x20) {
 391                 if (count < 4)
 392                         return -ENOMEM;
 393                 if (dev->nostat && count < 6)
 394                         return -ENOMEM;
 395                 if (cmd != dev->lastcmd || dev->nostat) {
 396                         if (count < 5)
 397                                 return -ENOMEM;
 398                         buf[idx++] = dev->lastcmd = cmd;
 399                 }
 400                 buf[idx++] = ev->data.control.param;
 401                 buf[idx++] = (ev->data.control.value >> 7) & 0x7f;
 402                 if (dev->nostat)
 403                         buf[idx++] = cmd;
 404                 buf[idx++] = ev->data.control.param + 0x20;
 405                 buf[idx++] = ev->data.control.value & 0x7f;
 406         } else {
 407                 if (count < 2)
 408                         return -ENOMEM;
 409                 if (cmd != dev->lastcmd || dev->nostat) {
 410                         if (count < 3)
 411                                 return -ENOMEM;
 412                         buf[idx++] = dev->lastcmd = cmd;
 413                 }
 414                 buf[idx++] = ev->data.control.param & 0x7f;
 415                 buf[idx++] = ev->data.control.value & 0x7f;
 416         }
 417         return idx;
 418 }
 419 
 420 /* decode reg/nonreg param */
 421 static int extra_decode_xrpn(struct snd_midi_event *dev, unsigned char *buf,
 422                              int count, struct snd_seq_event *ev)
 423 {
 424         unsigned char cmd;
 425         char *cbytes;
 426         static char cbytes_nrpn[4] = { MIDI_CTL_NONREG_PARM_NUM_MSB,
 427                                        MIDI_CTL_NONREG_PARM_NUM_LSB,
 428                                        MIDI_CTL_MSB_DATA_ENTRY,
 429                                        MIDI_CTL_LSB_DATA_ENTRY };
 430         static char cbytes_rpn[4] =  { MIDI_CTL_REGIST_PARM_NUM_MSB,
 431                                        MIDI_CTL_REGIST_PARM_NUM_LSB,
 432                                        MIDI_CTL_MSB_DATA_ENTRY,
 433                                        MIDI_CTL_LSB_DATA_ENTRY };
 434         unsigned char bytes[4];
 435         int idx = 0, i;
 436 
 437         if (count < 8)
 438                 return -ENOMEM;
 439         if (dev->nostat && count < 12)
 440                 return -ENOMEM;
 441         cmd = MIDI_CMD_CONTROL|(ev->data.control.channel & 0x0f);
 442         bytes[0] = (ev->data.control.param & 0x3f80) >> 7;
 443         bytes[1] = ev->data.control.param & 0x007f;
 444         bytes[2] = (ev->data.control.value & 0x3f80) >> 7;
 445         bytes[3] = ev->data.control.value & 0x007f;
 446         if (cmd != dev->lastcmd && !dev->nostat) {
 447                 if (count < 9)
 448                         return -ENOMEM;
 449                 buf[idx++] = dev->lastcmd = cmd;
 450         }
 451         cbytes = ev->type == SNDRV_SEQ_EVENT_NONREGPARAM ? cbytes_nrpn : cbytes_rpn;
 452         for (i = 0; i < 4; i++) {
 453                 if (dev->nostat)
 454                         buf[idx++] = dev->lastcmd = cmd;
 455                 buf[idx++] = cbytes[i];
 456                 buf[idx++] = bytes[i];
 457         }
 458         return idx;
 459 }

/* [<][>][^][v][top][bottom][index][help] */