From patchwork Thu May 18 14:09:41 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oswald Buddenhagen X-Patchwork-Id: 13246897 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 256E2C7EE2D for ; Thu, 18 May 2023 14:12:49 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 036AF852; Thu, 18 May 2023 16:11:57 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 036AF852 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1684419167; bh=EXCiVDg6DUvUXbxBS2iEv1dh72i9ZFkXftYNuSg4ofM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=q0PCgcq19iD91yteOoSh6pv/8vdWK9DGj0kZ/cHigHCDMvOCHpqQyljJgNLRtNlE/ uUPJzxbzf6EqyEWYtJrqBteaLsOCTdAEMHXUk66gNtrFycNYul/oZ4ddiVGdbraNBF XoqmUTLBScbuaPdedD/xl0depRbNKnQFkXSWJduk= Received: by alsa1.perex.cz (Postfix, from userid 50401) id 66328F805C8; Thu, 18 May 2023 16:10:13 +0200 (CEST) Received: from mailman-core.alsa-project.org (mailman-core.alsa-project.org [10.254.200.10]) by alsa1.perex.cz (Postfix) with ESMTP id E340DF805C4; Thu, 18 May 2023 16:10:12 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 015B4F80272; Thu, 18 May 2023 16:10:00 +0200 (CEST) Received: from bluemchen.kde.org (bluemchen.kde.org [IPv6:2001:470:142:8::100]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 0FE15F80431 for ; Thu, 18 May 2023 16:09:49 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 0FE15F80431 Received: from ugly.fritz.box (localhost [127.0.0.1]) by bluemchen.kde.org (Postfix) with ESMTP id 7B54923E9C; Thu, 18 May 2023 10:09:47 -0400 (EDT) Received: by ugly.fritz.box (masqmail 0.3.4, from userid 1000) id 1pzeKB-d9M-00; Thu, 18 May 2023 16:09:47 +0200 From: Oswald Buddenhagen To: alsa-devel@alsa-project.org Cc: Takashi Iwai , Jaroslav Kysela Subject: [PATCH 1/7] ALSA: emu10k1: simplify freeing synth voices Date: Thu, 18 May 2023 16:09:41 +0200 Message-Id: <20230518140947.3725394-2-oswald.buddenhagen@gmx.de> X-Mailer: git-send-email 2.40.0.152.g15d061e6df In-Reply-To: <20230518140947.3725394-1-oswald.buddenhagen@gmx.de> References: <20230518140947.3725394-1-oswald.buddenhagen@gmx.de> MIME-Version: 1.0 Message-ID-Hash: BTYYF777N57S7JQTLYNDNSESERPSHCZX X-Message-ID-Hash: BTYYF777N57S7JQTLYNDNSESERPSHCZX X-MailFrom: ossi@kde.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-alsa-devel.alsa-project.org-0; header-match-alsa-devel.alsa-project.org-1; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.8 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: snd_emu10k1_voice_free() resets the hardware itself, so doing that in the calling function as well is redundant. Signed-off-by: Oswald Buddenhagen --- sound/pci/emu10k1/emu10k1_callback.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/sound/pci/emu10k1/emu10k1_callback.c b/sound/pci/emu10k1/emu10k1_callback.c index 06440b97b5d7..4a8b2df06a28 100644 --- a/sound/pci/emu10k1/emu10k1_callback.c +++ b/sound/pci/emu10k1/emu10k1_callback.c @@ -160,11 +160,6 @@ free_voice(struct snd_emux_voice *vp) /* Problem apparent on plug, unplug then plug */ /* on the Audigy 2 ZS Notebook. */ if (hw && (vp->ch >= 0)) { - snd_emu10k1_ptr_write(hw, IFATN, vp->ch, 0xff00); - snd_emu10k1_ptr_write(hw, DCYSUSV, vp->ch, 0x807f | DCYSUSV_CHANNELENABLE_MASK); - // snd_emu10k1_ptr_write(hw, DCYSUSV, vp->ch, 0); - snd_emu10k1_ptr_write(hw, VTFT, vp->ch, 0xffff); - snd_emu10k1_ptr_write(hw, CVCF, vp->ch, 0xffff); snd_emu10k1_voice_free(hw, &hw->voices[vp->ch]); vp->emu->num_voices--; vp->ch = -1; From patchwork Thu May 18 14:09:42 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oswald Buddenhagen X-Patchwork-Id: 13246894 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id BB1AEC77B7A for ; Thu, 18 May 2023 14:12:08 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id D275D82A; Thu, 18 May 2023 16:11:16 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz D275D82A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1684419126; bh=2scjB2WtspAGTcKhshT83X+chUHMmtS8lGH+xUnHcLI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=RPMnaCu6vSt/uH3QPxGDsaY+oKzP1kNa/NL2JiySAFTB8HXhwPv01IXjGtAurfshy 67XAJ8fpCH74KDTc7+ohUFzSPCD4ADFOQNfHTPJflZnBJySLHnf3gpBbbiOYd1UprT x+keRG4MyEkDk+y0vjVT3iry581hxpJLKqeQDJxg= Received: by alsa1.perex.cz (Postfix, from userid 50401) id 6ACEAF805A1; Thu, 18 May 2023 16:10:07 +0200 (CEST) Received: from mailman-core.alsa-project.org (mailman-core.alsa-project.org [10.254.200.10]) by alsa1.perex.cz (Postfix) with ESMTP id 85066F80588; Thu, 18 May 2023 16:10:06 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 64DD5F8016D; Thu, 18 May 2023 16:09:57 +0200 (CEST) Received: from bluemchen.kde.org (bluemchen.kde.org [209.51.188.41]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id CC974F802E8 for ; Thu, 18 May 2023 16:09:49 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz CC974F802E8 Received: from ugly.fritz.box (localhost [127.0.0.1]) by bluemchen.kde.org (Postfix) with ESMTP id 7D66E23F20; Thu, 18 May 2023 10:09:47 -0400 (EDT) Received: by ugly.fritz.box (masqmail 0.3.4, from userid 1000) id 1pzeKB-d9S-00; Thu, 18 May 2023 16:09:47 +0200 From: Oswald Buddenhagen To: alsa-devel@alsa-project.org Cc: Takashi Iwai , Jaroslav Kysela Subject: [PATCH 2/7] ALSA: emu10k1: don't forget to reset reclaimed synth voices Date: Thu, 18 May 2023 16:09:42 +0200 Message-Id: <20230518140947.3725394-3-oswald.buddenhagen@gmx.de> X-Mailer: git-send-email 2.40.0.152.g15d061e6df In-Reply-To: <20230518140947.3725394-1-oswald.buddenhagen@gmx.de> References: <20230518140947.3725394-1-oswald.buddenhagen@gmx.de> MIME-Version: 1.0 Message-ID-Hash: MCPLVUYQCAVDNKJZF2KYRAEXO7D6BOGE X-Message-ID-Hash: MCPLVUYQCAVDNKJZF2KYRAEXO7D6BOGE X-MailFrom: ossi@kde.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-alsa-devel.alsa-project.org-0; header-match-alsa-devel.alsa-project.org-1; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.8 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: The subsequent allocation may still fail after freeing some voices, so we shouldn't leave them in their programmed state. Signed-off-by: Oswald Buddenhagen --- sound/pci/emu10k1/voice.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/sound/pci/emu10k1/voice.c b/sound/pci/emu10k1/voice.c index cbeb8443492c..a602df9117f6 100644 --- a/sound/pci/emu10k1/voice.c +++ b/sound/pci/emu10k1/voice.c @@ -98,6 +98,15 @@ static int voice_alloc(struct snd_emu10k1 *emu, int type, int number, return 0; } +static void voice_free(struct snd_emu10k1 *emu, + struct snd_emu10k1_voice *pvoice) +{ + snd_emu10k1_voice_init(emu, pvoice->number); + pvoice->interrupt = NULL; + pvoice->use = pvoice->pcm = pvoice->synth = pvoice->midi = pvoice->efx = 0; + pvoice->epcm = NULL; +} + int snd_emu10k1_voice_alloc(struct snd_emu10k1 *emu, int type, int number, struct snd_emu10k1_voice **rvoice) { @@ -118,12 +127,8 @@ int snd_emu10k1_voice_alloc(struct snd_emu10k1 *emu, int type, int number, /* free a voice from synth */ if (emu->get_synth_voice) { result = emu->get_synth_voice(emu); - if (result >= 0) { - struct snd_emu10k1_voice *pvoice = &emu->voices[result]; - pvoice->interrupt = NULL; - pvoice->use = pvoice->pcm = pvoice->synth = pvoice->midi = pvoice->efx = 0; - pvoice->epcm = NULL; - } + if (result >= 0) + voice_free(emu, &emu->voices[result]); } if (result < 0) break; @@ -143,10 +148,7 @@ int snd_emu10k1_voice_free(struct snd_emu10k1 *emu, if (snd_BUG_ON(!pvoice)) return -EINVAL; spin_lock_irqsave(&emu->voice_lock, flags); - pvoice->interrupt = NULL; - pvoice->use = pvoice->pcm = pvoice->synth = pvoice->midi = pvoice->efx = 0; - pvoice->epcm = NULL; - snd_emu10k1_voice_init(emu, pvoice->number); + voice_free(emu, pvoice); spin_unlock_irqrestore(&emu->voice_lock, flags); return 0; } From patchwork Thu May 18 14:09:43 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oswald Buddenhagen X-Patchwork-Id: 13246891 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 51014C7EE23 for ; Thu, 18 May 2023 14:11:18 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 1219520C; Thu, 18 May 2023 16:10:26 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 1219520C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1684419076; bh=qgQFb0o6zsRm9IvBp4N+RejTPae4lz030Wo5V7JzIyE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=Zm5BA/kgYwSj0+Q4K4NagyC+kINLzOcCHh25c6t3WVEXjGnWBnYGGrEeIC95dCowN mouNsgctEnUYOujs4poxK2V2vRQDwS6FPmc2DMfNdrKKYvvIGvk+ZrV0P+jbX/6TJB tkMP4yKdTEmPUmT4Vg3Kl2ombdOkLLOrLO3zyNdw= Received: by alsa1.perex.cz (Postfix, from userid 50401) id 1FAC2F80553; Thu, 18 May 2023 16:09:58 +0200 (CEST) Received: from mailman-core.alsa-project.org (mailman-core.alsa-project.org [10.254.200.10]) by alsa1.perex.cz (Postfix) with ESMTP id 76FBEF80553; Thu, 18 May 2023 16:09:57 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id BFF35F80549; Thu, 18 May 2023 16:09:53 +0200 (CEST) Received: from bluemchen.kde.org (bluemchen.kde.org [IPv6:2001:470:142:8::100]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 74B10F8025A for ; Thu, 18 May 2023 16:09:49 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 74B10F8025A Received: from ugly.fritz.box (localhost [127.0.0.1]) by bluemchen.kde.org (Postfix) with ESMTP id 7FF7423F5A; Thu, 18 May 2023 10:09:47 -0400 (EDT) Received: by ugly.fritz.box (masqmail 0.3.4, from userid 1000) id 1pzeKB-d9Y-00; Thu, 18 May 2023 16:09:47 +0200 From: Oswald Buddenhagen To: alsa-devel@alsa-project.org Cc: Takashi Iwai , Jaroslav Kysela Subject: [PATCH 3/7] ALSA: emu10k1: improve voice status display in /proc Date: Thu, 18 May 2023 16:09:43 +0200 Message-Id: <20230518140947.3725394-4-oswald.buddenhagen@gmx.de> X-Mailer: git-send-email 2.40.0.152.g15d061e6df In-Reply-To: <20230518140947.3725394-1-oswald.buddenhagen@gmx.de> References: <20230518140947.3725394-1-oswald.buddenhagen@gmx.de> MIME-Version: 1.0 Message-ID-Hash: 3ESA537Q2KEGRIRLKWAW2CYYDCPA3OLR X-Message-ID-Hash: 3ESA537Q2KEGRIRLKWAW2CYYDCPA3OLR X-MailFrom: ossi@kde.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-alsa-devel.alsa-project.org-0; header-match-alsa-devel.alsa-project.org-1; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.8 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Eliminate the MIDI type, as there is no such thing - the MPU401 port doesn't have anything to do with voices. For clarity, differentiate between regular and extra voices. Don't atomize the enum into bits in the table display. Simplify/optimize the storage. Signed-off-by: Oswald Buddenhagen --- include/sound/emu10k1.h | 13 ++++++------- sound/pci/emu10k1/emupcm.c | 2 +- sound/pci/emu10k1/emuproc.c | 16 ++++++++-------- sound/pci/emu10k1/voice.c | 20 +++----------------- 4 files changed, 18 insertions(+), 33 deletions(-) diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h index 9c5de1f45566..2d247f8f635b 100644 --- a/include/sound/emu10k1.h +++ b/include/sound/emu10k1.h @@ -1437,21 +1437,20 @@ SUB_REG_NC(A_EHC, A_I2S_CAPTURE_RATE, 0x00000e00) /* This sets the capture PCM /* ------------------- STRUCTURES -------------------- */ enum { + EMU10K1_UNUSED, // This must be zero EMU10K1_EFX, + EMU10K1_EFX_IRQ, EMU10K1_PCM, + EMU10K1_PCM_IRQ, EMU10K1_SYNTH, - EMU10K1_MIDI + EMU10K1_NUM_TYPES }; struct snd_emu10k1; struct snd_emu10k1_voice { - int number; - unsigned int use: 1, - pcm: 1, - efx: 1, - synth: 1, - midi: 1; + unsigned char number; + unsigned char use; void (*interrupt)(struct snd_emu10k1 *emu, struct snd_emu10k1_voice *pvoice); struct snd_emu10k1_pcm *epcm; diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c index 1ca16f0ddbed..aa3d6d573f05 100644 --- a/sound/pci/emu10k1/emupcm.c +++ b/sound/pci/emu10k1/emupcm.c @@ -117,7 +117,7 @@ static int snd_emu10k1_pcm_channel_alloc(struct snd_emu10k1_pcm * epcm, int voic // period-sized loop as the interrupt source. Additionally, the interrupt // timing of the hardware is "suboptimal" and needs some compensation. err = snd_emu10k1_voice_alloc(epcm->emu, - epcm->type == PLAYBACK_EMUVOICE ? EMU10K1_PCM : EMU10K1_EFX, + epcm->type == PLAYBACK_EMUVOICE ? EMU10K1_PCM_IRQ : EMU10K1_EFX_IRQ, 1, &epcm->extra); if (err < 0) { diff --git a/sound/pci/emu10k1/emuproc.c b/sound/pci/emu10k1/emuproc.c index 708aff6cf09a..c423a56ebf9e 100644 --- a/sound/pci/emu10k1/emuproc.c +++ b/sound/pci/emu10k1/emuproc.c @@ -367,17 +367,17 @@ static void snd_emu10k1_proc_voices_read(struct snd_info_entry *entry, struct snd_emu10k1 *emu = entry->private_data; struct snd_emu10k1_voice *voice; int idx; - - snd_iprintf(buffer, "ch\tuse\tpcm\tefx\tsynth\tmidi\n"); + static const char * const types[] = { + "Unused", "EFX", "EFX IRQ", "PCM", "PCM IRQ", "Synth" + }; + static_assert(ARRAY_SIZE(types) == EMU10K1_NUM_TYPES); + + snd_iprintf(buffer, "ch\tuse\n"); for (idx = 0; idx < NUM_G; idx++) { voice = &emu->voices[idx]; - snd_iprintf(buffer, "%i\t%i\t%i\t%i\t%i\t%i\n", + snd_iprintf(buffer, "%i\t%s\n", idx, - voice->use, - voice->pcm, - voice->efx, - voice->synth, - voice->midi); + types[voice->use]); } } diff --git a/sound/pci/emu10k1/voice.c b/sound/pci/emu10k1/voice.c index a602df9117f6..ac89d09ed9bc 100644 --- a/sound/pci/emu10k1/voice.c +++ b/sound/pci/emu10k1/voice.c @@ -78,32 +78,18 @@ static int voice_alloc(struct snd_emu10k1 *emu, int type, int number, dev_dbg(emu->card->dev, "voice alloc - %i, %i of %i\n", voice->number, idx-first_voice+1, number); */ - voice->use = 1; - switch (type) { - case EMU10K1_PCM: - voice->pcm = 1; - break; - case EMU10K1_SYNTH: - voice->synth = 1; - break; - case EMU10K1_MIDI: - voice->midi = 1; - break; - case EMU10K1_EFX: - voice->efx = 1; - break; - } + voice->use = type; } *rvoice = &emu->voices[first_voice]; return 0; } static void voice_free(struct snd_emu10k1 *emu, struct snd_emu10k1_voice *pvoice) { snd_emu10k1_voice_init(emu, pvoice->number); pvoice->interrupt = NULL; - pvoice->use = pvoice->pcm = pvoice->synth = pvoice->midi = pvoice->efx = 0; + pvoice->use = 0; pvoice->epcm = NULL; } @@ -121,7 +107,7 @@ int snd_emu10k1_voice_alloc(struct snd_emu10k1 *emu, int type, int number, spin_lock_irqsave(&emu->voice_lock, flags); for (;;) { result = voice_alloc(emu, type, number, rvoice); - if (result == 0 || type == EMU10K1_SYNTH || type == EMU10K1_MIDI) + if (result == 0 || type == EMU10K1_SYNTH) break; /* free a voice from synth */ From patchwork Thu May 18 14:09:44 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oswald Buddenhagen X-Patchwork-Id: 13246895 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 82083C7EE23 for ; Thu, 18 May 2023 14:12:30 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 6BB4B206; Thu, 18 May 2023 16:11:38 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 6BB4B206 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1684419148; bh=B8+VwJa6q4nnA/x8Ok2d17U7hI5O4USuHJvFesYsEjA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=nsAbw7HewEDARwRTdgVFFVzjeQEi77tv4or1ilB3B8d1zeeeVSl73mkBvyYfqfbvx g7Sy/gH3jUVtqgSiop0hVXw6ApdiR5nB5Xa9YaMHQaJjuUMuqe9DbUcg4LPAbuhEvW Srj7jym1LLp1Um/gm8VlPYfWFaTyoVwv1dFbp0G0= Received: by alsa1.perex.cz (Postfix, from userid 50401) id C541BF805AE; Thu, 18 May 2023 16:10:09 +0200 (CEST) Received: from mailman-core.alsa-project.org (mailman-core.alsa-project.org [10.254.200.10]) by alsa1.perex.cz (Postfix) with ESMTP id DC2B0F805AB; Thu, 18 May 2023 16:10:08 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id CEAB7F80558; Thu, 18 May 2023 16:09:58 +0200 (CEST) Received: from bluemchen.kde.org (bluemchen.kde.org [IPv6:2001:470:142:8::100]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 73E68F8053D for ; Thu, 18 May 2023 16:09:51 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 73E68F8053D Received: from ugly.fritz.box (localhost [127.0.0.1]) by bluemchen.kde.org (Postfix) with ESMTP id 8282624051; Thu, 18 May 2023 10:09:47 -0400 (EDT) Received: by ugly.fritz.box (masqmail 0.3.4, from userid 1000) id 1pzeKB-d9e-00; Thu, 18 May 2023 16:09:47 +0200 From: Oswald Buddenhagen To: alsa-devel@alsa-project.org Cc: Takashi Iwai , Jaroslav Kysela Subject: [PATCH 4/7] ALSA: emu10k1: make freeing untouched playback voices cheap Date: Thu, 18 May 2023 16:09:44 +0200 Message-Id: <20230518140947.3725394-5-oswald.buddenhagen@gmx.de> X-Mailer: git-send-email 2.40.0.152.g15d061e6df In-Reply-To: <20230518140947.3725394-1-oswald.buddenhagen@gmx.de> References: <20230518140947.3725394-1-oswald.buddenhagen@gmx.de> MIME-Version: 1.0 Message-ID-Hash: E5PRBLMOLU3V3J6WROSH6WKK43INZLJU X-Message-ID-Hash: E5PRBLMOLU3V3J6WROSH6WKK43INZLJU X-MailFrom: ossi@kde.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-alsa-devel.alsa-project.org-0; header-match-alsa-devel.alsa-project.org-1; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.8 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: 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 --- include/sound/emu10k1.h | 1 + sound/pci/emu10k1/emu10k1_callback.c | 1 + sound/pci/emu10k1/emupcm.c | 13 ++----------- sound/pci/emu10k1/emuproc.c | 5 +++-- sound/pci/emu10k1/voice.c | 5 +++-- 5 files changed, 10 insertions(+), 15 deletions(-) diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h index 2d247f8f635b..6ec2079534d4 100644 --- a/include/sound/emu10k1.h +++ b/include/sound/emu10k1.h @@ -1451,6 +1451,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; diff --git a/sound/pci/emu10k1/emu10k1_callback.c b/sound/pci/emu10k1/emu10k1_callback.c index 4a8b2df06a28..d70ca1f50705 100644 --- a/sound/pci/emu10k1/emu10k1_callback.c +++ b/sound/pci/emu10k1/emu10k1_callback.c @@ -458,6 +458,7 @@ start_voice(struct snd_emux_voice *vp) } #endif + hw->voices[ch].dirty = 1; return 0; } diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c index aa3d6d573f05..c4696c127028 100644 --- a/sound/pci/emu10k1/emupcm.c +++ b/sound/pci/emu10k1/emupcm.c @@ -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]); @@ -306,6 +295,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); } diff --git a/sound/pci/emu10k1/emuproc.c b/sound/pci/emu10k1/emuproc.c index c423a56ebf9e..abcec8a01760 100644 --- a/sound/pci/emu10k1/emuproc.c +++ b/sound/pci/emu10k1/emuproc.c @@ -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]); } } diff --git a/sound/pci/emu10k1/voice.c b/sound/pci/emu10k1/voice.c index ac89d09ed9bc..25e78fc188bf 100644 --- a/sound/pci/emu10k1/voice.c +++ b/sound/pci/emu10k1/voice.c @@ -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; } From patchwork Thu May 18 14:09:45 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oswald Buddenhagen X-Patchwork-Id: 13246892 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 731A9C7EE23 for ; Thu, 18 May 2023 14:11:41 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 276F66C1; Thu, 18 May 2023 16:10:49 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 276F66C1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1684419099; bh=xEhHDleqFO5sfvGT61hehxPPS+iZ6hhUf6oqBwaekIo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=jgc3kXDkKVIz9C4JuXJfFHvBR5c+NCZqCVheAY0mEUd3l6VeCt6JpOv5HEpwCSGqS zDwMWtFxOGR6Ip8CHWZ/+HW5QKnsbABFv1l6XX53hzpje8sO0geOgjIZZNT+BVC0wR GPAFTprgR6cRk4WLKf+6+Dj1kmCAf8+cxN+94ENw= Received: by alsa1.perex.cz (Postfix, from userid 50401) id 68BA5F80564; Thu, 18 May 2023 16:10:01 +0200 (CEST) Received: from mailman-core.alsa-project.org (mailman-core.alsa-project.org [10.254.200.10]) by alsa1.perex.cz (Postfix) with ESMTP id DE750F8025A; Thu, 18 May 2023 16:10:00 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 9F2D3F80548; Thu, 18 May 2023 16:09:54 +0200 (CEST) Received: from bluemchen.kde.org (bluemchen.kde.org [IPv6:2001:470:142:8::100]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 936A9F8016A for ; Thu, 18 May 2023 16:09:49 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 936A9F8016A Received: from ugly.fritz.box (localhost [127.0.0.1]) by bluemchen.kde.org (Postfix) with ESMTP id 8FADF240DB; Thu, 18 May 2023 10:09:47 -0400 (EDT) Received: by ugly.fritz.box (masqmail 0.3.4, from userid 1000) id 1pzeKB-d9k-00; Thu, 18 May 2023 16:09:47 +0200 From: Oswald Buddenhagen To: alsa-devel@alsa-project.org Cc: Takashi Iwai , Jaroslav Kysela Subject: [PATCH 5/7] ALSA: emu10k1: centralize freeing PCM voices Date: Thu, 18 May 2023 16:09:45 +0200 Message-Id: <20230518140947.3725394-6-oswald.buddenhagen@gmx.de> X-Mailer: git-send-email 2.40.0.152.g15d061e6df In-Reply-To: <20230518140947.3725394-1-oswald.buddenhagen@gmx.de> References: <20230518140947.3725394-1-oswald.buddenhagen@gmx.de> MIME-Version: 1.0 Message-ID-Hash: ZQLU75EIQKDYBKVMSPVWM7QWSW2WC7OL X-Message-ID-Hash: ZQLU75EIQKDYBKVMSPVWM7QWSW2WC7OL X-MailFrom: ossi@kde.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-alsa-devel.alsa-project.org-0; header-match-alsa-devel.alsa-project.org-1; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.8 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Signed-off-by: Oswald Buddenhagen --- sound/pci/emu10k1/emupcm.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c index c4696c127028..63e085aa65fe 100644 --- a/sound/pci/emu10k1/emupcm.c +++ b/sound/pci/emu10k1/emupcm.c @@ -76,16 +76,22 @@ static void snd_emu10k1_pcm_efx_interrupt(struct snd_emu10k1 *emu, snd_pcm_period_elapsed(emu->pcm_capture_efx_substream); } -static int snd_emu10k1_pcm_channel_alloc(struct snd_emu10k1_pcm * epcm, int voices) +static void snd_emu10k1_pcm_free_voices(struct snd_emu10k1_pcm *epcm) { - int err, i; - - for (i = 0; i < ARRAY_SIZE(epcm->voices); i++) { + for (unsigned i = 0; i < ARRAY_SIZE(epcm->voices); i++) { if (epcm->voices[i]) { snd_emu10k1_voice_free(epcm->emu, epcm->voices[i]); epcm->voices[i] = NULL; } } +} + +static int snd_emu10k1_pcm_channel_alloc(struct snd_emu10k1_pcm * epcm, int voices) +{ + int err, i; + + snd_emu10k1_pcm_free_voices(epcm); + err = snd_emu10k1_voice_alloc(epcm->emu, epcm->type == PLAYBACK_EMUVOICE ? EMU10K1_PCM : EMU10K1_EFX, voices, @@ -115,15 +121,13 @@ static int snd_emu10k1_pcm_channel_alloc(struct snd_emu10k1_pcm * epcm, int voic "failed extra: voices=%d, frame=%d\n", voices, frame); */ - for (i = 0; i < voices; i++) { - snd_emu10k1_voice_free(epcm->emu, epcm->voices[i]); - epcm->voices[i] = NULL; - } + snd_emu10k1_pcm_free_voices(epcm); return err; } epcm->extra->epcm = epcm; epcm->extra->interrupt = snd_emu10k1_pcm_interrupt; } + return 0; } @@ -342,21 +346,15 @@ static int snd_emu10k1_playback_hw_free(struct snd_pcm_substream *substream) struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; struct snd_emu10k1_pcm *epcm; - int i; if (runtime->private_data == NULL) return 0; epcm = runtime->private_data; if (epcm->extra) { snd_emu10k1_voice_free(epcm->emu, epcm->extra); epcm->extra = NULL; } - for (i = 0; i < NUM_EFX_PLAYBACK; i++) { - if (epcm->voices[i]) { - snd_emu10k1_voice_free(epcm->emu, epcm->voices[i]); - epcm->voices[i] = NULL; - } - } + snd_emu10k1_pcm_free_voices(epcm); if (epcm->memblk) { snd_emu10k1_free_pages(emu, epcm->memblk); epcm->memblk = NULL; From patchwork Thu May 18 14:09:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oswald Buddenhagen X-Patchwork-Id: 13246893 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A19BFC77B7A for ; Thu, 18 May 2023 14:11:51 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id DA5CC201; Thu, 18 May 2023 16:10:58 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz DA5CC201 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1684419108; bh=XChIAK5QBHytsi+G5ppn3Rn1hmAovJliB0T4FrrbfCU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=QxskHZlyrg3qk7MBcd6A/XZx2TiFMPzqo95JGjmVM/2Bhq6b2jaJqjf3Zun7gQlFq R8wpvK+gtprzQdabfxML21nO/IL4sZPzlf2XSRhVc+Bj0tQmIHEwntLj5aKxNUqeCV 7qe+zX3zLHjL2Th2P3/VCa7iPYhUMa0+FmICEC+g= Received: by alsa1.perex.cz (Postfix, from userid 50401) id D7035F8057D; Thu, 18 May 2023 16:10:04 +0200 (CEST) Received: from mailman-core.alsa-project.org (mailman-core.alsa-project.org [10.254.200.10]) by alsa1.perex.cz (Postfix) with ESMTP id E85F3F80568; Thu, 18 May 2023 16:10:03 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 7AEBBF80544; Thu, 18 May 2023 16:09:56 +0200 (CEST) Received: from bluemchen.kde.org (bluemchen.kde.org [209.51.188.41]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 48765F8016D for ; Thu, 18 May 2023 16:09:49 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 48765F8016D Received: from ugly.fritz.box (localhost [127.0.0.1]) by bluemchen.kde.org (Postfix) with ESMTP id 933F4240F9; Thu, 18 May 2023 10:09:47 -0400 (EDT) Received: by ugly.fritz.box (masqmail 0.3.4, from userid 1000) id 1pzeKB-d9q-00; Thu, 18 May 2023 16:09:47 +0200 From: Oswald Buddenhagen To: alsa-devel@alsa-project.org Cc: Takashi Iwai , Jaroslav Kysela Subject: [PATCH 6/7] ALSA: emu10k1: make snd_emu10k1_voice_alloc() assign voices' epcm Date: Thu, 18 May 2023 16:09:46 +0200 Message-Id: <20230518140947.3725394-7-oswald.buddenhagen@gmx.de> X-Mailer: git-send-email 2.40.0.152.g15d061e6df In-Reply-To: <20230518140947.3725394-1-oswald.buddenhagen@gmx.de> References: <20230518140947.3725394-1-oswald.buddenhagen@gmx.de> MIME-Version: 1.0 Message-ID-Hash: ZPJZ3UDWCDMQVQONFFGZ5WIZY4UPVA5Y X-Message-ID-Hash: ZPJZ3UDWCDMQVQONFFGZ5WIZY4UPVA5Y X-MailFrom: ossi@kde.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-alsa-devel.alsa-project.org-0; header-match-alsa-devel.alsa-project.org-1; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.8 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: The voice allocator clearly knows about the field (it resets it), so it's more consistent (and leads to less duplicated code) to have the constructor take it as a parameter. Signed-off-by: Oswald Buddenhagen --- include/sound/emu10k1.h | 3 ++- sound/pci/emu10k1/emu10k1_callback.c | 2 +- sound/pci/emu10k1/emupcm.c | 7 ++----- sound/pci/emu10k1/voice.c | 7 ++++--- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h index 6ec2079534d4..42959ba9c9f4 100644 --- a/include/sound/emu10k1.h +++ b/include/sound/emu10k1.h @@ -1848,7 +1848,8 @@ int snd_emu10k1_synth_copy_from_user(struct snd_emu10k1 *emu, struct snd_util_me int snd_emu10k1_memblk_map(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk); /* voice allocation */ -int snd_emu10k1_voice_alloc(struct snd_emu10k1 *emu, int type, int pair, struct snd_emu10k1_voice **rvoice); +int snd_emu10k1_voice_alloc(struct snd_emu10k1 *emu, int type, int pair, + struct snd_emu10k1_pcm *epcm, struct snd_emu10k1_voice **rvoice); int snd_emu10k1_voice_free(struct snd_emu10k1 *emu, struct snd_emu10k1_voice *pvoice); /* MIDI uart */ diff --git a/sound/pci/emu10k1/emu10k1_callback.c b/sound/pci/emu10k1/emu10k1_callback.c index d70ca1f50705..e256d3c22ee4 100644 --- a/sound/pci/emu10k1/emu10k1_callback.c +++ b/sound/pci/emu10k1/emu10k1_callback.c @@ -282,7 +282,7 @@ get_voice(struct snd_emux *emu, struct snd_emux_port *port) if (vp->ch < 0) { /* allocate a voice */ struct snd_emu10k1_voice *hwvoice; - if (snd_emu10k1_voice_alloc(hw, EMU10K1_SYNTH, 1, &hwvoice) < 0 || hwvoice == NULL) + if (snd_emu10k1_voice_alloc(hw, EMU10K1_SYNTH, 1, NULL, &hwvoice) < 0 || hwvoice == NULL) continue; vp->ch = hwvoice->number; emu->num_voices++; diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c index 63e085aa65fe..8bf0a4d8aaf1 100644 --- a/sound/pci/emu10k1/emupcm.c +++ b/sound/pci/emu10k1/emupcm.c @@ -95,36 +95,33 @@ static int snd_emu10k1_pcm_channel_alloc(struct snd_emu10k1_pcm * epcm, int voic err = snd_emu10k1_voice_alloc(epcm->emu, epcm->type == PLAYBACK_EMUVOICE ? EMU10K1_PCM : EMU10K1_EFX, voices, - &epcm->voices[0]); + epcm, &epcm->voices[0]); if (err < 0) return err; - epcm->voices[0]->epcm = epcm; if (voices > 1) { for (i = 1; i < voices; i++) { epcm->voices[i] = &epcm->emu->voices[(epcm->voices[0]->number + i) % NUM_G]; - epcm->voices[i]->epcm = epcm; } } if (epcm->extra == NULL) { // The hardware supports only (half-)loop interrupts, so to support an // arbitrary number of periods per buffer, we use an extra voice with a // period-sized loop as the interrupt source. Additionally, the interrupt // timing of the hardware is "suboptimal" and needs some compensation. err = snd_emu10k1_voice_alloc(epcm->emu, epcm->type == PLAYBACK_EMUVOICE ? EMU10K1_PCM_IRQ : EMU10K1_EFX_IRQ, 1, - &epcm->extra); + epcm, &epcm->extra); if (err < 0) { /* dev_dbg(emu->card->dev, "pcm_channel_alloc: " "failed extra: voices=%d, frame=%d\n", voices, frame); */ snd_emu10k1_pcm_free_voices(epcm); return err; } - epcm->extra->epcm = epcm; epcm->extra->interrupt = snd_emu10k1_pcm_interrupt; } diff --git a/sound/pci/emu10k1/voice.c b/sound/pci/emu10k1/voice.c index 25e78fc188bf..6c58e3bd14f7 100644 --- a/sound/pci/emu10k1/voice.c +++ b/sound/pci/emu10k1/voice.c @@ -32,7 +32,7 @@ */ static int voice_alloc(struct snd_emu10k1 *emu, int type, int number, - struct snd_emu10k1_voice **rvoice) + struct snd_emu10k1_pcm *epcm, struct snd_emu10k1_voice **rvoice) { struct snd_emu10k1_voice *voice; int i, j, k, first_voice, last_voice, skip; @@ -79,6 +79,7 @@ static int voice_alloc(struct snd_emu10k1 *emu, int type, int number, voice->number, idx-first_voice+1, number); */ voice->use = type; + voice->epcm = epcm; } *rvoice = &emu->voices[first_voice]; return 0; @@ -95,19 +96,19 @@ static void voice_free(struct snd_emu10k1 *emu, } int snd_emu10k1_voice_alloc(struct snd_emu10k1 *emu, int type, int number, - struct snd_emu10k1_voice **rvoice) + struct snd_emu10k1_pcm *epcm, struct snd_emu10k1_voice **rvoice) { unsigned long flags; int result; if (snd_BUG_ON(!rvoice)) return -EINVAL; if (snd_BUG_ON(!number)) return -EINVAL; spin_lock_irqsave(&emu->voice_lock, flags); for (;;) { - result = voice_alloc(emu, type, number, rvoice); + result = voice_alloc(emu, type, number, epcm, rvoice); if (result == 0 || type == EMU10K1_SYNTH) break; From patchwork Thu May 18 14:09:47 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oswald Buddenhagen X-Patchwork-Id: 13246898 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id ED6BBC77B7A for ; Thu, 18 May 2023 14:13:06 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id B8F167F4; Thu, 18 May 2023 16:12:14 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz B8F167F4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1684419184; bh=rTbwgxGmFhLBgXhjNasl/6vRTxUlIqBhzpA2WuRFo98=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=P8CZC/Cwt2OQkMCJ+30IWt3qivY8hSDA/TNx+BxlQGcwbnZqZ7tL285YpxUjdIN4L RJLOt8LgobGNBk966P0dTcN/5jC5Pd5QyxeCkHio1yzKUfo4nVBzaH30udGMhfz4iX RMTCHvEZX5S092An+8rnz4bXiBSonR0Gjiv+GTMg= Received: by alsa1.perex.cz (Postfix, from userid 50401) id 1F73EF805C5; Thu, 18 May 2023 16:10:15 +0200 (CEST) Received: from mailman-core.alsa-project.org (mailman-core.alsa-project.org [10.254.200.10]) by alsa1.perex.cz (Postfix) with ESMTP id 9E59FF805D4; Thu, 18 May 2023 16:10:14 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 187BCF8057F; Thu, 18 May 2023 16:10:05 +0200 (CEST) Received: from bluemchen.kde.org (bluemchen.kde.org [IPv6:2001:470:142:8::100]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 94AB5F80542 for ; Thu, 18 May 2023 16:09:51 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 94AB5F80542 Received: from ugly.fritz.box (localhost [127.0.0.1]) by bluemchen.kde.org (Postfix) with ESMTP id 9534A24125; Thu, 18 May 2023 10:09:47 -0400 (EDT) Received: by ugly.fritz.box (masqmail 0.3.4, from userid 1000) id 1pzeKB-d9w-00; Thu, 18 May 2023 16:09:47 +0200 From: Oswald Buddenhagen To: alsa-devel@alsa-project.org Cc: Takashi Iwai , Jaroslav Kysela Subject: [PATCH 7/7] ALSA: emu10k1: revamp playback voice allocator Date: Thu, 18 May 2023 16:09:47 +0200 Message-Id: <20230518140947.3725394-8-oswald.buddenhagen@gmx.de> X-Mailer: git-send-email 2.40.0.152.g15d061e6df In-Reply-To: <20230518140947.3725394-1-oswald.buddenhagen@gmx.de> References: <20230518140947.3725394-1-oswald.buddenhagen@gmx.de> MIME-Version: 1.0 Message-ID-Hash: UBIZMAJMW3WSXNWLO5URXUYO3JRDEPDU X-Message-ID-Hash: UBIZMAJMW3WSXNWLO5URXUYO3JRDEPDU X-MailFrom: ossi@kde.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-alsa-devel.alsa-project.org-0; header-match-alsa-devel.alsa-project.org-1; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.8 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Instead of separate voices, we now allocate non-interleaved channels, which may in turn contain two interleaved voices each. The higher-level code keeps only one pointer per channel. The channels are not allocated in one block any more, as there is no reason to do that. As a consequence of that, and because it is cleaner regardless, we now let the allocator store these pointers at a specified location, rather than returning only the first one and having the calling code deduce the remaining ones. Signed-off-by: Oswald Buddenhagen --- include/sound/emu10k1.h | 3 +- sound/pci/emu10k1/emu10k1_callback.c | 2 +- sound/pci/emu10k1/emumixer.c | 24 +++--- sound/pci/emu10k1/emupcm.c | 44 ++++++----- sound/pci/emu10k1/emuproc.c | 5 +- sound/pci/emu10k1/voice.c | 110 ++++++++++++++------------- 6 files changed, 97 insertions(+), 91 deletions(-) diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h index 42959ba9c9f4..50fb242656f7 100644 --- a/include/sound/emu10k1.h +++ b/include/sound/emu10k1.h @@ -1452,6 +1452,7 @@ struct snd_emu10k1_voice { unsigned char number; unsigned char use; unsigned char dirty; + unsigned char last; void (*interrupt)(struct snd_emu10k1 *emu, struct snd_emu10k1_voice *pvoice); struct snd_emu10k1_pcm *epcm; @@ -1848,7 +1849,7 @@ int snd_emu10k1_synth_copy_from_user(struct snd_emu10k1 *emu, struct snd_util_me int snd_emu10k1_memblk_map(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk); /* voice allocation */ -int snd_emu10k1_voice_alloc(struct snd_emu10k1 *emu, int type, int pair, +int snd_emu10k1_voice_alloc(struct snd_emu10k1 *emu, int type, int count, int channels, struct snd_emu10k1_pcm *epcm, struct snd_emu10k1_voice **rvoice); int snd_emu10k1_voice_free(struct snd_emu10k1 *emu, struct snd_emu10k1_voice *pvoice); diff --git a/sound/pci/emu10k1/emu10k1_callback.c b/sound/pci/emu10k1/emu10k1_callback.c index e256d3c22ee4..5691f2b610c4 100644 --- a/sound/pci/emu10k1/emu10k1_callback.c +++ b/sound/pci/emu10k1/emu10k1_callback.c @@ -282,7 +282,7 @@ get_voice(struct snd_emux *emu, struct snd_emux_port *port) if (vp->ch < 0) { /* allocate a voice */ struct snd_emu10k1_voice *hwvoice; - if (snd_emu10k1_voice_alloc(hw, EMU10K1_SYNTH, 1, NULL, &hwvoice) < 0 || hwvoice == NULL) + if (snd_emu10k1_voice_alloc(hw, EMU10K1_SYNTH, 1, 1, NULL, &hwvoice) < 0) continue; vp->ch = hwvoice->number; emu->num_voices++; diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c index 183051e846f2..a7dd88404ae1 100644 --- a/sound/pci/emu10k1/emumixer.c +++ b/sound/pci/emu10k1/emumixer.c @@ -1467,13 +1467,13 @@ static int snd_emu10k1_send_routing_put(struct snd_kcontrol *kcontrol, change = 1; } } - if (change && mix->epcm) { - if (mix->epcm->voices[0] && mix->epcm->voices[1]) { + if (change && mix->epcm && mix->epcm->voices[0]) { + if (!mix->epcm->voices[0]->last) { update_emu10k1_fxrt(emu, mix->epcm->voices[0]->number, &mix->send_routing[1][0]); - update_emu10k1_fxrt(emu, mix->epcm->voices[1]->number, + update_emu10k1_fxrt(emu, mix->epcm->voices[0]->number + 1, &mix->send_routing[2][0]); - } else if (mix->epcm->voices[0]) { + } else { update_emu10k1_fxrt(emu, mix->epcm->voices[0]->number, &mix->send_routing[0][0]); } @@ -1535,13 +1535,13 @@ static int snd_emu10k1_send_volume_put(struct snd_kcontrol *kcontrol, change = 1; } } - if (change && mix->epcm) { - if (mix->epcm->voices[0] && mix->epcm->voices[1]) { + if (change && mix->epcm && mix->epcm->voices[0]) { + if (!mix->epcm->voices[0]->last) { update_emu10k1_send_volume(emu, mix->epcm->voices[0]->number, &mix->send_volume[1][0]); - update_emu10k1_send_volume(emu, mix->epcm->voices[1]->number, + update_emu10k1_send_volume(emu, mix->epcm->voices[0]->number + 1, &mix->send_volume[2][0]); - } else if (mix->epcm->voices[0]) { + } else { update_emu10k1_send_volume(emu, mix->epcm->voices[0]->number, &mix->send_volume[0][0]); } @@ -1601,11 +1601,11 @@ static int snd_emu10k1_attn_put(struct snd_kcontrol *kcontrol, change = 1; } } - if (change && mix->epcm) { - if (mix->epcm->voices[0] && mix->epcm->voices[1]) { + if (change && mix->epcm && mix->epcm->voices[0]) { + if (!mix->epcm->voices[0]->last) { snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[0]->number, mix->attn[1]); - snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[1]->number, mix->attn[2]); - } else if (mix->epcm->voices[0]) { + snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[0]->number + 1, mix->attn[2]); + } else { snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[0]->number, mix->attn[0]); } } diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c index 8bf0a4d8aaf1..ab3f81dd439e 100644 --- a/sound/pci/emu10k1/emupcm.c +++ b/sound/pci/emu10k1/emupcm.c @@ -86,32 +86,26 @@ static void snd_emu10k1_pcm_free_voices(struct snd_emu10k1_pcm *epcm) } } -static int snd_emu10k1_pcm_channel_alloc(struct snd_emu10k1_pcm * epcm, int voices) +static int snd_emu10k1_pcm_channel_alloc(struct snd_emu10k1_pcm *epcm, + int type, int count, int channels) { - int err, i; + int err; snd_emu10k1_pcm_free_voices(epcm); err = snd_emu10k1_voice_alloc(epcm->emu, - epcm->type == PLAYBACK_EMUVOICE ? EMU10K1_PCM : EMU10K1_EFX, - voices, + type, count, channels, epcm, &epcm->voices[0]); - if (err < 0) return err; - if (voices > 1) { - for (i = 1; i < voices; i++) { - epcm->voices[i] = &epcm->emu->voices[(epcm->voices[0]->number + i) % NUM_G]; - } - } + if (epcm->extra == NULL) { // The hardware supports only (half-)loop interrupts, so to support an // arbitrary number of periods per buffer, we use an extra voice with a // period-sized loop as the interrupt source. Additionally, the interrupt // timing of the hardware is "suboptimal" and needs some compensation. err = snd_emu10k1_voice_alloc(epcm->emu, - epcm->type == PLAYBACK_EMUVOICE ? EMU10K1_PCM_IRQ : EMU10K1_EFX_IRQ, - 1, + type + 1, 1, 1, epcm, &epcm->extra); if (err < 0) { /* @@ -308,9 +302,19 @@ static int snd_emu10k1_playback_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_runtime *runtime = substream->runtime; struct snd_emu10k1_pcm *epcm = runtime->private_data; size_t alloc_size; + int type, channels, count; int err; - err = snd_emu10k1_pcm_channel_alloc(epcm, params_channels(hw_params)); + if (epcm->type == PLAYBACK_EMUVOICE) { + type = EMU10K1_PCM; + channels = 1; + count = params_channels(hw_params); + } else { + type = EMU10K1_EFX; + channels = params_channels(hw_params); + count = 1; + } + err = snd_emu10k1_pcm_channel_alloc(epcm, type, count, channels); if (err < 0) return err; @@ -380,8 +384,8 @@ static int snd_emu10k1_playback_prepare(struct snd_pcm_substream *substream) snd_emu10k1_pcm_init_voice(emu, 1, 0, epcm->voices[0], w_16, stereo, start_addr, end_addr, &emu->pcm_mixer[substream->number]); - if (epcm->voices[1]) - snd_emu10k1_pcm_init_voice(emu, 0, 0, epcm->voices[1], w_16, true, + if (stereo) + snd_emu10k1_pcm_init_voice(emu, 0, 0, epcm->voices[0] + 1, w_16, true, start_addr, end_addr, &emu->pcm_mixer[substream->number]); return 0; @@ -572,18 +576,14 @@ static void snd_emu10k1_playback_unmute_voice(struct snd_emu10k1 *emu, unsigned int vattn; unsigned int tmp; - if (evoice == NULL) /* skip second voice for mono */ - return; tmp = stereo ? (master ? 1 : 2) : 0; vattn = mix->attn[tmp] << 16; snd_emu10k1_playback_commit_volume(emu, evoice, vattn); } static void snd_emu10k1_playback_mute_voice(struct snd_emu10k1 *emu, struct snd_emu10k1_voice *evoice) { - if (evoice == NULL) - return; snd_emu10k1_playback_commit_volume(emu, evoice, 0); } @@ -655,19 +655,21 @@ static int snd_emu10k1_playback_trigger(struct snd_pcm_substream *substream, case SNDRV_PCM_TRIGGER_RESUME: mix = &emu->pcm_mixer[substream->number]; snd_emu10k1_playback_unmute_voice(emu, epcm->voices[0], stereo, true, mix); - snd_emu10k1_playback_unmute_voice(emu, epcm->voices[1], stereo, false, mix); + if (stereo) + snd_emu10k1_playback_unmute_voice(emu, epcm->voices[0] + 1, true, false, mix); snd_emu10k1_playback_set_running(emu, epcm); snd_emu10k1_playback_trigger_voice(emu, epcm->voices[0]); snd_emu10k1_playback_trigger_voice(emu, epcm->extra); break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: case SNDRV_PCM_TRIGGER_SUSPEND: snd_emu10k1_playback_stop_voice(emu, epcm->voices[0]); snd_emu10k1_playback_stop_voice(emu, epcm->extra); snd_emu10k1_playback_set_stopped(emu, epcm); snd_emu10k1_playback_mute_voice(emu, epcm->voices[0]); - snd_emu10k1_playback_mute_voice(emu, epcm->voices[1]); + if (stereo) + snd_emu10k1_playback_mute_voice(emu, epcm->voices[0] + 1); break; default: result = -EINVAL; diff --git a/sound/pci/emu10k1/emuproc.c b/sound/pci/emu10k1/emuproc.c index abcec8a01760..89ea3adff322 100644 --- a/sound/pci/emu10k1/emuproc.c +++ b/sound/pci/emu10k1/emuproc.c @@ -372,12 +372,13 @@ static void snd_emu10k1_proc_voices_read(struct snd_info_entry *entry, }; static_assert(ARRAY_SIZE(types) == EMU10K1_NUM_TYPES); - snd_iprintf(buffer, "ch\tdirty\tuse\n"); + snd_iprintf(buffer, "ch\tdirty\tlast\tuse\n"); for (idx = 0; idx < NUM_G; idx++) { voice = &emu->voices[idx]; - snd_iprintf(buffer, "%i\t%u\t%s\n", + snd_iprintf(buffer, "%i\t%u\t%u\t%s\n", idx, voice->dirty, + voice->last, types[voice->use]); } } diff --git a/sound/pci/emu10k1/voice.c b/sound/pci/emu10k1/voice.c index 6c58e3bd14f7..6939498e26f0 100644 --- a/sound/pci/emu10k1/voice.c +++ b/sound/pci/emu10k1/voice.c @@ -23,103 +23,101 @@ * allocator uses a round robin scheme. The next free voice is tracked in * the card record and each allocation begins where the last left off. The * hardware requires stereo interleaved voices be aligned to an even/odd - * boundary. For multichannel voice allocation we ensure than the block of - * voices does not cross the 32 voice boundary. This simplifies the - * multichannel support and ensures we can use a single write to the - * (set|clear)_loop_stop registers. Otherwise (for example) the voices would - * get out of sync when pausing/resuming a stream. + * boundary. * --rlrevell */ static int voice_alloc(struct snd_emu10k1 *emu, int type, int number, struct snd_emu10k1_pcm *epcm, struct snd_emu10k1_voice **rvoice) { struct snd_emu10k1_voice *voice; - int i, j, k, first_voice, last_voice, skip; + int i, j, k, skip; - *rvoice = NULL; - first_voice = last_voice = 0; - for (i = emu->next_free_voice, j = 0; j < NUM_G ; i += number, j += number) { + for (i = emu->next_free_voice, j = 0; j < NUM_G; i = (i + skip) % NUM_G, j += skip) { /* dev_dbg(emu->card->dev, "i %d j %d next free %d!\n", i, j, emu->next_free_voice); */ - i %= NUM_G; /* stereo voices must be even/odd */ - if ((number == 2) && (i % 2)) { - i++; + if ((number > 1) && (i % 2)) { + skip = 1; continue; } - - skip = 0; + for (k = 0; k < number; k++) { - voice = &emu->voices[(i+k) % NUM_G]; + voice = &emu->voices[i + k]; if (voice->use) { - skip = 1; - break; + skip = k + 1; + goto next; } } - if (!skip) { - /* dev_dbg(emu->card->dev, "allocated voice %d\n", i); */ - first_voice = i; - last_voice = (i + number) % NUM_G; - emu->next_free_voice = last_voice; - break; + + for (k = 0; k < number; k++) { + voice = &emu->voices[i + k]; + voice->use = type; + voice->epcm = epcm; + /* dev_dbg(emu->card->dev, "allocated voice %d\n", i + k); */ } + voice->last = 1; + + *rvoice = &emu->voices[i]; + emu->next_free_voice = (i + number) % NUM_G; + return 0; + + next: ; } - - if (first_voice == last_voice) - return -ENOMEM; - - for (i = 0; i < number; i++) { - voice = &emu->voices[(first_voice + i) % NUM_G]; - /* - dev_dbg(emu->card->dev, "voice alloc - %i, %i of %i\n", - voice->number, idx-first_voice+1, number); - */ - voice->use = type; - voice->epcm = epcm; - } - *rvoice = &emu->voices[first_voice]; - return 0; + return -ENOMEM; // -EBUSY would have been better } static void voice_free(struct snd_emu10k1 *emu, struct snd_emu10k1_voice *pvoice) { if (pvoice->dirty) snd_emu10k1_voice_init(emu, pvoice->number); pvoice->interrupt = NULL; - pvoice->use = pvoice->dirty = 0; + pvoice->use = pvoice->dirty = pvoice->last = 0; pvoice->epcm = NULL; } -int snd_emu10k1_voice_alloc(struct snd_emu10k1 *emu, int type, int number, +int snd_emu10k1_voice_alloc(struct snd_emu10k1 *emu, int type, int count, int channels, struct snd_emu10k1_pcm *epcm, struct snd_emu10k1_voice **rvoice) { unsigned long flags; int result; if (snd_BUG_ON(!rvoice)) return -EINVAL; - if (snd_BUG_ON(!number)) + if (snd_BUG_ON(!count)) + return -EINVAL; + if (snd_BUG_ON(!channels)) return -EINVAL; spin_lock_irqsave(&emu->voice_lock, flags); - for (;;) { - result = voice_alloc(emu, type, number, epcm, rvoice); - if (result == 0 || type == EMU10K1_SYNTH) - break; - - /* free a voice from synth */ - if (emu->get_synth_voice) { - result = emu->get_synth_voice(emu); - if (result >= 0) - voice_free(emu, &emu->voices[result]); + for (int got = 0; got < channels; ) { + result = voice_alloc(emu, type, count, epcm, &rvoice[got]); + if (result == 0) { + got++; + /* + dev_dbg(emu->card->dev, "voice alloc - %i, %i of %i\n", + rvoice[got - 1]->number, got, want); + */ + continue; } - if (result < 0) - break; + if (type != EMU10K1_SYNTH && emu->get_synth_voice) { + /* free a voice from synth */ + result = emu->get_synth_voice(emu); + if (result >= 0) { + voice_free(emu, &emu->voices[result]); + continue; + } + } + for (int i = 0; i < got; i++) { + for (int j = 0; j < count; j++) + voice_free(emu, rvoice[i] + j); + rvoice[i] = NULL; + } + break; } spin_unlock_irqrestore(&emu->voice_lock, flags); @@ -132,11 +130,15 @@ int snd_emu10k1_voice_free(struct snd_emu10k1 *emu, struct snd_emu10k1_voice *pvoice) { unsigned long flags; + int last; if (snd_BUG_ON(!pvoice)) return -EINVAL; spin_lock_irqsave(&emu->voice_lock, flags); - voice_free(emu, pvoice); + do { + last = pvoice->last; + voice_free(emu, pvoice++); + } while (!last); spin_unlock_irqrestore(&emu->voice_lock, flags); return 0; }