1/*
2 *  MIDI byte <-> sequencer event coder
3 *
4 *  Copyright (C) 1998,99 Takashi Iwai <tiwai@suse.de>,
5 *                        Jaroslav Kysela <perex@suse.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 <sound/driver.h>
23#include <linux/slab.h>
24#include <linux/errno.h>
25#include <linux/string.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@suse.cz>");
32MODULE_DESCRIPTION("MIDI byte <-> sequencer event coder");
33MODULE_LICENSE("GPL");
34
35/* queue type */
36/* from 0 to 7 are normal commands (note off, on, etc.) */
37#define ST_NOTEOFF	0
38#define ST_NOTEON	1
39#define ST_SPECIAL	8
40#define ST_SYSEX	ST_SPECIAL
41/* from 8 to 15 are events for 0xf0-0xf7 */
42
43
44/*
45 * prototypes
46 */
47static void note_event(struct snd_midi_event *dev, struct snd_seq_event *ev);
48static void one_param_ctrl_event(struct snd_midi_event *dev, struct snd_seq_event *ev);
49static void pitchbend_ctrl_event(struct snd_midi_event *dev, struct snd_seq_event *ev);
50static void two_param_ctrl_event(struct snd_midi_event *dev, struct snd_seq_event *ev);
51static void one_param_event(struct snd_midi_event *dev, struct snd_seq_event *ev);
52static void songpos_event(struct snd_midi_event *dev, struct snd_seq_event *ev);
53static void note_decode(struct snd_seq_event *ev, unsigned char *buf);
54static void one_param_decode(struct snd_seq_event *ev, unsigned char *buf);
55static void pitchbend_decode(struct snd_seq_event *ev, unsigned char *buf);
56static void two_param_decode(struct snd_seq_event *ev, unsigned char *buf);
57static void songpos_decode(struct snd_seq_event *ev, unsigned char *buf);
58
59/*
60 * event list
61 */
62static struct status_event_list {
63	int event;
64	int qlen;
65	void (*encode)(struct snd_midi_event *dev, struct snd_seq_event *ev);
66	void (*decode)(struct snd_seq_event *ev, unsigned char *buf);
67} status_event[] = {
68	/* 0x80 - 0xf0 */
69	{SNDRV_SEQ_EVENT_NOTEOFF,	2, note_event, note_decode},
70	{SNDRV_SEQ_EVENT_NOTEON,	2, note_event, note_decode},
71	{SNDRV_SEQ_EVENT_KEYPRESS,	2, note_event, note_decode},
72	{SNDRV_SEQ_EVENT_CONTROLLER,	2, two_param_ctrl_event, two_param_decode},
73	{SNDRV_SEQ_EVENT_PGMCHANGE,	1, one_param_ctrl_event, one_param_decode},
74	{SNDRV_SEQ_EVENT_CHANPRESS,	1, one_param_ctrl_event, one_param_decode},
75	{SNDRV_SEQ_EVENT_PITCHBEND,	2, pitchbend_ctrl_event, pitchbend_decode},
76	{SNDRV_SEQ_EVENT_NONE,		0, NULL, NULL}, /* 0xf0 */
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,		0, NULL, NULL}, /* 0xf4 */
83	{SNDRV_SEQ_EVENT_NONE,		0, NULL, NULL}, /* 0xf5 */
84	{SNDRV_SEQ_EVENT_TUNE_REQUEST,	0, NULL, NULL},	/* 0xf6 */
85	{SNDRV_SEQ_EVENT_NONE,		0, NULL, NULL}, /* 0xf7 */
86	{SNDRV_SEQ_EVENT_CLOCK,		0, NULL, NULL}, /* 0xf8 */
87	{SNDRV_SEQ_EVENT_NONE,		0, 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, 		0, 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	spin_lock_init(&dev->lock);
133	*rdev = dev;
134	return 0;
135}
136
137void snd_midi_event_free(struct snd_midi_event *dev)
138{
139	if (dev != NULL) {
140		kfree(dev->buf);
141		kfree(dev);
142	}
143}
144
145/*
146 * initialize record
147 */
148static inline void reset_encode(struct snd_midi_event *dev)
149{
150	dev->read = 0;
151	dev->qlen = 0;
152	dev->type = 0;
153}
154
155void snd_midi_event_reset_encode(struct snd_midi_event *dev)
156{
157	unsigned long flags;
158
159	spin_lock_irqsave(&dev->lock, flags);
160	reset_encode(dev);
161	spin_unlock_irqrestore(&dev->lock, flags);
162}
163
164void snd_midi_event_reset_decode(struct snd_midi_event *dev)
165{
166	unsigned long flags;
167
168	spin_lock_irqsave(&dev->lock, flags);
169	dev->lastcmd = 0xff;
170	spin_unlock_irqrestore(&dev->lock, flags);
171}
172
173
174void snd_midi_event_no_status(struct snd_midi_event *dev, int on)
175{
176	dev->nostat = on ? 1 : 0;
177}
178
179/*
180 * resize buffer
181 */
182
183/*
184 *  read bytes and encode to sequencer event if finished
185 *  return the size of encoded bytes
186 */
187long snd_midi_event_encode(struct snd_midi_event *dev, unsigned char *buf, long count,
188			   struct snd_seq_event *ev)
189{
190	long result = 0;
191	int rc;
192
193	ev->type = SNDRV_SEQ_EVENT_NONE;
194
195	while (count-- > 0) {
196		rc = snd_midi_event_encode_byte(dev, *buf++, ev);
197		result++;
198		if (rc < 0)
199			return rc;
200		else if (rc > 0)
201			return result;
202	}
203
204	return result;
205}
206
207/*
208 *  read one byte and encode to sequencer event:
209 *  return 1 if MIDI bytes are encoded to an event
210 *         0 data is not finished
211 *         negative for error
212 */
213int snd_midi_event_encode_byte(struct snd_midi_event *dev, int c,
214			       struct snd_seq_event *ev)
215{
216	int rc = 0;
217	unsigned long flags;
218
219	c &= 0xff;
220
221	if (c >= MIDI_CMD_COMMON_CLOCK) {
222		/* real-time event */
223		ev->type = status_event[ST_SPECIAL + c - 0xf0].event;
224		ev->flags &= ~SNDRV_SEQ_EVENT_LENGTH_MASK;
225		ev->flags |= SNDRV_SEQ_EVENT_LENGTH_FIXED;
226		return 1;
227	}
228
229	spin_lock_irqsave(&dev->lock, flags);
230	if (dev->qlen > 0) {
231		/* rest of command */
232		dev->buf[dev->read++] = c;
233		if (dev->type != ST_SYSEX)
234			dev->qlen--;
235	} else {
236		/* new command */
237		dev->read = 1;
238		if (c & 0x80) {
239			dev->buf[0] = c;
240			if ((c & 0xf0) == 0xf0) /* special events */
241				dev->type = (c & 0x0f) + ST_SPECIAL;
242			else
243				dev->type = (c >> 4) & 0x07;
244			dev->qlen = status_event[dev->type].qlen;
245		} else {
246			/* process this byte as argument */
247			dev->buf[dev->read++] = c;
248			dev->qlen = status_event[dev->type].qlen - 1;
249		}
250	}
251	if (dev->qlen == 0) {
252		ev->type = status_event[dev->type].event;
253		ev->flags &= ~SNDRV_SEQ_EVENT_LENGTH_MASK;
254		ev->flags |= SNDRV_SEQ_EVENT_LENGTH_FIXED;
255		if (status_event[dev->type].encode) /* set data values */
256			status_event[dev->type].encode(dev, ev);
257		rc = 1;
258	} else 	if (dev->type == ST_SYSEX) {
259		if (c == MIDI_CMD_COMMON_SYSEX_END ||
260		    dev->read >= dev->bufsize) {
261			ev->flags &= ~SNDRV_SEQ_EVENT_LENGTH_MASK;
262			ev->flags |= SNDRV_SEQ_EVENT_LENGTH_VARIABLE;
263			ev->type = SNDRV_SEQ_EVENT_SYSEX;
264			ev->data.ext.len = dev->read;
265			ev->data.ext.ptr = dev->buf;
266			if (c != MIDI_CMD_COMMON_SYSEX_END)
267				dev->read = 0; /* continue to parse */
268			else
269				reset_encode(dev); /* all parsed */
270			rc = 1;
271		}
272	}
273
274	spin_unlock_irqrestore(&dev->lock, flags);
275	return rc;
276}
277
278/* encode note event */
279static void note_event(struct snd_midi_event *dev, struct snd_seq_event *ev)
280{
281	ev->data.note.channel = dev->buf[0] & 0x0f;
282	ev->data.note.note = dev->buf[1];
283	ev->data.note.velocity = dev->buf[2];
284}
285
286/* encode one parameter controls */
287static void one_param_ctrl_event(struct snd_midi_event *dev, struct snd_seq_event *ev)
288{
289	ev->data.control.channel = dev->buf[0] & 0x0f;
290	ev->data.control.value = dev->buf[1];
291}
292
293/* encode pitch wheel change */
294static void pitchbend_ctrl_event(struct snd_midi_event *dev, struct snd_seq_event *ev)
295{
296	ev->data.control.channel = dev->buf[0] & 0x0f;
297	ev->data.control.value = (int)dev->buf[2] * 128 + (int)dev->buf[1] - 8192;
298}
299
300/* encode midi control change */
301static void two_param_ctrl_event(struct snd_midi_event *dev, struct snd_seq_event *ev)
302{
303	ev->data.control.channel = dev->buf[0] & 0x0f;
304	ev->data.control.param = dev->buf[1];
305	ev->data.control.value = dev->buf[2];
306}
307
308/* encode one parameter value*/
309static void one_param_event(struct snd_midi_event *dev, struct snd_seq_event *ev)
310{
311	ev->data.control.value = dev->buf[1];
312}
313
314/* encode song position */
315static void songpos_event(struct snd_midi_event *dev, struct snd_seq_event *ev)
316{
317	ev->data.control.value = (int)dev->buf[2] * 128 + (int)dev->buf[1];
318}
319
320/*
321 * decode from a sequencer event to midi bytes
322 * return the size of decoded midi events
323 */
324long snd_midi_event_decode(struct snd_midi_event *dev, unsigned char *buf, long count,
325			   struct snd_seq_event *ev)
326{
327	unsigned int cmd, type;
328
329	if (ev->type == SNDRV_SEQ_EVENT_NONE)
330		return -ENOENT;
331
332	for (type = 0; type < ARRAY_SIZE(status_event); type++) {
333		if (ev->type == status_event[type].event)
334			goto __found;
335	}
336	for (type = 0; type < ARRAY_SIZE(extra_event); type++) {
337		if (ev->type == extra_event[type].event)
338			return extra_event[type].decode(dev, buf, count, ev);
339	}
340	return -ENOENT;
341
342      __found:
343	if (type >= ST_SPECIAL)
344		cmd = 0xf0 + (type - ST_SPECIAL);
345	else
346		/* data.note.channel and data.control.channel is identical */
347		cmd = 0x80 | (type << 4) | (ev->data.note.channel & 0x0f);
348
349
350	if (cmd == MIDI_CMD_COMMON_SYSEX) {
351		snd_midi_event_reset_decode(dev);
352		return snd_seq_expand_var_event(ev, count, buf, 1, 0);
353	} else {
354		int qlen;
355		unsigned char xbuf[4];
356		unsigned long flags;
357
358		spin_lock_irqsave(&dev->lock, flags);
359		if ((cmd & 0xf0) == 0xf0 || dev->lastcmd != cmd || dev->nostat) {
360			dev->lastcmd = cmd;
361			spin_unlock_irqrestore(&dev->lock, flags);
362			xbuf[0] = cmd;
363			if (status_event[type].decode)
364				status_event[type].decode(ev, xbuf + 1);
365			qlen = status_event[type].qlen + 1;
366		} else {
367			spin_unlock_irqrestore(&dev->lock, flags);
368			if (status_event[type].decode)
369				status_event[type].decode(ev, xbuf + 0);
370			qlen = status_event[type].qlen;
371		}
372		if (count < qlen)
373			return -ENOMEM;
374		memcpy(buf, xbuf, qlen);
375		return qlen;
376	}
377}
378
379
380/* decode note event */
381static void note_decode(struct snd_seq_event *ev, unsigned char *buf)
382{
383	buf[0] = ev->data.note.note & 0x7f;
384	buf[1] = ev->data.note.velocity & 0x7f;
385}
386
387/* decode one parameter controls */
388static void one_param_decode(struct snd_seq_event *ev, unsigned char *buf)
389{
390	buf[0] = ev->data.control.value & 0x7f;
391}
392
393/* decode pitch wheel change */
394static void pitchbend_decode(struct snd_seq_event *ev, unsigned char *buf)
395{
396	int value = ev->data.control.value + 8192;
397	buf[0] = value & 0x7f;
398	buf[1] = (value >> 7) & 0x7f;
399}
400
401/* decode midi control change */
402static void two_param_decode(struct snd_seq_event *ev, unsigned char *buf)
403{
404	buf[0] = ev->data.control.param & 0x7f;
405	buf[1] = ev->data.control.value & 0x7f;
406}
407
408/* decode song position */
409static void songpos_decode(struct snd_seq_event *ev, unsigned char *buf)
410{
411	buf[0] = ev->data.control.value & 0x7f;
412	buf[1] = (ev->data.control.value >> 7) & 0x7f;
413}
414
415/* decode 14bit control */
416static int extra_decode_ctrl14(struct snd_midi_event *dev, unsigned char *buf,
417			       int count, struct snd_seq_event *ev)
418{
419	unsigned char cmd;
420	int idx = 0;
421
422	cmd = MIDI_CMD_CONTROL|(ev->data.control.channel & 0x0f);
423	if (ev->data.control.param < 0x20) {
424		if (count < 4)
425			return -ENOMEM;
426		if (dev->nostat && count < 6)
427			return -ENOMEM;
428		if (cmd != dev->lastcmd || dev->nostat) {
429			if (count < 5)
430				return -ENOMEM;
431			buf[idx++] = dev->lastcmd = cmd;
432		}
433		buf[idx++] = ev->data.control.param;
434		buf[idx++] = (ev->data.control.value >> 7) & 0x7f;
435		if (dev->nostat)
436			buf[idx++] = cmd;
437		buf[idx++] = ev->data.control.param + 0x20;
438		buf[idx++] = ev->data.control.value & 0x7f;
439	} else {
440		if (count < 2)
441			return -ENOMEM;
442		if (cmd != dev->lastcmd || dev->nostat) {
443			if (count < 3)
444				return -ENOMEM;
445			buf[idx++] = dev->lastcmd = cmd;
446		}
447		buf[idx++] = ev->data.control.param & 0x7f;
448		buf[idx++] = ev->data.control.value & 0x7f;
449	}
450	return idx;
451}
452
453/* decode reg/nonreg param */
454static int extra_decode_xrpn(struct snd_midi_event *dev, unsigned char *buf,
455			     int count, struct snd_seq_event *ev)
456{
457	unsigned char cmd;
458	char *cbytes;
459	static char cbytes_nrpn[4] = { MIDI_CTL_NONREG_PARM_NUM_MSB,
460				       MIDI_CTL_NONREG_PARM_NUM_LSB,
461				       MIDI_CTL_MSB_DATA_ENTRY,
462				       MIDI_CTL_LSB_DATA_ENTRY };
463	static char cbytes_rpn[4] =  { MIDI_CTL_REGIST_PARM_NUM_MSB,
464				       MIDI_CTL_REGIST_PARM_NUM_LSB,
465				       MIDI_CTL_MSB_DATA_ENTRY,
466				       MIDI_CTL_LSB_DATA_ENTRY };
467	unsigned char bytes[4];
468	int idx = 0, i;
469
470	if (count < 8)
471		return -ENOMEM;
472	if (dev->nostat && count < 12)
473		return -ENOMEM;
474	cmd = MIDI_CMD_CONTROL|(ev->data.control.channel & 0x0f);
475	bytes[0] = ev->data.control.param & 0x007f;
476	bytes[1] = (ev->data.control.param & 0x3f80) >> 7;
477	bytes[2] = ev->data.control.value & 0x007f;
478	bytes[3] = (ev->data.control.value & 0x3f80) >> 7;
479	if (cmd != dev->lastcmd && !dev->nostat) {
480		if (count < 9)
481			return -ENOMEM;
482		buf[idx++] = dev->lastcmd = cmd;
483	}
484	cbytes = ev->type == SNDRV_SEQ_EVENT_NONREGPARAM ? cbytes_nrpn : cbytes_rpn;
485	for (i = 0; i < 4; i++) {
486		if (dev->nostat)
487			buf[idx++] = dev->lastcmd = cmd;
488		buf[idx++] = cbytes[i];
489		buf[idx++] = bytes[i];
490	}
491	return idx;
492}
493
494/*
495 *  exports
496 */
497
498EXPORT_SYMBOL(snd_midi_event_new);
499EXPORT_SYMBOL(snd_midi_event_free);
500EXPORT_SYMBOL(snd_midi_event_reset_encode);
501EXPORT_SYMBOL(snd_midi_event_reset_decode);
502EXPORT_SYMBOL(snd_midi_event_no_status);
503EXPORT_SYMBOL(snd_midi_event_encode);
504EXPORT_SYMBOL(snd_midi_event_encode_byte);
505EXPORT_SYMBOL(snd_midi_event_decode);
506
507static int __init alsa_seq_midi_event_init(void)
508{
509	return 0;
510}
511
512static void __exit alsa_seq_midi_event_exit(void)
513{
514}
515
516module_init(alsa_seq_midi_event_init)
517module_exit(alsa_seq_midi_event_exit)
518