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

📄 gus_wave.c

📁 LINUX1.0内核源代码,学习LINUX编程的一定要看。
💻 C
📖 第 1 页 / 共 5 页
字号:
				 */	    gus_poke (target + i, data);	  }      }#else /*        * * * GUS_NO_DMA   */      {	unsigned long   address, hold_address;	unsigned char   dma_command;	unsigned long   flags;	/* 	 * OK, move now. First in and then out.	 */	COPY_FROM_USER (snd_raw_buf[gus_devnum][0],			addr, sizeof_patch + src_offs,			blk_size);	DISABLE_INTR (flags);	/******** INTERRUPTS DISABLED NOW ********/	gus_write8 (0x41, 0);	/* 				 * Disable GF1 DMA 				 */	DMAbuf_start_dma (gus_devnum, snd_raw_buf_phys[gus_devnum][0],			  blk_size, DMA_MODE_WRITE);	/* 	 * Set the DRAM address for the wave data	 */	address = target;	if (sound_dsp_dmachan[gus_devnum] > 3)	  {	    hold_address = address;	    address = address >> 1;	    address &= 0x0001ffffL;	    address |= (hold_address & 0x000c0000L);	  }	gus_write16 (0x42, (address >> 4) & 0xffff);	/* 							 * DRAM DMA address 							 */	/* 	 * Start the DMA transfer	 */	dma_command = 0x21;	/* 				 * IRQ enable, DMA start 				 */	if (patch.mode & WAVE_UNSIGNED)	  dma_command |= 0x80;	/* 				 * Invert MSB 				 */	if (patch.mode & WAVE_16_BITS)	  dma_command |= 0x40;	/* 				 * 16 bit _DATA_ 				 */	if (sound_dsp_dmachan[gus_devnum] > 3)	  dma_command |= 0x04;	/* 				 * 16 bit DMA channel 				 */	gus_write8 (0x41, dma_command);		/* 						 * Let's go luteet (=bugs) 						 */	/* 	 * Sleep here until the DRAM DMA done interrupt is served	 */	active_device = GUS_DEV_WAVE;	DO_SLEEP (dram_sleeper, dram_sleep_flag, HZ);	if (TIMED_OUT (dram_sleeper, dram_sleep_flag))	  printk ("GUS: DMA Transfer timed out\n");	RESTORE_INTR (flags);      }#endif /*         * * * GUS_NO_DMA   */      /*        * Now the next part       */      left -= blk_size;      src_offs += blk_size;      target += blk_size;      gus_write8 (0x41, 0);	/* 				 * Stop DMA 				 */    }  free_mem_ptr += patch.len;  if (!pmgr_flag)    pmgr_inform (dev, PM_E_PATCH_LOADED, instr, free_sample, 0, 0);  free_sample++;  return 0;}static voidguswave_hw_control (int dev, unsigned char *event){  int             voice, cmd;  unsigned short  p1, p2;  unsigned long   plong, flags;  cmd = event[2];  voice = event[3];  p1 = *(unsigned short *) &event[4];  p2 = *(unsigned short *) &event[6];  plong = *(unsigned long *) &event[4];  if ((voices[voice].volume_irq_mode == VMODE_START_NOTE) &&      (cmd != _GUS_VOICESAMPLE) && (cmd != _GUS_VOICE_POS))    do_volume_irq (voice);  switch (cmd)    {    case _GUS_NUMVOICES:      DISABLE_INTR (flags);      gus_select_voice (voice);      gus_select_max_voices (p1);      RESTORE_INTR (flags);      break;    case _GUS_VOICESAMPLE:      guswave_set_instr (dev, voice, p1);      break;    case _GUS_VOICEON:      DISABLE_INTR (flags);      gus_select_voice (voice);      p1 &= ~0x20;		/* 				 * Disable intr 				 */      gus_voice_on (p1);      RESTORE_INTR (flags);      break;    case _GUS_VOICEOFF:      DISABLE_INTR (flags);      gus_select_voice (voice);      gus_voice_off ();      RESTORE_INTR (flags);      break;    case _GUS_VOICEFADE:      DISABLE_INTR (flags);      gus_select_voice (voice);      gus_voice_fade (voice);      RESTORE_INTR (flags);      break;    case _GUS_VOICEMODE:      DISABLE_INTR (flags);      gus_select_voice (voice);      p1 &= ~0x20;		/* 				 * Disable intr 				 */      gus_voice_mode (p1);      RESTORE_INTR (flags);      break;    case _GUS_VOICEBALA:      DISABLE_INTR (flags);      gus_select_voice (voice);      gus_voice_balance (p1);      RESTORE_INTR (flags);      break;    case _GUS_VOICEFREQ:      DISABLE_INTR (flags);      gus_select_voice (voice);      gus_voice_freq (plong);      RESTORE_INTR (flags);      break;    case _GUS_VOICEVOL:      DISABLE_INTR (flags);      gus_select_voice (voice);      gus_voice_volume (p1);      RESTORE_INTR (flags);      break;    case _GUS_VOICEVOL2:	/* 				 * Just update the voice value 				 */      voices[voice].initial_volume =	voices[voice].current_volume = p1;      break;    case _GUS_RAMPRANGE:      if (voices[voice].mode & WAVE_ENVELOPES)	break;			/* 				 * NO-NO 				 */      DISABLE_INTR (flags);      gus_select_voice (voice);      gus_ramp_range (p1, p2);      RESTORE_INTR (flags);      break;    case _GUS_RAMPRATE:      if (voices[voice].mode & WAVE_ENVELOPES)	break;			/* 				 * NO-NO 				 */      DISABLE_INTR (flags);      gus_select_voice (voice);      gus_ramp_rate (p1, p2);      RESTORE_INTR (flags);      break;    case _GUS_RAMPMODE:      if (voices[voice].mode & WAVE_ENVELOPES)	break;			/* 				 * NO-NO 				 */      DISABLE_INTR (flags);      gus_select_voice (voice);      p1 &= ~0x20;		/* 				 * Disable intr 				 */      gus_ramp_mode (p1);      RESTORE_INTR (flags);      break;    case _GUS_RAMPON:      if (voices[voice].mode & WAVE_ENVELOPES)	break;			/* 				 * NO-NO 				 */      DISABLE_INTR (flags);      gus_select_voice (voice);      p1 &= ~0x20;		/* 				 * Disable intr 				 */      gus_rampon (p1);      RESTORE_INTR (flags);      break;    case _GUS_RAMPOFF:      if (voices[voice].mode & WAVE_ENVELOPES)	break;			/* 				 * NO-NO 				 */      DISABLE_INTR (flags);      gus_select_voice (voice);      gus_rampoff ();      RESTORE_INTR (flags);      break;    case _GUS_VOLUME_SCALE:      volume_base = p1;      volume_scale = p2;      break;    case _GUS_VOICE_POS:      DISABLE_INTR (flags);      gus_select_voice (voice);      gus_set_voice_pos (voice, plong);      RESTORE_INTR (flags);      break;    default:;    }}static intgus_sampling_set_speed (int speed){  if (speed <= 0)    return gus_sampling_speed;  if (speed > 44100)    speed = 44100;  gus_sampling_speed = speed;  return speed;}static intgus_sampling_set_channels (int channels){  if (!channels)    return gus_sampling_channels;  if (channels > 2)    channels = 2;  if (channels < 1)    channels = 1;  gus_sampling_channels = channels;  return channels;}static intgus_sampling_set_bits (int bits){  if (!bits)    return gus_sampling_bits;  if (bits != 8 && bits != 16)    bits = 8;  gus_sampling_bits = bits;  return bits;}static intgus_sampling_ioctl (int dev, unsigned int cmd, unsigned int arg, int local){  switch (cmd)    {    case SOUND_PCM_WRITE_RATE:      if (local)	return gus_sampling_set_speed (arg);      return IOCTL_OUT (arg, gus_sampling_set_speed (IOCTL_IN (arg)));      break;    case SOUND_PCM_READ_RATE:      if (local)	return gus_sampling_speed;      return IOCTL_OUT (arg, gus_sampling_speed);      break;    case SNDCTL_DSP_STEREO:      if (local)	return gus_sampling_set_channels (arg + 1) - 1;      return IOCTL_OUT (arg, gus_sampling_set_channels (IOCTL_IN (arg) + 1) - 1);      break;    case SOUND_PCM_WRITE_CHANNELS:      if (local)	return gus_sampling_set_channels (arg);      return IOCTL_OUT (arg, gus_sampling_set_channels (IOCTL_IN (arg)));      break;    case SOUND_PCM_READ_CHANNELS:      if (local)	return gus_sampling_channels;      return IOCTL_OUT (arg, gus_sampling_channels);      break;    case SNDCTL_DSP_SAMPLESIZE:      if (local)	return gus_sampling_set_bits (arg);      return IOCTL_OUT (arg, gus_sampling_set_bits (IOCTL_IN (arg)));      break;    case SOUND_PCM_READ_BITS:      if (local)	return gus_sampling_bits;      return IOCTL_OUT (arg, gus_sampling_bits);    case SOUND_PCM_WRITE_FILTER:	/* 					 * NOT YET IMPLEMENTED 					 */      return IOCTL_OUT (arg, RET_ERROR (EINVAL));      break;    case SOUND_PCM_READ_FILTER:      return IOCTL_OUT (arg, RET_ERROR (EINVAL));      break;    default:      return RET_ERROR (EINVAL);    }  return RET_ERROR (EINVAL);}static voidgus_sampling_reset (int dev){}static intgus_sampling_open (int dev, int mode){#ifdef GUS_NO_DMA  printk ("GUS: DMA mode not enabled. Device not supported\n");  return RET_ERROR (ENXIO);#endif  if (gus_busy)    return RET_ERROR (EBUSY);  gus_initialize ();  gus_busy = 1;  active_device = 0;  gus_reset ();  reset_sample_memory ();  gus_select_max_voices (14);  pcm_active = 0;  pcm_opened = 1;  if (mode & OPEN_READ)   {     recording_active = 1;     set_input_volumes();  }  return 0;}static voidgus_sampling_close (int dev){  gus_reset ();  gus_busy = 0;  pcm_opened = 0;  active_device = 0;  if (recording_active)     set_input_volumes();  recording_active = 0;}static voidgus_sampling_update_volume (void){  unsigned long   flags;  int             voice;  DISABLE_INTR (flags);  if (pcm_active && pcm_opened)    for (voice = 0; voice < gus_sampling_channels; voice++)      {	gus_select_voice (voice);	gus_rampoff ();	gus_voice_volume (1530 + (25 * gus_pcm_volume));	gus_ramp_range (65, 1530 + (25 * gus_pcm_volume));      }  RESTORE_INTR (flags);}static voidplay_next_pcm_block (void){  unsigned long   flags;  int             speed = gus_sampling_speed;  int             this_one, is16bits, chn;  unsigned long   dram_loc;  unsigned char   mode[2], ramp_mode[2];  if (!pcm_qlen)    return;  this_one = pcm_head;  for (chn = 0; chn < gus_sampling_channels; chn++)    {      mode[chn] = 0x00;      ramp_mode[chn] = 0x03;	/* 				 * Ramping and rollover off 				 */      if (chn == 0)	{	  mode[chn] |= 0x20;	/* 				 * Loop irq 				 */	  voices[chn].loop_irq_mode = LMODE_PCM;	}      if (gus_sampling_bits != 8)	{	  is16bits = 1;	  mode[chn] |= 0x04;	/* 				 * 16 bit data 				 */	}      else	is16bits = 0;      dram_loc = this_one * pcm_bsize;      dram_loc += chn * pcm_banksize;      if (this_one == (pcm_nblk - 1))	/* 					 * Last of the DRAM buffers 					 */	{	  mode[chn] |= 0x08;	/* 				 * Enable loop 				 */	  ramp_mode[chn] = 0x03;	/* 					 * Disable rollover 					 */	}      else	{	  if (chn == 0)	    ramp_mode[chn] = 0x04;	/* 					 * Enable rollover bit 					 */	}      DISABLE_INTR (flags);      gus_select_voice (chn);      gus_voice_freq (speed);      if (gus_sampling_channels == 1)	gus_voice_balance (7);	/* 				 * mono 				 */      else if (chn == 0)	gus_voice_balance (0);	/* 				 * left 				 */      else	gus_voice_balance (15);	/* 				 * right 				 */      if (!pcm_active)		/* 				 * Voice not started yet 				 */	{	  /* 	   * The playback was not started yet (or there has been a pause).	   * Start the voice (again) and ask for a rollover irq at the end of	   * this_one block. If this_one one is last of the buffers, use just	   * the normal loop with irq.	   */	  gus_voice_off ();	/* 				 * It could already be running 				 */	  gus_rampoff ();	  gus_voice_volume (1530 + (25 * gus_pcm_volume));	  gus_ramp_range (65, 1530 + (25 * gus_pcm_volume));	  gus_write_addr (0x0a, dram_loc, is16bits);	/* 							 * Starting position 							 */	  gus_write_addr (0x02, chn * pcm_banksize, is16bits);	/* 								 * Loop start 								 * location 								 */	  if (chn != 0)	    gus_write_addr (0x04, pcm_banksize + (pcm_bsize * pcm_nblk),			    is16bits);	/* 					 * Loop end location 					 */	}      if (chn == 0)	gus_write_addr (0x04, dram_loc + pcm_datasize[this_one], is16bits);	/* 										 * Loop 										 * end 										 * location 										 */      else	mode[chn] |= 0x08;	/* 				 * Enable loop 				 */      if (pcm_datasize[this_one] != pcm_bsize)	{	  /* 	   * Incomplete block. Possibly the last one. 	   */	  if (chn == 0)	    {	      mode[chn] &= ~0x08;	/* 					 * Disable loop 					 */	      mode[chn] |= 0x20;	/* 					 * Enable loop IRQ 					 */	      voices[0].loop_irq_mode = LMODE_PCM_STOP;	      ramp_mode[chn] = 0x03;	/* 					 * No rollover bit 					 */	    }	  else	    {	      gus_write_addr (0x04, dram_loc + pcm_datasize[this_one], is16bits);	/* 											 * Loop 											 * end 											 * location 											 */	      mode[chn] &= ~0x08;	/* 					 * Disable loop 					 */	    }	}      RESTORE_INTR (flags);    }  for (chn = 0; chn < gus_sampling_channels; chn++)    {      DISABLE_INTR (flags);      gus_select_voice (chn);      gus_write8 (0x0d, ramp_mode[chn]);      gus_voice_on (mode[chn]);      RESTORE_INTR (flags);    }  pcm_active = 1;}static voidgus_transfer_output_block (int dev, unsigned long buf,			   int total_count, int intrflag, int chn){  /*    * This routine transfers one block of audio data to the DRAM. In mono mode   * it's called just once. When in stereo mode, this_one routine is called   * once for both channels.   *    * The left/mono channel data is transferred to the beginning of dram and the

⌨️ 快捷键说明

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