From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.7 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C56E4C43616 for ; Wed, 5 May 2021 17:06:26 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id AF4886141B for ; Wed, 5 May 2021 17:06:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238517AbhEERGG (ORCPT ); Wed, 5 May 2021 13:06:06 -0400 Received: from mail.kernel.org ([198.145.29.99]:46172 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236243AbhEEQ4B (ORCPT ); Wed, 5 May 2021 12:56:01 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id A8FC761481; Wed, 5 May 2021 16:39:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1620232744; bh=4KpiqIkSPdogFIPBLLg6Z0qN5SzVJxhS+i54j/9U6Kc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NRaYmoojdtQgzP/QllZyye8kV3+bEkIQYseWLIzewE3o/pyvRA+A/UVkAbabplML3 V+HuzCy+2UNE/CEm+i5bcHyg0xIYXj/MRkIq1243Rk6JwV3ndmpiihdUogCydduj5I A4UPFV5WOdnEdNdwtXv7DZ/gbnRs9q7VIz36F83Ddm1D8sU9JrQyJZcl4Cxvcp+ji4 mIo3Nn7T6J2whS49LtC3GqdkYOWEvHp0E2a6Q11bXQ7efq4RClsdLSjOxVYPNr6M6R EC3dKfvm8ShjJYJTFYqb6pJa/94lCQ8IhSgH5Za/98g1jhh+4PFpCHhdLIijbQOIgg /e3cJ8Ol048iw== From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Mikhail Durnev , Mark Brown , Sasha Levin , alsa-devel@alsa-project.org Subject: [PATCH AUTOSEL 5.4 05/46] ASoC: rsnd: core: Check convert rate in rsnd_hw_params Date: Wed, 5 May 2021 12:38:15 -0400 Message-Id: <20210505163856.3463279-5-sashal@kernel.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210505163856.3463279-1-sashal@kernel.org> References: <20210505163856.3463279-1-sashal@kernel.org> MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Mikhail Durnev [ Upstream commit 19c6a63ced5e07e40f3a5255cb1f0fe0d3be7b14 ] snd_pcm_hw_params_set_rate_near can return incorrect sample rate in some cases, e.g. when the backend output rate is set to some value higher than 48000 Hz and the input rate is 8000 Hz. So passing the value returned by snd_pcm_hw_params_set_rate_near to snd_pcm_hw_params will result in "FSO/FSI ratio error" and playing no audio at all while the userland is not properly notified about the issue. If SRC is unable to convert the requested sample rate to the sample rate the backend is using, then the requested sample rate should be adjusted in rsnd_hw_params. The userland will be notified about that change in the returned hw_params structure. Signed-off-by: Mikhail Durnev Link: https://lore.kernel.org/r/1615870055-13954-1-git-send-email-mikhail_durnev@mentor.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/sh/rcar/core.c | 69 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index a6c1cf987e6e..df8d7b53b760 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -1426,8 +1426,75 @@ static int rsnd_hw_params(struct snd_pcm_substream *substream, } if (io->converted_chan) dev_dbg(dev, "convert channels = %d\n", io->converted_chan); - if (io->converted_rate) + if (io->converted_rate) { + /* + * SRC supports convert rates from params_rate(hw_params)/k_down + * to params_rate(hw_params)*k_up, where k_up is always 6, and + * k_down depends on number of channels and SRC unit. + * So all SRC units can upsample audio up to 6 times regardless + * its number of channels. And all SRC units can downsample + * 2 channel audio up to 6 times too. + */ + int k_up = 6; + int k_down = 6; + int channel; + struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io); + dev_dbg(dev, "convert rate = %d\n", io->converted_rate); + + channel = io->converted_chan ? io->converted_chan : + params_channels(hw_params); + + switch (rsnd_mod_id(src_mod)) { + /* + * SRC0 can downsample 4, 6 and 8 channel audio up to 4 times. + * SRC1, SRC3 and SRC4 can downsample 4 channel audio + * up to 4 times. + * SRC1, SRC3 and SRC4 can downsample 6 and 8 channel audio + * no more than twice. + */ + case 1: + case 3: + case 4: + if (channel > 4) { + k_down = 2; + break; + } + fallthrough; + case 0: + if (channel > 2) + k_down = 4; + break; + + /* Other SRC units do not support more than 2 channels */ + default: + if (channel > 2) + return -EINVAL; + } + + if (params_rate(hw_params) > io->converted_rate * k_down) { + hw_param_interval(hw_params, SNDRV_PCM_HW_PARAM_RATE)->min = + io->converted_rate * k_down; + hw_param_interval(hw_params, SNDRV_PCM_HW_PARAM_RATE)->max = + io->converted_rate * k_down; + hw_params->cmask |= SNDRV_PCM_HW_PARAM_RATE; + } else if (params_rate(hw_params) * k_up < io->converted_rate) { + hw_param_interval(hw_params, SNDRV_PCM_HW_PARAM_RATE)->min = + (io->converted_rate + k_up - 1) / k_up; + hw_param_interval(hw_params, SNDRV_PCM_HW_PARAM_RATE)->max = + (io->converted_rate + k_up - 1) / k_up; + hw_params->cmask |= SNDRV_PCM_HW_PARAM_RATE; + } + + /* + * TBD: Max SRC input and output rates also depend on number + * of channels and SRC unit: + * SRC1, SRC3 and SRC4 do not support more than 128kHz + * for 6 channel and 96kHz for 8 channel audio. + * Perhaps this function should return EINVAL if the input or + * the output rate exceeds the limitation. + */ + } } ret = rsnd_dai_call(hw_params, io, substream, hw_params); -- 2.30.2 From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.0 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_NONE,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 492D5C43470 for ; Wed, 5 May 2021 16:55:12 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id AECD6613F3 for ; Wed, 5 May 2021 16:55:11 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org AECD6613F3 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 3F91B1794; Wed, 5 May 2021 18:54:20 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 3F91B1794 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1620233710; bh=4KpiqIkSPdogFIPBLLg6Z0qN5SzVJxhS+i54j/9U6Kc=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=T/jcQxZYUS5pN+nPyLE1cfwJuSnHbwkwXjvJfcOwL4IOiZosl6HkEJwl9LvC+kL1r YlvCRmLK/tIEgRyKiVVp+ElxJfFzlzngshNLCTgK8YWqNlj+l8PovNmvrhF9dvdYFo Yc1+OOHLnjudDH5w2Lltk48ZJ7D6cQvPsHspTrSQ= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 5F0A9F80430; Wed, 5 May 2021 18:39:14 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id E122FF80619; Wed, 5 May 2021 18:39:12 +0200 (CEST) Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id F3520F8028D for ; Wed, 5 May 2021 18:39:05 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz F3520F8028D Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="NRaYmooj" Received: by mail.kernel.org (Postfix) with ESMTPSA id A8FC761481; Wed, 5 May 2021 16:39:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1620232744; bh=4KpiqIkSPdogFIPBLLg6Z0qN5SzVJxhS+i54j/9U6Kc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NRaYmoojdtQgzP/QllZyye8kV3+bEkIQYseWLIzewE3o/pyvRA+A/UVkAbabplML3 V+HuzCy+2UNE/CEm+i5bcHyg0xIYXj/MRkIq1243Rk6JwV3ndmpiihdUogCydduj5I A4UPFV5WOdnEdNdwtXv7DZ/gbnRs9q7VIz36F83Ddm1D8sU9JrQyJZcl4Cxvcp+ji4 mIo3Nn7T6J2whS49LtC3GqdkYOWEvHp0E2a6Q11bXQ7efq4RClsdLSjOxVYPNr6M6R EC3dKfvm8ShjJYJTFYqb6pJa/94lCQ8IhSgH5Za/98g1jhh+4PFpCHhdLIijbQOIgg /e3cJ8Ol048iw== From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Subject: [PATCH AUTOSEL 5.4 05/46] ASoC: rsnd: core: Check convert rate in rsnd_hw_params Date: Wed, 5 May 2021 12:38:15 -0400 Message-Id: <20210505163856.3463279-5-sashal@kernel.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210505163856.3463279-1-sashal@kernel.org> References: <20210505163856.3463279-1-sashal@kernel.org> MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit Cc: Sasha Levin , alsa-devel@alsa-project.org, Mark Brown , Mikhail Durnev X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Mikhail Durnev [ Upstream commit 19c6a63ced5e07e40f3a5255cb1f0fe0d3be7b14 ] snd_pcm_hw_params_set_rate_near can return incorrect sample rate in some cases, e.g. when the backend output rate is set to some value higher than 48000 Hz and the input rate is 8000 Hz. So passing the value returned by snd_pcm_hw_params_set_rate_near to snd_pcm_hw_params will result in "FSO/FSI ratio error" and playing no audio at all while the userland is not properly notified about the issue. If SRC is unable to convert the requested sample rate to the sample rate the backend is using, then the requested sample rate should be adjusted in rsnd_hw_params. The userland will be notified about that change in the returned hw_params structure. Signed-off-by: Mikhail Durnev Link: https://lore.kernel.org/r/1615870055-13954-1-git-send-email-mikhail_durnev@mentor.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/sh/rcar/core.c | 69 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index a6c1cf987e6e..df8d7b53b760 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -1426,8 +1426,75 @@ static int rsnd_hw_params(struct snd_pcm_substream *substream, } if (io->converted_chan) dev_dbg(dev, "convert channels = %d\n", io->converted_chan); - if (io->converted_rate) + if (io->converted_rate) { + /* + * SRC supports convert rates from params_rate(hw_params)/k_down + * to params_rate(hw_params)*k_up, where k_up is always 6, and + * k_down depends on number of channels and SRC unit. + * So all SRC units can upsample audio up to 6 times regardless + * its number of channels. And all SRC units can downsample + * 2 channel audio up to 6 times too. + */ + int k_up = 6; + int k_down = 6; + int channel; + struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io); + dev_dbg(dev, "convert rate = %d\n", io->converted_rate); + + channel = io->converted_chan ? io->converted_chan : + params_channels(hw_params); + + switch (rsnd_mod_id(src_mod)) { + /* + * SRC0 can downsample 4, 6 and 8 channel audio up to 4 times. + * SRC1, SRC3 and SRC4 can downsample 4 channel audio + * up to 4 times. + * SRC1, SRC3 and SRC4 can downsample 6 and 8 channel audio + * no more than twice. + */ + case 1: + case 3: + case 4: + if (channel > 4) { + k_down = 2; + break; + } + fallthrough; + case 0: + if (channel > 2) + k_down = 4; + break; + + /* Other SRC units do not support more than 2 channels */ + default: + if (channel > 2) + return -EINVAL; + } + + if (params_rate(hw_params) > io->converted_rate * k_down) { + hw_param_interval(hw_params, SNDRV_PCM_HW_PARAM_RATE)->min = + io->converted_rate * k_down; + hw_param_interval(hw_params, SNDRV_PCM_HW_PARAM_RATE)->max = + io->converted_rate * k_down; + hw_params->cmask |= SNDRV_PCM_HW_PARAM_RATE; + } else if (params_rate(hw_params) * k_up < io->converted_rate) { + hw_param_interval(hw_params, SNDRV_PCM_HW_PARAM_RATE)->min = + (io->converted_rate + k_up - 1) / k_up; + hw_param_interval(hw_params, SNDRV_PCM_HW_PARAM_RATE)->max = + (io->converted_rate + k_up - 1) / k_up; + hw_params->cmask |= SNDRV_PCM_HW_PARAM_RATE; + } + + /* + * TBD: Max SRC input and output rates also depend on number + * of channels and SRC unit: + * SRC1, SRC3 and SRC4 do not support more than 128kHz + * for 6 channel and 96kHz for 8 channel audio. + * Perhaps this function should return EINVAL if the input or + * the output rate exceeds the limitation. + */ + } } ret = rsnd_dai_call(hw_params, io, substream, hw_params); -- 2.30.2