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

📄 awe_wave.c

📁 iis s3c2410-uda1341语音系统的 开发
💻 C
📖 第 1 页 / 共 5 页
字号:
 */static struct synth_operations awe_operations ={	owner:		THIS_MODULE,	id:		"EMU8K",	info:		&awe_info,	midi_dev:	0,	synth_type:	SYNTH_TYPE_SAMPLE,	synth_subtype:	SAMPLE_TYPE_AWE32,	open:		awe_open,	close:		awe_close,	ioctl:		awe_ioctl,	kill_note:	awe_kill_note,	start_note:	awe_start_note,	set_instr:	awe_set_instr_2,	reset:		awe_reset,	hw_control:	awe_hw_control,	load_patch:	awe_load_patch,	aftertouch:	awe_aftertouch,	controller:	awe_controller,	panning:	awe_panning,	volume_method:	awe_volume_method,	bender:		awe_bender,	alloc_voice:	awe_alloc,	setup_voice:	awe_setup_voice};/* * General attach / unload interface */static int __init _attach_awe(void){	if (awe_present) return 0; /* for OSS38.. called twice? */	/* check presence of AWE32 card */	if (! awe_detect()) {		printk(KERN_ERR "AWE32: not detected\n");		return 0;	}	/* check AWE32 ports are available */	if (awe_check_port()) {		printk(KERN_ERR "AWE32: I/O area already used.\n");		return 0;	}	/* set buffers to NULL */	sfhead = sftail = NULL;	my_dev = sound_alloc_synthdev();	if (my_dev == -1) {		printk(KERN_ERR "AWE32 Error: too many synthesizers\n");		return 0;	}	voice_alloc = &awe_operations.alloc;	voice_alloc->max_voice = awe_max_voices;	synth_devs[my_dev] = &awe_operations;#ifdef CONFIG_AWE32_MIXER	attach_mixer();#endif#ifdef CONFIG_AWE32_MIDIEMU	attach_midiemu();#endif	/* reserve I/O ports for awedrv */	awe_request_region();	/* clear all samples */	awe_reset_samples();	/* intialize AWE32 hardware */	awe_initialize();	sprintf(awe_info.name, "AWE32-%s (RAM%dk)",		AWEDRV_VERSION, memsize/1024);	printk(KERN_INFO "<SoundBlaster EMU8000 (RAM%dk)>\n", memsize/1024);	awe_present = TRUE;	return 1;}static void free_tables(void){	if (sftail) {		sf_list *p, *prev;		for (p = sftail; p; p = prev) {			prev = p->prev;			awe_free_sf(p);		}	}	sfhead = sftail = NULL;}static void __exit _unload_awe(void){	if (awe_present) {		awe_reset_samples();		awe_release_region();		free_tables();#ifdef CONFIG_AWE32_MIXER		unload_mixer();#endif#ifdef CONFIG_AWE32_MIDIEMU		unload_midiemu();#endif		sound_unload_synthdev(my_dev);		awe_present = FALSE;	}}/* * clear sample tables  */static voidawe_reset_samples(void){	/* free all bank tables */	memset(preset_table, 0, sizeof(preset_table));	free_tables();	current_sf_id = 0;	locked_sf_id = 0;	patch_opened = 0;}/* * EMU register access *//* select a given AWE32 pointer */static int awe_ports[5];static int port_setuped = FALSE;static int awe_cur_cmd = -1;#define awe_set_cmd(cmd) \if (awe_cur_cmd != cmd) { outw(cmd, awe_ports[Pointer]); awe_cur_cmd = cmd; }/* store values to i/o port array */static void setup_ports(int port1, int port2, int port3){	awe_ports[0] = port1;	if (port2 == 0)		port2 = port1 + 0x400;	awe_ports[1] = port2;	awe_ports[2] = port2 + 2;	if (port3 == 0)		port3 = port1 + 0x800;	awe_ports[3] = port3;	awe_ports[4] = port3 + 2;	port_setuped = TRUE;}/* write 16bit data */static voidawe_poke(unsigned short cmd, unsigned short port, unsigned short data){	awe_set_cmd(cmd);	outw(data, awe_ports[port]);}/* write 32bit data */static voidawe_poke_dw(unsigned short cmd, unsigned short port, unsigned int data){	unsigned short addr = awe_ports[port];	awe_set_cmd(cmd);	outw(data, addr);		/* write lower 16 bits */	outw(data >> 16, addr + 2);	/* write higher 16 bits */}/* read 16bit data */static unsigned shortawe_peek(unsigned short cmd, unsigned short port){	unsigned short k;	awe_set_cmd(cmd);	k = inw(awe_ports[port]);	return k;}/* read 32bit data */static unsigned intawe_peek_dw(unsigned short cmd, unsigned short port){	unsigned int k1, k2;	unsigned short addr = awe_ports[port];	awe_set_cmd(cmd);	k1 = inw(addr);	k2 = inw(addr + 2);	k1 |= k2 << 16;	return k1;}/* wait delay number of AWE32 44100Hz clocks */#ifdef WAIT_BY_LOOP /* wait by loop -- that's not good.. */static voidawe_wait(unsigned short delay){	unsigned short clock, target;	unsigned short port = awe_ports[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;}#elsestatic void awe_wait(unsigned short delay){	current->state = TASK_INTERRUPTIBLE;	schedule_timeout((HZ*(unsigned long)delay + 44099)/44100);}/*static void awe_wait(unsigned short delay){	udelay(((unsigned long)delay * 1000000L + 44099) / 44100);}*/#endif /* wait by loop *//* write a word data */#define awe_write_dram(c)	awe_poke(AWE_SMLD, c)/* * port check / request *  0x620-623, 0xA20-A23, 0xE20-E23 */static int __initawe_check_port(void){	if (! port_setuped) return 0;	return (check_region(awe_ports[0], 4) ||		check_region(awe_ports[1], 4) ||		check_region(awe_ports[3], 4));}static void __initawe_request_region(void){	if (! port_setuped) return;	request_region(awe_ports[0], 4, "sound driver (AWE32)");	request_region(awe_ports[1], 4, "sound driver (AWE32)");	request_region(awe_ports[3], 4, "sound driver (AWE32)");}static void __exitawe_release_region(void){	if (! port_setuped) return;	release_region(awe_ports[0], 4);	release_region(awe_ports[1], 4);	release_region(awe_ports[3], 4);}/* * initialization of AWE driver */static voidawe_initialize(void){	DEBUG(0,printk("AWE32: initializing..\n"));	/* initialize hardware configuration */	awe_poke(AWE_HWCF1, 0x0059);	awe_poke(AWE_HWCF2, 0x0020);	/* disable audio; this seems to reduce a clicking noise a bit.. */	awe_poke(AWE_HWCF3, 0);	/* initialize audio channels */	awe_init_audio();	/* initialize DMA */	awe_init_dma();	/* initialize init array */	awe_init_array();	/* check DRAM memory 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);	/* set default values */	awe_init_ctrl_parms(TRUE);	/* set equalizer */	awe_update_equalizer();	/* set reverb & chorus modes */	awe_update_reverb_mode();	awe_update_chorus_mode();}/* * AWE32 voice parameters *//* initialize voice_info record */static voidawe_init_voice_info(awe_voice_info *vp){	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;}	#ifdef AWE_HAS_GUS_COMPATIBILITY/* convert frequency mHz to abstract cents (= midi key * 100) */static intfreq_to_note(int mHz){	/* abscents = log(mHz/8176) / log(2) * 1200 */	unsigned int max_val = (unsigned int)0xffffffff / 10000;	int i, times;	unsigned int base;	unsigned int 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 */

⌨️ 快捷键说明

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