Example #1
0
void
snd_seq_oss_synth_setup_midi(seq_oss_devinfo_t *dp)
{
	int i;

	if (dp->max_synthdev >= SNDRV_SEQ_OSS_MAX_SYNTH_DEVS)
		return;

	for (i = 0; i < dp->max_mididev; i++) {
		seq_oss_synthinfo_t *info;
		info = &dp->synths[dp->max_synthdev];
		if (snd_seq_oss_midi_open(dp, i, dp->file_mode) < 0)
			continue;
		info->arg.app_index = dp->port;
		info->arg.file_mode = dp->file_mode;
		info->arg.seq_mode = dp->seq_mode;
		info->arg.private_data = info;
		info->is_midi = 1;
		info->midi_mapped = i;
		info->arg.event_passing = SNDRV_SEQ_OSS_PASS_EVENTS;
		snd_seq_oss_midi_get_addr(dp, i, &info->arg.addr);
		info->opened = 1;
		midi_synth_dev.opened++;
		dp->max_synthdev++;
		if (dp->max_synthdev >= SNDRV_SEQ_OSS_MAX_SYNTH_DEVS)
			break;
	}
}
Example #2
0
/*
 * open all midi devices.  ignore errors.
 */
void
snd_seq_oss_midi_open_all(struct seq_oss_devinfo *dp, int file_mode)
{
	int i;
	for (i = 0; i < dp->max_mididev; i++)
		snd_seq_oss_midi_open(dp, i, file_mode);
}
int
snd_seq_oss_process_event(seq_oss_devinfo_t *dp, evrec_t *q, snd_seq_event_t *ev)
{
	switch (q->s.code) {
	case SEQ_EXTENDED:
		return extended_event(dp, q, ev);

	case EV_CHN_VOICE:
		return chn_voice_event(dp, q, ev);

	case EV_CHN_COMMON:
		return chn_common_event(dp, q, ev);

	case EV_TIMING:
		return timing_event(dp, q, ev);

	case EV_SEQ_LOCAL:
		return local_event(dp, q, ev);

	case EV_SYSEX:
		return snd_seq_oss_synth_sysex(dp, q->x.dev, q->x.buf, ev);

	case SEQ_MIDIPUTC:
		if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_MUSIC)
			return -EINVAL;
		/* put a midi byte */
		if (! is_write_mode(dp->file_mode))
			break;
		if (snd_seq_oss_midi_open(dp, q->s.dev, SNDRV_SEQ_OSS_FILE_WRITE))
			break;
		if (snd_seq_oss_midi_filemode(dp, q->s.dev) & SNDRV_SEQ_OSS_FILE_WRITE)
			return snd_seq_oss_midi_putc(dp, q->s.dev, q->s.parm1, ev);
		break;

	case SEQ_ECHO:
		if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_MUSIC)
			return -EINVAL;
		return set_echo_event(dp, q, ev);

	case SEQ_PRIVATE:
		if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_MUSIC)
			return -EINVAL;
		return snd_seq_oss_synth_raw_event(dp, q->c[1], q->c, ev);

	default:
		if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_MUSIC)
			return -EINVAL;
		return old_event(dp, q, ev);
	}
	return -EINVAL;
}
Example #4
0
/*
 * reset synth device:
 * call reset callback.  if no callback is defined, send a heartbeat
 * event to the corresponding port.
 */
