Example #1
0
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);
	}
}
Example #2
0
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);
}