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 const char *cbytes; 426 static const 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 const 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 } 460