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 1fa7816c07fda75eff948aa17a88f4ec8a703f0e..0ce84beb644187e43803a508caf5ec824cbb42da 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 6686ca8ce5fc5f9b597310761140e49bd8efc3cc..6d483bda46dfa43978819098d209225324a48ac6 100644 (file)
@@ -437,6 +437,7 @@ start_voice(struct snd_emux_voice *vp)
 
                REGLIST_END);
 
+       hw->voices[ch].dirty = 1;
        return 0;
 }
 
index 216b6cde326f5ba9132a11e02364107b13731096..324db1141479bc908e1dc40e456231f85fc14d87 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 c423a56ebf9eb49da5d66ef5a69e723d264b069a..abcec8a01760ea6e78132ecc0439fcdb0726d8a9 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 ac89d09ed9bc2a44b6d1870b9999061e31c1161d..25e78fc188bfd42962272285181e3b768eb33f70 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;
 }