void
snd_seq_oss_synth_reset(seq_oss_devinfo_t *dp, int dev)
{
	seq_oss_synth_t *rec;
	seq_oss_synthinfo_t *info;

	snd_assert(dev >= 0 && dev < dp->max_synthdev, return);
	info = &dp->synths[dev];
	if (! info->opened)
		return;
	if (info->sysex)
		info->sysex->len = 0; /* reset sysex */
	reset_channels(info);
	if (info->is_midi) {
		if (midi_synth_dev.opened <= 0)
			return;
		snd_seq_oss_midi_reset(dp, info->midi_mapped);
		/* reopen the device */
		snd_seq_oss_midi_close(dp, dev);
		if (snd_seq_oss_midi_open(dp, info->midi_mapped,
					  dp->file_mode) < 0) {
			midi_synth_dev.opened--;
			info->opened = 0;
			if (info->sysex) {
				kfree(info->sysex);
				info->sysex = NULL;
			}
			if (info->ch) {
				kfree(info->ch);
				info->ch = NULL;
			}
		}
		return;
	}

	rec = get_sdev(dev);
	if (rec == NULL)
		return;
	if (rec->oper.reset) {
		rec->oper.reset(&info->arg);
	} else {
		snd_seq_event_t ev;
		memset(&ev, 0, sizeof(ev));
		snd_seq_oss_fill_addr(dp, &ev, info->arg.addr.client,
				      info->arg.addr.port);
		ev.type = SNDRV_SEQ_EVENT_RESET;
		snd_seq_oss_dispatch(dp, &ev, 0, 0);
	}
	snd_use_lock_free(&rec->use_lock);
}
Example #5
0
int
snd_seq_oss_ioctl(struct seq_oss_devinfo *dp, unsigned int cmd, unsigned long carg)
{
	int dev, val;
	void __user *arg = (void __user *)carg;
	int __user *p = arg;

	switch (cmd) {
	case SNDCTL_TMR_TIMEBASE:
	case SNDCTL_TMR_TEMPO:
	case SNDCTL_TMR_START:
	case SNDCTL_TMR_STOP:
	case SNDCTL_TMR_CONTINUE:
	case SNDCTL_TMR_METRONOME:
	case SNDCTL_TMR_SOURCE:
	case SNDCTL_TMR_SELECT:
	case SNDCTL_SEQ_CTRLRATE:
		return snd_seq_oss_timer_ioctl(dp->timer, cmd, arg);

	case SNDCTL_SEQ_PANIC:
		debug_printk(("panic\n"));
		snd_seq_oss_reset(dp);
		return -EINVAL;

	case SNDCTL_SEQ_SYNC:
		debug_printk(("sync\n"));
		if (! is_write_mode(dp->file_mode) || dp->writeq == NULL)
			return 0;
		while (snd_seq_oss_writeq_sync(dp->writeq))
			;
		if (signal_pending(current))
			return -ERESTARTSYS;
		return 0;

	case SNDCTL_SEQ_RESET:
		debug_printk(("reset\n"));
		snd_seq_oss_reset(dp);
		return 0;

	case SNDCTL_SEQ_TESTMIDI:
		debug_printk(("test midi\n"));
		if (get_user(dev, p))
			return -EFAULT;
		return snd_seq_oss_midi_open(dp, dev, dp->file_mode);

	case SNDCTL_SEQ_GETINCOUNT:
		debug_printk(("get in count\n"));
		if (dp->readq == NULL || ! is_read_mode(dp->file_mode))
			return 0;
		return put_user(dp->readq->qlen, p) ? -EFAULT : 0;

	case SNDCTL_SEQ_GETOUTCOUNT:
		debug_printk(("get out count\n"));
		if (! is_write_mode(dp->file_mode) || dp->writeq == NULL)
			return 0;
		return put_user(snd_seq_oss_writeq_get_free_size(dp->writeq), p) ? -EFAULT : 0;

	case SNDCTL_SEQ_GETTIME:
		debug_printk(("get time\n"));
		return put_user(snd_seq_oss_timer_cur_tick(dp->timer), p) ? -EFAULT : 0;

	case SNDCTL_SEQ_RESETSAMPLES:
		debug_printk(("reset samples\n"));
		if (get_user(dev, p))
			return -EFAULT;
		return snd_seq_oss_synth_ioctl(dp, dev, cmd, carg);

	case SNDCTL_SEQ_NRSYNTHS:
		debug_printk(("nr synths\n"));
		return put_user(dp->max_synthdev, p) ? -EFAULT : 0;

	case SNDCTL_SEQ_NRMIDIS:
		debug_printk(("nr midis\n"));
		return put_user(dp->max_mididev, p) ? -EFAULT : 0;

	case SNDCTL_SYNTH_MEMAVL:
		debug_printk(("mem avail\n"));
		if (get_user(dev, p))
			return -EFAULT;
		val = snd_seq_oss_synth_ioctl(dp, dev, cmd, carg);
		return put_user(val, p) ? -EFAULT : 0;

	case SNDCTL_FM_4OP_ENABLE:
		debug_printk(("4op\n"));
		if (get_user(dev, p))
			return -EFAULT;
		snd_seq_oss_synth_ioctl(dp, dev, cmd, carg);
		return 0;

	case SNDCTL_SYNTH_INFO:
	case SNDCTL_SYNTH_ID:
		debug_printk(("synth info\n"));
		return snd_seq_oss_synth_info_user(dp, arg);

	case SNDCTL_SEQ_OUTOFBAND:
		debug_printk(("out of band\n"));
		return snd_seq_oss_oob_user(dp, arg);

	case SNDCTL_MIDI_INFO:
		debug_printk(("midi info\n"));
		return snd_seq_oss_midi_info_user(dp, arg);

	case SNDCTL_SEQ_THRESHOLD:
		debug_printk(("threshold\n"));
		if (! is_write_mode(dp->file_mode))
			return 0;
		if (get_user(val, p))
			return -EFAULT;
		if (val < 1)
			val = 1;
		if (val >= dp->writeq->maxlen)
			val = dp->writeq->maxlen - 1;
		snd_seq_oss_writeq_set_output(dp->writeq, val);
		return 0;

	case SNDCTL_MIDI_PRETIME:
		debug_printk(("pretime\n"));
		if (dp->readq == NULL || !is_read_mode(dp->file_mode))
			return 0;
		if (get_user(val, p))
			return -EFAULT;
		if (val <= 0)
			val = -1;
		else
			val = (HZ * val) / 10;
		dp->readq->pre_event_timeout = val;
		return put_user(val, p) ? -EFAULT : 0;

	default:
		debug_printk(("others\n"));
		if (! is_write_mode(dp->file_mode))
			return -EIO;
		return snd_seq_oss_synth_ioctl(dp, 0, cmd, carg);
	}
	return 0;
}