📄 gus_simple.c
字号:
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 + -