ALSA: emu10k1: make freeing untouched playback voices cheap
authorOswald Buddenhagen <oswald.buddenhagen@gmx.de>
Thu, 18 May 2023 14:09:44 +0000 (16:09 +0200)
committerTakashi Iwai <tiwai@suse.de>
Thu, 18 May 2023 14:55:56 +0000 (16:55 +0200)
This allows us to drop the code that tries to preserve already allocated
voices upon repeated hw_param callback invocations. Getting it right for
multi-channel voices would otherwise get a bit hairy.

Signed-off-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
Link: https://lore.kernel.org/r/20230518140947.3725394-5-oswald.buddenhagen@gmx.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
include/sound/emu10k1.h
sound/pci/emu10k1/emu10k1_callback.c
sound/pci/emu10k1/emupcm.c
sound/pci/emu10k1/emuproc.c
sound/pci/emu10k1/voice.c

index 1fa7816..0ce84be 100644 (file)
@@ -1453,6 +1453,7 @@ struct snd_emu10k1;
 struct snd_emu10k1_voice {
        unsigned char number;
        unsigned char use;
+       unsigned char dirty;
        void (*interrupt)(struct snd_emu10k1 *emu, struct snd_emu10k1_voice *pvoice);
 
        struct snd_emu10k1_pcm *epcm;
index 6686ca8..6d483bd 100644 (file)
@@ -437,6 +437,7 @@ start_voice(struct snd_emux_voice *vp)
 
                REGLIST_END);
 
+       hw->voices[ch].dirty = 1;
        return 0;
 }
 
index 216b6cd..324db11 100644 (file)
@@ -80,17 +80,6 @@ static int snd_emu10k1_pcm_channel_alloc(struct snd_emu10k1_pcm * epcm, int voic
 {
        int err, i;
 
-       if (epcm->voices[1] != NULL && voices < 2) {
-               snd_emu10k1_voice_free(epcm->emu, epcm->voices[1]);
-               epcm->voices[1] = NULL;
-       }
-       for (i = 0; i < voices; i++) {
-               if (epcm->voices[i] == NULL)
-                       break;
-       }
-       if (i == voices)
-               return 0; /* already allocated */
-
        for (i = 0; i < ARRAY_SIZE(epcm->voices); i++) {
                if (epcm->voices[i]) {
                        snd_emu10k1_voice_free(epcm->emu, epcm->voices[i]);
@@ -323,6 +312,8 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu,
                                      snd_emu10k1_compose_send_routing(send_routing));
        }
 
+       emu->voices[voice].dirty = 1;
+
        spin_unlock_irqrestore(&emu->reg_lock, flags);
 }
 
index c423a56..abcec8a 100644 (file)
@@ -372,11 +372,12 @@ static void snd_emu10k1_proc_voices_read(struct snd_info_entry *entry,
        };
        static_assert(ARRAY_SIZE(types) == EMU10K1_NUM_TYPES);
 
-       snd_iprintf(buffer, "ch\tuse\n");
+       snd_iprintf(buffer, "ch\tdirty\tuse\n");
        for (idx = 0; idx < NUM_G; idx++) {
                voice = &emu->voices[idx];
-               snd_iprintf(buffer, "%i\t%s\n",
+               snd_iprintf(buffer, "%i\t%u\t%s\n",
                        idx,
+                       voice->dirty,
                        types[voice->use]);
        }
 }
index ac89d09..25e78fc 100644 (file)
@@ -87,9 +87,10 @@ static int voice_alloc(struct snd_emu10k1 *emu, int type, int number,
 static void voice_free(struct snd_emu10k1 *emu,
                       struct snd_emu10k1_voice *pvoice)
 {
-       snd_emu10k1_voice_init(emu, pvoice->number);
+       if (pvoice->dirty)
+               snd_emu10k1_voice_init(emu, pvoice->number);
        pvoice->interrupt = NULL;
-       pvoice->use = 0;
+       pvoice->use = pvoice->dirty = 0;
        pvoice->epcm = NULL;
 }