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

📄 sequencer.c

📁 freebsd v4.4内核源码
💻 C
📖 第 1 页 / 共 3 页
字号:
    default:;    }}static intseq_timing_event (unsigned char *event){  unsigned char   cmd = event[1];  unsigned int    parm = *(int *) &event[4];  if (seq_mode == SEQ_2)    {      int             ret;      if ((ret = tmr->event (tmr_no, event)) == TIMER_ARMED)	{	  if ((SEQ_MAX_QUEUE - qlen) >= output_treshold)	    {	      unsigned long   flags;	      DISABLE_INTR (flags);	      if (SOMEONE_WAITING (seq_sleeper, seq_sleep_flag))		{		  WAKE_UP (seq_sleeper, seq_sleep_flag);		}	      RESTORE_INTR (flags);#if defined(__FreeBSD__)		/* must issue a wakeup for anyone waiting (select) XXX */#endif	    }	}      return ret;    }  switch (cmd)    {    case TMR_WAIT_REL:      parm += prev_event_time;      /*         * NOTE!  No break here. Execution of TMR_WAIT_REL continues in the         * next case (TMR_WAIT_ABS)       */    case TMR_WAIT_ABS:      if (parm > 0)	{	  long            time;	  seq_playing = 1;	  time = parm;	  prev_event_time = time;	  request_sound_timer (time);	  if ((SEQ_MAX_QUEUE - qlen) >= output_treshold)	    {	      unsigned long   flags;	      DISABLE_INTR (flags);	      if (SOMEONE_WAITING (seq_sleeper, seq_sleep_flag))		{		  WAKE_UP (seq_sleeper, seq_sleep_flag);		}	      RESTORE_INTR (flags);#if defined(__FreeBSD__)		/* must issue a wakeup for select XXX */#endif	    }	  return TIMER_ARMED;	}      break;    case TMR_START:      seq_time = GET_TIME ();      prev_input_time = 0;      prev_event_time = 0;      break;    case TMR_STOP:      break;    case TMR_CONTINUE:      break;    case TMR_TEMPO:      break;    case TMR_ECHO:      if (seq_mode == SEQ_2)	seq_copy_to_input (event, 8);      else	{	  parm = (parm << 8 | SEQ_ECHO);	  seq_copy_to_input ((unsigned char *) &parm, 4);	}      break;    default:;    }  return TIMER_NOT_ARMED;}static voidseq_local_event (unsigned char *event){  /* unsigned char   cmd = event[1]; */  printk ("seq_local_event() called. WHY????????\n");}static intplay_event (unsigned char *q){  /*     * NOTE! This routine returns     *   0 = normal event played.     *   1 = Timer armed. Suspend playback until timer callback.     *   2 = MIDI output buffer full. Restore queue and suspend until timer   */  unsigned long  *delay;  switch (q[0])    {    case SEQ_NOTEOFF:      if (synth_open_mask & (1 << 0))	if (synth_devs[0])	  synth_devs[0]->kill_note (0, q[1], 255, q[3]);      break;    case SEQ_NOTEON:      if (q[4] < 128 || q[4] == 255)	if (synth_open_mask & (1 << 0))	  if (synth_devs[0])	    synth_devs[0]->start_note (0, q[1], q[2], q[3]);      break;    case SEQ_WAIT:      delay = (unsigned long *) q;	/*					 * Bytes 1 to 3 are containing the *					 * delay in GET_TIME()					 */      *delay = (*delay >> 8) & 0xffffff;      if (*delay > 0)	{	  long            time;	  seq_playing = 1;	  time = *delay;	  prev_event_time = time;	  request_sound_timer (time);	  if ((SEQ_MAX_QUEUE - qlen) >= output_treshold)	    {	      unsigned long   flags;	      DISABLE_INTR (flags);	      if (SOMEONE_WAITING (seq_sleeper, seq_sleep_flag))		{		  WAKE_UP (seq_sleeper, seq_sleep_flag);		}	      RESTORE_INTR (flags);#if defined(__FreeBSD__)		/* must issue a wakeup for selects XXX */#endif	    }	  /*	     * The timer is now active and will reinvoke this function	     * after the timer expires. Return to the caller now.	   */	  return 1;	}      break;    case SEQ_PGMCHANGE:      if (synth_open_mask & (1 << 0))	if (synth_devs[0])	  synth_devs[0]->set_instr (0, q[1], q[2]);      break;    case SEQ_SYNCTIMER:	/*				   * Reset timer				 */      seq_time = GET_TIME ();      prev_input_time = 0;      prev_event_time = 0;      break;    case SEQ_MIDIPUTC:		/*				 * Put a midi character				 */      if (midi_opened[q[2]])	{	  int             dev;	  dev = q[2];	  if (!midi_devs[dev]->putc (dev, q[1]))	    {	      /*	         * Output FIFO is full. Wait one timer cycle and try again.	       */	      seq_playing = 1;	      request_sound_timer (-1);	      return 2;	    }	  else	    midi_written[dev] = 1;	}      break;    case SEQ_ECHO:      seq_copy_to_input (q, 4);	/*				   * Echo back to the process				 */      break;    case SEQ_PRIVATE:      if ((int) q[1] < max_synthdev)	synth_devs[q[1]]->hw_control (q[1], q);      break;    case SEQ_EXTENDED:      extended_event (q);      break;    case EV_CHN_VOICE:      seq_chn_voice_event (q);      break;    case EV_CHN_COMMON:      seq_chn_common_event (q);      break;    case EV_TIMING:      if (seq_timing_event (q) == TIMER_ARMED)	{	  return 1;	}      break;    case EV_SEQ_LOCAL:      seq_local_event (q);      break;    default:;    }  return 0;}static voidseq_startplay (void){  unsigned long   flags;  int             this_one, action;  while (qlen > 0)    {      DISABLE_INTR (flags);      qhead = ((this_one = qhead) + 1) % SEQ_MAX_QUEUE;      qlen--;      RESTORE_INTR (flags);      seq_playing = 1;      if ((action = play_event (&queue[this_one * EV_SZ])))	{			/* Suspend playback. Next timer routine invokes this routine again */	  if (action == 2)	    {	      qlen++;	      qhead = this_one;	    }	  return;	}    }  seq_playing = 0;  if ((SEQ_MAX_QUEUE - qlen) >= output_treshold)    {      unsigned long   flags;      DISABLE_INTR (flags);      if (SOMEONE_WAITING (seq_sleeper, seq_sleep_flag))	{	  WAKE_UP (seq_sleeper, seq_sleep_flag);	}      RESTORE_INTR (flags);#if defined(__FreeBSD__)	/* must issue a wakeup for selects XXX */#endif    }}static voidreset_controllers (int dev, unsigned char *controller, int update_dev){  int             i;  for (i = 0; i < 128; i++)    controller[i] = ctrl_def_values[i];}static voidsetup_mode2 (void){  int             dev;  max_synthdev = num_synths;  for (dev = 0; dev < num_midis; dev++)    if (midi_devs[dev]->converter != NULL)      {	synth_devs[max_synthdev++] =	  midi_devs[dev]->converter;      }  for (dev = 0; dev < max_synthdev; dev++)    {      int             chn;      for (chn = 0; chn < 16; chn++)	{	  synth_devs[dev]->chn_info[chn].pgm_num = 0;	  reset_controllers (dev,			     synth_devs[dev]->chn_info[chn].controllers,			     0);	  synth_devs[dev]->chn_info[chn].bender_value = (1 << 7);	/* Neutral */	}    }  max_mididev = 0;  seq_mode = SEQ_2;}intsequencer_open (int dev, struct fileinfo *file){  int             retval, mode, i;  int             level, tmp;  level = ((dev & 0x0f) == SND_DEV_SEQ2) ? 2 : 1;  dev = dev >> 4;  mode = file->mode & O_ACCMODE;  DEB (printk ("sequencer_open(dev=%d)\n", dev));  if (!sequencer_ok)    {      printk ("Soundcard: Sequencer not initialized\n");      return RET_ERROR (ENXIO);    }  if (dev)			/*				 * Patch manager device				 */    {      int             err;      dev--;      if (dev >= MAX_SYNTH_DEV)	return RET_ERROR (ENXIO);      if (pmgr_present[dev])	return RET_ERROR (EBUSY);      if ((err = pmgr_open (dev)) < 0)	return err;		/*				 * Failed				 */      pmgr_present[dev] = 1;      return err;    }  if (sequencer_busy)    {      printk ("Sequencer busy\n");      return RET_ERROR (EBUSY);    }  max_mididev = num_midis;  max_synthdev = num_synths;  pre_event_timeout = 0;  seq_mode = SEQ_1;  if (pending_timer != -1)    {      tmr_no = pending_timer;      pending_timer = -1;    }  if (tmr_no == -1)		/* Not selected yet */    {      int             i, best;      best = -1;      for (i = 0; i < num_sound_timers; i++)	if (sound_timer_devs[i]->priority > best)	  {	    tmr_no = i;	    best = sound_timer_devs[i]->priority;	  }      if (tmr_no == -1)		/* Should not be */	tmr_no = 0;    }  tmr = sound_timer_devs[tmr_no];  if (level == 2)    {      if (tmr == NULL)	{	  printk ("sequencer: No timer for level 2\n");	  return RET_ERROR (ENXIO);	}      setup_mode2 ();    }  if (seq_mode == SEQ_1 && (mode == OPEN_READ || mode == OPEN_READWRITE))    if (!max_mididev)      {	printk ("Sequencer: No Midi devices. Input not possible\n");	return RET_ERROR (ENXIO);      }  if (!max_synthdev && !max_mididev)    return RET_ERROR (ENXIO);  synth_open_mask = 0;  for (i = 0; i < max_mididev; i++)    {      midi_opened[i] = 0;      midi_written[i] = 0;    }  /*   * if (mode == OPEN_WRITE || mode == OPEN_READWRITE)   */  for (i = 0; i < max_synthdev; i++)	/*					 * Open synth devices					 */    if ((tmp = synth_devs[i]->open (i, mode)) < 0)      {	printk ("Sequencer: Warning! Cannot open synth device #%d (%d)\n", i, tmp);	if (synth_devs[i]->midi_dev)	  printk ("(Maps to MIDI dev #%d)\n", synth_devs[i]->midi_dev);      }    else      {	synth_open_mask |= (1 << i);	if (synth_devs[i]->midi_dev)	/*					 * Is a midi interface					 */	  midi_opened[synth_devs[i]->midi_dev] = 1;      }  seq_time = GET_TIME ();  prev_input_time = 0;  prev_event_time = 0;  if (seq_mode == SEQ_1 && (mode == OPEN_READ || mode == OPEN_READWRITE))    {				/*				 * Initialize midi input devices				 */      for (i = 0; i < max_mididev; i++)	if (!midi_opened[i])	  {	    if ((retval = midi_devs[i]->open (i, mode,			 sequencer_midi_input, sequencer_midi_output)) >= 0)	      midi_opened[i] = 1;	  }    }  if (seq_mode == SEQ_2)    {      tmr->open (tmr_no, seq_mode);    }  sequencer_busy = 1;  RESET_WAIT_QUEUE (seq_sleeper, seq_sleep_flag);  RESET_WAIT_QUEUE (midi_sleeper, midi_sleep_flag);  output_treshold = SEQ_MAX_QUEUE / 2;  for (i = 0; i < num_synths; i++)    if (pmgr_present[i])      pmgr_inform (i, PM_E_OPENED, 0, 0, 0, 0);  return 0;}voidseq_drain_midi_queues (void){  int             i, n;  /*   * Give the Midi drivers time to drain their output queues   */  n = 1;  while (!PROCESS_ABORTING (seq_sleeper, seq_sleep_flag) && n)    {      n = 0;      for (i = 0; i < max_mididev; i++)	if (midi_opened[i] && midi_written[i])	  if (midi_devs[i]->buffer_status != NULL)	    if (midi_devs[i]->buffer_status (i))	      n++;      /*       * Let's have a delay       */      if (n)	{	  DO_SLEEP (seq_sleeper, seq_sleep_flag, HZ / 10);	}    }}voidsequencer_release (int dev, struct fileinfo *file){  int             i;  int             mode = file->mode & O_ACCMODE;  dev = dev >> 4;  DEB (printk ("sequencer_release(dev=%d)\n", dev));  if (dev)			/*				 * Patch manager device				 */    {      dev--;      pmgr_release (dev);      pmgr_present[dev] = 0;      return;    }  /*   * * Wait until the queue is empty (if we don't have nonblock)   */  if (mode != OPEN_READ && !ISSET_FILE_FLAG (file, O_NONBLOCK))    while (!PROCESS_ABORTING (seq_sleeper, seq_sleep_flag) && qlen)      {	seq_sync ();      }  if (mode != OPEN_READ)    seq_drain_midi_queues ();	/*				 * Ensure the output queues are empty				 */  seq_reset ();  if (mode != OPEN_READ)    seq_drain_midi_queues ();	/*				 * Flush the all notes off messages				 */  for (i = 0; i < max_synthdev; i++)    if (synth_open_mask & (1 << i))	/*					 * Actually opened					 */      if (synth_devs[i])	{	  synth_devs[i]->close (i);	  if (synth_devs[i]->midi_dev)	    midi_opened[synth_devs[i]->midi_dev] = 0;	}  for (i = 0; i < num_synths; i++)    if (pmgr_present[i])      pmgr_inform (i, PM_E_CLOSED, 0, 0, 0, 0);  for (i = 0; i < max_mididev; i++)    if (midi_opened[i])      midi_devs[i]->close (i);  if (seq_mode == SEQ_2)    tmr->close (tmr_no);  sequencer_busy = 0;}static intseq_sync (void){  unsigned long   flags;  if (qlen && !seq_playing && !PROCESS_ABORTING (seq_sleeper, seq_sleep_flag))    seq_startplay ();  DISABLE_INTR (flags);  if (qlen && !SOMEONE_WAITING (seq_sleeper, seq_sleep_flag))    {      DO_SLEEP (seq_sleeper, seq_sleep_flag, 0);    }  RESTORE_INTR (flags);  return qlen;}static voidmidi_outc (int dev, unsigned char data){  /*   * NOTE! Calls sleep(). Don't call this from interrupt.   */  int             n;  unsigned long   flags;  /*   * This routine sends one byte to the Midi channel.   * If the output Fifo is full, it waits until there   * is space in the queue   */  n = 3 * HZ;			/* Timeout */  DISABLE_INTR (flags);  while (n && !midi_devs[dev]->putc (dev, data))    {      DO_SLEEP (seq_sleeper, seq_sleep_flag, 4);      n--;    }  RESTORE_INTR (flags);}static voidseq_reset (void){  /*   * NOTE! Calls sleep(). Don't call this from interrupt.   */  int             i;  int             chn;  unsigned long   flags;  sound_stop_timer ();  seq_time = GET_TIME ();  prev_input_time = 0;  prev_event_time = 0;  qlen = qhead = qtail = 0;  iqlen = iqhead = iqtail = 0;

⌨️ 快捷键说明

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