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

📄 awe_wave.c

📁 iis s3c2410-uda1341语音系统的 开发
💻 C
📖 第 1 页 / 共 5 页
字号:
/* change pan; this could make a click noise.. */static voidawe_set_pan(int voice, int forced){	unsigned int temp;	int addr;	awe_voice_info *vp;	FX_Rec *fx = &voices[voice].cinfo->fx;	FX_Rec *fx_lay = NULL;	if (voices[voice].layer < MAX_LAYERS)		fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];	if (IS_NO_EFFECT(voice) && !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].cinfo->panning; /* -128 - 127 */		temp = 127 - pos;	}	limitvalue(temp, 0, 255);	if (ctrls[AWE_MD_PAN_EXCHANGE]) {		temp = 255 - temp;	}	if (forced || temp != voices[voice].apan) {		voices[voice].apan = temp;		if (temp == 0)			voices[voice].aaux = 0xff;		else			voices[voice].aaux = (-temp) & 0xff;		addr = vp->loopstart - 1;		addr += FX_OFFSET(fx, fx_lay, AWE_FX_LOOP_START,				  AWE_FX_COARSE_LOOP_START, vp->mode);		temp = (temp<<24) | (unsigned int)addr;		awe_poke_dw(AWE_PSST(voice), temp);		DEBUG(4,printk("AWE32: [-- loopstart=%x/%x]\n", vp->loopstart, addr));	}}/* effects change during playing */static voidawe_fx_fmmod(int voice, int forced){	awe_voice_info *vp;	FX_Rec *fx = &voices[voice].cinfo->fx;	FX_Rec *fx_lay = NULL;	if (voices[voice].layer < MAX_LAYERS)		fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];	if (IS_NO_EFFECT(voice) && !forced) return;	if ((vp = voices[voice].sample) == NULL || vp->index == 0)		return;	awe_poke(AWE_FMMOD(voice),		 FX_COMB(fx, fx_lay, AWE_FX_LFO1_PITCH, AWE_FX_LFO1_CUTOFF,			 vp->parm.fmmod));}/* set tremolo (lfo1) volume & frequency */static voidawe_fx_tremfrq(int voice, int forced){	awe_voice_info *vp;	FX_Rec *fx = &voices[voice].cinfo->fx;	FX_Rec *fx_lay = NULL;	if (voices[voice].layer < MAX_LAYERS)		fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];	if (IS_NO_EFFECT(voice) && !forced) return;	if ((vp = voices[voice].sample) == NULL || vp->index == 0)		return;	awe_poke(AWE_TREMFRQ(voice),		 FX_COMB(fx, fx_lay, AWE_FX_LFO1_VOLUME, AWE_FX_LFO1_FREQ,			 vp->parm.tremfrq));}/* set lfo2 pitch & frequency */static voidawe_fx_fm2frq2(int voice, int forced){	awe_voice_info *vp;	FX_Rec *fx = &voices[voice].cinfo->fx;	FX_Rec *fx_lay = NULL;	if (voices[voice].layer < MAX_LAYERS)		fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];	if (IS_NO_EFFECT(voice) && !forced) return;	if ((vp = voices[voice].sample) == NULL || vp->index == 0)		return;	awe_poke(AWE_FM2FRQ2(voice),		 FX_COMB(fx, fx_lay, AWE_FX_LFO2_PITCH, AWE_FX_LFO2_FREQ,			 vp->parm.fm2frq2));}/* Q & current address (Q 4bit value, MSB) */static voidawe_fx_filterQ(int voice, int forced){	unsigned int addr;	awe_voice_info *vp;	FX_Rec *fx = &voices[voice].cinfo->fx;	FX_Rec *fx_lay = NULL;	if (voices[voice].layer < MAX_LAYERS)		fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];	if (IS_NO_EFFECT(voice) && !forced) return;	if ((vp = voices[voice].sample) == NULL || vp->index == 0)		return;	addr = awe_peek_dw(AWE_CCCA(voice)) & 0xffffff;	addr |= (FX_BYTE(fx, fx_lay, AWE_FX_FILTERQ, vp->parm.filterQ) << 28);	awe_poke_dw(AWE_CCCA(voice), addr);}/* * 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;	awe_chan_info *cp = voices[voice].cinfo;	int offset;	/* search voice information */	if ((ap = vp->sample) == NULL)			return;	if (ap->index == 0) {		DEBUG(3,printk("AWE32: set sample (%d)\n", ap->sample));		if (awe_set_sample((awe_voice_list*)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 = (offset * ap->scaleTuning) / 100;	DEBUG(4,printk("AWE32: p-> scale* ofs=%d\n", offset));	offset += ap->tune * 4096 / 1200;	DEBUG(4,printk("AWE32: p-> tune+ ofs=%d\n", offset));	if (cp->bender != 0) {		DEBUG(3,printk("AWE32: p-> bend(%d) %d\n", voice, cp->bender));		/* (819200: 1 semitone) ==> (4096: 12 semitones) */		offset += cp->bender * cp->bender_range / 2400;	}	/* add initial pitch correction */	if (FX_ON(&cp->fx_layer[vp->layer], AWE_FX_INIT_PITCH))		offset += cp->fx_layer[vp->layer].val[AWE_FX_INIT_PITCH];	else if (FX_ON(&cp->fx, AWE_FX_INIT_PITCH))		offset += cp->fx.val[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;}#ifdef AWE_HAS_GUS_COMPATIBILITY/* calculate MIDI key and semitone from the specified frequency */static voidawe_calc_pitch_from_freq(int voice, int freq){	voice_info *vp = &voices[voice];	awe_voice_info *ap;	FX_Rec *fx = &voices[voice].cinfo->fx;	FX_Rec *fx_lay = NULL;	int offset;	int note;	if (voices[voice].layer < MAX_LAYERS)		fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];	/* search voice information */	if ((ap = vp->sample) == NULL)		return;	if (ap->index == 0) {		DEBUG(3,printk("AWE32: set sample (%d)\n", ap->sample));		if (awe_set_sample((awe_voice_list*)ap) == 0)			return;	}	note = freq_to_note(freq);	offset = (note - ap->root * 100 + ap->tune) * 4096 / 1200;	offset = (offset * ap->scaleTuning) / 100;	if (fx_lay && FX_ON(fx_lay, AWE_FX_INIT_PITCH))		offset += fx_lay->val[AWE_FX_INIT_PITCH];	else if (FX_ON(fx, AWE_FX_INIT_PITCH))		offset += fx->val[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;}#endif /* AWE_HAS_GUS_COMPATIBILITY *//* * 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,};/* tables for volume->attenuation calculation */static unsigned char voltab1[128] = {   0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,   0x63, 0x2b, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22,   0x21, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a,   0x19, 0x19, 0x18, 0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x14,   0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10,   0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0d,   0x0d, 0x0d, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b,   0x0b, 0x0a, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,   0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06,   0x06, 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04,   0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02,   0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,   0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};static unsigned char voltab2[128] = {   0x32, 0x31, 0x30, 0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x2a,   0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x24, 0x23, 0x22, 0x21,   0x21, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1c, 0x1b, 0x1a,   0x1a, 0x19, 0x19, 0x18, 0x18, 0x17, 0x16, 0x16, 0x15, 0x15,   0x14, 0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x10,   0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d,   0x0d, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a, 0x0a,   0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x08, 0x08, 0x08,   0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06,   0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,   0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03,   0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01,   0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00};static unsigned char expressiontab[128] = {   0x7f, 0x6c, 0x62, 0x5a, 0x54, 0x50, 0x4b, 0x48, 0x45, 0x42,   0x40, 0x3d, 0x3b, 0x39, 0x38, 0x36, 0x34, 0x33, 0x31, 0x30,   0x2f, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25,   0x24, 0x24, 0x23, 0x22, 0x21, 0x21, 0x20, 0x1f, 0x1e, 0x1e,   0x1d, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a, 0x1a, 0x19, 0x18, 0x18,   0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x15, 0x14, 0x14, 0x13,   0x13, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10, 0x10, 0x0f, 0x0f,   0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 0x0d, 0x0c, 0x0c, 0x0c,   0x0b, 0x0b, 0x0b, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09,   0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06,   0x06, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03,   0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,   0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};static voidawe_calc_volume(int voice){	voice_info *vp = &voices[voice];	awe_voice_info *ap;	awe_chan_info *cp = voices[voice].cinfo;	int vol;	/* search voice information */	if ((ap = vp->sample) == NULL)		return;	ap = vp->sample;	if (ap->index == 0) {		DEBUG(3,printk("AWE32: set sample (%d)\n", ap->sample));		if (awe_set_sample((awe_voice_list*)ap) == 0)			return;	}		if (ctrls[AWE_MD_NEW_VOLUME_CALC]) {		int main_vol = cp->main_vol * ap->amplitude / 127;		limitvalue(vp->velocity, 0, 127);		limitvalue(main_vol, 0, 127);		limitvalue(cp->expression_vol, 0, 127);		vol = voltab1[main_vol] + voltab2[vp->velocity];		vol = (vol * 8) / 3;		vol += ap->attenuation;		if (cp->expression_vol < 127)			vol += ((0x100 - vol) * expressiontab[cp->expression_vol])/128;		vol += atten_offset;		if (atten_relative)			vol += ctrls[AWE_MD_ZERO_ATTEN];		limitvalue(vol, 0, 255);		vp->avol = vol;			} else {		/* 0 - 127 */		vol = (vp->velocity * cp->main_vol * cp->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 += (int)ap->attenuation;		vol += atten_offset;		if (atten_relative)			vol += ctrls[AWE_MD_ZERO_ATTEN];		if (vol > 255) vol = 255;		vp->avol = vol;	}	if (cp->bank !=  AWE_DRUM_BANK && ((awe_voice_parm_block*)(&ap->parm))->volatk < 0x7d) {		int atten;		if (vp->velocity < 70) atten = 70;		else atten = vp->velocity;		vp->acutoff = (atten * ap->parm.cutoff + 0xa0) >> 7;	} else {		vp->acutoff = ap->parm.cutoff;	}	DEBUG(3,printk("AWE32: [-- voice(%d) vol=%x]\n", voice, vol));}/* change master volume */static voidawe_change_master_volume(short val){	limitvalue(val, 0, 127);	atten_offset = vol_table[val];	atten_relative = TRUE;	awe_update_volume();}/* update volumes of all available channels */static void awe_update_volume(void){	int i;	for (i = 0; i < awe_max_voices; i++)		awe_set_voice_vol(i, TRUE);}/* set sostenuto on */static void awe_sostenuto_on(int voice, int forced){	if (IS_NO_EFFECT(voice) && !forced) return;	voices[voice].sostenuto = 127;}/* drop sustain */static void awe_sustain_off(int voice, int forced){	if (voices[voice].state == AWE_ST_SUSTAINED) {		awe_note_off(voice);		awe_fx_init(voices[voice].ch);		awe_voice_init(voice, FALSE);	}}/* terminate and initialize voice */static void awe_terminate_and_init(int voice, int forced){	awe_terminate(voice);	awe_fx_init(voices[voice].ch);	awe_voice_init(voice, TRUE);}/* * synth operation routines */#define AWE_VOICE_KEY(v)	(0x8000 | (v))#define AWE_CHAN_KEY(c,n)	(((c) << 8) | ((n) + 1))#define KEY_CHAN_MATCH(key,c)	(((key) >> 8) == (c))/* initialize the voice */static voidawe_voice_init(int voice, int init_all){	voice_info *vp = &voices[voice];	/* reset voice search key */	if (playing_mode == AWE_PLAY_DIRECT)		vp->key = AWE_VOICE_KEY(voice);	else		vp->key = 0;	/* clear voice mapping */	voice_alloc->map[voice] = 0;	/* touch the timing flag */	vp->time = current_alloc_time;	/* initialize other parameters if necessary */	if (init_all) {		vp->note = -1;		vp->velocity = 0;		vp->sostenuto = 0;		vp->sample = NULL;		vp->cinfo = &channels[voice];		vp->ch = voice;		vp->state = AWE_ST_OFF;		/* emu8000 parameters */		vp->apitch = 0;		vp->avol = 255;		vp->apan = -1;	}}/* clear effects */static void awe_fx_init(int ch){	if (SINGLE_LAYER_MODE() && !ctrls[AWE_MD_KEEP_EFFECT]) {		memset(&channels[ch].fx, 0, sizeof(channels[ch].fx));		memset(&channels[ch].fx_layer, 0, sizeof(&channels[ch].fx_layer));	}}/* initialize channel info */static void awe_channel_init(int ch, int init_all){	awe_chan_info *cp = &channels[ch];	cp->channel = ch;	if (init_all) {		cp->panning = 0; /* zero center */		cp->bender_range = 200; /* sense * 100 */		cp->main_vol = 127;		if (MULTI_LAYER_MODE() && IS_DRUM_CHANNEL(ch)) {			cp->instr = ctrls[AWE_MD_DEF_DRUM];			cp->bank = AWE_DRUM_BANK;		} else {			cp->instr = ctrls[AWE_MD_DEF_PRESET];			cp->bank = ctrls[AWE_MD_DEF_BANK];		}	}	cp->bender = 0; /* zero tune skew */	cp->expression_vol = 127;	cp->chan_press = 0;	cp->sustained = 0;	if (! ctrls[AWE_MD_KEEP_EFFECT]) {		memset(&cp->fx, 0, sizeof(cp->fx));		memset(&cp->fx_layer, 0, sizeof(cp->fx_layer));	}}/* change the voice parameters; voice = channel */static void awe_voice_change(int voice, fx_affect_func func){	int i; 	switch (playing_mode) {	case AWE_PLAY_DIRECT:		func(voice, FALSE);		break;	case AWE_PLAY_INDIRECT:		for (i = 0; i < awe_max_voices; i++)			if (voices[i].key == AWE_VOICE_KEY(voice))				func(i, FALSE);		break;	default:		for (i = 0; i < awe_max_voices; i++)

⌨️ 快捷键说明

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