0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/slab.h>
0010 #include <linux/errno.h>
0011 #include <linux/string.h>
0012 #include <linux/module.h>
0013 #include <sound/core.h>
0014 #include <sound/seq_kernel.h>
0015 #include <sound/seq_midi_event.h>
0016 #include <sound/asoundef.h>
0017
0018 MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>, Jaroslav Kysela <perex@perex.cz>");
0019 MODULE_DESCRIPTION("MIDI byte <-> sequencer event coder");
0020 MODULE_LICENSE("GPL");
0021
0022
0023
0024 #define ST_INVALID 7
0025 #define ST_SPECIAL 8
0026 #define ST_SYSEX ST_SPECIAL
0027
0028
0029
0030
0031
0032
0033 static void note_event(struct snd_midi_event *dev, struct snd_seq_event *ev);
0034 static void one_param_ctrl_event(struct snd_midi_event *dev, struct snd_seq_event *ev);
0035 static void pitchbend_ctrl_event(struct snd_midi_event *dev, struct snd_seq_event *ev);
0036 static void two_param_ctrl_event(struct snd_midi_event *dev, struct snd_seq_event *ev);
0037 static void one_param_event(struct snd_midi_event *dev, struct snd_seq_event *ev);
0038 static void songpos_event(struct snd_midi_event *dev, struct snd_seq_event *ev);
0039 static void note_decode(struct snd_seq_event *ev, unsigned char *buf);
0040 static void one_param_decode(struct snd_seq_event *ev, unsigned char *buf);
0041 static void pitchbend_decode(struct snd_seq_event *ev, unsigned char *buf);
0042 static void two_param_decode(struct snd_seq_event *ev, unsigned char *buf);
0043 static void songpos_decode(struct snd_seq_event *ev, unsigned char *buf);
0044
0045
0046
0047
0048 static struct status_event_list {
0049 int event;
0050 int qlen;
0051 void (*encode)(struct snd_midi_event *dev, struct snd_seq_event *ev);
0052 void (*decode)(struct snd_seq_event *ev, unsigned char *buf);
0053 } status_event[] = {
0054
0055 {SNDRV_SEQ_EVENT_NOTEOFF, 2, note_event, note_decode},
0056 {SNDRV_SEQ_EVENT_NOTEON, 2, note_event, note_decode},
0057 {SNDRV_SEQ_EVENT_KEYPRESS, 2, note_event, note_decode},
0058 {SNDRV_SEQ_EVENT_CONTROLLER, 2, two_param_ctrl_event, two_param_decode},
0059 {SNDRV_SEQ_EVENT_PGMCHANGE, 1, one_param_ctrl_event, one_param_decode},
0060 {SNDRV_SEQ_EVENT_CHANPRESS, 1, one_param_ctrl_event, one_param_decode},
0061 {SNDRV_SEQ_EVENT_PITCHBEND, 2, pitchbend_ctrl_event, pitchbend_decode},
0062
0063 {SNDRV_SEQ_EVENT_NONE, -1, NULL, NULL},
0064
0065 {SNDRV_SEQ_EVENT_SYSEX, 1, NULL, NULL},
0066 {SNDRV_SEQ_EVENT_QFRAME, 1, one_param_event, one_param_decode},
0067 {SNDRV_SEQ_EVENT_SONGPOS, 2, songpos_event, songpos_decode},
0068 {SNDRV_SEQ_EVENT_SONGSEL, 1, one_param_event, one_param_decode},
0069 {SNDRV_SEQ_EVENT_NONE, -1, NULL, NULL},
0070 {SNDRV_SEQ_EVENT_NONE, -1, NULL, NULL},
0071 {SNDRV_SEQ_EVENT_TUNE_REQUEST, 0, NULL, NULL},
0072 {SNDRV_SEQ_EVENT_NONE, -1, NULL, NULL},
0073 {SNDRV_SEQ_EVENT_CLOCK, 0, NULL, NULL},
0074 {SNDRV_SEQ_EVENT_NONE, -1, NULL, NULL},
0075 {SNDRV_SEQ_EVENT_START, 0, NULL, NULL},
0076 {SNDRV_SEQ_EVENT_CONTINUE, 0, NULL, NULL},
0077 {SNDRV_SEQ_EVENT_STOP, 0, NULL, NULL},
0078 {SNDRV_SEQ_EVENT_NONE, -1, NULL, NULL},
0079 {SNDRV_SEQ_EVENT_SENSING, 0, NULL, NULL},
0080 {SNDRV_SEQ_EVENT_RESET, 0, NULL, NULL},
0081 };
0082
0083 static int extra_decode_ctrl14(struct snd_midi_event *dev, unsigned char *buf, int len,
0084 struct snd_seq_event *ev);
0085 static int extra_decode_xrpn(struct snd_midi_event *dev, unsigned char *buf, int count,
0086 struct snd_seq_event *ev);
0087
0088 static struct extra_event_list {
0089 int event;
0090 int (*decode)(struct snd_midi_event *dev, unsigned char *buf, int len,
0091 struct snd_seq_event *ev);
0092 } extra_event[] = {
0093 {SNDRV_SEQ_EVENT_CONTROL14, extra_decode_ctrl14},
0094 {SNDRV_SEQ_EVENT_NONREGPARAM, extra_decode_xrpn},
0095 {SNDRV_SEQ_EVENT_REGPARAM, extra_decode_xrpn},
0096 };
0097
0098
0099
0100
0101
0102 int snd_midi_event_new(int bufsize, struct snd_midi_event **rdev)
0103 {
0104 struct snd_midi_event *dev;
0105
0106 *rdev = NULL;
0107 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
0108 if (dev == NULL)
0109 return -ENOMEM;
0110 if (bufsize > 0) {
0111 dev->buf = kmalloc(bufsize, GFP_KERNEL);
0112 if (dev->buf == NULL) {
0113 kfree(dev);
0114 return -ENOMEM;
0115 }
0116 }
0117 dev->bufsize = bufsize;
0118 dev->lastcmd = 0xff;
0119 dev->type = ST_INVALID;
0120 spin_lock_init(&dev->lock);
0121 *rdev = dev;
0122 return 0;
0123 }
0124 EXPORT_SYMBOL(snd_midi_event_new);
0125
0126 void snd_midi_event_free(struct snd_midi_event *dev)
0127 {
0128 if (dev != NULL) {
0129 kfree(dev->buf);
0130 kfree(dev);
0131 }
0132 }
0133 EXPORT_SYMBOL(snd_midi_event_free);
0134
0135
0136
0137
0138 static inline void reset_encode(struct snd_midi_event *dev)
0139 {
0140 dev->read = 0;
0141 dev->qlen = 0;
0142 dev->type = ST_INVALID;
0143 }
0144
0145 void snd_midi_event_reset_encode(struct snd_midi_event *dev)
0146 {
0147 unsigned long flags;
0148
0149 spin_lock_irqsave(&dev->lock, flags);
0150 reset_encode(dev);
0151 spin_unlock_irqrestore(&dev->lock, flags);
0152 }
0153 EXPORT_SYMBOL(snd_midi_event_reset_encode);
0154
0155 void snd_midi_event_reset_decode(struct snd_midi_event *dev)
0156 {
0157 unsigned long flags;
0158
0159 spin_lock_irqsave(&dev->lock, flags);
0160 dev->lastcmd = 0xff;
0161 spin_unlock_irqrestore(&dev->lock, flags);
0162 }
0163 EXPORT_SYMBOL(snd_midi_event_reset_decode);
0164
0165 void snd_midi_event_no_status(struct snd_midi_event *dev, int on)
0166 {
0167 dev->nostat = on ? 1 : 0;
0168 }
0169 EXPORT_SYMBOL(snd_midi_event_no_status);
0170
0171
0172
0173
0174
0175
0176 bool snd_midi_event_encode_byte(struct snd_midi_event *dev, unsigned char c,
0177 struct snd_seq_event *ev)
0178 {
0179 bool rc = false;
0180 unsigned long flags;
0181
0182 if (c >= MIDI_CMD_COMMON_CLOCK) {
0183
0184 ev->type = status_event[ST_SPECIAL + c - 0xf0].event;
0185 ev->flags &= ~SNDRV_SEQ_EVENT_LENGTH_MASK;
0186 ev->flags |= SNDRV_SEQ_EVENT_LENGTH_FIXED;
0187 return ev->type != SNDRV_SEQ_EVENT_NONE;
0188 }
0189
0190 spin_lock_irqsave(&dev->lock, flags);
0191 if ((c & 0x80) &&
0192 (c != MIDI_CMD_COMMON_SYSEX_END || dev->type != ST_SYSEX)) {
0193
0194 dev->buf[0] = c;
0195 if ((c & 0xf0) == 0xf0)
0196 dev->type = (c & 0x0f) + ST_SPECIAL;
0197 else
0198 dev->type = (c >> 4) & 0x07;
0199 dev->read = 1;
0200 dev->qlen = status_event[dev->type].qlen;
0201 } else {
0202 if (dev->qlen > 0) {
0203
0204 dev->buf[dev->read++] = c;
0205 if (dev->type != ST_SYSEX)
0206 dev->qlen--;
0207 } else {
0208
0209 dev->buf[1] = c;
0210 dev->qlen = status_event[dev->type].qlen - 1;
0211 dev->read = 2;
0212 }
0213 }
0214 if (dev->qlen == 0) {
0215 ev->type = status_event[dev->type].event;
0216 ev->flags &= ~SNDRV_SEQ_EVENT_LENGTH_MASK;
0217 ev->flags |= SNDRV_SEQ_EVENT_LENGTH_FIXED;
0218 if (status_event[dev->type].encode)
0219 status_event[dev->type].encode(dev, ev);
0220 if (dev->type >= ST_SPECIAL)
0221 dev->type = ST_INVALID;
0222 rc = true;
0223 } else if (dev->type == ST_SYSEX) {
0224 if (c == MIDI_CMD_COMMON_SYSEX_END ||
0225 dev->read >= dev->bufsize) {
0226 ev->flags &= ~SNDRV_SEQ_EVENT_LENGTH_MASK;
0227 ev->flags |= SNDRV_SEQ_EVENT_LENGTH_VARIABLE;
0228 ev->type = SNDRV_SEQ_EVENT_SYSEX;
0229 ev->data.ext.len = dev->read;
0230 ev->data.ext.ptr = dev->buf;
0231 if (c != MIDI_CMD_COMMON_SYSEX_END)
0232 dev->read = 0;
0233 else
0234 reset_encode(dev);
0235 rc = true;
0236 }
0237 }
0238
0239 spin_unlock_irqrestore(&dev->lock, flags);
0240 return rc;
0241 }
0242 EXPORT_SYMBOL(snd_midi_event_encode_byte);
0243
0244
0245 static void note_event(struct snd_midi_event *dev, struct snd_seq_event *ev)
0246 {
0247 ev->data.note.channel = dev->buf[0] & 0x0f;
0248 ev->data.note.note = dev->buf[1];
0249 ev->data.note.velocity = dev->buf[2];
0250 }
0251
0252
0253 static void one_param_ctrl_event(struct snd_midi_event *dev, struct snd_seq_event *ev)
0254 {
0255 ev->data.control.channel = dev->buf[0] & 0x0f;
0256 ev->data.control.value = dev->buf[1];
0257 }
0258
0259
0260 static void pitchbend_ctrl_event(struct snd_midi_event *dev, struct snd_seq_event *ev)
0261 {
0262 ev->data.control.channel = dev->buf[0] & 0x0f;
0263 ev->data.control.value = (int)dev->buf[2] * 128 + (int)dev->buf[1] - 8192;
0264 }
0265
0266
0267 static void two_param_ctrl_event(struct snd_midi_event *dev, struct snd_seq_event *ev)
0268 {
0269 ev->data.control.channel = dev->buf[0] & 0x0f;
0270 ev->data.control.param = dev->buf[1];
0271 ev->data.control.value = dev->buf[2];
0272 }
0273
0274
0275 static void one_param_event(struct snd_midi_event *dev, struct snd_seq_event *ev)
0276 {
0277 ev->data.control.value = dev->buf[1];
0278 }
0279
0280
0281 static void songpos_event(struct snd_midi_event *dev, struct snd_seq_event *ev)
0282 {
0283 ev->data.control.value = (int)dev->buf[2] * 128 + (int)dev->buf[1];
0284 }
0285
0286
0287
0288
0289
0290 long snd_midi_event_decode(struct snd_midi_event *dev, unsigned char *buf, long count,
0291 struct snd_seq_event *ev)
0292 {
0293 unsigned int cmd, type;
0294
0295 if (ev->type == SNDRV_SEQ_EVENT_NONE)
0296 return -ENOENT;
0297
0298 for (type = 0; type < ARRAY_SIZE(status_event); type++) {
0299 if (ev->type == status_event[type].event)
0300 goto __found;
0301 }
0302 for (type = 0; type < ARRAY_SIZE(extra_event); type++) {
0303 if (ev->type == extra_event[type].event)
0304 return extra_event[type].decode(dev, buf, count, ev);
0305 }
0306 return -ENOENT;
0307
0308 __found:
0309 if (type >= ST_SPECIAL)
0310 cmd = 0xf0 + (type - ST_SPECIAL);
0311 else
0312
0313 cmd = 0x80 | (type << 4) | (ev->data.note.channel & 0x0f);
0314
0315
0316 if (cmd == MIDI_CMD_COMMON_SYSEX) {
0317 snd_midi_event_reset_decode(dev);
0318 return snd_seq_expand_var_event(ev, count, buf, 1, 0);
0319 } else {
0320 int qlen;
0321 unsigned char xbuf[4];
0322 unsigned long flags;
0323
0324 spin_lock_irqsave(&dev->lock, flags);
0325 if ((cmd & 0xf0) == 0xf0 || dev->lastcmd != cmd || dev->nostat) {
0326 dev->lastcmd = cmd;
0327 spin_unlock_irqrestore(&dev->lock, flags);
0328 xbuf[0] = cmd;
0329 if (status_event[type].decode)
0330 status_event[type].decode(ev, xbuf + 1);
0331 qlen = status_event[type].qlen + 1;
0332 } else {
0333 spin_unlock_irqrestore(&dev->lock, flags);
0334 if (status_event[type].decode)
0335 status_event[type].decode(ev, xbuf + 0);
0336 qlen = status_event[type].qlen;
0337 }
0338 if (count < qlen)
0339 return -ENOMEM;
0340 memcpy(buf, xbuf, qlen);
0341 return qlen;
0342 }
0343 }
0344 EXPORT_SYMBOL(snd_midi_event_decode);
0345
0346
0347
0348 static void note_decode(struct snd_seq_event *ev, unsigned char *buf)
0349 {
0350 buf[0] = ev->data.note.note & 0x7f;
0351 buf[1] = ev->data.note.velocity & 0x7f;
0352 }
0353
0354
0355 static void one_param_decode(struct snd_seq_event *ev, unsigned char *buf)
0356 {
0357 buf[0] = ev->data.control.value & 0x7f;
0358 }
0359
0360
0361 static void pitchbend_decode(struct snd_seq_event *ev, unsigned char *buf)
0362 {
0363 int value = ev->data.control.value + 8192;
0364 buf[0] = value & 0x7f;
0365 buf[1] = (value >> 7) & 0x7f;
0366 }
0367
0368
0369 static void two_param_decode(struct snd_seq_event *ev, unsigned char *buf)
0370 {
0371 buf[0] = ev->data.control.param & 0x7f;
0372 buf[1] = ev->data.control.value & 0x7f;
0373 }
0374
0375
0376 static void songpos_decode(struct snd_seq_event *ev, unsigned char *buf)
0377 {
0378 buf[0] = ev->data.control.value & 0x7f;
0379 buf[1] = (ev->data.control.value >> 7) & 0x7f;
0380 }
0381
0382
0383 static int extra_decode_ctrl14(struct snd_midi_event *dev, unsigned char *buf,
0384 int count, struct snd_seq_event *ev)
0385 {
0386 unsigned char cmd;
0387 int idx = 0;
0388
0389 cmd = MIDI_CMD_CONTROL|(ev->data.control.channel & 0x0f);
0390 if (ev->data.control.param < 0x20) {
0391 if (count < 4)
0392 return -ENOMEM;
0393 if (dev->nostat && count < 6)
0394 return -ENOMEM;
0395 if (cmd != dev->lastcmd || dev->nostat) {
0396 if (count < 5)
0397 return -ENOMEM;
0398 buf[idx++] = dev->lastcmd = cmd;
0399 }
0400 buf[idx++] = ev->data.control.param;
0401 buf[idx++] = (ev->data.control.value >> 7) & 0x7f;
0402 if (dev->nostat)
0403 buf[idx++] = cmd;
0404 buf[idx++] = ev->data.control.param + 0x20;
0405 buf[idx++] = ev->data.control.value & 0x7f;
0406 } else {
0407 if (count < 2)
0408 return -ENOMEM;
0409 if (cmd != dev->lastcmd || dev->nostat) {
0410 if (count < 3)
0411 return -ENOMEM;
0412 buf[idx++] = dev->lastcmd = cmd;
0413 }
0414 buf[idx++] = ev->data.control.param & 0x7f;
0415 buf[idx++] = ev->data.control.value & 0x7f;
0416 }
0417 return idx;
0418 }
0419
0420
0421 static int extra_decode_xrpn(struct snd_midi_event *dev, unsigned char *buf,
0422 int count, struct snd_seq_event *ev)
0423 {
0424 unsigned char cmd;
0425 const char *cbytes;
0426 static const char cbytes_nrpn[4] = { MIDI_CTL_NONREG_PARM_NUM_MSB,
0427 MIDI_CTL_NONREG_PARM_NUM_LSB,
0428 MIDI_CTL_MSB_DATA_ENTRY,
0429 MIDI_CTL_LSB_DATA_ENTRY };
0430 static const char cbytes_rpn[4] = { MIDI_CTL_REGIST_PARM_NUM_MSB,
0431 MIDI_CTL_REGIST_PARM_NUM_LSB,
0432 MIDI_CTL_MSB_DATA_ENTRY,
0433 MIDI_CTL_LSB_DATA_ENTRY };
0434 unsigned char bytes[4];
0435 int idx = 0, i;
0436
0437 if (count < 8)
0438 return -ENOMEM;
0439 if (dev->nostat && count < 12)
0440 return -ENOMEM;
0441 cmd = MIDI_CMD_CONTROL|(ev->data.control.channel & 0x0f);
0442 bytes[0] = (ev->data.control.param & 0x3f80) >> 7;
0443 bytes[1] = ev->data.control.param & 0x007f;
0444 bytes[2] = (ev->data.control.value & 0x3f80) >> 7;
0445 bytes[3] = ev->data.control.value & 0x007f;
0446 if (cmd != dev->lastcmd && !dev->nostat) {
0447 if (count < 9)
0448 return -ENOMEM;
0449 buf[idx++] = dev->lastcmd = cmd;
0450 }
0451 cbytes = ev->type == SNDRV_SEQ_EVENT_NONREGPARAM ? cbytes_nrpn : cbytes_rpn;
0452 for (i = 0; i < 4; i++) {
0453 if (dev->nostat)
0454 buf[idx++] = dev->lastcmd = cmd;
0455 buf[idx++] = cbytes[i];
0456 buf[idx++] = bytes[i];
0457 }
0458 return idx;
0459 }