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

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

?? gus_wave.c

?? LINUX1.0源代碼,代碼條理清晰
?? C
?? 第 1 頁 / 共 5 頁
字號:

/* 
 * sound/gus_wave.c
 * 
 * Driver for the Gravis UltraSound wave table synth.
 * 
 * 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"
#include <linux/ultrasound.h>
#include "gus_hw.h"

#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_GUS)

#define MAX_SAMPLE	128
#define MAX_PATCH	256

struct voice_info
  {
    unsigned long   orig_freq;
    unsigned long   current_freq;
    unsigned long   mode;
    int             bender;
    int             bender_range;
    int             panning;
    int             midi_volume;
    unsigned int    initial_volume;
    unsigned int    current_volume;
    int             loop_irq_mode, loop_irq_parm;
#define LMODE_FINISH		1
#define LMODE_PCM		2
#define LMODE_PCM_STOP		3
    int             volume_irq_mode, volume_irq_parm;
#define VMODE_HALT		1
#define VMODE_ENVELOPE		2
#define VMODE_START_NOTE	3

    int             env_phase;
    unsigned char   env_rate[6];
    unsigned char   env_offset[6];

    /* 
     * Volume computation parameters for gus_adagio_vol()
     */
    int             main_vol, expression_vol, patch_vol;

    /* Variables for "Ultraclick" removal */
    int             dev_pending, note_pending, volume_pending, sample_pending;
    char            kill_pending;
    long            offset_pending;

  };

extern int      gus_base;
extern int      gus_irq, gus_dma;
extern char    *snd_raw_buf[MAX_DSP_DEV][DSP_BUFFCOUNT];
extern unsigned long snd_raw_buf_phys[MAX_DSP_DEV][DSP_BUFFCOUNT];
extern int      snd_raw_count[MAX_DSP_DEV];
static long     gus_mem_size = 0;
static long     free_mem_ptr = 0;
static int      gus_busy = 0;
static int      nr_voices = 0;
static int      gus_devnum = 0;
static int      volume_base, volume_scale, volume_method;
static int	gus_line_vol = 100, gus_mic_vol = 0;
static int	gus_recmask = SOUND_MASK_MIC;
static int	recording_active = 0;

#define VOL_METHOD_ADAGIO	1
int             gus_wave_volume = 60;
int             gus_pcm_volume = 80;
static unsigned char mix_image = 0x00;

/* 
 * Current version of this driver doesn't allow synth and PCM functions
 * at the same time. The active_device specifies the active driver
 */
static int      active_device = 0;

#define GUS_DEV_WAVE		1	/* 
					 * * * Wave table synth   */
#define GUS_DEV_PCM_DONE	2	/* 
					 * * * PCM device, transfer done   */
#define GUS_DEV_PCM_CONTINUE	3	/* 
					 * * * PCM device, transfer the
					 * second * * * chn   */

static int      gus_sampling_speed;
static int      gus_sampling_channels;
static int      gus_sampling_bits;

DEFINE_WAIT_QUEUE (dram_sleeper, dram_sleep_flag);

/* 
 * Variables and buffers for PCM output
 */
#define MAX_PCM_BUFFERS		(32*MAX_REALTIME_FACTOR)	/* 
								 * * * Don't
								 * * * change 
								 * 
								 */

static int      pcm_bsize,	/* 
				 * Current blocksize 
				 */
                pcm_nblk,	/* 
				 * Current # of blocks 
				 */
                pcm_banksize;	/* 

				 * 
				 * *  * * # bytes allocated for channels   */
static int      pcm_datasize[MAX_PCM_BUFFERS];	/* 

						 * 
						 * *  * * Actual # of bytes
						 * in blk  *  */
static volatile int pcm_head, pcm_tail, pcm_qlen;	/* 

							 * 
							 * *  * * DRAM queue
							 *  */
static volatile int pcm_active;
static int      pcm_opened = 0;
static int      pcm_current_dev;
static int      pcm_current_block;
static unsigned long pcm_current_buf;
static int      pcm_current_count;
static int      pcm_current_intrflag;

struct voice_info voices[32];

