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

📄 pas2_midi.c

📁 LINUX1.0内核源代码,学习LINUX编程的一定要看。
💻 C
字号:
/* * sound/pas2_midi.c *  * The low level driver for the PAS Midi Interface. *  * Copyright by Hannu Savolainen 1993 *  * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. 2. * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. *  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. *  */#include "sound_config.h"#ifdef CONFIGURE_SOUNDCARD#include "pas.h"#if !defined(EXCLUDE_PAS) && !defined(EXCLUDE_MIDI) && defined(EXCLUDE_PRO_MIDI)static int      midi_busy = 0, input_opened = 0;static int      my_dev;static volatile int ofifo_bytes = 0;static unsigned char tmp_queue[256];static volatile int qlen;static volatile unsigned char qhead, qtail;static void     (*midi_input_intr) (int dev, unsigned char data);static intpas_midi_open (int dev, int mode,	       void            (*input) (int dev, unsigned char data),	       void            (*output) (int dev)){  int             err;  unsigned long   flags;  unsigned char   ctrl;  if (midi_busy)    {      printk ("PAS2: Midi busy\n");      return RET_ERROR (EBUSY);    }  /* Reset input and output FIFO pointers */  pas_write (M_C_RESET_INPUT_FIFO | M_C_RESET_OUTPUT_FIFO,	     MIDI_CONTROL);  DISABLE_INTR (flags);  if ((err = pas_set_intr (I_M_MIDI_IRQ_ENABLE)) < 0)    return err;  /* Enable input available and output FIFO empty interrupts */  ctrl = 0;  input_opened = 0;  midi_input_intr = input;  if (mode == OPEN_READ || mode == OPEN_READWRITE)    {      ctrl |= M_C_ENA_INPUT_IRQ;/* Enable input */      input_opened = 1;    }  if (mode == OPEN_WRITE || mode == OPEN_READWRITE)    {      ctrl |= M_C_ENA_OUTPUT_IRQ |	/* Enable output */	M_C_ENA_OUTPUT_HALF_IRQ;    }  pas_write (ctrl,	     MIDI_CONTROL);  /* Acknowledge any pending interrupts */  pas_write (0xff, MIDI_STATUS);  ofifo_bytes = 0;  RESTORE_INTR (flags);  midi_busy = 1;  qlen = qhead = qtail = 0;  return 0;}static voidpas_midi_close (int dev){  /* Reset FIFO pointers, disable intrs */  pas_write (M_C_RESET_INPUT_FIFO | M_C_RESET_OUTPUT_FIFO, MIDI_CONTROL);  pas_remove_intr (I_M_MIDI_IRQ_ENABLE);  midi_busy = 0;}static intdump_to_midi (unsigned char midi_byte){  int             fifo_space, x;  fifo_space = ((x = pas_read (MIDI_FIFO_STATUS)) >> 4) & 0x0f;  if (fifo_space == 15 || (fifo_space < 2 && ofifo_bytes > 13))	/* Fifo full */    {      return 0;			/* Upper layer will call again */    }  ofifo_bytes++;  pas_write (midi_byte, MIDI_DATA);  return 1;}static intpas_midi_out (int dev, unsigned char midi_byte){  unsigned long   flags;  /*   * Drain the local queue first   */  DISABLE_INTR (flags);  while (qlen && dump_to_midi (tmp_queue[qhead]))    {      qlen--;      qhead++;    }  RESTORE_INTR (flags);  /*   * Output the byte if the local queue is empty.   */  if (!qlen)    if (dump_to_midi (midi_byte))      return 1;			/* OK */  /*   * Put to the local queue   */  if (qlen >= 256)    return 0;			/* Local queue full */  DISABLE_INTR (flags);  tmp_queue[qtail] = midi_byte;  qlen++;  qtail++;  RESTORE_INTR (flags);  return 1;}static intpas_midi_start_read (int dev){  return 0;}static intpas_midi_end_read (int dev){  return 0;}static intpas_midi_ioctl (int dev, unsigned cmd, unsigned arg){  return RET_ERROR (EINVAL);}static voidpas_midi_kick (int dev){  ofifo_bytes = 0;}static intpas_buffer_status (int dev){  return !qlen;}static struct midi_operations pas_midi_operations ={  {"Pro Audio Spectrum", 0, 0, SNDCARD_PAS},  pas_midi_open,  pas_midi_close,  pas_midi_ioctl,  pas_midi_out,  pas_midi_start_read,  pas_midi_end_read,  pas_midi_kick,  NULL,				/* command */  pas_buffer_status};longpas_midi_init (long mem_start){  my_dev = num_midis;  midi_devs[num_midis++] = &pas_midi_operations;  return mem_start;}voidpas_midi_interrupt (void){  unsigned char   stat;  int             i, incount;  unsigned long   flags;  stat = pas_read (MIDI_STATUS);  if (stat & M_S_INPUT_AVAIL)	/* Input byte available */    {      incount = pas_read (MIDI_FIFO_STATUS) & 0x0f;	/* Input FIFO count */      if (!incount)	incount = 16;      for (i = 0; i < incount; i++)	if (input_opened)	  {	    midi_input_intr (my_dev, pas_read (MIDI_DATA));	  }	else	  pas_read (MIDI_DATA);	/* Flush */    }  if (stat & (M_S_OUTPUT_EMPTY | M_S_OUTPUT_HALF_EMPTY))    {      if (!(stat & M_S_OUTPUT_EMPTY))	{	  ofifo_bytes = 8;	}      else	{	  ofifo_bytes = 0;	}      DISABLE_INTR (flags);      while (qlen && dump_to_midi (tmp_queue[qhead]))	{	  qlen--;	  qhead++;	}      RESTORE_INTR (flags);    }  if (stat & M_S_FRAMING_ERROR)    printk ("MIDI framing error\n");  if (stat & M_S_OUTPUT_OVERRUN)    {      printk ("MIDI output overrun %x,%x,%d \n", pas_read (MIDI_FIFO_STATUS), stat, ofifo_bytes);      ofifo_bytes = 100;    }  pas_write (stat, MIDI_STATUS);/* Acknowledge interrupts */}#endif#endif

⌨️ 快捷键说明

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