egion_ptr *regions;
	struct opl4_voice *voice[2];
	const struct opl4_sound *sound[2];
	int voices = 0, i;
	unsigned long flags;

	/* determine the number of voices and voice parameters */
	i = chan->drum_channel ? 0x80 : (chan->midi_program & 0x7f);
	regions = &snd_yrw801_regions[i];
	for (i = 0; i < regions->count; i++) {
		if (note >= regions->regions[i].key_min &&
		    note <= regions->regions[i].key_max) {
			sound[voices] = &regions->regions[i].sound;
			if (++voices >= 2)
				break;
		}
	}

	/* allocate and initialize the needed voices */
	spin_lock_irqsave(&opl4->reg_lock, flags);
	for (i = 0; i < voices; i++) {
		voice[i] = snd_opl4_get_voice(opl4);
		list_move_tail(&voice[i]->list, &opl4->on_voices);
		voice[i]->chan = chan;
		voice[i]->note = note;
		voice[i]->velocity = vel & 0x7f;
		voice[i]->sound = sound[i];
	}

	/* set tone number (triggers header loading) */
	for (i = 0; i < voices; i++) {
		voice[i]->reg_f_number =
			(sound[i]->tone >> 8) & OPL4_TONE_NUMBER_BIT8;
		snd_opl4_write(opl4, OPL4_REG_F_NUMBER + voice[i]->number,
			       voice[i]->reg_f_number);
		snd_opl4_write(opl4, OPL4_REG_TONE_NUMBER + voice[i]->number,
			       sound[i]->tone & 0xff);
	}

	/* set parameters which can be set while loading */
	for (i = 0; i < voices; i++) {
		voice[i]->reg_misc = OPL4_LFO_RESET_BIT;
		snd_opl4_update_pan(opl4, voice[i]);
		snd_opl4_update_pitch(opl4, voice[i]);
		voice[i]->level_direct = OPL4_LEVEL_DIRECT_BIT;
		snd_opl4_update_volume(opl4, voice[i]);
	}
	spin_unlock_irqrestore(&opl4->reg_lock, flags);

	/* wait for completion of loading */
	snd_opl4_wait_for_wave_headers(opl4);

	/* set remaining parameters */
	spin_lock_irqsave(&opl4->reg_lock, flags);
	for (i = 0; i < voices; i++) {
		snd_opl4_update_tone_parameters(opl4, voice[i]);
		voice[i]->reg_lfo_vibrato = voice[i]->sound->reg_lfo_vibrato;
		snd_opl4_update_vibrato_depth(opl4, voice[i]);
	}

	/* finally, switch on all voices */
	for (i = 0; i < voices; i++) {
		voice[i]->reg_misc =
			(voice[i]->reg_misc & 0x1f) | OPL4_KEY_ON_BIT;
		sn