static int      freq_div_table[] =
{
  44100,			/* 
				 * 14 
				 */
  41160,			/* 
				 * 15 
				 */
  38587,			/* 
				 * 16 
				 */
  36317,			/* 
				 * 17 
				 */
  34300,			/* 
				 * 18 
				 */
  32494,			/* 
				 * 19 
				 */
  30870,			/* 
				 * 20 
				 */
  29400,			/* 
				 * 21 
				 */
  28063,			/* 
				 * 22 
				 */
  26843,			/* 
				 * 23 
				 */
  25725,			/* 
				 * 24 
				 */
  24696,			/* 
				 * 25 
				 */
  23746,			/* 
				 * 26 
				 */
  22866,			/* 
				 * 27 
				 */
  22050,			/* 
				 * 28 
				 */
  21289,			/* 
				 * 29 
				 */
  20580,			/* 
				 * 30 
				 */
  19916,			/* 
				 * 31 
				 */
  19293				/* 
				 * 32 
				 */
};

static struct patch_info *samples;
static long     sample_ptrs[MAX_SAMPLE + 1];
static int      sample_map[32];
static int      free_sample;


static int      patch_table[MAX_PATCH];
static int      patch_map[32];

static struct synth_info gus_info =
{"Gravis UltraSound", 0, SYNTH_TYPE_SAMPLE, SAMPLE_TYPE_GUS, 0, 16, 0, MAX_PATCH};

static void     gus_poke (long addr, unsigned char data);
static void     compute_and_set_volume (int voice, int volume, int ramp_time);
extern unsigned short gus_adagio_vol (int vel, int mainv, int xpn, int voicev);
static void     compute_volume (int voice, int volume);
static void     do_volume_irq (int voice);
static void	set_input_volumes(void);

#define	INSTANT_RAMP		-1	/* 
					 * * * Dont use ramping   */
#define FAST_RAMP		0	/* 
					 * * * Fastest possible ramp   */

static void
reset_sample_memory (void)
{
  int             i;

  for (i = 0; i <= MAX_SAMPLE; i++)
    sample_ptrs[i] = -1;
  for (i = 0; i < 32; i++)
    sample_map[i] = -1;
  for (i = 0; i < 32; i++)
    patch_map[i] = -1;

  gus_poke (0, 0);		/* 
				 * Put silence here 
				 */
  gus_poke (1, 0);

  free_mem_ptr = 2;
  free_sample = 0;

  for (i = 0; i < MAX_PATCH; i++)
    patch_table[i] = -1;
}

void
gus_delay (void)
{
  int             i;

  for (i = 0; i < 7; i++)
    INB (u_DRAMIO);
}

static void
gus_poke (long addr, unsigned char data)
{
  unsigned long   flags;

  DISABLE_INTR (flags);
  OUTB (0x43, u_Command);
  OUTB (addr & 0xff, u_DataLo);
  OUTB ((addr >> 8) & 0xff, u_DataHi);

  OUTB (0x44, u_Command);
  OUTB ((addr >> 16) & 0xff, u_DataHi);
  OUTB (data, u_DRAMIO);
  RESTORE_INTR (flags);
}

static unsigned char
gus_peek (long addr)
{
  unsigned long   flags;
  unsigned char   tmp;

  DISABLE_INTR (flags);
  OUTB (0x43, u_Command);
  OUTB (addr & 0xff, u_DataLo);
  OUTB ((addr >> 8) & 0xff, u_DataHi);

  OUTB (0x44, u_Command);
  OUTB ((addr >> 16) & 0xff, u_DataHi);
  tmp = INB (u_DRAMIO);
  RESTORE_INTR (flags);

  return tmp;
}

void
gus_write8 (int reg, unsigned int data)
{
  unsigned long   flags;

  DISABLE_INTR (flags);

  OUTB (reg, u_Command);
  OUTB ((unsigned char) (data & 0xff), u_DataHi);

  RESTORE_INTR (flags);
}

unsigned char
gus_read8 (int reg)
{
  unsigned long   flags;
  unsigned char   val;

  DISABLE_INTR (flags);
  OUTB (reg | 0x80, u_Command);
  val = INB (u_DataHi);
  RESTORE_INTR (flags);

  return val;
}

unsigned char
gus_look8 (int reg)
{
  unsigned long   flags;
  unsigned char   val;

  DISABLE_INTR (flags);
  OUTB (reg, u_Command);
  val = INB (u_DataHi);
  RESTORE_INTR (flags);

  return val;
}

