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