Linux Audio

Check our new training course

Loading...
  1/*
  2 * OSS compatible sequencer driver
  3 *
  4 * synth device handlers
  5 *
  6 * Copyright (C) 1998,99 Takashi Iwai <tiwai@suse.de>
  7 *
  8 * This program is free software; you can redistribute it and/or modify
  9 * it under the terms of the GNU General Public License as published by
 10 * the Free Software Foundation; either version 2 of the License, or
 11 * (at your option) any later version.
 12 *
 13 * This program is distributed in the hope that it will be useful,
 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 16 * GNU General Public License for more details.
 17 *
 18 * You should have received a copy of the GNU General Public License
 19 * along with this program; if not, write to the Free Software
 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 21 */
 22
 23#include "seq_oss_synth.h"
 24#include "seq_oss_midi.h"
 25#include "../seq_lock.h"
 26#include <linux/init.h>
 27#include <linux/module.h>
 28#include <linux/slab.h>
 29
 30/*
 31 * constants
 32 */
 33#define SNDRV_SEQ_OSS_MAX_SYNTH_NAME	30
 34#define MAX_SYSEX_BUFLEN		128
 35
 36
 37/*
 38 * definition of synth info records
 39 */
 40
 41/* sysex buffer */
 42struct seq_oss_synth_sysex {
 43	int len;
 44	int skip;
 45	unsigned char buf[MAX_SYSEX_BUFLEN];
 46};
 47
 48/* synth info */
 49struct seq_oss_synth {
 50	int seq_device;
 51
 52	/* for synth_info */
 53	int synth_type;
 54	int synth_subtype;
 55	int nr_voices;
 56
 57	char name[SNDRV_SEQ_OSS_MAX_SYNTH_NAME];
 58	struct snd_seq_oss_callback oper;
 59
 60	int opened;
 61
 62	void *private_data;
 63	snd_use_lock_t use_lock;
 64};
 65
 66
 67/*
 68 * device table
 69 */
 70static int max_synth_devs;
 71static struct seq_oss_synth *synth_devs[SNDRV_SEQ_OSS_MAX_SYNTH_DEVS];
 72static struct seq_oss_synth midi_synth_dev = {
 73	-1, /* seq_device */
 74	SYNTH_TYPE_MIDI, /* synth_type */
 75	0, /* synth_subtype */
 76	16, /* nr_voices */
 77	"MIDI", /* name */
 78};
 79
 80static DEFINE_SPINLOCK(register_lock);
 81
 82/*
 83 * prototypes
 84 */
 85static struct seq_oss_synth *get_synthdev(struct seq_oss_devinfo *dp, int dev);
 86static void reset_channels(struct seq_oss_synthinfo *info);
 87
 88/*
 89 * global initialization
 90 */
 91void __init
 92snd_seq_oss_synth_init(void)
 93{
 94	snd_use_lock_init(&midi_synth_dev.use_lock);
 95}
 96
 97/*
 98 * registration of the synth device
 99 */
