亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? gus_wave.c

?? LINUX1.0源代碼,代碼條理清晰
?? C
?? 第 1 頁 / 共 5 頁
字號:
  target = voices[voice].initial_volume;

  if (ramp_time == INSTANT_RAMP)
    {
      gus_rampoff ();
      gus_voice_volume (target);
      RESTORE_INTR (flags);
      return;
    }

  if (ramp_time == FAST_RAMP)
    rate = 63;
  else
    rate = 16;
  gus_ramp_rate (0, rate);

  if ((target - current) / 64 == 0)	/* 
					 * Too close 
					 */
    {
      gus_rampoff ();
      gus_voice_volume (target);
      RESTORE_INTR (flags);
      return;
    }

  if (target > current)
    {
      if (target > (4095 - 65))
	target = 4095 - 65;
      gus_ramp_range (current, target);
      gus_rampon (0x00);	/* 
				 * Ramp up, once, no irq 
				 */
    }
  else
    {
      if (target < 65)
	target = 65;

      gus_ramp_range (target, current);
      gus_rampon (0x40);	/* 
				 * Ramp down, once, no irq 
				 */
    }
  RESTORE_INTR (flags);
}

static void
dynamic_volume_change (int voice)
{
  unsigned char   status;
  unsigned long   flags;

  DISABLE_INTR (flags);
  gus_select_voice (voice);
  status = gus_read8 (0x00);	/* 
				 * Voice status 
				 */
  RESTORE_INTR (flags);

  if (status & 0x03)
    return;			/* 
				 * Voice not started 
				 */

  if (!(voices[voice].mode & WAVE_ENVELOPES))
    {
      compute_and_set_volume (voice, voices[voice].midi_volume, 1);
      return;
    }

  /* 
   * Voice is running and has envelopes.
   */

  DISABLE_INTR (flags);
  gus_select_voice (voice);
  status = gus_read8 (0x0d);	/* 
				 * Ramping status 
				 */
  RESTORE_INTR (flags);

  if (status & 0x03)		/* 
				 * Sustain phase? 
				 */
    {
      compute_and_set_volume (voice, voices[voice].midi_volume, 1);
      return;
    }

  if (voices[voice].env_phase < 0)
    return;

  compute_volume (voice, voices[voice].midi_volume);

#if 0				/* 
				 * * * Is this really required   */
  voices[voice].current_volume =
    gus_read16 (0x09) >> 4;	/* 
				 * Get current volume 
				 */

  voices[voice].env_phase--;
  step_envelope (voice);
#endif
}

static void
guswave_controller (int dev, int voice, int ctrl_num, int value)
{
  unsigned long   flags;
  unsigned long   freq;

  if (voice < 0 || voice > 31)
    return;

  switch (ctrl_num)
    {
    case CTRL_PITCH_BENDER:
      voices[voice].bender = value;

      if (voices[voice].volume_irq_mode != VMODE_START_NOTE)
        {
          freq = compute_finetune (voices[voice].orig_freq, value, voices[voice].bender_range);
          voices[voice].current_freq = freq;

          DISABLE_INTR (flags);
          gus_select_voice (voice);
          gus_voice_freq (freq);
          RESTORE_INTR (flags);
        }
      break;

    case CTRL_PITCH_BENDER_RANGE:
      voices[voice].bender_range = value;
      break;
#ifdef FUTURE_VERSION
    case CTL_EXPRESSION:
      value /= 128;
#endif
    case CTRL_EXPRESSION:
      volume_method = VOL_METHOD_ADAGIO;
      voices[voice].expression_vol = value;
      if (voices[voice].volume_irq_mode != VMODE_START_NOTE)
         dynamic_volume_change (voice);
      break;

#ifdef FUTURE_VERSION
    case CTL_PAN:
      voices[voice].panning = (value * 2) - 128;
      break;

    case CTL_MAIN_VOLUME:
      value = (value * 100) / 16383;
#endif

    case CTRL_MAIN_VOLUME:
      volume_method = VOL_METHOD_ADAGIO;
      voices[voice].main_vol = value;
      if (voices[voice].volume_irq_mode != VMODE_START_NOTE)
         dynamic_volume_change (voice);
      break;

    default:			/* 
				 * Ignore 
				 */
      break;
    }
}

