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>
 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;
 
 
                REGLIST_END);
 
+       hw->voices[ch].dirty = 1;
        return 0;
 }
 
 
 {
        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]);
                                      snd_emu10k1_compose_send_routing(send_routing));
        }
 
+       emu->voices[voice].dirty = 1;
+
        spin_unlock_irqrestore(&emu->reg_lock, flags);
 }
 
 
        };
        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]);
        }
 }
 
 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;
 }