void
gus_write16 (int reg, unsigned int data)
{
  unsigned long   flags;

  DISABLE_INTR (flags);

  OUTB (reg, u_Command);

  OUTB ((unsigned char) (data & 0xff), u_DataLo);
  OUTB ((unsigned char) ((data >> 8) & 0xff), u_DataHi);

  RESTORE_INTR (flags);
}

unsigned short
gus_read16 (int reg)
{
  unsigned long   flags;
  unsigned char   hi, lo;

  DISABLE_INTR (flags);

  OUTB (reg | 0x80, u_Command);

  lo = INB (u_DataLo);
  hi = INB (u_DataHi);

  RESTORE_INTR (flags);

  return ((hi << 8) & 0xff00) | lo;
}

void
gus_write_addr (int reg, unsigned long address, int is16bit)
{
  unsigned long   hold_address;

  if (is16bit)
    {
      /* 
       * Special processing required for 16 bit patches
       */

      hold_address = address;
      address = address >> 1;
      address &= 0x0001ffffL;
      address |= (hold_address & 0x000c0000L);
    }

  gus_write16 (reg, (unsigned short) ((address >> 7) & 0xffff));
  gus_write16 (reg + 1, (unsigned short) ((address << 9) & 0xffff));
}

static void
gus_select_voice (int voice)
{
  if (voice < 0 || voice > 31)
    return;

  OUTB (voice, u_Voice);
}

static void
gus_select_max_voices (int nvoices)
{
  if (nvoices < 14)
    nvoices = 14;
  if (nvoices > 32)
    nvoices = 32;

  nr_voices = nvoices;

  gus_write8 (0x0e, (nvoices - 1) | 0xc0);
}

static void
gus_voice_on (unsigned int mode)
{
  gus_write8 (0x00, (unsigned char) (mode & 0xfc));
  gus_delay ();
  gus_write8 (0x00, (unsigned char) (mode & 0xfc));
}

static void
gus_voice_off (void)
{
  gus_write8 (0x00, gus_read8 (0x00) | 0x03);
}

static void
gus_voice_mode (unsigned int m)
{
  unsigned char   mode = (unsigned char) (m & 0xff);

  gus_write8 (0x00, (gus_read8 (0x00) & 0x03) | (mode & 0xfc));		/* 
									 * Don't 
									 * start 
									 * or 
									 * stop
									 * *
									 * voice 
									 */
  gus_delay ();
  gus_write8 (0x00, (gus_read8 (0x00) & 0x03) | (mode & 0xfc));
}

static void
gus_voice_freq (unsigned long freq)
{
  unsigned long   divisor = freq_div_table[nr_voices - 14];
  unsigned short  fc;

  fc = (unsigned short) (((freq << 9) + (divisor >> 1)) / divisor);
  fc = fc << 1;

  gus_write16 (0x01, fc);
}

static void
gus_voice_volume (unsigned int vol)
{
  gus_write8 (0x0d, 0x03);	/* 
				 * Stop ramp before setting volume 
				 */
  gus_write16 (0x09, (unsigned short) (vol << 4));
}

static void
gus_voice_balance (unsigned int balance)
{
  gus_write8 (0x0c, (unsigned char) (balance & 0xff));
}

static void
gus_ramp_range (unsigned int low, unsigned int high)
{
  gus_write8 (0x07, (unsigned char) ((low >> 4) & 0xff));
  gus_write8 (0x08, (unsigned char) ((high >> 4) & 0xff));
}

static void
gus_ramp_rate (unsigned int scale, unsigned int rate)
{
  gus_write8 (0x06, (unsigned char) (((scale & 0x03) << 6) | (rate & 0x3f)));
}

static void
gus_rampon (unsigned int m)
{
  unsigned char   mode = (unsigned char) (m & 0xff);

  gus_write8 (0x0d, mode & 0xfc);
  gus_delay ();
  gus_write8 (0x0d, mode & 0xfc);
}

static void
gus_ramp_mode (unsigned int m)
{
  unsigned char   mode = (unsigned char) (m & 0xff);

  gus_write8 (0x0d, (gus_read8 (0x0d) & 0x03) | (mode & 0xfc));		/* 
									 * Don't 
									 * start 
									 * or 
									 * stop
									 * *
									 * ramping 
									 */
  gus_delay ();
  gus_write8 (0x0d, (gus_read8 (0x0d) & 0x03) | (mode & 0xfc));
}

static void
gus_rampoff (void)
{
  gus_write8 (0x0d, 0x03);
}

