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

📄 awe_wave.c

📁 freebsd v4.4内核源码
💻 C
📖 第 1 页 / 共 5 页
字号:
		awe_release_region();	}}#ifdef AWE_OBSOLETE_VOXWAREint probe_awe_obsolete(struct address_info *hw_config){	return 1;	/*return awe_detect();*/}#endif/*================================================================ * clear sample tables  *================================================================*/static voidawe_reset_samples(void){	int i;	/* free all bank tables */	for (i = 0; i < AWE_MAX_PRESETS; i++) {		preset_table[i] = NULL;	}	free_mem_ptr = 0;	last_sample = free_sample = 0;	last_info = free_info = 0;	current_sf_id = 0;	loaded_once = 0;}/*================================================================ * EMU register access *================================================================*//* select a given AWE32 pointer */static int awe_cur_cmd = -1;#define awe_set_cmd(cmd) \if (awe_cur_cmd != cmd) { OUTW(cmd, awe_base + 0x802); awe_cur_cmd = cmd; }#define awe_port(port)		(awe_base - 0x620 + port)/* write 16bit data */INLINE static voidawe_poke(unsigned short cmd, unsigned short port, unsigned short data){	awe_set_cmd(cmd);	OUTW(data, awe_port(port));}/* write 32bit data */INLINE static voidawe_poke_dw(unsigned short cmd, unsigned short port, unsigned long data){	awe_set_cmd(cmd);	OUTW(data, awe_port(port));		/* write lower 16 bits */	OUTW(data >> 16, awe_port(port)+2);	/* write higher 16 bits */}/* read 16bit data */INLINE static unsigned shortawe_peek(unsigned short cmd, unsigned short port){	unsigned short k;	awe_set_cmd(cmd);	k = inw(awe_port(port));	return k;}/* read 32bit data */INLINE static unsigned longawe_peek_dw(unsigned short cmd, unsigned short port){	unsigned long k1, k2;	awe_set_cmd(cmd);	k1 = inw(awe_port(port));	k2 = inw(awe_port(port)+2);	k1 |= k2 << 16;	return k1;}/* wait delay number of AWE32 44100Hz clocks */static voidawe_wait(unsigned short delay){	unsigned short clock, target;	unsigned short port = awe_port(AWE_WC_Port);	int counter;  	/* sample counter */	awe_set_cmd(AWE_WC_Cmd);	clock = (unsigned short)inw(port);	target = clock + delay;	counter = 0;	if (target < clock) {		for (; (unsigned short)inw(port) > target; counter++)			if (counter > 65536)				break;	}	for (; (unsigned short)inw(port) < target; counter++)		if (counter > 65536)			break;}#ifndef AWE_OBSOLETE_VOXWARE/*================================================================ * port check / request *  0x620-622, 0xA20-A22, 0xE20-E22 *================================================================*/static intawe_check_port(void){	return (check_region(awe_port(Data0), 3) ||		check_region(awe_port(Data1), 3) ||		check_region(awe_port(Data3), 3));}static voidawe_request_region(void){	request_region(awe_port(Data0), 3, "sound driver (AWE32)");	request_region(awe_port(Data1), 3, "sound driver (AWE32)");	request_region(awe_port(Data3), 3, "sound driver (AWE32)");}static voidawe_release_region(void){	release_region(awe_port(Data0), 3);	release_region(awe_port(Data1), 3);	release_region(awe_port(Data3), 3);}#endif /* !AWE_OBSOLETE_VOXWARE *//*================================================================ * AWE32 initialization *================================================================*/static voidawe_initialize(void){	unsigned short data;	DECL_INTR_FLAGS(flags);	DEBUG(0,printk("AWE32: initializing..\n"));	DISABLE_INTR(flags);	/* check for an error condition */	data = awe_peek(AWE_U1);	if (!(data & 0x000F) == 0x000C) {		FATALERR(printk("AWE32: can't initialize AWE32\n"));	}	/* initialize hardware configuration */	awe_poke(AWE_HWCF1, 0x0059);	awe_poke(AWE_HWCF2, 0x0020);	/* disable audio output */	awe_poke(AWE_HWCF3, 0x0000);	/* initialize audio channels */	awe_init_audio();	/* initialize init array */	awe_init_dma();	awe_init_array();	/* check DRAM memory size */	awe_mem_size = awe_check_dram();	/* initialize the FM section of the AWE32 */	awe_init_fm();	/* set up voice envelopes */	awe_tweak();	/* enable audio */	awe_poke(AWE_HWCF3, 0x0004);	data = awe_peek(AWE_HWCF2);	if (~data & 0x40) {		FATALERR(printk("AWE32: Unable to initialize AWE32.\n"));	}	RESTORE_INTR(flags);}/*================================================================ * AWE32 voice parameters *================================================================*//* initialize voice_info record */static voidawe_init_voice_info(awe_voice_info *vp){	vp->sf_id = 0;	vp->sample = 0;	vp->rate_offset = 0;	vp->start = 0;	vp->end = 0;	vp->loopstart = 0;	vp->loopend = 0;	vp->mode = 0;	vp->root = 60;	vp->tune = 0;	vp->low = 0;	vp->high = 127;	vp->vellow = 0;	vp->velhigh = 127;	vp->fixkey = -1;	vp->fixvel = -1;	vp->fixpan = -1;	vp->pan = -1;	vp->exclusiveClass = 0;	vp->amplitude = 127;	vp->attenuation = 0;	vp->scaleTuning = 100;	awe_init_voice_parm(&vp->parm);}/* initialize voice_parm record: * Env1/2: delay=0, attack=0, hold=0, sustain=0, decay=0, release=0. * Vibrato and Tremolo effects are zero. * Cutoff is maximum. * Chorus and Reverb effects are zero. */static voidawe_init_voice_parm(awe_voice_parm *pp){	pp->moddelay = 0x8000;	pp->modatkhld = 0x7f7f;	pp->moddcysus = 0x7f7f;	pp->modrelease = 0x807f;	pp->modkeyhold = 0;	pp->modkeydecay = 0;	pp->voldelay = 0x8000;	pp->volatkhld = 0x7f7f;	pp->voldcysus = 0x7f7f;	pp->volrelease = 0x807f;	pp->volkeyhold = 0;	pp->volkeydecay = 0;	pp->lfo1delay = 0x8000;	pp->lfo2delay = 0x8000;	pp->pefe = 0;	pp->fmmod = 0;	pp->tremfrq = 0;	pp->fm2frq2 = 0;	pp->cutoff = 0xff;	pp->filterQ = 0;	pp->chorus = 0;	pp->reverb = 0;}	/* convert frequency mHz to abstract cents (= midi key * 100) */static intfreq_to_note(int mHz){	/* abscents = log(mHz/8176) / log(2) * 1200 */	unsigned long max_val = (unsigned long)0xffffffff / 10000;	int i, times;	unsigned long base;	unsigned long freq;	int note, tune;	if (mHz == 0)		return 0;	if (mHz < 0)		return 12799; /* maximum */	freq = mHz;	note = 0;	for (base = 8176 * 2; freq >= base; base *= 2) {		note += 12;		if (note >= 128) /* over maximum */			return 12799;	}	base /= 2;	/* to avoid overflow... */	times = 10000;	while (freq > max_val) {		max_val *= 10;		times /= 10;		base /= 10;	}	freq = freq * times / base;	for (i = 0; i < 12; i++) {		if (freq < semitone_tuning[i+1])			break;		note++;	}	tune = 0;	freq = freq * 10000 / semitone_tuning[i];	for (i = 0; i < 100; i++) {		if (freq < cent_tuning[i+1])			break;		tune++;	}	return note * 100 + tune;}/* convert Hz to AWE32 rate offset: * sample pitch offset for the specified sample rate * rate=44100 is no offset, each 4096 is 1 octave (twice). * eg, when rate is 22050, this offset becomes -4096. */static intcalc_rate_offset(int Hz){	/* offset = log(Hz / 44100) / log(2) * 4096 */	int freq, base, i;	/* maybe smaller than max (44100Hz) */	if (Hz <= 0 || Hz >= 44100) return 0;	base = 0;	for (freq = Hz * 2; freq < 44100; freq *= 2)		base++;	base *= 1200;	freq = 44100 * 10000 / (freq/2);	for (i = 0; i < 12; i++) {		if (freq < semitone_tuning[i+1])			break;		base += 100;	}	freq = freq * 10000 / semitone_tuning[i];	for (i = 0; i < 100; i++) {		if (freq < cent_tuning[i+1])			break;		base++;	}	return -base * 4096 / 1200;}/*---------------------------------------------------------------- * convert envelope time parameter to AWE32 raw parameter *----------------------------------------------------------------*//* attack & decay/release time table (mHz) */static short attack_time_tbl[128] = {32767, 5939, 3959, 2969, 2375, 1979, 1696, 1484, 1319, 1187, 1079, 989, 913, 848, 791, 742, 698, 659, 625, 593, 565, 539, 516, 494, 475, 456, 439, 424, 409, 395, 383, 371, 359, 344, 330, 316, 302, 290, 277, 266, 255, 244, 233, 224, 214, 205, 196, 188, 180, 173, 165, 158, 152, 145, 139, 133, 127, 122, 117, 112, 107, 103, 98, 94, 90, 86, 83, 79, 76, 73, 69, 67, 64, 61, 58, 56, 54, 51, 49, 47, 45, 43, 41, 39, 38, 36, 35, 33, 32, 30, 29, 28, 27, 25, 24, 23, 22, 21, 20, 20, 19, 18, 17, 16, 16, 15, 14, 14, 13, 13, 12, 11, 11, 10, 10, 10, 9, 9, 8, 8, 8, 7, 7, 7, 6, 6, 6, 0,};static short decay_time_tbl[128] = {32767, 3651, 3508, 3371, 3239, 3113, 2991, 2874, 2761, 2653, 2550, 2450, 2354, 2262, 2174, 2089, 2007, 1928, 1853, 1781, 1711, 1644, 1580, 1518, 1459, 1401, 1347, 1294, 1243, 1195, 1148, 1103, 1060, 1018, 979, 940, 904, 868, 834, 802, 770, 740, 711, 683, 657, 631, 606, 582, 560, 538, 517, 496, 477, 458, 440, 423, 407, 391, 375, 361, 347, 333, 320, 307, 295, 284, 273, 262, 252, 242, 232, 223, 215, 206, 198, 190, 183, 176, 169, 162, 156, 150, 144, 138, 133, 128, 123, 118, 113, 109, 104, 100, 96, 93, 89, 85, 82, 79, 76, 73, 70, 67, 64, 62, 60, 57, 55, 53, 51, 49, 47, 45, 43, 41, 40, 38, 37, 35, 34, 32, 31, 30, 29, 28, 27, 25, 24, 0,};/*static intcalc_parm_delay(int msec){	return (0x8000 - msec * 1000 / 725);}*/static intcalc_parm_hold(int msec){	int val = 0x7f - (unsigned char)(msec / 92);	if (val < 1) val = 1;	if (val > 127) val = 127;	return val;}static intcalc_parm_attack(int msec){	return calc_parm_search(msec, attack_time_tbl);}static intcalc_parm_decay(int msec){	return calc_parm_search(msec, decay_time_tbl);}static intcalc_parm_search(int msec, short *table){	int left = 0, right = 127, mid;	while (left < right) {		mid = (left + right) / 2;		if (msec < (int)table[mid])			left = mid + 1;		else			right = mid;	}	return left;}/*================================================================ * effects table *================================================================*//* set an effect value */#define FX_SET(v,type,value) \(voices[v].fx_flags[(type)/8] |= (1<<((type)%8)),\ voices[v].fx[type] = (value))/* check the effect value is set */#define FX_ON(v,type)	(voices[v].fx_flags[(type)/8] & (1<<((type)%8)))#if 0#define FX_BYTE(v,type,value)\	(FX_ON(v,type) ? (unsigned char)voices[v].fx[type] :\	 (unsigned char)(value))#define FX_WORD(v,type,value)\	(FX_ON(v,type) ? (unsigned short)voices[v].fx[type] :\	 (unsigned short)(value))#else/* get byte effect value */static unsigned char FX_BYTE(int v, int type, unsigned char value){	unsigned char tmp;	if (FX_ON(v,type))		tmp = (unsigned char)voices[v].fx[type];	else		tmp = value;	DEBUG(4,printk("AWE32: [-- byte(%d) = %x]\n", type, tmp));	return tmp;}/* get word effect value */static unsigned short FX_WORD(int v, int type, unsigned short value){	unsigned short tmp;	if (FX_ON(v,type))		tmp = (unsigned short)voices[v].fx[type];	else		tmp = value;	DEBUG(4,printk("AWE32: [-- word(%d) = %x]\n", type, tmp));	return tmp;}#endif/* get word (upper=type1/lower=type2) effect value */static unsigned short FX_COMB(int v, int type1, int type2, unsigned short value){	unsigned short tmp;	if (FX_ON(v, type1))		tmp = (unsigned short)(voices[v].fx[type1]) << 8;	else		tmp = value & 0xff00;	if (FX_ON(v, type2))		tmp |= (unsigned short)(voices[v].fx[type2]) & 0xff;	else		tmp |= value & 0xff;	DEBUG(4,printk("AWE32: [-- comb(%d/%d) = %x]\n", type1, type2, tmp));	return tmp;}/* address offset */static longFX_OFFSET(int voice, int lo, int hi){	awe_voice_info *vp;	long addr;	if ((vp = voices[voice].sample) == NULL || vp->index < 0)		return 0;

⌨️ 快捷键说明

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