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

📄 awe_wave.c

📁 iis s3c2410-uda1341语音系统的 开发
💻 C
📖 第 1 页 / 共 5 页
字号:
			if (KEY_CHAN_MATCH(voices[i].key, voice))				func(i, FALSE);		break;	}}/* * device open / close *//* open device: *   reset status of all voices, and clear sample position flag */static intawe_open(int dev, int mode){	if (awe_busy)		return -EBUSY;	awe_busy = TRUE;	/* set default mode */	awe_init_ctrl_parms(FALSE);	atten_relative = TRUE;	atten_offset = 0;	drum_flags = DEFAULT_DRUM_FLAGS;	playing_mode = AWE_PLAY_INDIRECT;	/* reset voices & channels */	awe_reset(dev);	patch_opened = 0;	return 0;}/* close device: *   reset all voices again (terminate sounds) */static voidawe_close(int dev){	awe_reset(dev);	awe_busy = FALSE;}/* set miscellaneous mode parameters */static voidawe_init_ctrl_parms(int init_all){	int i;	for (i = 0; i < AWE_MD_END; i++) {		if (init_all || ctrl_parms[i].init_each_time)			ctrls[i] = ctrl_parms[i].value;	}}/* sequencer I/O control: */static intawe_ioctl(int dev, unsigned int cmd, caddr_t arg){	switch (cmd) {	case SNDCTL_SYNTH_INFO:		if (playing_mode == AWE_PLAY_DIRECT)			awe_info.nr_voices = awe_max_voices;		else			awe_info.nr_voices = AWE_MAX_CHANNELS;		memcpy((char*)arg, &awe_info, sizeof(awe_info));		return 0;		break;	case SNDCTL_SEQ_RESETSAMPLES:		awe_reset(dev);		awe_reset_samples();		return 0;		break;	case SNDCTL_SEQ_PERCMODE:		/* what's this? */		return 0;		break;	case SNDCTL_SYNTH_MEMAVL:		return memsize - awe_free_mem_ptr() * 2;	default:		printk(KERN_WARNING "AWE32: unsupported ioctl %d\n", cmd);		return -EINVAL;	}}static int voice_in_range(int voice){	if (playing_mode == AWE_PLAY_DIRECT) {		if (voice < 0 || voice >= awe_max_voices)			return FALSE;	} else {		if (voice < 0 || voice >= AWE_MAX_CHANNELS)			return FALSE;	}	return TRUE;}static void release_voice(int voice, int do_sustain){	if (IS_NO_SOUND(voice))		return;	if (do_sustain && (voices[voice].cinfo->sustained == 127 ||			    voices[voice].sostenuto == 127))		voices[voice].state = AWE_ST_SUSTAINED;	else {		awe_note_off(voice);		awe_fx_init(voices[voice].ch);		awe_voice_init(voice, FALSE);	}}/* release all notes */static void awe_note_off_all(int do_sustain){	int i;	for (i = 0; i < awe_max_voices; i++)		release_voice(i, do_sustain);}/* kill a voice: *   not terminate, just release the voice. */static intawe_kill_note(int dev, int voice, int note, int velocity){	int i, v2, key;	DEBUG(2,printk("AWE32: [off(%d) nt=%d vl=%d]\n", voice, note, velocity));	if (! voice_in_range(voice))		return -EINVAL;	switch (playing_mode) {	case AWE_PLAY_DIRECT:	case AWE_PLAY_INDIRECT:		key = AWE_VOICE_KEY(voice);		break;	case AWE_PLAY_MULTI2:		v2 = voice_alloc->map[voice] >> 8;		voice_alloc->map[voice] = 0;		voice = v2;		if (voice < 0 || voice >= AWE_MAX_CHANNELS)			return -EINVAL;		/* continue to below */	default:		key = AWE_CHAN_KEY(voice, note);		break;	}	for (i = 0; i < awe_max_voices; i++) {		if (voices[i].key == key)			release_voice(i, TRUE);	}	return 0;}static void start_or_volume_change(int voice, int velocity){	voices[voice].velocity = velocity;	awe_calc_volume(voice);	if (voices[voice].state == AWE_ST_STANDBY)		awe_note_on(voice);	else if (voices[voice].state == AWE_ST_ON)		awe_set_volume(voice, FALSE);}static void set_and_start_voice(int voice, int state){	/* calculate pitch & volume parameters */	voices[voice].state = state;	awe_calc_pitch(voice);	awe_calc_volume(voice);	if (state == AWE_ST_ON)		awe_note_on(voice);}/* start a voice: *   if note is 255, identical with aftertouch function. *   Otherwise, start a voice with specified not and volume. */static intawe_start_note(int dev, int voice, int note, int velocity){	int i, key, state, volonly;	DEBUG(2,printk("AWE32: [on(%d) nt=%d vl=%d]\n", voice, note, velocity));	if (! voice_in_range(voice))		return -EINVAL;	    	if (velocity == 0)		state = AWE_ST_STANDBY; /* stand by for playing */	else		state = AWE_ST_ON;	/* really play */	volonly = FALSE;	switch (playing_mode) {	case AWE_PLAY_DIRECT:	case AWE_PLAY_INDIRECT:		key = AWE_VOICE_KEY(voice);		if (note == 255)			volonly = TRUE;		break;	case AWE_PLAY_MULTI2:		voice = voice_alloc->map[voice] >> 8;		if (voice < 0 || voice >= AWE_MAX_CHANNELS)			return -EINVAL;		/* continue to below */	default:		if (note >= 128) { /* key volume mode */			note -= 128;			volonly = TRUE;		}		key = AWE_CHAN_KEY(voice, note);		break;	}	/* dynamic volume change */	if (volonly) {		for (i = 0; i < awe_max_voices; i++) {			if (voices[i].key == key)				start_or_volume_change(i, velocity);		}		return 0;	}	/* if the same note still playing, stop it */	if (playing_mode != AWE_PLAY_DIRECT || ctrls[AWE_MD_EXCLUSIVE_SOUND]) {		for (i = 0; i < awe_max_voices; i++)			if (voices[i].key == key) {				if (voices[i].state == AWE_ST_ON) {					awe_note_off(i);					awe_voice_init(i, FALSE);				} else if (voices[i].state == AWE_ST_STANDBY)					awe_voice_init(i, TRUE);			}	}	/* allocate voices */	if (playing_mode == AWE_PLAY_DIRECT)		awe_alloc_one_voice(voice, note, velocity);	else		awe_alloc_multi_voices(voice, note, velocity, key);	/* turn off other voices exlusively (for drums) */	for (i = 0; i < awe_max_voices; i++)		if (voices[i].key == key)			awe_exclusive_off(i);	/* set up pitch and volume parameters */	for (i = 0; i < awe_max_voices; i++) {		if (voices[i].key == key && voices[i].state == AWE_ST_OFF)			set_and_start_voice(i, state);	}	return 0;}/* calculate hash key */static intawe_search_key(int bank, int preset, int note){	unsigned int key;#if 1 /* new hash table */	if (bank == AWE_DRUM_BANK)		key = preset + note + 128;	else		key = bank + preset;#else	key = preset;#endif	key %= AWE_MAX_PRESETS;	return (int)key;}/* search instrument from hash table */static awe_voice_list *awe_search_instr(int bank, int preset, int note){	awe_voice_list *p;	int key, key2;	key = awe_search_key(bank, preset, note);	for (p = preset_table[key]; p; p = p->next_bank) {		if (p->instr == preset && p->bank == bank)			return p;	}	key2 = awe_search_key(bank, preset, 0); /* search default */	if (key == key2)		return NULL;	for (p = preset_table[key2]; p; p = p->next_bank) {		if (p->instr == preset && p->bank == bank)			return p;	}	return NULL;}/* assign the instrument to a voice */static intawe_set_instr_2(int dev, int voice, int instr_no){	if (playing_mode == AWE_PLAY_MULTI2) {		voice = voice_alloc->map[voice] >> 8;		if (voice < 0 || voice >= AWE_MAX_CHANNELS)			return -EINVAL;	}	return awe_set_instr(dev, voice, instr_no);}/* assign the instrument to a channel; voice is the channel number */static intawe_set_instr(int dev, int voice, int instr_no){	awe_chan_info *cinfo;	if (! voice_in_range(voice))		return -EINVAL;	if (instr_no < 0 || instr_no >= AWE_MAX_PRESETS)		return -EINVAL;	cinfo = &channels[voice];	cinfo->instr = instr_no;	DEBUG(2,printk("AWE32: [program(%d) %d]\n", voice, instr_no));	return 0;}/* reset all voices; terminate sounds and initialize parameters */static voidawe_reset(int dev){	int i;	current_alloc_time = 0;	/* don't turn off voice 31 and 32.  they are used also for FM voices */	for (i = 0; i < awe_max_voices; i++) {		awe_terminate(i);		awe_voice_init(i, TRUE);	}	for (i = 0; i < AWE_MAX_CHANNELS; i++)		awe_channel_init(i, TRUE);	for (i = 0; i < 16; i++) {		awe_operations.chn_info[i].controllers[CTL_MAIN_VOLUME] = 127;		awe_operations.chn_info[i].controllers[CTL_EXPRESSION] = 127;	}	awe_init_fm();	awe_tweak();}/* hardware specific control: *   GUS specific and AWE32 specific controls are available. */static voidawe_hw_control(int dev, unsigned char *event){	int cmd = event[2];	if (cmd & _AWE_MODE_FLAG)		awe_hw_awe_control(dev, cmd & _AWE_MODE_VALUE_MASK, event);#ifdef AWE_HAS_GUS_COMPATIBILITY	else		awe_hw_gus_control(dev, cmd & _AWE_MODE_VALUE_MASK, event);#endif}#ifdef AWE_HAS_GUS_COMPATIBILITY/* GUS compatible controls */static voidawe_hw_gus_control(int dev, int cmd, unsigned char *event){	int voice, i, key;	unsigned short p1;	short p2;	int plong;	if (MULTI_LAYER_MODE())		return;	if (cmd == _GUS_NUMVOICES)		return;	voice = event[3];	if (! voice_in_range(voice))		return;	p1 = *(unsigned short *) &event[4];	p2 = *(short *) &event[6];	plong = *(int*) &event[4];	switch (cmd) {	case _GUS_VOICESAMPLE:		awe_set_instr(dev, voice, p1);		return;	case _GUS_VOICEBALA:		/* 0 to 15 --> -128 to 127 */		awe_panning(dev, voice, ((int)p1 << 4) - 128);		return;	case _GUS_VOICEVOL:	case _GUS_VOICEVOL2:		/* not supported yet */		return;	case _GUS_RAMPRANGE:	case _GUS_RAMPRATE:	case _GUS_RAMPMODE:	case _GUS_RAMPON:	case _GUS_RAMPOFF:		/* volume ramping not supported */		return;	case _GUS_VOLUME_SCALE:		return;	case _GUS_VOICE_POS:		FX_SET(&channels[voice].fx, AWE_FX_SAMPLE_START,		       (short)(plong & 0x7fff));		FX_SET(&channels[voice].fx, AWE_FX_COARSE_SAMPLE_START,		       (plong >> 15) & 0xffff);		return;	}	key = AWE_VOICE_KEY(voice);	for (i = 0; i < awe_max_voices; i++) {		if (voices[i].key == key) {			switch (cmd) {			case _GUS_VOICEON:				awe_note_on(i);				break;			case _GUS_VOICEOFF:				awe_terminate(i);				awe_fx_init(voices[i].ch);				awe_voice_init(i, TRUE);				break;			case _GUS_VOICEFADE:				awe_note_off(i);				awe_fx_init(voices[i].ch);				awe_voice_init(i, FALSE);				break;			case _GUS_VOICEFREQ:				awe_calc_pitch_from_freq(i, plong);				break;			}		}	}}#endif /* gus_compat *//* AWE32 specific controls */static voidawe_hw_awe_control(int dev, int cmd, unsigned char *event){	int voice;	unsigned short p1;	short p2;	int i;	voice = event[3];	if (! voice_in_range(voice))		return;	if (playing_mode == AWE_PLAY_MULTI2) {		voice = voice_alloc->map[voice] >> 8;		if (voice < 0 || voice >= AWE_MAX_CHANNELS)			return;	}	p1 = *(unsigned short *) &eve

⌨️ 快捷键说明

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