static void
gus_set_voice_pos (int voice, long position)
{
  int             sample_no;

  if ((sample_no = sample_map[voice]) != -1)
    if (position < samples[sample_no].len)
      if (voices[voice].volume_irq_mode == VMODE_START_NOTE)
	voices[voice].offset_pending = position;
      else
	gus_write_addr (0x0a, sample_ptrs[sample_no] + position,
			samples[sample_no].mode & WAVE_16_BITS);
}

static void
gus_voice_init (int voice)
{
  unsigned long   flags;

  DISABLE_INTR (flags);
  gus_select_voice (voice);
  gus_voice_volume (0);
  gus_write_addr (0x0a, 0, 0);	/* 
				 * Set current position to 0 
				 */
  gus_write8 (0x00, 0x03);	/* 
				 * Voice off 
				 */
  gus_write8 (0x0d, 0x03);	/* 
				 * Ramping off 
				 */
  RESTORE_INTR (flags);

}

static void
gus_voice_init2 (int voice)
{
  voices[voice].panning = 0;
  voices[voice].mode = 0;
  voices[voice].orig_freq = 20000;
  voices[voice].current_freq = 20000;
  voices[voice].bender = 0;
  voices[voice].bender_range = 200;
  voices[voice].initial_volume = 0;
  voices[voice].current_volume = 0;
  voices[voice].loop_irq_mode = 0;
  voices[voice].loop_irq_parm = 0;
  voices[voice].volume_irq_mode = 0;
  voices[voice].volume_irq_parm = 0;
  voices[voice].env_phase = 0;
  voices[voice].main_vol = 127;
  voices[voice].patch_vol = 127;
  voices[voice].expression_vol = 127;
  voices[voice].sample_pending = -1;
}

