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

📄 caiaq-midi.c

📁 linux 内核源代码
💻 C
字号:
/* *   Copyright (c) 2006,2007 Daniel Mack * *   This program is free software; you can redistribute it and/or modify *   it under the terms of the GNU General Public License as published by *   the Free Software Foundation; either version 2 of the License, or *   (at your option) any later version. * *   This program is distributed in the hope that it will be useful, *   but WITHOUT ANY WARRANTY; without even the implied warranty of *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *   GNU General Public License for more details. * *   You should have received a copy of the GNU General Public License *   along with this program; if not, write to the Free Software *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA*/#include <linux/init.h>#include <linux/module.h>#include <linux/moduleparam.h>#include <linux/interrupt.h>#include <linux/usb.h>#include <linux/input.h>#include <linux/spinlock.h>#include <sound/driver.h>#include <sound/core.h>#include <sound/rawmidi.h>#include <sound/pcm.h>#include "caiaq-device.h"#include "caiaq-midi.h"static int snd_usb_caiaq_midi_input_open(struct snd_rawmidi_substream *substream){	return 0;}static int snd_usb_caiaq_midi_input_close(struct snd_rawmidi_substream *substream){	return 0;}static void snd_usb_caiaq_midi_input_trigger(struct snd_rawmidi_substream *substream, int up){	struct snd_usb_caiaqdev *dev = substream->rmidi->private_data;	if (!dev)		return;		dev->midi_receive_substream = up ? substream : NULL;}static int snd_usb_caiaq_midi_output_open(struct snd_rawmidi_substream *substream){	return 0;}static int snd_usb_caiaq_midi_output_close(struct snd_rawmidi_substream *substream){	return 0;}static void snd_usb_caiaq_midi_send(struct snd_usb_caiaqdev *dev,				    struct snd_rawmidi_substream *substream){	int len, ret;		dev->midi_out_buf[0] = EP1_CMD_MIDI_WRITE;	dev->midi_out_buf[1] = 0; /* port */	len = snd_rawmidi_transmit_peek(substream, dev->midi_out_buf+3, EP1_BUFSIZE-3);		if (len <= 0)		return;		dev->midi_out_buf[2] = len;	dev->midi_out_urb.transfer_buffer_length = len+3;		ret = usb_submit_urb(&dev->midi_out_urb, GFP_ATOMIC);	if (ret < 0)		log("snd_usb_caiaq_midi_send(%p): usb_submit_urb() failed, %d\n",				substream, ret);}static void snd_usb_caiaq_midi_output_trigger(struct snd_rawmidi_substream *substream, int up){	struct snd_usb_caiaqdev *dev = substream->rmidi->private_data;		if (dev->midi_out_substream != NULL)		return;		if (!up) {		dev->midi_out_substream = NULL;		return;	}		dev->midi_out_substream = substream;	snd_usb_caiaq_midi_send(dev, substream);}static struct snd_rawmidi_ops snd_usb_caiaq_midi_output ={	.open =		snd_usb_caiaq_midi_output_open,	.close =	snd_usb_caiaq_midi_output_close,	.trigger =      snd_usb_caiaq_midi_output_trigger,};static struct snd_rawmidi_ops snd_usb_caiaq_midi_input ={	.open =		snd_usb_caiaq_midi_input_open,	.close =	snd_usb_caiaq_midi_input_close,	.trigger =      snd_usb_caiaq_midi_input_trigger,};void snd_usb_caiaq_midi_handle_input(struct snd_usb_caiaqdev *dev, 				     int port, const char *buf, int len){	if (!dev->midi_receive_substream)		return;		snd_rawmidi_receive(dev->midi_receive_substream, buf, len);}int __devinit snd_usb_caiaq_midi_init(struct snd_usb_caiaqdev *device){	int ret;	struct snd_rawmidi *rmidi;	ret = snd_rawmidi_new(device->chip.card, device->product_name, 0,					device->spec.num_midi_out,					device->spec.num_midi_in,					&rmidi);	if (ret < 0)		return ret;	strcpy(rmidi->name, device->product_name);	rmidi->info_flags = SNDRV_RAWMIDI_INFO_DUPLEX;	rmidi->private_data = device;	if (device->spec.num_midi_out > 0) {		rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT;		snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, 				    &snd_usb_caiaq_midi_output);	}	if (device->spec.num_midi_in > 0) {		rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT;		snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, 				    &snd_usb_caiaq_midi_input);	}		device->rmidi = rmidi;	return 0;}void snd_usb_caiaq_midi_output_done(struct urb* urb){	struct snd_usb_caiaqdev *dev = urb->context;      	char *buf = urb->transfer_buffer;		if (urb->status != 0)		return;	if (!dev->midi_out_substream)		return;	snd_rawmidi_transmit_ack(dev->midi_out_substream, buf[2]);	dev->midi_out_substream = NULL;	snd_usb_caiaq_midi_send(dev, dev->midi_out_substream);}

⌨️ 快捷键说明

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