static void select_instrument(snd_gus_card_t * gus, snd_gus_voice_t * v) { snd_seq_kinstr_t *instr; #if 0 printk("select instrument: cluster = %li, std = 0x%x, bank = %i, prg = %i\n", v->instr.cluster, v->instr.std, v->instr.bank, v->instr.prg); #endif instr = snd_seq_instr_find(gus->gf1.ilist, &v->instr, 0, 1); if (instr != NULL) { if (instr->ops) { if (!strcmp(instr->ops->instr_type, SNDRV_SEQ_INSTR_ID_SIMPLE)) snd_gf1_simple_init(v); } snd_seq_instr_free_use(gus->gf1.ilist, instr); } }
static void sample_start(trident_t * trident, snd_trident_voice_t * voice, snd_seq_position_t position) { simple_instrument_t *simple; snd_seq_kinstr_t *instr; unsigned long flags; unsigned int loop_start, loop_end, sample_start, sample_end, start_offset; unsigned int value; unsigned int shift = 0; instr = snd_seq_instr_find(trident->synth.ilist, &voice->instr, 0, 1); if (instr == NULL) return; voice->instr = instr->instr; /* copy ID to speedup aliases */ simple = KINSTR_DATA(instr); spin_lock_irqsave(&trident->reg_lock, flags); if (trident->device == TRIDENT_DEVICE_ID_SI7018) voice->GVSel = 1; /* route to Wave volume */ voice->CTRL = 0; voice->Alpha = 0; voice->FMS = 0; loop_start = simple->loop_start >> 4; loop_end = simple->loop_end >> 4; sample_start = (simple->start + position) >> 4; if( sample_start >= simple->size ) sample_start = simple->start >> 4; sample_end = simple->size; start_offset = position >> 4; if (simple->format & SIMPLE_WAVE_16BIT) { voice->CTRL |= 8; shift++; } if (simple->format & SIMPLE_WAVE_STEREO) { voice->CTRL |= 4; shift++; } if (!(simple->format & SIMPLE_WAVE_UNSIGNED)) voice->CTRL |= 2; voice->LBA = simple->address.memory; if (simple->format & SIMPLE_WAVE_LOOP) { voice->CTRL |= 1; voice->LBA += loop_start << shift; if( start_offset >= loop_start ) { voice->CSO = start_offset - loop_start; voice->negCSO = 0; } else { voice->CSO = loop_start - start_offset; voice->negCSO = 1; } voice->ESO = loop_end - loop_start - 1; } else { voice->LBA += start_offset << shift; voice->CSO = sample_start; voice->ESO = sample_end - 1; voice->negCSO = 0; } if (voice->flags & SNDRV_TRIDENT_VFLG_RUNNING) { snd_trident_stop_voice(trident, voice->number); voice->flags &= ~SNDRV_TRIDENT_VFLG_RUNNING; } /* set CSO sign */ value = inl(TRID_REG(trident, T4D_SIGN_CSO_A)); if( voice->negCSO ) { value |= 1 << (voice->number&31); } else { value &= ~(1 << (voice->number&31)); } outl(value,TRID_REG(trident, T4D_SIGN_CSO_A)); voice->Attribute = 0; snd_trident_write_voice_regs(trident, voice); snd_trident_start_voice(trident, voice->number); voice->flags |= SNDRV_TRIDENT_VFLG_RUNNING; spin_unlock_irqrestore(&trident->reg_lock, flags); snd_seq_instr_free_use(trident->synth.ilist, instr); }