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}
 137
 138void snd_midi_event_free(struct snd_midi_event *dev)
 139{
 140        if (dev != NULL) {
 141                kfree(dev->buf);
 142                kfree(dev);
 143        }
 144}
 145
 146/*
 147 * initialize record
 148 */
 149static inline void reset_encode(struct snd_midi_event *dev)
 150{
 151        dev->read = 0;
 152        dev->qlen = 0;
 153        dev->type = ST_INVALID;
 154}
 155
 156void snd_midi_event_reset_encode(struct snd_midi_event *dev)
 157{
 158        unsigned long flags;
 159
 160        spin_lock_irqsave(&dev->lock, flags);
 161        reset_encode(dev);
 162        spin_unlock_irqrestore(&dev->lock, flags);
 163}
 164
 165void snd_midi_event_reset_decode(struct snd_midi_event *dev)
 166{
 167        unsigned long flags;
 168
 169        spin_lock_irqsave(&dev->lock, flags);
 170        dev->lastcmd = 0xff;
 171        spin_unlock_irqrestore(&dev->lock, flags);
 172}
 173
 174#if 0
 175void snd_midi_event_init(struct snd_midi_event *dev)
 176{
 177        snd_midi_event_reset_encode(dev);
 178        snd_midi_event_reset_decode(dev);
 179}
 180#endif  /*  0  */
 181
 182void snd_midi_event_no_status(struct snd_midi_event *dev, int on)
 183{
 184        dev->nostat = on ? 1 : 0;
 185}
 186
 187/*
 188 * resize buffer
 189 */
 190#if 0
 191int snd_midi_event_resize_buffer(struct snd_midi_event *dev, int bufsize)
 192{
 193        unsigned char *new_buf, *old_buf;
 194        unsigned long flags;
 195
 196        if (bufsize == dev->bufsize)
 197                return 0;
 198        new_buf = kmalloc(bufsize, GFP_KERNEL);
 199        if (new_buf == NULL)
 200                return -ENOMEM;
 201        spin_lock_irqsave(&dev->lock, flags);
 202        old_buf = dev->buf;
 203        dev->buf = new_buf;
 204        dev->bufsize = bufsize;
 205        reset_encode(dev);
 206        spin_unlock_irqrestore(&dev->lock, flags);
 207        kfree(old_buf);
 208        return 0;
 209}
 210#endif  /*  0  */
 211
 212/*
 213 *  read bytes and encode to sequencer event if finished
 214 *  return the size of encoded bytes
 215 */
 216long snd_midi_event_encode(struct snd_midi_event *dev, unsigned char *buf, long count,
 217                           struct snd_seq_event *ev)
 218{
 219        long result = 0;
 220        int rc;
 221
 222        ev->type = SNDRV_SEQ_EVENT_NONE;
 223
 224        while (count-- > 0) {
 225                rc = snd_midi_event_encode_byte(dev, *buf++, ev);
 226                result++;
 227                if (rc < 0)
 228                        return rc;
 229                else if (rc > 0)
 230                        return result;
 231        }
 232
 233        return result;
 234}
 235
 236/*
 237 *  read one byte and encode to sequencer event:
 238 *  return 1 if MIDI bytes are encoded to an event
 239 *         0 data is not finished
 240 *         negative for error
 241 */
 242int snd_midi_event_encode_byte(struct snd_midi_event *dev, int c,
 243                               struct snd_seq_event *ev)
 244{
 245        int rc = 0;
 246        unsigned long flags;
 247
 248        c &= 0xff;
 249
 250        if (c >= MIDI_CMD_COMMON_CLOCK) {
 251                /* real-time event */
 252                ev->type = status_event[ST_SPECIAL + c - 0xf0].event;
 253                ev->flags &= ~SNDRV_SEQ_EVENT_LENGTH_MASK;
 254                ev->flags |= SNDRV_SEQ_EVENT_LENGTH_FIXED;
 255                return ev->type != SNDRV_SEQ_EVENT_NONE;
 256        }
 257
 258        spin_lock_irqsave(&dev->lock, flags);
 259        if ((c & 0x80) &&
 260            (c != MIDI_CMD_COMMON_SYSEX_END || dev->type != ST_SYSEX)) {
 261                /* new command */
 262                dev->buf[0] = c;
 263                if ((c & 0xf0) == 0xf0) /* system messages */
 264                        dev->type = (c & 0x0f) + ST_SPECIAL;
 265                else
 266                        dev->type = (c >> 4) & 0x07;
 267                dev->read = 1;
 268                dev->qlen = status_event[dev->type].qlen;
 269        } else {
 270                if (dev->qlen > 0) {
 271                        /* rest of command */
 272                        dev->buf[dev->read++] = c;
 273                        if (dev->type != ST_SYSEX)
 274                                dev->qlen--;
 275                } else {
 276                        /* running status */
 277                        dev->buf[1] = c;
 278                        dev->qlen = status_event[dev->type].qlen - 1;
 279                        dev->read = 2;
 280                }
 281        }
 282        if (dev->qlen == 0) {
 283                ev->type = status_event[dev->type].event;
 284                ev->flags &= ~SNDRV_SEQ_EVENT_LENGTH_MASK;
 285                ev->flags |= SNDRV_SEQ_EVENT_LENGTH_FIXED;
 286                if (status_event[dev->type].encode) /* set data values */
 287                        status_event[dev->type].encode(dev, ev);
 288                if (dev->type >= ST_SPECIAL)
 289                        dev->type = ST_INVALID;
 290                rc = 1;
 291        } else  if (dev->type == ST_SYSEX) {
 292                if (c == MIDI_CMD_COMMON_SYSEX_END ||
 293                    dev->read >= dev->bufsize) {
 294                        ev->flags &= ~SNDRV_SEQ_EVENT_LENGTH_MASK;
 295                        ev->flags |= SNDRV_SEQ_EVENT_LENGTH_VARIABLE;
 296                        ev->type = SNDRV_SEQ_EVENT_SYSEX;
 297                        ev->data.ext.len = dev->read;
 298                        ev->data.ext.ptr = dev->buf;
 299                        if (c != MIDI_CMD_COMMON_SYSEX_END)
 300                                dev->read = 0; /* continue to parse */
 301                        else
 302                                reset_encode(dev); /* all parsed */
 303                        rc = 1;
 304                }
 305        }
 306
 307        spin_unlock_irqrestore(&dev->lock, flags);
 308        return rc;
 309}
 310
 311/* encode note event */
 312static void note_event(struct snd_midi_event *dev, struct snd_seq_event *ev)
 313{
 314        ev->data.note.channel = dev->buf[0] & 0x0f;
 315        ev->data.note.note = dev->buf[1];
 316        ev->data.note.velocity = dev->buf[2];
 317}
 318
 319/* encode one parameter controls */
 320static void one_param_ctrl_event(struct snd_midi_event *dev, struct snd_seq_event *ev)
 321{
 322        ev->data.control.channel = dev->buf[0] & 0x0f;
 323        ev->data.control.value = dev->buf[1];
 324}
 325
 326/* encode pitch wheel change */
 327static void pitchbend_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 = (int)dev->buf[2] * 128 + (int)dev->buf[1] - 8192;
 331}
 332
 333/* encode midi control change */
 334static void two_param_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.param = dev->buf[1];
 338        ev->data.control.value = dev->buf[2];
 339}
 340
 341/* encode one parameter value*/
 342static void one_param_event(struct snd_midi_event *dev, struct snd_seq_event *ev)
 343{
 344        ev->data.control.value = dev->buf[1];
 345}
 346
 347/* encode song position */
 348static void songpos_event(struct snd_midi_event *dev, struct snd_seq_event *ev)
 349{
 350        ev->data.control.value = (int)dev->buf[2] * 128 + (int)dev->buf[1];
 351}
 352
 353/*
 354 * decode from a sequencer event to midi bytes
 355 * return the size of decoded midi events
 356 */
 357long snd_midi_event_decode(struct snd_midi_event *dev, unsigned char *buf, long count,
 358                           struct snd_seq_event *ev)
 359{
 360        unsigned int cmd, type;
 361
 362        if (ev->type == SNDRV_SEQ_EVENT_NONE)
 363                return -ENOENT;
 364
 365        for (type = 0; type < ARRAY_SIZE(status_event); type++) {
 366                if (ev->type == status_event[type].event)
 367                        goto __found;
 368        }
 369        for (type = 0; type < ARRAY_SIZE(extra_event); type++) {
 370                if (ev->type == extra_event[type].event)
 371                        return extra_event[type].decode(dev, buf, count, ev);
 372        }
 373        return -ENOENT;
 374
 375      __found:
 376        if (type >= ST_SPECIAL)
 377                cmd = 0xf0 + (type - ST_SPECIAL);
 378        else
 379                /* data.note.channel and data.control.channel is identical */
 380                cmd = 0x80 | (type << 4) | (ev->data.note.channel & 0x0f);
 381
 382
 383        if (cmd == MIDI_CMD_COMMON_SYSEX) {
 384                snd_midi_event_reset_decode(dev);
 385                return snd_seq_expand_var_event(ev, count, buf, 1, 0);
 386        } else {
 387                int qlen;
 388                unsigned char xbuf[4];
 389                unsigned long flags;
 390
 391                spin_lock_irqsave(&dev->lock, flags);
 392                if ((cmd & 0xf0) == 0xf0 || dev->lastcmd != cmd || dev->nostat) {
 393                        dev->lastcmd = cmd;
 394                        spin_unlock_irqrestore(&dev->lock, flags);
 395                        xbuf[0] = cmd;
 396                        if (status_event[type].decode)
 397                                status_event[type].decode(ev, xbuf + 1);
 398                        qlen = status_event[type].qlen + 1;
 399                } else {
 400                        spin_unlock_irqrestore(&dev->lock, flags);
 401                        if (status_event[type].decode)
 402                                status_event[type].decode(ev, xbuf + 0);
 403                        qlen = status_event[type].qlen;
 404                }
 405                if (count < qlen)
 406                        return -ENOMEM;
 407                memcpy(buf, xbuf, qlen);
 408                return qlen;
 409        }
 410}
 411
 412
 413/* decode note event */
 414static void note_decode(struct snd_seq_event *ev, unsigned char *buf)
 415{
 416        buf[0] = ev->data.note.note & 0x7f;
 417        buf[1] = ev->data.note.velocity & 0x7f;
 418}
 419
 420/* decode one parameter controls */
 421static void one_param_decode(struct snd_seq_event *ev, unsigned char *buf)
 422{
 423        buf[0] = ev->data.control.value & 0x7f;
 424}
 425
 426/* decode pitch wheel change */
 427static void pitchbend_decode(struct snd_seq_event *ev, unsigned char *buf)
 428{
 429        int value = ev->data.control.value + 8192;
 430        buf[0] = value & 0x7f;
 431        buf[1] = (value >> 7) & 0x7f;
 432}
 433
 434/* decode midi control change */
 435static void two_param_decode(struct snd_seq_event *ev, unsigned char *buf)
 436{
 437        buf[0] = ev->data.control.param & 0x7f;
 438        buf[1] = ev->data.control.value & 0x7f;
 439}
 440
 441/* decode song position */
 442static void songpos_decode(struct snd_seq_event *ev, unsigned char *buf)
 443{
 444        buf[0] = ev->data.control.value & 0x7f;
 445        buf[1] = (ev->data.control.value >> 7) & 0x7f;
 446}
 447
 448/* decode 14bit control */
 449static int extra_decode_ctrl14(struct snd_midi_event *dev, unsigned char *buf,
 450                               int count, struct snd_seq_event *ev)
 451{
 452        unsigned char cmd;
 453        int idx = 0;
 454
 455        cmd = MIDI_CMD_CONTROL|(ev->data.control.channel & 0x0f);
 456        if (ev->data.control.param < 0x20) {
 457                if (count < 4)
 458                        return -ENOMEM;
 459                if (dev->nostat && count < 6)
 460                        return -ENOMEM;
 461                if (cmd != dev->lastcmd || dev->nostat) {
 462                        if (count < 5)
 463                                return -ENOMEM;
 464                        buf[idx++] = dev->lastcmd = cmd;
 465                }
 466                buf[idx++] = ev->data.control.param;
 467                buf[idx++] = (ev->data.control.value >> 7) & 0x7f;
 468                if (dev->nostat)
 469                        buf[idx++] = cmd;
 470                buf[idx++] = ev->data.control.param + 0x20;
 471                buf[idx++] = ev->data.control.value & 0x7f;
 472        } else {
 473                if (count < 2)
 474                        return -ENOMEM;
 475                if (cmd != dev->lastcmd || dev->nostat) {
 476                        if (count < 3)
 477                                return -ENOMEM;
 478                        buf[idx++] = dev->lastcmd = cmd;
 479                }
 480                buf[idx++] = ev->data.control.param & 0x7f;
 481                buf[idx++] = ev->data.control.value & 0x7f;
 482        }
 483        return idx;
 484}
 485
 486/* decode reg/nonreg param */
 487static int extra_decode_xrpn(struct snd_midi_event *dev, unsigned char *buf,
 488                             int count, struct snd_seq_event *ev)
 489{
 490        unsigned char cmd;
 491        char *cbytes;
 492        static char cbytes_nrpn[4] = { MIDI_CTL_NONREG_PARM_NUM_MSB,
 493                                       MIDI_CTL_NONREG_PARM_NUM_LSB,
 494                                       MIDI_CTL_MSB_DATA_ENTRY,
 495                                       MIDI_CTL_LSB_DATA_ENTRY };
 496        static char cbytes_rpn[4] =  { MIDI_CTL_REGIST_PARM_NUM_MSB,
 497                                       MIDI_CTL_REGIST_PARM_NUM_LSB,
 498                                       MIDI_CTL_MSB_DATA_ENTRY,
 499                                       MIDI_CTL_LSB_DATA_ENTRY };
 500        unsigned char bytes[4];
 501        int idx = 0, i;
 502
 503        if (count < 8)
 504                return -ENOMEM;
 505        if (dev->nostat && count < 12)
 506                return -ENOMEM;
 507        cmd = MIDI_CMD_CONTROL|(ev->data.control.channel & 0x0f);
 508        bytes[0] = (ev->data.control.param & 0x3f80) >> 7;
 509        bytes[1] = ev->data.control.param & 0x007f;
 510        bytes[2] = (ev->data.control.value & 0x3f80) >> 7;
 511        bytes[3] = ev->data.control.value & 0x007f;
 512        if (cmd != dev->lastcmd && !dev->nostat) {
 513                if (count < 9)
 514                        return -ENOMEM;
 515                buf[idx++] = dev->lastcmd = cmd;
 516        }
 517        cbytes = ev->type == SNDRV_SEQ_EVENT_NONREGPARAM ? cbytes_nrpn : cbytes_rpn;
 518        for (i = 0; i < 4; i++) {
 519                if (dev->nostat)
 520                        buf[idx++] = dev->lastcmd = cmd;
 521                buf[idx++] = cbytes[i];
 522                buf[idx++] = bytes[i];
 523        }
 524        return idx;
 525}
 526
 527/*
 528 *  exports
 529 */
 530 
 531EXPORT_SYMBOL(snd_midi_event_new);
 532EXPORT_SYMBOL(snd_midi_event_free);
 533EXPORT_SYMBOL(snd_midi_event_reset_encode);
 534EXPORT_SYMBOL(snd_midi_event_reset_decode);
 535EXPORT_SYMBOL(snd_midi_event_no_status);
 536EXPORT_SYMBOL(snd_midi_event_encode);
 537EXPORT_SYMBOL(snd_midi_event_encode_byte);
 538EXPORT_SYMBOL(snd_midi_event_decode);
 539
 540static int __init alsa_seq_midi_event_init(void)
 541{
 542        return 0;
 543}
 544
 545static void __exit alsa_seq_midi_event_exit(void)
 546{
 547}
 548
 549module_init(alsa_seq_midi_event_init)
 550module_exit(alsa_seq_midi_event_exit)
 551