Commit e68235c8 authored by Oswald Buddenhagen's avatar Oswald Buddenhagen Committed by Takashi Iwai

ALSA: emu10k1: fix synthesizer pitch for E-MU cards at 44.1 kHz

This is only a very partial fix - the frequency-dependent envelope & LFO
register values aren't adjusted.

But I'm not sure they were even correct at 48 kHz to start with, as most
of them are precalculated by common code which assumes an EMU8K-specific
44.1 kHz word clock, and it seems somewhat unlikely that the hardware's
register interpretation was adjusted to compensate for the different
word clock.

In any case I'm not going to spend time on fixing that, as this code is
unlikely to be actually used by anyone today.
Signed-off-by: default avatarOswald Buddenhagen <oswald.buddenhagen@gmx.de>
Link: https://lore.kernel.org/r/20230612191325.1315854-6-oswald.buddenhagen@gmx.deSigned-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 19b89d15
...@@ -54,6 +54,7 @@ struct snd_emux_operators { ...@@ -54,6 +54,7 @@ struct snd_emux_operators {
#if IS_ENABLED(CONFIG_SND_SEQUENCER_OSS) #if IS_ENABLED(CONFIG_SND_SEQUENCER_OSS)
int (*oss_ioctl)(struct snd_emux *emu, int cmd, int p1, int p2); int (*oss_ioctl)(struct snd_emux *emu, int cmd, int p1, int p2);
#endif #endif
int (*get_pitch_shift)(struct snd_emux *emu);
}; };
...@@ -82,7 +83,6 @@ struct snd_emux { ...@@ -82,7 +83,6 @@ struct snd_emux {
int max_voices; /* Number of voices */ int max_voices; /* Number of voices */
int mem_size; /* memory size (in byte) */ int mem_size; /* memory size (in byte) */
int num_ports; /* number of ports to be created */ int num_ports; /* number of ports to be created */
int pitch_shift; /* pitch shift value (for Emu10k1) */
struct snd_emux_operators ops; /* operators */ struct snd_emux_operators ops; /* operators */
void *hw; /* hardware */ void *hw; /* hardware */
unsigned long flags; /* other conditions */ unsigned long flags; /* other conditions */
......
...@@ -35,6 +35,7 @@ static void terminate_voice(struct snd_emux_voice *vp); ...@@ -35,6 +35,7 @@ static void terminate_voice(struct snd_emux_voice *vp);
static void free_voice(struct snd_emux_voice *vp); static void free_voice(struct snd_emux_voice *vp);
static u32 make_fmmod(struct snd_emux_voice *vp); static u32 make_fmmod(struct snd_emux_voice *vp);
static u32 make_fm2frq2(struct snd_emux_voice *vp); static u32 make_fm2frq2(struct snd_emux_voice *vp);
static int get_pitch_shift(struct snd_emux *emu);
/* /*
* Ensure a value is between two points * Ensure a value is between two points
...@@ -58,6 +59,7 @@ static const struct snd_emux_operators emu10k1_ops = { ...@@ -58,6 +59,7 @@ static const struct snd_emux_operators emu10k1_ops = {
.free_voice = free_voice, .free_voice = free_voice,
.sample_new = snd_emu10k1_sample_new, .sample_new = snd_emu10k1_sample_new,
.sample_free = snd_emu10k1_sample_free, .sample_free = snd_emu10k1_sample_free,
.get_pitch_shift = get_pitch_shift,
}; };
void void
...@@ -508,3 +510,11 @@ make_fm2frq2(struct snd_emux_voice *vp) ...@@ -508,3 +510,11 @@ make_fm2frq2(struct snd_emux_voice *vp)
LIMITVALUE(pitch, -128, 127); LIMITVALUE(pitch, -128, 127);
return ((unsigned char)pitch << 8) | freq; return ((unsigned char)pitch << 8) | freq;
} }
static int get_pitch_shift(struct snd_emux *emu)
{
struct snd_emu10k1 *hw = emu->hw;
return (hw->card_capabilities->emu_model &&
hw->emu1010.word_clock == 44100) ? 0 : -501;
}
...@@ -43,7 +43,6 @@ static int snd_emu10k1_synth_probe(struct device *_dev) ...@@ -43,7 +43,6 @@ static int snd_emu10k1_synth_probe(struct device *_dev)
emux->hw = hw; emux->hw = hw;
emux->max_voices = arg->max_voices; emux->max_voices = arg->max_voices;
emux->num_ports = arg->seq_ports; emux->num_ports = arg->seq_ports;
emux->pitch_shift = -501;
emux->memhdr = hw->memhdr; emux->memhdr = hw->memhdr;
/* maximum two ports */ /* maximum two ports */
emux->midi_ports = arg->seq_ports < 2 ? arg->seq_ports : 2; emux->midi_ports = arg->seq_ports < 2 ? arg->seq_ports : 2;
......
...@@ -845,7 +845,8 @@ calc_pitch(struct snd_emux_voice *vp) ...@@ -845,7 +845,8 @@ calc_pitch(struct snd_emux_voice *vp)
/* 0xe000: root pitch */ /* 0xe000: root pitch */
offset += 0xe000 + vp->reg.rate_offset; offset += 0xe000 + vp->reg.rate_offset;
offset += vp->emu->pitch_shift; if (vp->emu->ops.get_pitch_shift)
offset += vp->emu->ops.get_pitch_shift(vp->emu);
LIMITVALUE(offset, 0, 0xffff); LIMITVALUE(offset, 0, 0xffff);
if (offset == vp->apitch) if (offset == vp->apitch)
return 0; /* unchanged */ return 0; /* unchanged */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment