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

📄 gus_simple.c

📁 h内核
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (instr == NULL)		return;	voice->instr = instr->instr;	/* copy ID to speedup aliases */	simple = KINSTR_DATA(instr);	begin = simple->address.memory << 4;	w_16 = simple->format & SIMPLE_WAVE_16BIT ? 0x04 : 0;	addr_start = simple->loop_start;	if (simple->format & SIMPLE_WAVE_LOOP) {		addr_end = simple->loop_end;	} else {		addr_end = (simple->size << 4) - (w_16 ? 40 : 24);	}	if (simple->format & SIMPLE_WAVE_BACKWARD) {		addr = simple->loop_end;		if (position < simple->loop_end)			addr -= position;	} else {		addr = position;	}	voice->control = 0x00;	voice->mode = 0x20;		/* enable offset registers */	if (simple->format & SIMPLE_WAVE_16BIT)		voice->control |= 0x04;	if (simple->format & SIMPLE_WAVE_BACKWARD)		voice->control |= 0x40;	if (simple->format & SIMPLE_WAVE_LOOP) {		voice->control |= 0x08;	} else {		voice->control |= 0x20;	}	if (simple->format & SIMPLE_WAVE_BIDIR)		voice->control |= 0x10;	if (simple->format & SIMPLE_WAVE_ULAW)		voice->mode |= 0x40;	if (w_16) {		addr = ((addr << 1) & ~0x1f) | (addr & 0x0f);		addr_start = ((addr_start << 1) & ~0x1f) | (addr_start & 0x0f);		addr_end = ((addr_end << 1) & ~0x1f) | (addr_end & 0x0f);	}	addr += begin;	addr_start += begin;	addr_end += begin;	snd_gf1_stop_voice(gus, voice->number);		spin_lock_irqsave(&gus->reg_lock, flags);	snd_gf1_select_voice(gus, voice->number);	snd_gf1_write16(gus, SNDRV_GF1_VW_FREQUENCY, voice->fc_register + voice->fc_lfo);	voice->venv_state = VENV_BEFORE;	voice->volume_control = 0x03;	snd_gf1_write_addr(gus, SNDRV_GF1_VA_START, addr_start, w_16);	snd_gf1_write_addr(gus, SNDRV_GF1_VA_END, addr_end, w_16);	snd_gf1_write_addr(gus, SNDRV_GF1_VA_CURRENT, addr, w_16);	if (!gus->gf1.enh_mode) {		snd_gf1_write8(gus, SNDRV_GF1_VB_PAN, voice->gf1_pan);	} else {		snd_gf1_write16(gus, SNDRV_GF1_VW_OFFSET_LEFT, voice->vlo);		snd_gf1_write16(gus, SNDRV_GF1_VW_OFFSET_LEFT_FINAL, voice->vlo);		snd_gf1_write16(gus, SNDRV_GF1_VW_OFFSET_RIGHT, voice->vro);		snd_gf1_write16(gus, SNDRV_GF1_VW_OFFSET_RIGHT_FINAL, voice->vro);		snd_gf1_write8(gus, SNDRV_GF1_VB_ACCUMULATOR, voice->effect_accumulator);		snd_gf1_write16(gus, SNDRV_GF1_VW_EFFECT_VOLUME, voice->gf1_effect_volume);		snd_gf1_write16(gus, SNDRV_GF1_VW_EFFECT_VOLUME_FINAL, voice->gf1_effect_volume);	}	spin_unlock_irqrestore(&gus->reg_lock, flags);	do_volume_envelope(gus, voice);	spin_lock_irqsave(&gus->reg_lock, flags);	snd_gf1_select_voice(gus, voice->number);	if (gus->gf1.enh_mode)		snd_gf1_write8(gus, SNDRV_GF1_VB_MODE, voice->mode);	snd_gf1_write8(gus, SNDRV_GF1_VB_ADDRESS_CONTROL, voice->control);	if (!gus->gf1.enh_mode) {		snd_gf1_delay(gus);		snd_gf1_write8(gus, SNDRV_GF1_VB_ADDRESS_CONTROL, voice->control );	}	spin_unlock_irqrestore(&gus->reg_lock, flags);#if 0	snd_gf1_print_voice_registers(gus);#endif	voice->flags |= SNDRV_GF1_VFLG_RUNNING;	snd_seq_instr_free_use(gus->gf1.ilist, instr);}static void sample_stop(snd_gus_card_t *gus, snd_gus_voice_t *voice, snd_seq_stop_mode_t mode){	unsigned char control;	unsigned long flags;	if (!(voice->flags & SNDRV_GF1_VFLG_RUNNING))		return;	switch (mode) {	default:		if (gus->gf1.volume_ramp > 0) {			if (voice->venv_state < VENV_RELEASE) {				voice->venv_state = VENV_RELEASE;				do_volume_envelope(gus, voice);			}		}		if (mode != SAMPLE_STOP_VENVELOPE) {			snd_gf1_stop_voice(gus, voice->number);			spin_lock_irqsave(&gus->reg_lock, flags);			snd_gf1_select_voice(gus, voice->number);			snd_gf1_write16(gus, SNDRV_GF1_VW_VOLUME, SNDRV_GF1_MIN_VOLUME);			spin_unlock_irqrestore(&gus->reg_lock, flags);			voice->flags &= ~SNDRV_GF1_VFLG_RUNNING;		}		break;	case SAMPLE_STOP_LOOP:		/* disable loop only */		spin_lock_irqsave(&gus->reg_lock, flags);		snd_gf1_select_voice(gus, voice->number);		control = snd_gf1_read8(gus, SNDRV_GF1_VB_ADDRESS_CONTROL);		control &= ~(0x83 | 0x04);		control |= 0x20;		snd_gf1_write8(gus, SNDRV_GF1_VB_ADDRESS_CONTROL, control);		spin_unlock_irqrestore(&gus->reg_lock, flags);		break;	}}static void sample_freq(snd_gus_card_t *gus, snd_gus_voice_t *voice, snd_seq_frequency_t freq){	unsigned long flags;	spin_lock_irqsave(&gus->reg_lock, flags);	voice->fc_register = snd_gf1_translate_freq(gus, freq);	snd_gf1_select_voice(gus, voice->number);	snd_gf1_write16(gus, SNDRV_GF1_VW_FREQUENCY, voice->fc_register + voice->fc_lfo);	spin_unlock_irqrestore(&gus->reg_lock, flags);}static void sample_volume(snd_gus_card_t *gus, snd_gus_voice_t *voice, snd_seq_ev_volume_t *volume){	if (volume->volume >= 0) {		volume->volume &= 0x3fff;		voice->gf1_volume = snd_gf1_lvol_to_gvol_raw(volume->volume << 2) << 4;		voice->venv_state_prev = VENV_SUSTAIN;		voice->venv_state = VENV_VOLUME;		do_volume_envelope(gus, voice);        }	if (volume->lr >= 0) {		volume->lr &= 0x3fff;		if (!gus->gf1.enh_mode) {			voice->gf1_pan = (volume->lr >> 10) & 15;			if (!gus->gf1.full_range_pan) {				if (voice->gf1_pan == 0)					voice->gf1_pan++;				if (voice->gf1_pan == 15)					voice->gf1_pan--;			}			voice->flags &= ~SNDRV_GF1_VFLG_PAN;	/* before */			do_pan_envelope(gus, voice);		} else {			set_enhanced_pan(gus, voice, volume->lr >> 7);		}	}}static void sample_loop(snd_gus_card_t *gus, snd_gus_voice_t *voice, snd_seq_ev_loop_t *loop){	unsigned long flags;	int w_16 = voice->control & 0x04;	unsigned int begin, addr_start, addr_end;	simple_instrument_t *simple;	snd_seq_kinstr_t *instr;#if 0	printk("voice_loop: start = 0x%x, end = 0x%x\n", loop->start, loop->end);#endif	instr = snd_seq_instr_find(gus->gf1.ilist, &voice->instr, 0, 1);	if (instr == NULL)		return;	voice->instr = instr->instr;	/* copy ID to speedup aliases */	simple = KINSTR_DATA(instr);	begin = simple->address.memory;	addr_start = loop->start;	addr_end = loop->end;	addr_start = (((addr_start << 1) & ~0x1f) | (addr_start & 0x0f)) + begin;	addr_end = (((addr_end << 1) & ~0x1f) | (addr_end & 0x0f)) + begin;	spin_lock_irqsave(&gus->reg_lock, flags);	snd_gf1_select_voice(gus, voice->number);	snd_gf1_write_addr(gus, SNDRV_GF1_VA_START, addr_start, w_16);	snd_gf1_write_addr(gus, SNDRV_GF1_VA_END, addr_end, w_16);	spin_unlock_irqrestore(&gus->reg_lock, flags);	snd_seq_instr_free_use(gus->gf1.ilist, instr);}static void sample_pos(snd_gus_card_t *gus, snd_gus_voice_t *voice, snd_seq_position_t position){	unsigned long flags;	int w_16 = voice->control & 0x04;	unsigned int begin, addr;	simple_instrument_t *simple;	snd_seq_kinstr_t *instr;#if 0	printk("voice_loop: start = 0x%x, end = 0x%x\n", loop->start, loop->end);#endif	instr = snd_seq_instr_find(gus->gf1.ilist, &voice->instr, 0, 1);	if (instr == NULL)		return;	voice->instr = instr->instr;	/* copy ID to speedup aliases */	simple = KINSTR_DATA(instr);	begin = simple->address.memory;	addr = (((position << 1) & ~0x1f) | (position & 0x0f)) + begin;	spin_lock_irqsave(&gus->reg_lock, flags);	snd_gf1_select_voice(gus, voice->number);	snd_gf1_write_addr(gus, SNDRV_GF1_VA_CURRENT, addr, w_16);	spin_unlock_irqrestore(&gus->reg_lock, flags);	snd_seq_instr_free_use(gus->gf1.ilist, instr);}#if 0static unsigned char get_effects_mask( ultra_card_t *card, int value ){  if ( value > 7 ) return 0;  if ( card -> gf1.effects && card -> gf1.effects -> chip_type == ULTRA_EFFECT_CHIP_INTERWAVE )    return card -> gf1.effects -> chip.interwave.voice_output[ value ];  return 0;}#endifstatic void sample_private1(snd_gus_card_t *card, snd_gus_voice_t *voice, unsigned char *data){#if 0  unsigned long flags;  unsigned char uc;  switch ( *data ) {    case ULTRA_PRIV1_IW_EFFECT:      uc = get_effects_mask( card, ultra_get_byte( data, 4 ) );      uc |= get_effects_mask( card, ultra_get_byte( data, 4 ) >> 4 );      uc |= get_effects_mask( card, ultra_get_byte( data, 5 ) );      uc |= get_effects_mask( card, ultra_get_byte( data, 5 ) >> 4 );      voice -> data.simple.effect_accumulator = uc;      voice -> data.simple.effect_volume = ultra_translate_voice_volume( card, ultra_get_word( data, 2 ) ) << 4;      if ( !card -> gf1.enh_mode ) return;      if ( voice -> flags & VFLG_WAIT_FOR_START ) return;      if ( voice -> flags & VFLG_RUNNING )        {          CLI( &flags );          gf1_select_voice( card, voice -> number );          ultra_write8( card, GF1_VB_ACCUMULATOR, voice -> data.simple.effect_accumulator );          ultra_write16( card, GF1_VW_EFFECT_VOLUME_FINAL, voice -> data.simple.effect_volume );          STI( &flags );        }      break;   case ULTRA_PRIV1_IW_LFO:     ultra_lfo_command( card, voice -> number, data );  }#endif}#if 0/* * */static void note_stop( ultra_card_t *card, ultra_voice_t *voice, int wait ){}static void note_wait( ultra_card_t *card, ultra_voice_t *voice ){}static void note_off( ultra_card_t *card, ultra_voice_t *voice ){}static void note_volume( ultra_card_t *card, ultra_voice_t *voice ){}static void note_pitchbend( ultra_card_t *card, ultra_voice_t *voice ){}static void note_vibrato( ultra_card_t *card, ultra_voice_t *voice ){}static void note_tremolo( ultra_card_t *card, ultra_voice_t *voice ){}/* * */ static void chn_trigger_down( ultra_card_t *card, ultra_channel_t *channel, ultra_instrument_t *instrument, unsigned char note, unsigned char velocity, unsigned char priority ){}static void chn_trigger_up( ultra_card_t *card, ultra_note_t *note ){}static void chn_control( ultra_card_t *card, ultra_channel_t *channel, unsigned short p1, unsigned short p2 ){}/* * */ #endifvoid snd_gf1_simple_init(snd_gus_voice_t *voice){	voice->handler_wave = interrupt_wave;	voice->handler_volume = interrupt_volume;	voice->handler_effect = interrupt_effect;	voice->volume_change = NULL;	voice->sample_ops = &sample_ops;}

⌨️ 快捷键说明

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