static int
guswave_start_note2 (int dev, int voice, int note_num, int volume)
{
  int             sample, best_sample, best_delta, delta_freq;
  int             is16bits, samplep, patch, pan;
  unsigned long   note_freq, base_note, freq, flags;
  unsigned char   mode = 0;

  if (voice < 0 || voice > 31)
    {
      printk ("GUS: Invalid voice\n");
      return RET_ERROR (EINVAL);
    }

  if (note_num == 255)
    {
      if (voices[voice].mode & WAVE_ENVELOPES)
	{
	  voices[voice].midi_volume = volume;
	  dynamic_volume_change (voice);
	  return 0;
	}

      compute_and_set_volume (voice, volume, 1);
      return 0;
    }

  if ((patch = patch_map[voice]) == -1)
    {
      return RET_ERROR (EINVAL);
    }

  if ((samplep = patch_table[patch]) == -1)
    {
      return RET_ERROR (EINVAL);
    }

  note_freq = note_to_freq (note_num);

  /* 
   * Find a sample within a patch so that the note_freq is between low_note
   * and high_note.
   */
  sample = -1;

  best_sample = samplep;
  best_delta = 1000000;
  while (samplep >= 0 && sample == -1)
    {
      delta_freq = note_freq - samples[samplep].base_note;
      if (delta_freq < 0)
	delta_freq = -delta_freq;
      if (delta_freq < best_delta)
	{
	  best_sample = samplep;
	  best_delta = delta_freq;
	}
      if (samples[samplep].low_note <= note_freq && note_freq <= samples[samplep].high_note)
	sample = samplep;
      else
	samplep = samples[samplep].key;		/* 
						 * Follow link 
						 */
    }
  if (sample == -1)
    sample = best_sample;

  if (sample == -1)
    {
      printk ("GUS: Patch %d not defined for note %d\n", patch, note_num);
      return 0;			/* 
				 * Should play default patch ??? 
				 */
    }

  is16bits = (samples[sample].mode & WAVE_16_BITS) ? 1 : 0;	/* 
								 * 8 or 16
								 * bit
								 * samples 
								 */
  voices[voice].mode = samples[sample].mode;
  voices[voice].patch_vol = samples[sample].volume;

  if (voices[voice].mode & WAVE_ENVELOPES)
    {
      int             i;

      for (i = 0; i < 6; i++)
	{
	  voices[voice].env_rate[i] = samples[sample].env_rate[i];
	  voices[voice].env_offset[i] = samples[sample].env_offset[i];
	}
    }

  sample_map[voice] = sample;

  base_note = samples[sample].base_note / 100;	/* 
						 * To avoid overflows 
						 */
  note_freq /= 100;

  freq = samples[sample].base_freq * note_freq / base_note;

  voices[voice].orig_freq = freq;

  /* 
   * Since the pitch bender may have been set before playing the note, we
   * have to calculate the bending now.
   */

  freq = compute_finetune (voices[voice].orig_freq, voices[voice].bender, voices[voice].bender_range);
  voices[voice].current_freq = freq;

  pan = (samples[sample].panning + voices[voice].panning) / 32;
  pan += 7;
  if (pan < 0)
    pan = 0;
  if (pan > 15)
    pan = 15;

  if (samples[sample].mode & WAVE_16_BITS)
    {
      mode |= 0x04;		/* 
				 * 16 bits 
				 */
      if ((sample_ptrs[sample] >> 18) !=
	  ((sample_ptrs[sample] + samples[sample].len) >> 18))
	printk ("GUS: Sample address error\n");
    }

  /*************************************************************************
   *    CAUTION!        Interrupts disabled. Don't return before enabling
   *************************************************************************/

  DISABLE_INTR (flags);
  gus_select_voice (voice);
  gus_voice_off ();		/* 
				 * It may still be running 
				 */
  gus_rampoff ();
  if (voices[voice].mode & WAVE_ENVELOPES)
    {
      compute_volume (voice, volume);
      init_envelope (voice);
    }
  else
    compute_and_set_volume (voice, volume, 0);

  if (samples[sample].mode & WAVE_LOOP_BACK)
    gus_write_addr (0x0a, sample_ptrs[sample] + samples[sample].len -
		    voices[voice].offset_pending, is16bits);	/* Sample
								 * start=end */
  else
    gus_write_addr (0x0a, sample_ptrs[sample] + voices[voice].offset_pending,
		    is16bits);	/* Sample start=begin */

  if (samples[sample].mode & WAVE_LOOPING)
    {
      mode |= 0x08;		/* 
				 * Looping on 
				 */

      if (samples[sample].mode & WAVE_BIDIR_LOOP)
	mode |= 0x10;		/* 
				 * Bidirectional looping on 
				 */

      if (samples[sample].mode & WAVE_LOOP_BACK)
	{
	  gus_write_addr (0x0a,
			  sample_ptrs[sample] + samples[sample].loop_end -
			  voices[voice].offset_pending, is16bits);
	  mode |= 0x40;
	}

      gus_write_addr (0x02, sample_ptrs[sample] + samples[sample].loop_start, is16bits);	/* 
												 * Loop 
												 * start 
												 * location 
												 */
      gus_write_addr (0x04, sample_ptrs[sample] + samples[sample].loop_end, is16bits);	/* 
											 * Loop 
											 * end 
											 * location 
											 */
    }
  else
    {
      mode |= 0x20;		/* 
				 * Loop irq at the end 
				 */
      voices[voice].loop_irq_mode = LMODE_FINISH;	/* 
							 * Ramp it down at
							 * the * end 
							 */
      voices[voice].loop_irq_parm = 1;
      gus_write_addr (0x02, sample_ptrs[sample], is16bits);	/* 
								 * Loop start 
								 * location 
								 */
      gus_write_addr (0x04, sample_ptrs[sample] + samples[sample].len-1, is16bits);	/* 
											 * Loop 
											 * end 
											 * location 
											 */
    }
  gus_voice_freq (freq);
  gus_voice_balance (pan);
  gus_voice_on (mode);
  RESTORE_INTR (flags);

  return 0;
}

