(&opl4->reg_lock, flags);
	for (i = 0; i < OPL4_MAX_VOICES; i++) {
		voice = &opl4->voices[i];
		if (voice->chan)
			func(opl4, voice);
	}
	spin_unlock_irqrestore(&opl4->reg_lock, flags);
}

static void snd_opl4_update_volume(struct snd_opl4 *opl4, struct opl4_voice *voice)
{
	int att;

	att = voice->sound->tone_attenuate;
	att += snd_opl4_volume_table[opl4->chset->gs_master_volume & 0x7f];
	att += snd_opl4_volume_table[voice->chan->gm_volume & 0x7f];
	att += snd_opl4_volume_table[voice->chan->gm_expression & 0x7f];
	att += snd_opl4_volume_table[voice->velocity];
	att = 0x7f - (0x7f - att) * (voice->sound->volume_factor) / 0xfe - volume_boost;
	if (att < 0)
		att = 0;
	else if (att > 0x7e)
		att = 0x7e;
	snd_opl4_write(opl4, OPL4_REG_LEVEL + voice->number,
		       (att << 1) | voice->level_direct);
	voice->level_direct = 0;
}

static void snd_opl4_update_pan(struct snd_opl4 *opl4, struct opl4_voice *voice)
{
	int pan = voice->sound->panpot;

	if (!voice->chan->drum_channel)
		pan += (voice->chan->control[MIDI_CTL_MSB_PAN] - 0x40) >> 3;
	if (pan < -7)
		pan = -7;
	else if (pan > 7)
		pan = 7;
	voice->reg_misc = (voice->reg_misc & ~OPL4_PAN_POT_MASK)
		| (pan & OPL4_PAN_POT_MASK);
	snd_opl4_write(opl4, OPL4_REG_MISC + voice->number, voice->reg_misc);
}

static void snd_opl4_update_vibrato_depth(struct snd_opl4 *opl4,
					  struct opl4_voice *voice)
{
	int depth;

	if (voice->chan->drum_channel)
		return;
	depth = (7 - voice->sound->vibrato)
		* (voice->chan->control[MIDI_CTL_VIBRATO_DEPTH] & 0x7f);
	depth = (depth >> 7) + voice->sound->vibrato;
	voice->reg_lfo_vibrato &= ~OPL4_VIBRATO_DEPTH_MASK;
	voice->reg_lfo_vibrato |= depth & OPL4_VIBRATO_DEPTH_MASK;
	snd_opl4_write(opl4, OPL4_REG_LFO_VIBRATO + voice->number,
		       voice->reg_lfo_vibrato);
}

static void snd_opl4_update_pitch(struct snd_opl4 *opl4,
				  struct opl4_voice *voice)
{
	struct snd_midi_channel *chan = voice->chan;
	int note, pitch, octave;

	note = chan->drum_channel ? 60 : voice->note;
	/*
	 * pitch is in 100/128 cents, so 0x80 is one semito