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

📄 sequencer.c

📁 freebsd v4.4内核源码
💻 C
📖 第 1 页 / 共 3 页
字号:
  for (i = 0; i < max_synthdev; i++)    if (synth_open_mask & (1 << i))      if (synth_devs[i])	synth_devs[i]->reset (i);  if (seq_mode == SEQ_2)    {      for (chn = 0; chn < 16; chn++)	for (i = 0; i < max_synthdev; i++)	  if (synth_open_mask & (1 << i))	    if (synth_devs[i])	      {		synth_devs[i]->controller (i, chn, 123, 0);	/* All notes off */		synth_devs[i]->controller (i, chn, 121, 0);	/* Reset all ctl */		synth_devs[i]->bender (i, chn, 1 << 13);	/* Bender off */	      }    }  else    /* seq_mode == SEQ_1 */    {      for (i = 0; i < max_mididev; i++)	if (midi_written[i])	/*				 * Midi used. Some notes may still be playing				 */	  {	    /*	       *      Sending just a ACTIVE SENSING message should be enough to stop all	       *      playing notes. Since there are devices not recognizing the	       *      active sensing, we have to send some all notes off messages also.	     */	    midi_outc (i, 0xfe);	    for (chn = 0; chn < 16; chn++)	      {		midi_outc (i,			   (unsigned char) (0xb0 + (chn & 0x0f)));	/* control change */		midi_outc (i, 0x7b);	/* All notes off */		midi_outc (i, 0);	/* Dummy parameter */	      }	    midi_devs[i]->close (i);	    midi_written[i] = 0;	    midi_opened[i] = 0;	  }    }  seq_playing = 0;  DISABLE_INTR (flags);  if (SOMEONE_WAITING (seq_sleeper, seq_sleep_flag))    {      /*      printk ("Sequencer Warning: Unexpected sleeping process - Waking up\n"); */      WAKE_UP (seq_sleeper, seq_sleep_flag);    }  RESTORE_INTR (flags);}static voidseq_panic (void){  /*     * This routine is called by the application in case the user     * wants to reset the system to the default state.   */  seq_reset ();  /*     * Since some of the devices don't recognize the active sensing and     * all notes off messages, we have to shut all notes manually.     *     *      TO BE IMPLEMENTED LATER   */  /*     * Also return the controllers to their default states   */}intsequencer_ioctl (int dev, struct fileinfo *file,		 unsigned int cmd, unsigned int arg){  int             midi_dev, orig_dev;  int             mode = file->mode & O_ACCMODE;  orig_dev = dev = dev >> 4;  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:      if (dev)			/* Patch manager */	return RET_ERROR (EIO);      if (seq_mode != SEQ_2)	return RET_ERROR (EINVAL);      return tmr->ioctl (tmr_no, cmd, arg);      break;    case SNDCTL_TMR_SELECT:      if (dev)			/* Patch manager */	return RET_ERROR (EIO);      if (seq_mode != SEQ_2)	return RET_ERROR (EINVAL);      pending_timer = IOCTL_IN (arg);      if (pending_timer < 0 || pending_timer >= num_sound_timers)	{	  pending_timer = -1;	  return RET_ERROR (EINVAL);	}      return IOCTL_OUT (arg, pending_timer);      break;    case SNDCTL_SEQ_PANIC:      seq_panic ();      break;    case SNDCTL_SEQ_SYNC:      if (dev)			/*				 * Patch manager				 */	return RET_ERROR (EIO);      if (mode == OPEN_READ)	return 0;      while (qlen && !PROCESS_ABORTING (seq_sleeper, seq_sleep_flag))	seq_sync ();      if (qlen)	return RET_ERROR (EINTR);      else	return 0;      break;    case SNDCTL_SEQ_RESET:      if (dev)			/*				 * Patch manager				 */	return RET_ERROR (EIO);      seq_reset ();      return 0;      break;    case SNDCTL_SEQ_TESTMIDI:      if (dev)			/*				 * Patch manager				 */	return RET_ERROR (EIO);      midi_dev = IOCTL_IN (arg);      if (midi_dev >= max_mididev)	return RET_ERROR (ENXIO);      if (!midi_opened[midi_dev])	{	  int             err, mode;	  mode = file->mode & O_ACCMODE;	  if ((err = midi_devs[midi_dev]->open (midi_dev, mode,						sequencer_midi_input,						sequencer_midi_output)) < 0)	    return err;	}      midi_opened[midi_dev] = 1;      return 0;      break;    case SNDCTL_SEQ_GETINCOUNT:      if (dev)			/*				 * Patch manager				 */	return RET_ERROR (EIO);      if (mode == OPEN_WRITE)	return 0;      return IOCTL_OUT (arg, iqlen);      break;    case SNDCTL_SEQ_GETOUTCOUNT:      if (mode == OPEN_READ)	return 0;      return IOCTL_OUT (arg, SEQ_MAX_QUEUE - qlen);      break;    case SNDCTL_SEQ_CTRLRATE:      if (dev)			/* Patch manager */	return RET_ERROR (EIO);      /*       * If *arg == 0, just return the current rate       */      if (seq_mode == SEQ_2)	return tmr->ioctl (tmr_no, cmd, arg);      if (IOCTL_IN (arg) != 0)	return RET_ERROR (EINVAL);      return IOCTL_OUT (arg, HZ);      break;    case SNDCTL_SEQ_RESETSAMPLES:      dev = IOCTL_IN (arg);      if (dev < 0 || dev >= num_synths)	return RET_ERROR (ENXIO);      if (!(synth_open_mask & (1 << dev)) && !orig_dev)	return RET_ERROR (EBUSY);      if (!orig_dev && pmgr_present[dev])	pmgr_inform (dev, PM_E_PATCH_RESET, 0, 0, 0, 0);      return synth_devs[dev]->ioctl (dev, cmd, arg);      break;    case SNDCTL_SEQ_NRSYNTHS:      return IOCTL_OUT (arg, max_synthdev);      break;    case SNDCTL_SEQ_NRMIDIS:      return IOCTL_OUT (arg, max_mididev);      break;    case SNDCTL_SYNTH_MEMAVL:      {	int             dev = IOCTL_IN (arg);	if (dev < 0 || dev >= num_synths)	  return RET_ERROR (ENXIO);	if (!(synth_open_mask & (1 << dev)) && !orig_dev)	  return RET_ERROR (EBUSY);	return IOCTL_OUT (arg, synth_devs[dev]->ioctl (dev, cmd, arg));      }      break;    case SNDCTL_FM_4OP_ENABLE:      {	int             dev = IOCTL_IN (arg);	if (dev < 0 || dev >= num_synths)	  return RET_ERROR (ENXIO);	if (!(synth_open_mask & (1 << dev)))	  return RET_ERROR (ENXIO);	synth_devs[dev]->ioctl (dev, cmd, arg);	return 0;      }      break;    case SNDCTL_SYNTH_INFO:      {	struct synth_info inf;	int             dev;	IOCTL_FROM_USER ((char *) &inf, (char *) arg, 0, sizeof (inf));	dev = inf.device;	if (dev < 0 || dev >= max_synthdev)	  return RET_ERROR (ENXIO);	if (!(synth_open_mask & (1 << dev)) && !orig_dev)	  return RET_ERROR (EBUSY);	return synth_devs[dev]->ioctl (dev, cmd, arg);      }      break;    case SNDCTL_SEQ_OUTOFBAND:      {	struct seq_event_rec event;	unsigned long   flags;	IOCTL_FROM_USER ((char *) &event, (char *) arg, 0, sizeof (event));	DISABLE_INTR (flags);	play_event (event.arr);	RESTORE_INTR (flags);	return 0;      }      break;    case SNDCTL_MIDI_INFO:      {	struct midi_info inf;	int             dev;	IOCTL_FROM_USER ((char *) &inf, (char *) arg, 0, sizeof (inf));	dev = inf.device;	if (dev < 0 || dev >= max_mididev)	  return RET_ERROR (ENXIO);	IOCTL_TO_USER ((char *) arg, 0, (char *) &(midi_devs[dev]->info), sizeof (inf));	return 0;      }      break;    case SNDCTL_PMGR_IFACE:      {	struct patmgr_info *inf;	int             dev, err;	if ((inf = (struct patmgr_info *) KERNEL_MALLOC (sizeof (*inf))) == NULL)	  {	    printk ("patmgr: Can't allocate memory for a message\n");	    return RET_ERROR (EIO);	  }	IOCTL_FROM_USER ((char *) inf, (char *) arg, 0, sizeof (*inf));	dev = inf->device;	if (dev < 0 || dev >= num_synths)	  {	    KERNEL_FREE (inf);	    return RET_ERROR (ENXIO);	  }	if (!synth_devs[dev]->pmgr_interface)	  {	    KERNEL_FREE (inf);	    return RET_ERROR (ENXIO);	  }	if ((err = synth_devs[dev]->pmgr_interface (dev, inf)) == -1)	  {	    KERNEL_FREE (inf);	    return err;	  }	IOCTL_TO_USER ((char *) arg, 0, (char *) inf, sizeof (*inf));	KERNEL_FREE (inf);	return 0;      }      break;    case SNDCTL_PMGR_ACCESS:      {	struct patmgr_info *inf;	int             dev, err;	if ((inf = (struct patmgr_info *) KERNEL_MALLOC (sizeof (*inf))) == NULL)	  {	    printk ("patmgr: Can't allocate memory for a message\n");	    return RET_ERROR (EIO);	  }	IOCTL_FROM_USER ((char *) inf, (char *) arg, 0, sizeof (*inf));	dev = inf->device;	if (dev < 0 || dev >= num_synths)	  {	    KERNEL_FREE (inf);	    return RET_ERROR (ENXIO);	  }	if (!pmgr_present[dev])	  {	    KERNEL_FREE (inf);	    return RET_ERROR (ESRCH);	  }	if ((err = pmgr_access (dev, inf)) < 0)	  {	    KERNEL_FREE (inf);	    return err;	  }	IOCTL_TO_USER ((char *) arg, 0, (char *) inf, sizeof (*inf));	KERNEL_FREE (inf);	return 0;      }      break;    case SNDCTL_SEQ_TRESHOLD:      {	int             tmp = IOCTL_IN (arg);	if (dev)		/*				 * Patch manager				 */	  return RET_ERROR (EIO);	if (tmp < 1)	  tmp = 1;	if (tmp >= SEQ_MAX_QUEUE)	  tmp = SEQ_MAX_QUEUE - 1;	output_treshold = tmp;	return 0;      }      break;    case SNDCTL_MIDI_PRETIME:      {	int             val = IOCTL_IN (arg);	if (val < 0)	  val = 0;	val = (HZ * val) / 10;	pre_event_timeout = val;	return IOCTL_OUT (arg, val);      }      break;    default:      if (dev)			/*				 * Patch manager				 */	return RET_ERROR (EIO);      if (mode == OPEN_READ)	return RET_ERROR (EIO);      if (!synth_devs[0])	return RET_ERROR (ENXIO);      if (!(synth_open_mask & (1 << 0)))	return RET_ERROR (ENXIO);      return synth_devs[0]->ioctl (0, cmd, arg);      break;    }  return RET_ERROR (EINVAL);}#ifdef ALLOW_SELECTintsequencer_select (int dev, struct fileinfo *file, int sel_type, select_table * wait){  unsigned long   flags;  dev = dev >> 4;  switch (sel_type)    {    case SEL_IN:      DISABLE_INTR (flags);      if (!iqlen)	{#if defined(__FreeBSD__)          selrecord(wait, &selinfo[dev]);#else	  midi_sleep_flag.mode = WK_SLEEP;	  select_wait (&midi_sleeper, wait);#endif	  RESTORE_INTR (flags);	  return 0;	}      midi_sleep_flag.mode &= ~WK_SLEEP;      RESTORE_INTR (flags);      return 1;      break;    case SEL_OUT:      DISABLE_INTR (flags);      if (qlen >= SEQ_MAX_QUEUE)	{#if defined(__FreeBSD__)          selrecord(wait, &selinfo[dev]);#else	  seq_sleep_flag.mode = WK_SLEEP;	  select_wait (&seq_sleeper, wait);#endif	  RESTORE_INTR (flags);	  return 0;	}      seq_sleep_flag.mode &= ~WK_SLEEP;      RESTORE_INTR (flags);      return 1;      break;    case SEL_EX:      return 0;    }  return 0;}#endifvoidsequencer_timer (void){  seq_startplay ();}intnote_to_freq (int note_num){  /*   * This routine converts a midi note to a frequency (multiplied by 1000)   */  int             note, octave, note_freq;  int             notes[] =  {    261632, 277189, 293671, 311132, 329632, 349232,    369998, 391998, 415306, 440000, 466162, 493880  };#define BASE_OCTAVE	5  octave = note_num / 12;  note = note_num % 12;  note_freq = notes[note];  if (octave < BASE_OCTAVE)    note_freq >>= (BASE_OCTAVE - octave);  else if (octave > BASE_OCTAVE)    note_freq <<= (octave - BASE_OCTAVE);  /*   * note_freq >>= 1;   */  return note_freq;}unsigned longcompute_finetune (unsigned long base_freq, int bend, int range){  unsigned long   amount;  int             negative, semitones, cents, multiplier = 1;  if (!bend)    return base_freq;  if (!range)    return base_freq;  if (!base_freq)    return base_freq;  if (range >= 8192)    range = 8191;  bend = bend * range / 8192;  if (!bend)    return base_freq;  negative = bend < 0 ? 1 : 0;  if (bend < 0)    bend *= -1;  if (bend > range)    bend = range;  /*     if (bend > 2399)     bend = 2399;   */  while (bend > 2399)    {      multiplier *= 4;      bend -= 2400;    }  semitones = bend / 100;  cents = bend % 100;  amount = (int) (semitone_tuning[semitones] * multiplier * cent_tuning[cents])    / 10000;  if (negative)    return (base_freq * 10000) / amount;	/*						 * Bend down						 */  else    return (base_freq * amount) / 10000;	/*						 * Bend up						 */}longsequencer_init (long mem_start){  sequencer_ok = 1;  PERMANENT_MALLOC (unsigned char *, queue, SEQ_MAX_QUEUE * EV_SZ, mem_start);  PERMANENT_MALLOC (unsigned char *, iqueue, SEQ_MAX_QUEUE * IEV_SZ, mem_start);  return mem_start;}#else/* * Stub version */intsequencer_read (int dev, struct fileinfo *file, snd_rw_buf * buf, int count){  return RET_ERROR (EIO);}intsequencer_write (int dev, struct fileinfo *file, snd_rw_buf * buf, int count){  return RET_ERROR (EIO);}intsequencer_open (int dev, struct fileinfo *file){  return RET_ERROR (ENXIO);}voidsequencer_release (int dev, struct fileinfo *file){}intsequencer_ioctl (int dev, struct fileinfo *file,		 unsigned int cmd, unsigned int arg){  return RET_ERROR (EIO);}intsequencer_lseek (int dev, struct fileinfo *file, off_t offset, int orig){  return RET_ERROR (EIO);}longsequencer_init (long mem_start){  return mem_start;}#ifdef ALLOW_SELECTintsequencer_select (int dev, struct fileinfo *file, int sel_type, select_table * wait){  return RET_ERROR (EIO);}#endif#endif#endif

⌨️ 快捷键说明

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