/* 
 * * New guswave_start_note by Andrew J. Robinson attempts to minimize
 * clicking  * when the note playing on the voice is changed.  It uses volume 
 * ramping. */

static int
guswave_start_note (int dev, int voice, int note_num, int volume)
{
  long int        flags;
  int             mode;
  int             ret_val = 0;

  DISABLE_INTR (flags);
  if (note_num == 255)
    {
      if (voices[voice].volume_irq_mode == VMODE_START_NOTE)
	voices[voice].volume_pending = volume;
      else
	ret_val = guswave_start_note2 (dev, voice, note_num, volume);
    }
  else
    {
       gus_select_voice (voice);
       mode = gus_read8 (0x00);
       if (mode & 0x20)
         gus_write8 (0x00, mode & 0xdf);    /* No interrupt! */

       voices[voice].offset_pending = 0;
       voices[voice].kill_pending = 0;
       voices[voice].volume_irq_mode = 0;
       voices[voice].loop_irq_mode = 0;

       if (voices[voice].sample_pending >= 0)
       {
         guswave_set_instr (voices[voice].dev_pending, voice,
         voices[voice].sample_pending);
         voices[voice].sample_pending = -1;
       }

      if ((mode & 0x01) || ((gus_read16 (0x09) >> 4) < 2065))
	{
	  ret_val = guswave_start_note2 (dev, voice, note_num, volume);
	}
      else
	{
	  voices[voice].dev_pending = dev;
	  voices[voice].note_pending = note_num;
	  voices[voice].volume_pending = volume;
	  voices[voice].volume_irq_mode = VMODE_START_NOTE;

	  gus_rampoff ();
	  gus_ramp_range (2000, 4065);
	  gus_ramp_rate (0, 63);	/* Fastest possible rate */
	  gus_rampon (0x20 | 0x40);	/* Ramp down, once, irq */
	}
    }
  RESTORE_INTR (flags);
  return ret_val;
}

static void
guswave_reset (int dev)
{
  int             i;

  for (i = 0; i < 32; i++)
    {
      gus_voice_init (i);
      gus_voice_init2 (i);
    }
}

static int
guswave_open (int dev, int mode)
{
  int             err;

  if (gus_busy)
    return RET_ERROR (EBUSY);

  gus_initialize ();

  if ((err = DMAbuf_open_dma (gus_devnum)))
    return err;

  RESET_WAIT_QUEUE (dram_sleeper, dram_sleep_flag);
  gus_busy = 1;
  active_device = GUS_DEV_WAVE;

  gus_reset ();

  return 0;
}

static void
guswave_close (int dev)
{
  gus_busy = 0;
  active_device = 0;
  gus_reset ();

  DMAbuf_close_dma (gus_devnum);
}

