ne and
	 * 0x600 is one octave.
	 */
	pitch = ((note - 60) << 7) * voice->sound->key_scaling / 100 + (60 << 7);
	pitch += voice->sound->pitch_offset;
	if (!chan->drum_channel)
		pitch += chan->gm_rpn_coarse_tuning;
	pitch += chan->gm_rpn_fine_tuning >> 7;
	pitch += chan->midi_pitchbend * chan->gm_rpn_pitch_bend_range / 0x2000;
	if (pitch < 0)
		pitch = 0;
	else if (pitch >= 0x6000)
		pitch = 0x5fff;
	octave = pitch / 0x600 - 8;
	pitch = snd_opl4_pitch_map[pitch % 0x600];

	snd_opl4_write(opl4, OPL4_REG_OCTAVE + voice->number,
		       (octave << 4) | ((pitch >> 7) & OPL4_F_NUMBER_HIGH_MASK));
	voice->reg_f_number = (voice->reg_f_number & OPL4_TONE_NUMBER_BIT8)
		| ((pitch << 1) & OPL4_F_NUMBER_LOW_MASK);
	snd_opl4_write(opl4, OPL4_REG_F_NUMBER + voice->number, voice->reg_f_number);
}

static void snd_opl4_update_tone_parameters(struct snd_opl4 *opl4,
					    struct opl4_voice *voice)
{
	snd_opl4_write(opl4, OPL4_REG_ATTACK_DECAY1 + voice->number,
		       voice->sound->reg_attack_decay1);
	snd_opl4_write(opl4, OPL4_REG_LEVEL_DECAY2 + voice->number,
		       voice->sound->reg_level_decay2);
	snd_opl4_write(opl4, OPL4_REG_RELEASE_CORRECTION + voice->number,
		       voice->sound->reg_release_correction);
	snd_opl4_write(opl4, OPL4_REG_TREMOLO + voice->number,
		       voice->sound->reg_tremolo);
}

/* allocate one voice */
static struct opl4_voice *snd_opl4_get_voice(struct snd_opl4 *opl4)
{
	/* first, try to get the oldest key-off voice */
	if (!list_empty(&opl4->off_voices))
		return list_entry(opl4->off_voices.next, struct opl4_voice, list);
	/* then get the oldest key-on voice */
	snd_BUG_ON(list_empty(&opl4->on_voices));
	return list_entry(opl4->on_voices.next, struct opl4_voice, list);
}

static void snd_opl4_wait_for_wave_headers(struct snd_opl4 *opl4)
{
	int timeout = 200;

	while ((inb(opl4->fm_port) & OPL4_STATUS_LOAD) && --timeout > 0)
		udelay(10);
}

void snd_opl4_note_on(void *private_data, int note, int vel, struct snd_midi_channel *chan)
{
	struct snd_opl4 *opl4 = private_data;
	const struct opl4_r