ALSA: emu10k1: fix synthesizer pitch for E-MU cards at 44.1 kHz
authorOswald Buddenhagen <oswald.buddenhagen@gmx.de>
Mon, 12 Jun 2023 19:13:21 +0000 (21:13 +0200)
committerTakashi Iwai <tiwai@suse.de>
Tue, 13 Jun 2023 05:42:08 +0000 (07:42 +0200)
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: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
Link: https://lore.kernel.org/r/20230612191325.1315854-6-oswald.buddenhagen@gmx.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
include/sound/emux_synth.h
sound/pci/emu10k1/emu10k1_callback.c
sound/pci/emu10k1/emu10k1_synth.c
sound/synth/emux/emux_synth.c

index d499b68122a3f7e273d31d514615a230ee50c794..1cc530434b97b4bc1a9996e216f826d1b663dc00 100644 (file)
@@ -54,6 +54,7 @@ struct snd_emux_operators {
 #if IS_ENABLED(CONFIG_SND_SEQUENCER_OSS)
        int (*oss_ioctl)(struct snd_emux *emu, int cmd, int p1, int p2);
 #endif
+       int (*get_pitch_shift)(struct snd_emux *emu);
 };
 
 
@@ -82,7 +83,6 @@ struct snd_emux {
        int max_voices;         /* Number of voices */
        int mem_size;           /* memory size (in byte) */
        int num_ports;          /* number of ports to be created */
-       int pitch_shift;        /* pitch shift value (for Emu10k1) */
        struct snd_emux_operators ops;  /* operators */
        void *hw;               /* hardware */
        unsigned long flags;    /* other conditions */
index ad0dea0c2be988d75c4665508420be9670c6addc..d36234b88fb4219fec68e3f68103d01ee4c224ab 100644 (file)
@@ -35,6 +35,7 @@ static void terminate_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_fm2frq2(struct snd_emux_voice *vp);
+static int get_pitch_shift(struct snd_emux *emu);
 
 /*
  * Ensure a value is between two points
@@ -58,6 +59,7 @@ static const struct snd_emux_operators emu10k1_ops = {
        .free_voice =   free_voice,
        .sample_new =   snd_emu10k1_sample_new,
        .sample_free =  snd_emu10k1_sample_free,
+       .get_pitch_shift = get_pitch_shift,
 };
 
 void
@@ -508,3 +510,11 @@ make_fm2frq2(struct snd_emux_voice *vp)
        LIMITVALUE(pitch, -128, 127);
        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;
+}
index 549013a4a80bef9d9dfe818f99d7b10ad9c1f9a0..759e66e1105ab0069087daebb86b15f6c53c0674 100644 (file)
@@ -43,7 +43,6 @@ static int snd_emu10k1_synth_probe(struct device *_dev)
        emux->hw = hw;
        emux->max_voices = arg->max_voices;
        emux->num_ports = arg->seq_ports;
-       emux->pitch_shift = -501;
        emux->memhdr = hw->memhdr;
        /* maximum two ports */
        emux->midi_ports = arg->seq_ports < 2 ? arg->seq_ports : 2;
index a5385efcedb6c3fb310aa8e37748a15607833a1e..075358a533a0eafdd679395ab18e985145d8b020 100644 (file)
@@ -845,7 +845,8 @@ calc_pitch(struct snd_emux_voice *vp)
 
        /* 0xe000: root pitch */
        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);
        if (offset == vp->apitch)
                return 0; /* unchanged */