static int
guswave_load_patch (int dev, int format, snd_rw_buf * addr,
		    int offs, int count, int pmgr_flag)
{
  struct patch_info patch;
  int             instr;
  long            sizeof_patch;

  unsigned long   blk_size, blk_end, left, src_offs, target;

  sizeof_patch = (long) &patch.data[0] - (long) &patch;		/* 
								 * Size of
								 * the header
								 * * info 
								 */

  if (format != GUS_PATCH)
    {
      printk ("GUS Error: Invalid patch format (key) 0x%x\n", format);
      return RET_ERROR (EINVAL);
    }

  if (count < sizeof_patch)
    {
      printk ("GUS Error: Patch header too short\n");
      return RET_ERROR (EINVAL);
    }

  count -= sizeof_patch;

  if (free_sample >= MAX_SAMPLE)
    {
      printk ("GUS: Sample table full\n");
      return RET_ERROR (ENOSPC);
    }

  /* 
   * Copy the header from user space but ignore the first bytes which have
   * been transferred already.
   */

  COPY_FROM_USER (&((char *) &patch)[offs], addr, offs, sizeof_patch - offs);

  instr = patch.instr_no;

  if (instr < 0 || instr > MAX_PATCH)
    {
      printk ("GUS: Invalid patch number %d\n", instr);
      return RET_ERROR (EINVAL);
    }

  if (count < patch.len)
    {
      printk ("GUS Warning: Patch record too short (%d<%d)\n",
	      count, (int) patch.len);
      patch.len = count;
    }

  if (patch.len <= 0 || patch.len > gus_mem_size)
    {
      printk ("GUS: Invalid sample length %d\n", (int) patch.len);
      return RET_ERROR (EINVAL);
    }

  if (patch.mode & WAVE_LOOPING)
    {
      if (patch.loop_start < 0 || patch.loop_start >= patch.len)
	{
	  printk ("GUS: Invalid loop start\n");
	  return RET_ERROR (EINVAL);
	}

      if (patch.loop_end < patch.loop_start || patch.loop_end > patch.len)
	{
	  printk ("GUS: Invalid loop end\n");
	  return RET_ERROR (EINVAL);
	}
    }

  free_mem_ptr = (free_mem_ptr + 31) & ~31;	/* 
						 * Alignment 32 bytes 
						 */

#define GUS_BANK_SIZE (256*1024)

  if (patch.mode & WAVE_16_BITS)
    {
      /* 
       * 16 bit samples must fit one 256k bank.
       */
      if (patch.len >= GUS_BANK_SIZE)
	{
	  printk ("GUS: Sample (16 bit) too long %d\n", (int) patch.len);
	  return RET_ERROR (ENOSPC);
	}

      if ((free_mem_ptr / GUS_BANK_SIZE) !=
	  ((free_mem_ptr + patch.len) / GUS_BANK_SIZE))
	{
	  unsigned long   tmp_mem =	/* 
					 * Align to 256K*N 
					 */
	  ((free_mem_ptr / GUS_BANK_SIZE) + 1) * GUS_BANK_SIZE;

	  if ((tmp_mem + patch.len) > gus_mem_size)

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产精品一品视频| 在线精品亚洲一区二区不卡| 99国产精品一区| 欧美精品久久一区二区三区| 国产精品国产三级国产aⅴ无密码| 国产精品自拍av| 欧美日韩一区二区三区视频| 久久精品这里都是精品| 日韩国产在线观看一区| 欧美在线不卡一区| 亚洲人精品午夜| 成人免费毛片aaaaa**| 欧美r级电影在线观看| 婷婷成人激情在线网| 色哟哟日韩精品| 18欧美乱大交hd1984| 国产a精品视频| 久久亚洲精品小早川怜子| 蜜臀av在线播放一区二区三区| 欧洲视频一区二区| 亚洲色图欧洲色图婷婷| 成人激情动漫在线观看| 欧美xingq一区二区| 日本亚洲电影天堂| 日韩欧美国产一区二区在线播放 | 日韩欧美国产一区在线观看| 一区二区三区四区在线| 99热99精品| 中文字幕亚洲区| 成人av片在线观看| 亚洲欧美日韩在线播放| 97精品视频在线观看自产线路二| 国产精品久久久久久一区二区三区| 国产精品888| 国产精品欧美精品| 99精品久久只有精品| 亚洲国产精品av| 大桥未久av一区二区三区中文| 国产欧美一区二区三区在线看蜜臀 | 欧美丝袜丝交足nylons图片| 中文字幕欧美一| 日韩三级免费观看| 亚洲综合小说图片| 精品视频123区在线观看| 天涯成人国产亚洲精品一区av| 欧美疯狂性受xxxxx喷水图片| 日本成人在线不卡视频| 日韩午夜电影av| 国产真实乱对白精彩久久| 国产亚洲综合在线| 色诱亚洲精品久久久久久| 亚洲韩国精品一区| 日韩一级片网址| 国产成人超碰人人澡人人澡| 亚洲欧美国产毛片在线| 欧美日韩一区不卡| 狠狠色综合色综合网络| 综合分类小说区另类春色亚洲小说欧美| 91一区二区在线| 天天综合色天天| 国产亚洲精品中文字幕| 在线国产亚洲欧美| 国产一区二区三区四区在线观看| 国产精品久久久久久久久久免费看 | 石原莉奈在线亚洲三区| 日韩精品一区二区三区老鸭窝| 美女诱惑一区二区| 中文字幕一区二区三区四区不卡| 欧美亚州韩日在线看免费版国语版 | 成人欧美一区二区三区视频网页| 91最新地址在线播放| 日精品一区二区| 国产精品久久久久久久久图文区 | 国产精品网站一区| 欧美日韩精品三区| 成人精品在线视频观看| 日本欧美在线观看| 日韩一区欧美小说| 2021中文字幕一区亚洲| 欧美三级日本三级少妇99| 91免费版在线看| 日本不卡在线视频| 亚洲丝袜自拍清纯另类| 精品人伦一区二区色婷婷| 色综合久久88色综合天天免费| 精品一区二区三区在线观看| 亚洲一区二区三区四区在线| 中文一区一区三区高中清不卡| 宅男噜噜噜66一区二区66| 色av一区二区| 不卡在线视频中文字幕| 国产自产v一区二区三区c| 天天操天天色综合| 亚洲午夜久久久久久久久久久 | 欧美精品一区二| 欧美性大战xxxxx久久久| 国产91精品久久久久久久网曝门| 日韩电影在线观看一区| 亚洲一级二级三级在线免费观看| 国产精品国产三级国产aⅴ原创 | 色www精品视频在线观看| 国产精品1024| 久久99国产精品尤物| 日本不卡一区二区| 天天操天天综合网| 日韩专区在线视频| 日韩精彩视频在线观看| 视频一区在线视频| 日韩专区在线视频| 青青草国产成人99久久| 美日韩一级片在线观看| 麻豆成人久久精品二区三区红| 日本一区中文字幕| 九九精品一区二区| 国产一区在线观看视频| 国产麻豆一精品一av一免费| 国产麻豆9l精品三级站| 粉嫩欧美一区二区三区高清影视| 成人精品视频一区二区三区尤物| 成人自拍视频在线| 91免费精品国自产拍在线不卡| 色又黄又爽网站www久久| 欧美在线高清视频| 日韩午夜在线观看| 久久久亚洲国产美女国产盗摄| 精品国产网站在线观看| 中文字幕久久午夜不卡| 综合精品久久久| 午夜影院久久久| 不卡电影一区二区三区| 91免费看视频| 7777精品伊人久久久大香线蕉| 欧美一激情一区二区三区| 久久精品一级爱片| 日韩毛片精品高清免费| 亚洲成人黄色影院| 国内精品国产三级国产a久久| 国产成人免费在线观看不卡| 99久久久无码国产精品| 欧美日韩精品一区二区在线播放| 欧美一区二区三区免费视频 | 国产精品77777| 色综合久久中文字幕综合网| 欧美三级在线看| 精品国产91久久久久久久妲己 | 欧美亚洲国产一区二区三区| 在线成人av影院| 国产午夜亚洲精品理论片色戒| 亚洲图片另类小说| 捆绑紧缚一区二区三区视频| 国产v日产∨综合v精品视频| 色哟哟国产精品免费观看| 91精品国产欧美日韩| 欧美激情艳妇裸体舞| 日韩综合小视频| thepron国产精品| 日韩欧美国产精品| 一区二区三区美女视频| 国内精品国产三级国产a久久| 色88888久久久久久影院野外| 欧美一级欧美三级在线观看 | 色婷婷综合激情| 欧美大片一区二区| 亚洲电影一级黄| 成人中文字幕在线| 亚洲精品一线二线三线无人区| 一区二区三区在线看| 风流少妇一区二区| 欧美一区三区二区| 亚洲综合色自拍一区| 国产99精品视频| 欧美大白屁股肥臀xxxxxx| 亚洲在线视频网站| 成人h精品动漫一区二区三区| 精品国产免费久久| 日韩影院精彩在线| 欧洲精品一区二区| 亚洲美腿欧美偷拍| www.亚洲国产| 国产精品美女久久久久aⅴ国产馆| 久久成人免费网| 911国产精品| 视频一区二区三区在线| 欧美色区777第一页| 亚洲色图视频免费播放| 99久久久无码国产精品| 国产精品对白交换视频 | 中文字幕一区二区在线播放| 国产精品一品视频| 久久蜜桃av一区精品变态类天堂 | 首页亚洲欧美制服丝腿| 欧美日产在线观看| 午夜精品久久一牛影视| 欧美日韩激情一区二区三区| 亚洲成人精品影院| 欧美日本在线观看| 蜜桃视频第一区免费观看| 日韩欧美国产一二三区| 极品少妇xxxx精品少妇偷拍| xnxx国产精品|