static void
step_envelope (int voice)
{
  unsigned        vol, prev_vol, phase;
  unsigned char   rate;

  if (voices[voice].mode & WAVE_SUSTAIN_ON && voices[voice].env_phase == 2)
    {
      gus_rampoff ();

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
亚洲欧洲三级电影| 欧美一区二区视频免费观看| 国产精品色婷婷久久58| 国产成人高清视频| 亚洲色欲色欲www| 欧美日韩一级二级| 国产精品一级片在线观看| 精品国产伦一区二区三区观看方式| 麻豆一区二区在线| 国产视频一区二区三区在线观看| 国产91露脸合集magnet| 综合自拍亚洲综合图不卡区| 欧美天堂亚洲电影院在线播放| 日韩国产精品久久久| 精品99999| 91在线观看免费视频| 三级欧美在线一区| 日本一区二区三区在线观看| 在线观看视频欧美| 激情综合色播激情啊| 亚洲日本护士毛茸茸| 欧美另类videos死尸| 国产不卡视频在线播放| 亚洲午夜在线电影| 欧美激情综合五月色丁香小说| 在线影院国内精品| 国产精品一区二区在线播放 | 久久色在线视频| 成a人片国产精品| 日本不卡一二三| 一色桃子久久精品亚洲| 欧美二区在线观看| kk眼镜猥琐国模调教系列一区二区| 亚洲电影激情视频网站| 日本一区免费视频| 欧美一级国产精品| 91美女福利视频| 国产激情91久久精品导航| 亚洲成人av电影| 国产精品无人区| 欧美va天堂va视频va在线| 在线观看国产日韩| 成人avav影音| 国产乱色国产精品免费视频| 亚洲成年人影院| 亚洲桃色在线一区| 国产午夜精品在线观看| 日韩一级大片在线| 国产欧美视频一区二区| 欧美一区二区视频观看视频| 色偷偷成人一区二区三区91| 国产**成人网毛片九色 | 亚洲一区二区三区四区的| 久久综合九色综合欧美就去吻| 在线成人高清不卡| 在线免费亚洲电影| 91在线一区二区三区| 国产成人午夜精品5599| 国产一区二区在线看| 日本少妇一区二区| 日韩黄色免费电影| 午夜视频在线观看一区二区 | 在线免费观看日本欧美| 波多野结衣的一区二区三区| 国产成人鲁色资源国产91色综| 国内不卡的二区三区中文字幕| 日本 国产 欧美色综合| 日韩国产精品久久| 日韩电影网1区2区| 欧美96一区二区免费视频| 日本免费在线视频不卡一不卡二| 亚洲最大成人综合| 一区二区三区在线视频免费| 亚洲人成7777| 一区二区三区波多野结衣在线观看 | 午夜国产精品影院在线观看| 亚洲电影一区二区三区| 性感美女久久精品| 日韩电影网1区2区| 久久国产精品免费| 国产一区二区三区观看| 国产成人av电影在线播放| 国产成人免费在线观看不卡| 69堂精品视频| 日韩一区二区免费高清| 日韩一区二区在线免费观看| 日韩欧美色电影| 精品成人一区二区三区| 久久网站热最新地址| 国产欧美精品区一区二区三区| 国产精品免费av| 亚洲精品视频在线| 日韩成人精品视频| 国模无码大尺度一区二区三区| 国产成人精品网址| 91免费看片在线观看| 欧美日韩午夜影院| 精品国产免费视频| 国产精品午夜在线| 亚洲一区二区欧美日韩 | 欧美精品一区二区在线观看| 久久综合九色综合欧美98| 国产精品视频yy9299一区| 亚洲视频在线一区观看| 午夜精品123| 国产精品456| 日本韩国精品在线| 日韩精品专区在线影院观看| 国产精品每日更新在线播放网址| 亚洲一区二区三区四区在线免费观看| 蜜桃在线一区二区三区| 成av人片一区二区| 欧美一卡2卡3卡4卡| 国产人成亚洲第一网站在线播放| 依依成人精品视频| 精品影院一区二区久久久| 成人国产亚洲欧美成人综合网| 欧美性感一区二区三区| 国产偷国产偷精品高清尤物| 亚洲制服丝袜一区| 国产乱一区二区| 欧美老女人在线| 国产精品久久久久久久久免费樱桃| 亚洲成av人片一区二区| 成人免费毛片a| 日韩一区二区免费高清| 一区二区三区在线不卡| 国产精品白丝jk白祙喷水网站| 欧美日韩视频在线一区二区| 久久精品男人天堂av| 日本不卡的三区四区五区| 91蝌蚪porny九色| 国产欧美日本一区二区三区| 日韩av一区二区三区四区| 91丨porny丨蝌蚪视频| 国产亚洲欧洲997久久综合| 天堂精品中文字幕在线| 91麻豆产精品久久久久久 | 不卡的电视剧免费网站有什么| 欧美一区二区三区在线视频 | 亚洲成人av一区| 91网上在线视频| 中文字幕欧美国产| 国产在线精品一区二区三区不卡| 欧美日韩国产美| 亚洲一区二区视频在线| 99精品欧美一区二区蜜桃免费| 国产香蕉久久精品综合网| 精品在线免费观看| 日韩三级精品电影久久久| 一区二区三区日韩在线观看| 99re8在线精品视频免费播放| 国产女人18毛片水真多成人如厕 | 国产精品卡一卡二卡三| 国产在线日韩欧美| 欧美一区二区三区爱爱| 日韩成人精品在线| 3atv一区二区三区| 琪琪一区二区三区| 日韩欧美一区二区免费| 男女激情视频一区| 日韩一区二区在线看| 蜜臀国产一区二区三区在线播放| 欧美精品亚洲二区| 免费高清在线一区| 精品国产露脸精彩对白| 激情久久五月天| 久久综合九色综合97_久久久| 国产尤物一区二区在线 | 国产精品久久久久久一区二区三区 | 亚洲一区在线观看视频| 91久久精品网| 亚洲一区二区av在线| 欧美四级电影网| 欧美aⅴ一区二区三区视频| 日韩精品一区二区三区老鸭窝| 精品一区二区免费| 欧美极品少妇xxxxⅹ高跟鞋| 国产不卡视频一区二区三区| 综合色中文字幕| 欧美视频精品在线观看| 日日夜夜精品视频天天综合网| 日韩精品一区二区三区在线| 国产麻豆精品久久一二三| 欧美国产激情二区三区| 在线视频中文字幕一区二区| 日韩高清一区二区| 久久久久久99精品| 一本大道av伊人久久综合| 天堂va蜜桃一区二区三区漫画版| 欧美va亚洲va香蕉在线| av在线不卡电影| 天堂一区二区在线免费观看| 久久色成人在线| 成人国产精品视频| 一区二区三区成人| 久久天堂av综合合色蜜桃网| 色吊一区二区三区| 狠狠网亚洲精品| 中文字幕一区在线观看视频|