100int
101snd_seq_oss_synth_register(struct snd_seq_device *dev)
102{
103	int i;
104	struct seq_oss_synth *rec;
105	struct snd_seq_oss_reg *reg = SNDRV_SEQ_DEVICE_ARGPTR(dev);
106	unsigned long flags;
107
108	if ((rec = kzalloc(sizeof(*rec), GFP_KERNEL)) == NULL) {
109		snd_printk(KERN_ERR "can't malloc synth info\n");
110		return -ENOMEM;
111	}
112	rec->seq_device = -1;
113	rec->synth_type = reg->type;
114	rec->synth_subtype = reg->subtype;
115	rec->nr_voices = reg->nvoices;
116	rec->oper = reg->oper;
117	rec->private_data = reg->private_data;
118	rec->opened = 0;
119	snd_use_lock_init(&rec->use_lock);
120
121	/* copy and truncate the name of synth device */
122	strlcpy(rec->name, dev->name, sizeof(rec->name));
123
124	/* registration */
125	spin_lock_irqsave(&register_lock, flags);
126	for (i = 0; i < max_synth_devs; i++) {
127		if (synth_devs[i] == NULL)
128			break;
129	}
130	if (i >= max_synth_devs) {
131		if (max_synth_devs >= SNDRV_SEQ_OSS_MAX_SYNTH_DEVS) {
132			spin_unlock_irqrestore(&register_lock, flags);
133			snd_printk(KERN_ERR "no more synth slot\n");
134			kfree(rec);
135			return -ENOMEM;
136		}
137		max_synth_devs++;
138	}
139	rec->seq_device = i;
140	synth_devs[i] = rec;
141	debug_printk(("synth %s registered %d\n", rec->name, i));
142	spin_unlock_irqrestore(&register_lock, flags);
143	dev->driver_data = rec;
144#ifdef SNDRV_OSS_INFO_DEV_SYNTH
145	if (i < SNDRV_CARDS)
146		snd_oss_info_register(SNDRV_OSS_INFO_DEV_SYNTH, i, rec->name);
147#endif
148	return 0;
149}
150
151
152int
153snd_seq_oss_synth_unregister(struct snd_seq_device *dev)
154{
155	int index;
156	struct seq_oss_synth *rec = dev->driver_data;
157	unsigned long flags;
158
159	spin_lock_irqsave(&register_lock, flags);
160	for (index = 0; index < max_synth_devs; index++) {
161		if (synth_devs[index] == rec)
162			break;
163	}
164	if (index >= max_synth_devs) {
165		spin_unlock_irqrestore(&register_lock, flags);
166		snd_printk(KERN_ERR "can't unregister synth\n");
167		return -EINVAL;
168	}
169	synth_devs[index] = NULL;
170	if (index == max_synth_devs - 1) {
171		for (index--; index >= 0; index--) {
172			if (synth_devs[index])
173				break;
174		}
175		max_synth_devs = index + 1;
176	}
177	spin_unlock_irqrestore(&register_lock, flags);
178#ifdef SNDRV_OSS_INFO_DEV_SYNTH
179	if (rec->seq_device < SNDRV_CARDS)
180		snd_oss_info_unregister(SNDRV_OSS_INFO_DEV_SYNTH, rec->seq_device);
181#endif
182
183	snd_use_lock_sync(&rec->use_lock);
184	kfree(rec);
185
186	return 0;
187}
188
189
190/*
191 */
192static struct seq_oss_synth *
193get_sdev(int dev)
194{
195	struct seq_oss_synth *rec;
196	unsigned long flags;
197
198	spin_lock_irqsave(&register_lock, flags);
199	rec = synth_devs[dev];
200	if (rec)
201		snd_use_lock_use(&rec->use_lock);
202	spin_unlock_irqrestore(&register_lock, flags);
203	return rec;
204}
205
206
207/*
208 * set up synth tables
209 */
210
211void
212snd_seq_oss_synth_setup(struct seq_oss_devinfo *dp)
213{
214	int i;
215	struct seq_oss_synth *rec;
216	struct seq_oss_synthinfo *info;
217
218	dp->max_synthdev = max_synth_devs;
219	dp->synth_opened = 0;
220	memset(dp->synths, 0, sizeof(dp->synths));
221	for (i = 0; i < dp->max_synthdev; i++) {
222		rec = get_sdev(i);
223		if (rec == NULL)
224			continue;
225		if (rec->oper.open == NULL || rec->oper.close == NULL) {
226			snd_use_lock_free(&rec->use_lock);
227			continue;
228		}
229		info = &dp->synths[i];
230		info->arg.app_index = dp->port;
231		info->arg.file_mode = dp->file_mode;
232		info->arg.seq_mode = dp->seq_mode;
233		if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_SYNTH)
234			info->arg.event_passing = SNDRV_SEQ_OSS_PROCESS_EVENTS;
235		else
236			info->arg.event_passing = SNDRV_SEQ_OSS_PASS_EVENTS;
237		info->opened = 0;
238		if (!try_module_get(rec->oper.owner)) {
239			snd_use_lock_free(&rec->use_lock);
240			continue;
241		}
242		if (rec->oper.open(&info->arg, rec->private_data) < 0) {
243			module_put(rec->oper.owner);
244			snd_use_lock_free(&rec->use_lock);
245			continue;
246		}
247		info->nr_voices = rec->nr_voices;
248		if (info->nr_voices > 0) {
249			info->ch = kcalloc(info->nr_voices, sizeof(struct seq_oss_chinfo), GFP_KERNEL);
250			if (!info->ch) {
251				snd_printk(KERN_ERR "Cannot malloc\n");
252				rec->oper.close(&info->arg);
253				module_put(rec->oper.owner);
254				snd_use_lock_free(&rec->use_lock);
255				continue;
256			}
257			reset_channels(info);
258		}
259		debug_printk(("synth %d assigned\n", i));
260		info->opened++;
261		rec->opened++;
262		dp->synth_opened++;
263		snd_use_lock_free(&rec->use_lock);
264	}
265}
266
267
268/*
269 * set up synth tables for MIDI emulation - /dev/music mode only
270 */
271
272void
273snd_seq_oss_synth_setup_midi(struct seq_oss_devinfo *dp)
274{
275	int i;
276
277	if (dp->max_synthdev >= SNDRV_SEQ_OSS_MAX_SYNTH_DEVS)
278		return;
279
280	for (i = 0; i < dp->max_mididev; i++) {
281		struct seq_oss_synthinfo *info;
282		info = &dp->synths[dp->max_synthdev];
283		if (snd_seq_oss_midi_open(dp, i, dp->file_mode) < 0)
284			continue;
285		info->arg.app_index = dp->port;
286		info->arg.file_mode = dp->file_mode;
287		info->arg.seq_mode = dp->seq_mode;
288		info->arg.private_data = info;
289		info->is_midi = 1;
290		info->midi_mapped = i;
291		info->arg.event_passing = SNDRV_SEQ_OSS_PASS_EVENTS;
292		snd_seq_oss_midi_get_addr(dp, i, &info->arg.addr);
293		info->opened = 1;
294		midi_synth_dev.opened++;
295		dp->max_synthdev++;
296		if (dp->max_synthdev >= SNDRV_SEQ_OSS_MAX_SYNTH_DEVS)
297			break;
298	}
299}
300
301
302/*
303 * clean up synth tables
304 */
305
306void
307snd_seq_oss_synth_cleanup(struct seq_oss_devinfo *dp)
308{
309	int i;
310	struct seq_oss_synth *rec;
311	struct seq_oss_synthinfo *info;
312
313	if (snd_BUG_ON(dp->max_synthdev >= SNDRV_SEQ_OSS_MAX_SYNTH_DEVS))
314		return;
315	for (i = 0; i < dp->max_synthdev; i++) {
316		info = &dp->synths[i];
317		if (! info->opened)
318			continue;
319		if (info->is_midi) {
320			if (midi_synth_dev.opened > 0) {
321				snd_seq_oss_midi_close(dp, info->midi_mapped);
322				midi_synth_dev.opened--;
323			}
324		} else {
325			rec = get_sdev(i);
326			if (rec == NULL)
327				continue;
328			if (rec->opened > 0) {
329				debug_printk(("synth %d closed\n", i));
330				rec->oper.close(&info->arg);
331				module_put(rec->oper.owner);
332				rec->opened = 0;
333			}
334			snd_use_lock_free(&rec->use_lock);
335		}
336		kfree(info->sysex);
337		info->sysex = NULL;
338		kfree(info->ch);
339		info->ch = NULL;
340	}
341	dp->synth_opened = 0;
342	dp->max_synthdev = 0;
343}
344
345/*
346 * check if the specified device is MIDI mapped device
347 */
348static int
349is_midi_dev(struct seq_oss_devinfo *dp, int dev)
350{
351	if (dev < 0 || dev >= dp->max_synthdev)
352		return 0;
353	if (dp->synths[dev].is_midi)
354		return 1;
355	return 0;
356}
357
358/*
359 * return synth device information pointer
360 */
361static struct seq_oss_synth *
362get_synthdev(struct seq_oss_devinfo *dp, int dev)
363{
364	struct seq_oss_synth *rec;
365	if (dev < 0 || dev >= dp->max_synthdev)
366		return NULL;
367	if (! dp->synths[dev].opened)
368		return NULL;
369	if (dp->synths[dev].is_midi)
370		return &midi_synth_dev;
371	if ((rec = get_sdev(dev)) == NULL)
372		return NULL;
373	if (! rec->opened) {
374		snd_use_lock_free(&rec->use_lock);
375		return NULL;
376	}
377	return rec;
378}
379
380
381/*
382 * reset note and velocity on each channel.
383 */
384static void
385reset_channels(struct seq_oss_synthinfo *info)
386{
387	int i;
388	if (info->ch == NULL || ! info->nr_voices)
389		return;
390	for (i = 0; i < info->nr_voices; i++) {
391		info->ch[i].note = -1;
392		info->ch[i].vel = 0;
393	}
394}
395
396
397/*
398 * reset synth device:
399 * call reset callback.  if no callback is defined, send a heartbeat
400 * event to the corresponding port.
401 */
402void
403snd_seq_oss_synth_reset(struct seq_oss_devinfo *dp, int dev)
404{
405	struct seq_oss_synth *rec;
406	struct seq_oss_synthinfo *info;
407
408	if (snd_BUG_ON(dev < 0 || dev >= dp->max_synthdev))
409		return;
410	info = &dp->synths[dev];
411	if (! info->opened)
412		return;
413	if (info->sysex)
414		info->sysex->len = 0; /* reset sysex */
415	reset_channels(info);
416	if (info->is_midi) {
417		if (midi_synth_dev.opened <= 0)
418			return;
419		snd_seq_oss_midi_reset(dp, info->midi_mapped);
420		/* reopen the device */
421		snd_seq_oss_midi_close(dp, dev);
422		if (snd_seq_oss_midi_open(dp, info->midi_mapped,
423					  dp->file_mode) < 0) {
424			midi_synth_dev.opened--;
425			info->opened = 0;
426			kfree(info->sysex);
427			info->sysex = NULL;
428			kfree(info->ch);
429			info->ch = NULL;
430		}
431		return;
432	}
433
434	rec = get_sdev(dev);
435	if (rec == NULL)
436		return;
437	if (rec->oper.reset) {
438		rec->oper.reset(&info->arg);
439	} else {
440		struct snd_seq_event ev;
441		memset(&ev, 0, sizeof(ev));
442		snd_seq_oss_fill_addr(dp, &ev, info->arg.addr.client,
443				      info->arg.addr.port);
444		ev.type = SNDRV_SEQ_EVENT_RESET;
445		snd_seq_oss_dispatch(dp, &ev, 0, 0);
446	}
447	snd_use_lock_free(&rec->use_lock);
448}
449
450
451/*
452 * load a patch record:
453 * call load_patch callback function
454 */
455int
456snd_seq_oss_synth_load_patch(struct seq_oss_devinfo *dp, int dev, int fmt,
457			    const char __user *buf, int p, int c)
458{
459	struct seq_oss_synth *rec;
460	int rc;
461
462	if (dev < 0 || dev >= dp->max_synthdev)
463		return -ENXIO;
464
465	if (is_midi_dev(dp, dev))
466		return 0;
467	if ((rec = get_synthdev(dp, dev)) == NULL)
468		return -ENXIO;
469
470	if (rec->oper.load_patch == NULL)
471		rc = -ENXIO;
472	else
473		rc = rec->oper.load_patch(&dp->synths[dev].arg, fmt, buf, p, c);
474	snd_use_lock_free(&rec->use_lock);
475	return rc;
476}
477
478/*
479 * check if the device is valid synth device
480 */
481int
482snd_seq_oss_synth_is_valid(struct seq_oss_devinfo *dp, int dev)
483{
484	struct seq_oss_synth *rec;
485	rec = get_synthdev(dp, dev);
486	if (rec) {
487		snd_use_lock_free(&rec->use_lock);
488		return 1;
489	}
490	return 0;
491}
492
493
494/*
495 * receive OSS 6 byte sysex packet:
496 * the full sysex message will be sent if it reaches to the end of data
497 * (0xff).
498 */
499int
500snd_seq_oss_synth_sysex(struct seq_oss_devinfo *dp, int dev, unsigned char *buf, struct snd_seq_event *ev)
501{
502	int i, send;
503	unsigned char *dest;
504	struct seq_oss_synth_sysex *sysex;
505
506	if (! snd_seq_oss_synth_is_valid(dp, dev))
507		return -ENXIO;
508
509	sysex = dp->synths[dev].sysex;
510	if (sysex == NULL) {
511		sysex = kzalloc(sizeof(*sysex), GFP_KERNEL);
512		if (sysex == NULL)
513			return -ENOMEM;
514		dp->synths[dev].sysex = sysex;
515	}
516
517	send = 0;
518	dest = sysex->buf + sysex->len;
519	/* copy 6 byte packet to the buffer */
520	for (i = 0; i < 6; i++) {
521		if (buf[i] == 0xff) {
522			send = 1;
523			break;
524		}
525		dest[i] = buf[i];
526		sysex->len++;
527		if (sysex->len >= MAX_SYSEX_BUFLEN) {
528			sysex->len = 0;
529			sysex->skip = 1;
530			break;
531		}
532	}
533
534	if (sysex->len && send) {
535		if (sysex->skip) {
536			sysex->skip = 0;
537			sysex->len = 0;
538			return -EINVAL; /* skip */
539		}
540		/* copy the data to event record and send it */
541		ev->flags = SNDRV_SEQ_EVENT_LENGTH_VARIABLE;
542		if (snd_seq_oss_synth_addr(dp, dev, ev))
543			return -EINVAL;
544		ev->data.ext.len = sysex->len;
545		ev->data.ext.ptr = sysex->buf;
546		sysex->len = 0;
547		return 0;
548	}
549
550	return -EINVAL; /* skip */
551}
552
553/*
554 * fill the event source/destination addresses
555 */
556int
557snd_seq_oss_synth_addr(struct seq_oss_devinfo *dp, int dev, struct snd_seq_event *ev)
558{
559	if (! snd_seq_oss_synth_is_valid(dp, dev))
560		return -EINVAL;
561	snd_seq_oss_fill_addr(dp, ev, dp->synths[dev].arg.addr.client,
562			      dp->synths[dev].arg.addr.port);
563	return 0;
564}
565
566
567/*
568 * OSS compatible ioctl
569 */
570int
571snd_seq_oss_synth_ioctl(struct seq_oss_devinfo *dp, int dev, unsigned int cmd, unsigned long addr)
572{
573	struct seq_oss_synth *rec;
574	int rc;
575
576	if (is_midi_dev(dp, dev))
577		return -ENXIO;
578	if ((rec = get_synthdev(dp, dev)) == NULL)
579		return -ENXIO;
580	if (rec->oper.ioctl == NULL)
581		rc = -ENXIO;
582	else
583		rc = rec->oper.ioctl(&dp->synths[dev].arg, cmd, addr);
584	snd_use_lock_free(&rec->use_lock);
585	return rc;
586}
587
588
589/*
590 * send OSS raw events - SEQ_PRIVATE and SEQ_VOLUME
591 */
592int
593snd_seq_oss_synth_raw_event(struct seq_oss_devinfo *dp, int dev, unsigned char *data, struct snd_seq_event *ev)
594{
595	if (! snd_seq_oss_synth_is_valid(dp, dev) || is_midi_dev(dp, dev))
596		return -ENXIO;
597	ev->type = SNDRV_SEQ_EVENT_OSS;
598	memcpy(ev->data.raw8.d, data, 8);
599	return snd_seq_oss_synth_addr(dp, dev, ev);
600}
601
602
603/*
604 * create OSS compatible synth_info record
605 */
606int
607snd_seq_oss_synth_make_info(struct seq_oss_devinfo *dp, int dev, struct synth_info *inf)
608{
609	struct seq_oss_synth *rec;
610
611	if (dev < 0 || dev >= dp->max_synthdev)
612		return -ENXIO;
613
614	if (dp->synths[dev].is_midi) {
615		struct midi_info minf;
616		snd_seq_oss_midi_make_info(dp, dp->synths[dev].midi_mapped, &minf);
617		inf->synth_type = SYNTH_TYPE_MIDI;
618		inf->synth_subtype = 0;
619		inf->nr_voices = 16;
620		inf->device = dev;
621		strlcpy(inf->name, minf.name, sizeof(inf->name));
622	} else {
623		if ((rec = get_synthdev(dp, dev)) == NULL)
624			return -ENXIO;
625		inf->synth_type = rec->synth_type;
626		inf->synth_subtype = rec->synth_subtype;
627		inf->nr_voices = rec->nr_voices;
628		inf->device = dev;
629		strlcpy(inf->name, rec->name, sizeof(inf->name));
630		snd_use_lock_free(&rec->use_lock);
631	}
632	return 0;
633}
634
635
636#ifdef CONFIG_PROC_FS
637/*
638 * proc interface
639 */
640void
641snd_seq_oss_synth_info_read(struct snd_info_buffer *buf)
642{
643	int i;
644	struct seq_oss_synth *rec;
645
646	snd_iprintf(buf, "\nNumber of synth devices: %d\n", max_synth_devs);
647	for (i = 0; i < max_synth_devs; i++) {
648		snd_iprintf(buf, "\nsynth %d: ", i);
649		rec = get_sdev(i);
650		if (rec == NULL) {
651			snd_iprintf(buf, "*empty*\n");
652			continue;
653		}
654		snd_iprintf(buf, "[%s]\n", rec->name);
655		snd_iprintf(buf, "  type 0x%x : subtype 0x%x : voices %d\n",
656			    rec->synth_type, rec->synth_subtype,
657			    rec->nr_voices);
658		snd_iprintf(buf, "  capabilities : ioctl %s / load_patch %s\n",
659			    enabled_str((long)rec->oper.ioctl),
660			    enabled_str((long)rec->oper.load_patch));
661		snd_use_lock_free(&rec->use_lock);
662	}
663}
664#endif /* CONFIG_PROC_FS */