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

📄 awe_wave.c

📁 freebsd v4.4内核源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	addr = 0;	if (FX_ON(voice, hi)) {		addr = (short)voices[voice].fx[hi];		addr = addr << 15;	}	if (FX_ON(voice, lo))		addr += (short)voices[voice].fx[lo];	if (!(vp->mode & (AWE_SAMPLE_8BITS<<6)))		addr /= 2;	return addr;}/* converter function table for realtime paramter change */typedef void (*fx_affect_func)(int voice);static fx_affect_func fx_realtime[] = {	/* env1: delay, attack, hold, decay, release, sustain, pitch, cutoff*/	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,	/* env2: delay, attack, hold, decay, release, sustain */	NULL, NULL, NULL, NULL, NULL, NULL,	/* lfo1: delay, freq, volume, pitch, cutoff */	NULL, awe_fx_tremfrq, awe_fx_tremfrq, awe_fx_fmmod, awe_fx_fmmod,	/* lfo2: delay, freq, pitch */	NULL, awe_fx_fm2frq2, awe_fx_fm2frq2,	/* global: initpitch, chorus, reverb, cutoff, filterQ */	awe_fx_initpitch, NULL, NULL, awe_fx_cutoff, NULL,	/* sample: start, loopstart, loopend */	NULL, NULL, NULL,};/*================================================================ * turn on/off sample *================================================================*/static voidawe_note_on(int voice){	unsigned long temp;	long addr;	unsigned short tmp2;	awe_voice_info *vp;	/* A voice sample must assigned before calling */	if ((vp = voices[voice].sample) == NULL || vp->index < 0)		return;	/* channel to be silent and idle */	awe_poke(AWE_DCYSUSV(voice), 0x0080);	awe_poke(AWE_VTFT(voice), 0);	awe_poke(AWE_CVCF(voice), 0);	awe_poke(AWE_PTRX(voice), 0);	awe_poke(AWE_CPF(voice), 0);	/* modulation & volume envelope */	awe_poke(AWE_ENVVAL(voice),		 FX_WORD(voice, AWE_FX_ENV1_DELAY, vp->parm.moddelay));	awe_poke(AWE_ATKHLD(voice),		 FX_COMB(voice, AWE_FX_ENV1_ATTACK, AWE_FX_ENV1_HOLD,			 vp->parm.modatkhld));	awe_poke(AWE_DCYSUS(voice),		 FX_COMB(voice, AWE_FX_ENV1_SUSTAIN, AWE_FX_ENV1_DECAY,			  vp->parm.moddcysus));	awe_poke(AWE_ENVVOL(voice),		 FX_WORD(voice, AWE_FX_ENV2_DELAY, vp->parm.voldelay));	awe_poke(AWE_ATKHLDV(voice),		 FX_COMB(voice, AWE_FX_ENV2_ATTACK, AWE_FX_ENV2_HOLD,			 vp->parm.volatkhld));	/* decay/sustain parameter for volume envelope must be set at last */	/* pitch offset */	awe_poke(AWE_IP(voice), voices[voice].apitch);	DEBUG(3,printk("AWE32: [-- pitch=%x]\n", voices[voice].apitch));	/* cutoff and volume */	tmp2 = FX_BYTE(voice, AWE_FX_CUTOFF, vp->parm.cutoff);	tmp2 = (tmp2 << 8) | voices[voice].avol;	awe_poke(AWE_IFATN(voice), tmp2);	/* modulation envelope heights */	awe_poke(AWE_PEFE(voice),		 FX_COMB(voice, AWE_FX_ENV1_PITCH, AWE_FX_ENV1_CUTOFF,			 vp->parm.pefe));	/* lfo1/2 delay */	awe_poke(AWE_LFO1VAL(voice),		 FX_WORD(voice, AWE_FX_LFO1_DELAY, vp->parm.lfo1delay));	awe_poke(AWE_LFO2VAL(voice),		 FX_WORD(voice, AWE_FX_LFO2_DELAY, vp->parm.lfo2delay));	/* lfo1 pitch & cutoff shift */	awe_poke(AWE_FMMOD(voice),		 FX_COMB(voice, AWE_FX_LFO1_PITCH, AWE_FX_LFO1_CUTOFF,			 vp->parm.fmmod));	/* lfo1 volume & freq */	awe_poke(AWE_TREMFRQ(voice),		 FX_COMB(voice, AWE_FX_LFO1_VOLUME, AWE_FX_LFO1_FREQ,			 vp->parm.tremfrq));	/* lfo2 pitch & freq */	awe_poke(AWE_FM2FRQ2(voice),		 FX_COMB(voice, AWE_FX_LFO2_PITCH, AWE_FX_LFO2_FREQ,			 vp->parm.fm2frq2));	/* pan & loop start */	 awe_set_pan(voice, 1);	/* chorus & loop end (chorus 8bit, MSB) */	addr = vp->loopend - 1;	addr += FX_OFFSET(voice, AWE_FX_LOOP_END,			  AWE_FX_COARSE_LOOP_END);	temp = FX_BYTE(voice, AWE_FX_CHORUS, vp->parm.chorus);	temp = (temp <<24) | (unsigned long)addr;	awe_poke_dw(AWE_CSL(voice), temp);	/* Q & current address (Q 4bit value, MSB) */	addr = vp->start - 1;	addr += FX_OFFSET(voice, AWE_FX_SAMPLE_START,			  AWE_FX_COARSE_SAMPLE_START);	temp = FX_BYTE(voice, AWE_FX_FILTERQ, vp->parm.filterQ);	temp = (temp<<28) | (unsigned long)addr;	awe_poke_dw(AWE_CCCA(voice), temp);	/* reset volume */	awe_poke_dw(AWE_VTFT(voice), 0x0000FFFF);	awe_poke_dw(AWE_CVCF(voice), 0x0000FFFF);	/* turn on envelope */	awe_poke(AWE_DCYSUSV(voice),		 FX_COMB(voice, AWE_FX_ENV2_SUSTAIN, AWE_FX_ENV2_DECAY,			  vp->parm.voldcysus));	/* set chorus */	temp = FX_BYTE(voice, AWE_FX_REVERB, vp->parm.reverb);	temp = (awe_peek_dw(AWE_PTRX(voice)) & 0xffff0000) | (temp<<8);	awe_poke_dw(AWE_PTRX(voice), temp);	awe_poke_dw(AWE_CPF(voice), 0x40000000);	DEBUG(3,printk("AWE32: [-- start=%x loop=%x]\n",		       (int)vp->start, (int)vp->loopstart));}/* turn off the voice */static voidawe_note_off(int voice){	awe_voice_info *vp;	unsigned short tmp;	if ((vp = voices[voice].sample) == NULL || !voices[voice].state)		return;	if (FX_ON(voice, AWE_FX_ENV1_RELEASE))		tmp = 0x8000 | voices[voice].fx[AWE_FX_ENV1_RELEASE];	else		tmp = vp->parm.modrelease;	awe_poke(AWE_DCYSUS(voice), tmp);	if (FX_ON(voice, AWE_FX_ENV2_RELEASE))		tmp = 0x8000 | voices[voice].fx[AWE_FX_ENV2_RELEASE];	else		tmp = vp->parm.volrelease;	awe_poke(AWE_DCYSUSV(voice), tmp);}/* force to terminate the voice (no releasing echo) */static voidawe_terminate(int voice){	awe_poke(AWE_DCYSUSV(voice), 0x807F);}/* turn off other voices with the same exclusive class (for drums) */static voidawe_exclusive_off(int voice){	int i, excls;	if (voices[voice].sample == NULL) /* no sample */		return;	excls = voices[voice].sample->exclusiveClass;	if (excls == 0)	/* not exclusive */		return;	/* turn off voices with the same class */	for (i = 0; i < awe_max_voices; i++) {		if (i != voice && voices[voice].state &&		    voices[i].sample &&		    voices[i].sample->exclusiveClass == excls) {			DEBUG(4,printk("AWE32: [exoff(%d)]\n", i));			awe_note_off(i);			awe_voice_init(i, 1);		}	}}/*================================================================ * change the parameters of an audible voice *================================================================*//* change pitch */static voidawe_set_pitch(int voice){	if (!voices[voice].state) return;	awe_poke(AWE_IP(voice), voices[voice].apitch);}/* change volume */static voidawe_set_volume(int voice){	awe_voice_info *vp;	unsigned short tmp2;	if (!voices[voice].state) return;	if ((vp = voices[voice].sample) == NULL || vp->index < 0)		return;	tmp2 = FX_BYTE(voice, AWE_FX_CUTOFF, vp->parm.cutoff);	tmp2 = (tmp2 << 8) | voices[voice].avol;	awe_poke(AWE_IFATN(voice), tmp2);}/* change pan; this could make a click noise.. */static voidawe_set_pan(int voice, int forced){	unsigned long temp;	long addr;	awe_voice_info *vp;	if (!voices[voice].state && !forced) return;	if ((vp = voices[voice].sample) == NULL || vp->index < 0)		return;	/* pan & loop start (pan 8bit, MSB, 0:right, 0xff:left) */	if (vp->fixpan > 0)	/* 0-127 */		temp = 255 - (int)vp->fixpan * 2;	else {		int pos = 0;		if (vp->pan >= 0) /* 0-127 */			pos = (int)vp->pan * 2 - 128;		pos += voices[voice].panning; /* -128 - 127 */		pos = 127 - pos;		if (pos < 0)			temp = 0;		else if (pos > 255)			temp = 255;		else			temp = pos;	}	addr = vp->loopstart - 1;	addr += FX_OFFSET(voice, AWE_FX_LOOP_START,			  AWE_FX_COARSE_LOOP_START);	temp = (temp<<24) | (unsigned long)addr;	awe_poke_dw(AWE_PSST(voice), temp);}/* effects change during playing */static voidawe_fx_fmmod(int voice){	awe_voice_info *vp;	if (!voices[voice].state) return;	if ((vp = voices[voice].sample) == NULL || vp->index < 0)		return;	awe_poke(AWE_FMMOD(voice),		 FX_COMB(voice, AWE_FX_LFO1_PITCH, AWE_FX_LFO1_CUTOFF,			 vp->parm.fmmod));}static voidawe_fx_tremfrq(int voice){	awe_voice_info *vp;	if (!voices[voice].state) return;	if ((vp = voices[voice].sample) == NULL || vp->index < 0)		return;	awe_poke(AWE_TREMFRQ(voice),		 FX_COMB(voice, AWE_FX_LFO1_VOLUME, AWE_FX_LFO1_FREQ,			 vp->parm.tremfrq));}static voidawe_fx_fm2frq2(int voice){	awe_voice_info *vp;	if (!voices[voice].state) return;	if ((vp = voices[voice].sample) == NULL || vp->index < 0)		return;	awe_poke(AWE_FM2FRQ2(voice),		 FX_COMB(voice, AWE_FX_LFO2_PITCH, AWE_FX_LFO2_FREQ,			 vp->parm.fm2frq2));}static voidawe_fx_cutoff(int voice){	unsigned short tmp2;	awe_voice_info *vp;	if (!voices[voice].state) return;	if ((vp = voices[voice].sample) == NULL || vp->index < 0)		return;	tmp2 = FX_BYTE(voice, AWE_FX_CUTOFF, vp->parm.cutoff);	tmp2 = (tmp2 << 8) | voices[voice].avol;	awe_poke(AWE_IFATN(voice), tmp2);}static voidawe_fx_initpitch(int voice){	if (!voices[voice].state) return;	if (FX_ON(voice, AWE_FX_INIT_PITCH)) {		DEBUG(3,printk("AWE32: initpitch ok\n"));	} else {		DEBUG(3,printk("AWE32: BAD initpitch %d\n", AWE_FX_INIT_PITCH));	}	awe_calc_pitch(voice);	awe_poke(AWE_IP(voice), voices[voice].apitch);}/*================================================================ * calculate pitch offset *---------------------------------------------------------------- * 0xE000 is no pitch offset at 44100Hz sample. * Every 4096 is one octave. *================================================================*/static voidawe_calc_pitch(int voice){	voice_info *vp = &voices[voice];	awe_voice_info *ap;	int offset;	/* search voice information */	if ((ap = vp->sample) == NULL)			return;	if (ap->index < 0) {		if (awe_set_sample(ap) < 0)			return;	}	/* calculate offset */	if (ap->fixkey >= 0) {		DEBUG(3,printk("AWE32: p-> fixkey(%d) tune(%d)\n", ap->fixkey, ap->tune));		offset = (ap->fixkey - ap->root) * 4096 / 12;	} else {		DEBUG(3,printk("AWE32: p(%d)-> root(%d) tune(%d)\n", vp->note, ap->root, ap->tune));		offset = (vp->note - ap->root) * 4096 / 12;		DEBUG(4,printk("AWE32: p-> ofs=%d\n", offset));	}	offset += ap->tune * 4096 / 1200;	DEBUG(4,printk("AWE32: p-> tune+ ofs=%d\n", offset));	if (vp->bender != 0) {		DEBUG(3,printk("AWE32: p-> bend(%d) %d\n", voice, vp->bender));		/* (819200: 1 semitone) ==> (4096: 12 semitones) */		offset += vp->bender * vp->bender_range / 2400;	}	offset = (offset * ap->scaleTuning) / 100;	DEBUG(4,printk("AWE32: p-> scale* ofs=%d\n", offset));	/* add initial pitch correction */	if (FX_ON(voice, AWE_FX_INIT_PITCH)) {		DEBUG(3,printk("AWE32: fx_pitch(%d) %d\n", voice, vp->fx[AWE_FX_INIT_PITCH]));		offset += vp->fx[AWE_FX_INIT_PITCH];	}	/* 0xe000: root pitch */	vp->apitch = 0xe000 + ap->rate_offset + offset;	DEBUG(4,printk("AWE32: p-> sum aofs=%x, rate_ofs=%d\n", vp->apitch, ap->rate_offset));	if (vp->apitch > 0xffff)		vp->apitch = 0xffff;	if (vp->apitch < 0)		vp->apitch = 0;}static voidawe_calc_pitch_from_freq(int voice, int freq){	voice_info *vp = &voices[voice];	awe_voice_info *ap;	int offset;	int note;	/* search voice information */	if ((ap = vp->sample) == NULL)		return;	if (ap->index < 0) {		if (awe_set_sample(ap) < 0)			return;	}	note = freq_to_note(freq);	offset = (note - ap->root * 100 + ap->tune) * 4096 / 1200;	offset = (offset * ap->scaleTuning) / 100;	if (FX_ON(voice, AWE_FX_INIT_PITCH))		offset += vp->fx[AWE_FX_INIT_PITCH];	vp->apitch = 0xe000 + ap->rate_offset + offset;	if (vp->apitch > 0xffff)		vp->apitch = 0xffff;	if (vp->apitch < 0)		vp->apitch = 0;}/*================================================================ * calculate volume attenuation *---------------------------------------------------------------- * Voice volume is controlled by volume attenuation parameter. * So volume becomes maximum when avol is 0 (no attenuation), and * minimum when 255 (-96dB or silence). *================================================================*/static int vol_table[128] = {	255,111,95,86,79,74,70,66,63,61,58,56,54,52,50,49,	47,46,45,43,42,41,40,39,38,37,36,35,34,34,33,32,	31,31,30,29,29,28,27,27,26,26,25,24,24,23,23,22,	22,21,21,21,20,20,19,19,18,18,18,17,17,16,16,16,	15,15,15,14,14,14,13,13,13,12,12,12,11,11,11,10,	10,10,10,9,9,9,8,8,8,8,7,7,7,7,6,6,	6,6,5,5,5,5,5,4,4,4,4,3,3,3,3,3,	2,2,2,2,2,1,1,1,1,1,0,0,0,0,0,0,};static voidawe_calc_volume(int voice){	voice_info *vp = &voices[voice];	awe_voice_info *ap;	int vol;	/* search voice information */	if ((ap = vp->sample) == NULL)		return;	ap = vp->sample;	if (ap->index < 0) {		if (awe_set_sample(ap) < 0)			return;	}		if (vp->velocity < ap->vellow)		vp->velocity = ap->vellow;	else if (vp->velocity > ap->velhigh)		vp->velocity = ap->velhigh;	/* 0 - 127 */	vol = (vp->velocity * vp->main_vol * vp->expression_vol) / (127*127);	vol = vol * ap->amplitude / 127;	if (vol < 0) vol = 0;	if (vol > 127) vol = 127;	/* calc to attenuation */	vol = vol_table[vol];	vol = vol + (int)ap->attenuation + init_atten;	if (vol > 255) vol = 255;	vp->avol = vol;	DEBUG(3,printk("AWE32: [-- voice(%d) vol=%x]\n", voice, vol));}/*================================================================ * synth operation routines *================================================================*//* initialize the voice */static voidawe_voice_init(int voice, int inst_only){	if (! inst_only) {		/* clear voice parameters */		voices[voice].note = -1;		voices[voice].velocity = 0;		voices[voice].panning = 0; /* zero center */		voices[voice].bender = 0; /* zero tune skew */		voices[voice].bender_range = 200; /* sense * 100 */		voices[voice].main_vol = 127;		voices[voice].expression_vol = 127;		voices[voice].bank = AWE_DEFAULT_BANK;		voices[voice].instr = -1;		voices[voice].vrec = NULL;		voices[voice].sample = NULL;	}	/* clear voice mapping */	voices[voice].state = 0;	voice_alloc->map[voice] = 0;	/* emu8000 parameters */	voices[voice].apitch = 0;	voices[voice].avol = 255;	/* clear effects */	BZERO(voices[voice].fx_flags, sizeof(voices[voice].fx_flags));}/*---------------------------------------------------------------- * device open / close *----------------------------------------------------------------*//* open device:

⌨️ 快捷键说明

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