⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 seq_oss_midi.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
		return 0;	}	perm &= ~mdev->opened;	memset(&subs, 0, sizeof(subs));	if (perm & PERM_WRITE) {		subs.sender = dp->addr;		subs.dest.client = mdev->client;		subs.dest.port = mdev->port;		if (snd_seq_kernel_client_ctl(dp->cseq, SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT, &subs) >= 0)			mdev->opened |= PERM_WRITE;	}	if (perm & PERM_READ) {		subs.sender.client = mdev->client;		subs.sender.port = mdev->port;		subs.dest = dp->addr;		subs.flags = SNDRV_SEQ_PORT_SUBS_TIMESTAMP;		subs.queue = dp->queue;		/* queue for timestamps */		if (snd_seq_kernel_client_ctl(dp->cseq, SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT, &subs) >= 0)			mdev->opened |= PERM_READ;	}	if (! mdev->opened) {		snd_use_lock_free(&mdev->use_lock);		return -ENXIO;	}	mdev->devinfo = dp;	snd_use_lock_free(&mdev->use_lock);	return 0;}/* * close the midi device if already opened */intsnd_seq_oss_midi_close(seq_oss_devinfo_t *dp, int dev){	seq_oss_midi_t *mdev;	snd_seq_port_subscribe_t subs;	if ((mdev = get_mididev(dp, dev)) == NULL)		return -ENODEV;	if (! mdev->opened || mdev->devinfo != dp) {		snd_use_lock_free(&mdev->use_lock);		return 0;	}	debug_printk(("closing client %d port %d mode %d\n", mdev->client, mdev->port, mdev->opened));	memset(&subs, 0, sizeof(subs));	if (mdev->opened & PERM_WRITE) {		subs.sender = dp->addr;		subs.dest.client = mdev->client;		subs.dest.port = mdev->port;		snd_seq_kernel_client_ctl(dp->cseq, SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT, &subs);	}	if (mdev->opened & PERM_READ) {		subs.sender.client = mdev->client;		subs.sender.port = mdev->port;		subs.dest = dp->addr;		snd_seq_kernel_client_ctl(dp->cseq, SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT, &subs);	}	mdev->opened = 0;	mdev->devinfo = NULL;	snd_use_lock_free(&mdev->use_lock);	return 0;}/* * change seq capability flags to file mode flags */intsnd_seq_oss_midi_filemode(seq_oss_devinfo_t *dp, int dev){	seq_oss_midi_t *mdev;	int mode;	if ((mdev = get_mididev(dp, dev)) == NULL)		return 0;	mode = 0;	if (mdev->opened & PERM_WRITE)		mode |= SNDRV_SEQ_OSS_FILE_WRITE;	if (mdev->opened & PERM_READ)		mode |= SNDRV_SEQ_OSS_FILE_READ;	snd_use_lock_free(&mdev->use_lock);	return mode;}/* * reset the midi device and close it: * so far, only close the device. */voidsnd_seq_oss_midi_reset(seq_oss_devinfo_t *dp, int dev){	seq_oss_midi_t *mdev;	if ((mdev = get_mididev(dp, dev)) == NULL)		return;	if (! mdev->opened) {		snd_use_lock_free(&mdev->use_lock);		return;	}	if (mdev->opened & PERM_WRITE) {		snd_seq_event_t ev;		int c;		debug_printk(("resetting client %d port %d\n", mdev->client, mdev->port));		memset(&ev, 0, sizeof(ev));		ev.dest.client = mdev->client;		ev.dest.port = mdev->port;		ev.queue = dp->queue;		ev.source.port = dp->port;		if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_SYNTH) {			ev.type = SNDRV_SEQ_EVENT_SENSING;			snd_seq_oss_dispatch(dp, &ev, 0, 0); /* active sensing */		}		for (c = 0; c < 16; c++) {			ev.type = SNDRV_SEQ_EVENT_CONTROLLER;			ev.data.control.channel = c;			ev.data.control.param = 123;			snd_seq_oss_dispatch(dp, &ev, 0, 0); /* all notes off */			if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_MUSIC) {				ev.data.control.param = 121;				snd_seq_oss_dispatch(dp, &ev, 0, 0); /* reset all controllers */				ev.type = SNDRV_SEQ_EVENT_PITCHBEND;				ev.data.control.value = 0;				snd_seq_oss_dispatch(dp, &ev, 0, 0); /* bender off */			}		}	}	// snd_seq_oss_midi_close(dp, dev);	snd_use_lock_free(&mdev->use_lock);}/* * get client/port of the specified MIDI device */voidsnd_seq_oss_midi_get_addr(seq_oss_devinfo_t *dp, int dev, snd_seq_addr_t *addr){	seq_oss_midi_t *mdev;	if ((mdev = get_mididev(dp, dev)) == NULL)		return;	addr->client = mdev->client;	addr->port = mdev->port;	snd_use_lock_free(&mdev->use_lock);}/* * input callback - this can be atomic */intsnd_seq_oss_midi_input(snd_seq_event_t *ev, int direct, void *private_data){	seq_oss_devinfo_t *dp = (seq_oss_devinfo_t *)private_data;	seq_oss_midi_t *mdev;	int rc;	if (dp->readq == NULL)		return 0;	if ((mdev = find_slot(ev->source.client, ev->source.port)) == NULL)		return 0;	if (! (mdev->opened & PERM_READ)) {		snd_use_lock_free(&mdev->use_lock);		return 0;	}	if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_MUSIC)		rc = send_synth_event(dp, ev, mdev->seq_device);	else		rc = send_midi_event(dp, ev, mdev);	snd_use_lock_free(&mdev->use_lock);	return rc;}/* * convert ALSA sequencer event to OSS synth event */static intsend_synth_event(seq_oss_devinfo_t *dp, snd_seq_event_t *ev, int dev){	evrec_t ossev;	memset(&ossev, 0, sizeof(ossev));	switch (ev->type) {	case SNDRV_SEQ_EVENT_NOTEON:		ossev.v.cmd = MIDI_NOTEON; break;	case SNDRV_SEQ_EVENT_NOTEOFF:		ossev.v.cmd = MIDI_NOTEOFF; break;	case SNDRV_SEQ_EVENT_KEYPRESS:		ossev.v.cmd = MIDI_KEY_PRESSURE; break;	case SNDRV_SEQ_EVENT_CONTROLLER:		ossev.l.cmd = MIDI_CTL_CHANGE; break;	case SNDRV_SEQ_EVENT_PGMCHANGE:		ossev.l.cmd = MIDI_PGM_CHANGE; break;	case SNDRV_SEQ_EVENT_CHANPRESS:		ossev.l.cmd = MIDI_CHN_PRESSURE; break;	case SNDRV_SEQ_EVENT_PITCHBEND:		ossev.l.cmd = MIDI_PITCH_BEND; break;	default:		return 0; /* not supported */	}	ossev.v.dev = dev;	switch (ev->type) {	case SNDRV_SEQ_EVENT_NOTEON:	case SNDRV_SEQ_EVENT_NOTEOFF:	case SNDRV_SEQ_EVENT_KEYPRESS:		ossev.v.code = EV_CHN_VOICE;		ossev.v.note = ev->data.note.note;		ossev.v.parm = ev->data.note.velocity;		ossev.v.chn = ev->data.note.channel;		break;	case SNDRV_SEQ_EVENT_CONTROLLER:	case SNDRV_SEQ_EVENT_PGMCHANGE:	case SNDRV_SEQ_EVENT_CHANPRESS:		ossev.l.code = EV_CHN_COMMON;		ossev.l.p1 = ev->data.control.param;		ossev.l.val = ev->data.control.value;		ossev.l.chn = ev->data.control.channel;		break;	case SNDRV_SEQ_EVENT_PITCHBEND:		ossev.l.code = EV_CHN_COMMON;		ossev.l.val = ev->data.control.value + 8192;		ossev.l.chn = ev->data.control.channel;		break;	}		snd_seq_oss_readq_put_timestamp(dp->readq, ev->time.tick, dp->seq_mode);	snd_seq_oss_readq_put_event(dp->readq, &ossev);	return 0;}/* * decode event and send MIDI bytes to read queue */static intsend_midi_event(seq_oss_devinfo_t *dp, snd_seq_event_t *ev, seq_oss_midi_t *mdev){	char msg[32];	int len;		snd_seq_oss_readq_put_timestamp(dp->readq, ev->time.tick, dp->seq_mode);	if (!dp->timer->running)		len = snd_seq_oss_timer_start(dp->timer);	if (ev->type == SNDRV_SEQ_EVENT_SYSEX) {		if ((ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) == SNDRV_SEQ_EVENT_LENGTH_VARIABLE)			snd_seq_oss_readq_puts(dp->readq, mdev->seq_device,					       ev->data.ext.ptr, ev->data.ext.len);	} else {		len = snd_midi_event_decode(mdev->coder, msg, sizeof(msg), ev);		if (len > 0)			snd_seq_oss_readq_puts(dp->readq, mdev->seq_device, msg, len);	}	return 0;}/* * dump midi data * return 0 : enqueued *        non-zero : invalid - ignored */intsnd_seq_oss_midi_putc(seq_oss_devinfo_t *dp, int dev, unsigned char c, snd_seq_event_t *ev){	seq_oss_midi_t *mdev;	if ((mdev = get_mididev(dp, dev)) == NULL)		return -ENODEV;	if (snd_midi_event_encode_byte(mdev->coder, c, ev) > 0) {		snd_seq_oss_fill_addr(dp, ev, mdev->client, mdev->port);		snd_use_lock_free(&mdev->use_lock);		return 0;	}	snd_use_lock_free(&mdev->use_lock);	return -EINVAL;}/* * create OSS compatible midi_info record */intsnd_seq_oss_midi_make_info(seq_oss_devinfo_t *dp, int dev, struct midi_info *inf){	seq_oss_midi_t *mdev;	if ((mdev = get_mididev(dp, dev)) == NULL)		return -ENXIO;	inf->device = dev;	inf->dev_type = 0; /* FIXME: ?? */	inf->capabilities = 0; /* FIXME: ?? */	strlcpy(inf->name, mdev->name, sizeof(inf->name));	snd_use_lock_free(&mdev->use_lock);	return 0;}/* * proc interface */static char *capmode_str(int val){	val &= PERM_READ|PERM_WRITE;	if (val == (PERM_READ|PERM_WRITE))		return "read/write";	else if (val == PERM_READ)		return "read";	else if (val == PERM_WRITE)		return "write";	else		return "none";}voidsnd_seq_oss_midi_info_read(snd_info_buffer_t *buf){	int i;	seq_oss_midi_t *mdev;	snd_iprintf(buf, "\nNumber of MIDI devices: %d\n", max_midi_devs);	for (i = 0; i < max_midi_devs; i++) {		snd_iprintf(buf, "\nmidi %d: ", i);		mdev = get_mdev(i);		if (mdev == NULL) {			snd_iprintf(buf, "*empty*\n");			continue;		}		snd_iprintf(buf, "[%s] ALSA port %d:%d\n", mdev->name,			    mdev->client, mdev->port);		snd_iprintf(buf, "  capability %s / opened %s\n",			    capmode_str(mdev->flags),			    capmode_str(mdev->opened));		snd_use_lock_free(&mdev->use_lock);	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -