From patchwork Tue May 2 11:50:07 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jaroslav Kysela X-Patchwork-Id: 13228817 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 2A81BC77B73 for ; Tue, 2 May 2023 11:53:25 +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 D14661663; Tue, 2 May 2023 13:52:32 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz D14661663 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1683028402; bh=5TDJBGho7NuyI7LYiIBjLXEGotRwakyWWtTnk21Vgv8=; h=From:To:Subject:Date:In-Reply-To:References:List-Id:List-Archive: List-Help:List-Owner:List-Post:List-Subscribe:List-Unsubscribe: From; b=ARlDJzMqugyfk7oN7Ku65L2kj2J1eKXyKukGdzoJMNMsiSXOFnpzMwEiSLRMlFh+k 2a1L73zoEVZn/B09rI2CDpnUUfWef6xjjHgYQkc2TSKZnz3x+ISzjnzaNOvG1SZcb/ wYyEso2f60oA8AZh8TaRdMlWsY8SheOGCJxkwESM= Received: from mailman-core.alsa-project.org (mailman-core.alsa-project.org [10.254.200.10]) by alsa1.perex.cz (Postfix) with ESMTP id 692E2F80114; Tue, 2 May 2023 13:51:29 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 336DFF80551; Tue, 2 May 2023 13:51:27 +0200 (CEST) Received: from mail1.perex.cz (mail1.perex.cz [77.48.224.245]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id B2E28F80114 for ; Tue, 2 May 2023 13:50:40 +0200 (CEST) Received: from mail1.perex.cz (localhost [127.0.0.1]) by smtp1.perex.cz (Perex's E-mail Delivery System) with ESMTP id F18F411E2; Tue, 2 May 2023 13:50:39 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.perex.cz F18F411E2 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=perex.cz; s=default; t=1683028240; bh=Ebl8z2/5a0VHyBfxYsbeJHRJ4u/yYHRaSR7H8RSYqts=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=3A2nMTN7Y0vWZHjh4YhHwoxUzFQL0HHaVuT7/Eexicxt0o2Th3/AMrH53W0i9AjyH WKA4MXZntubk8otIRKb/sOPFODujIPI/fOrFywavVWUy2XjTiORoWMunMQrZnGamy2 KRa+akkC2HIJVh2Qt9d9y68lsrKHpCdscQIJO4zY= Received: from p1gen2.perex-int.cz (unknown [192.168.100.98]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: perex) by mail1.perex.cz (Perex's E-mail Delivery System) with ESMTPSA; Tue, 2 May 2023 13:50:37 +0200 (CEST) From: Jaroslav Kysela To: ALSA development Subject: [PATCH alsa-lib 1/4] pcm: hw: setup explicit silencing for snd_pcm_drain by default Date: Tue, 2 May 2023 13:50:07 +0200 Message-Id: <20230502115010.986325-2-perex@perex.cz> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230502115010.986325-1-perex@perex.cz> References: <20230502115010.986325-1-perex@perex.cz> MIME-Version: 1.0 Message-ID-Hash: JXQ22QLOYFJDDBOTM3LHGV2J24KHN7IC X-Message-ID-Hash: JXQ22QLOYFJDDBOTM3LHGV2J24KHN7IC X-MailFrom: perex@perex.cz 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: Some applications may not follow the period_size transfer blocks and also the driver developers may not follow the consequeces of the access beyond valid samples in the playback DMA buffer. To avoid clicks, fill a little silence at the end of the playback ring buffer when the snd_pcm_drain() is called. Related: https://lore.kernel.org/alsa-devel/20230420113324.877164-2-oswald.buddenhagen@gmx.de/ Related: https://lore.kernel.org/alsa-devel/20230405201219.2197789-2-oswald.buddenhagen@gmx.de/ Signed-off-by: Jaroslav Kysela --- src/pcm/pcm.c | 33 ++++++++++++++++++------------- src/pcm/pcm_hw.c | 47 +++++++++++++++++++++++++++++++++++++++++++++ src/pcm/pcm_local.h | 4 ++++ 3 files changed, 71 insertions(+), 13 deletions(-) diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c index 2b966d44..88b13ed4 100644 --- a/src/pcm/pcm.c +++ b/src/pcm/pcm.c @@ -6167,6 +6167,25 @@ int snd_pcm_hw_params_get_min_align(const snd_pcm_hw_params_t *params, snd_pcm_u return 0; } +#ifndef DOXYGEN +void snd_pcm_sw_params_current_no_lock(snd_pcm_t *pcm, snd_pcm_sw_params_t *params) +{ + params->proto = SNDRV_PCM_VERSION; + params->tstamp_mode = pcm->tstamp_mode; + params->tstamp_type = pcm->tstamp_type; + params->period_step = pcm->period_step; + params->sleep_min = 0; + params->avail_min = pcm->avail_min; + sw_set_period_event(params, pcm->period_event); + params->xfer_align = 1; + params->start_threshold = pcm->start_threshold; + params->stop_threshold = pcm->stop_threshold; + params->silence_threshold = pcm->silence_threshold; + params->silence_size = pcm->silence_size; + params->boundary = pcm->boundary; +} +#endif + /** * \brief Return current software configuration for a PCM * \param pcm PCM handle @@ -6183,19 +6202,7 @@ int snd_pcm_sw_params_current(snd_pcm_t *pcm, snd_pcm_sw_params_t *params) return -EIO; } __snd_pcm_lock(pcm); /* forced lock due to pcm field changes */ - params->proto = SNDRV_PCM_VERSION; - params->tstamp_mode = pcm->tstamp_mode; - params->tstamp_type = pcm->tstamp_type; - params->period_step = pcm->period_step; - params->sleep_min = 0; - params->avail_min = pcm->avail_min; - sw_set_period_event(params, pcm->period_event); - params->xfer_align = 1; - params->start_threshold = pcm->start_threshold; - params->stop_threshold = pcm->stop_threshold; - params->silence_threshold = pcm->silence_threshold; - params->silence_size = pcm->silence_size; - params->boundary = pcm->boundary; + snd_pcm_sw_params_current_no_lock(pcm, params); __snd_pcm_unlock(pcm); return 0; } diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c index daa3e1ff..d8f32bd9 100644 --- a/src/pcm/pcm_hw.c +++ b/src/pcm/pcm_hw.c @@ -98,6 +98,8 @@ typedef struct { bool mmap_control_fallbacked; struct snd_pcm_sync_ptr *sync_ptr; + bool prepare_reset_sw_params; + int period_event; snd_timer_t *period_timer; struct pollfd period_timer_pfd; @@ -534,6 +536,7 @@ static int snd_pcm_hw_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params) SYSMSG("SNDRV_PCM_IOCTL_SW_PARAMS failed (%i)", err); goto out; } + hw->prepare_reset_sw_params = false; if ((snd_pcm_tstamp_type_t) params->tstamp_type != pcm->tstamp_type) { if (hw->version < SNDRV_PROTOCOL_VERSION(2, 0, 12)) { int on = (snd_pcm_tstamp_type_t) params->tstamp_type == @@ -660,7 +663,18 @@ static int snd_pcm_hw_hwsync(snd_pcm_t *pcm) static int snd_pcm_hw_prepare(snd_pcm_t *pcm) { snd_pcm_hw_t *hw = pcm->private_data; + snd_pcm_sw_params_t sw_params; int fd = hw->fd, err; + + if (hw->prepare_reset_sw_params) { + snd_pcm_sw_params_current_no_lock(pcm, &sw_params); + if (ioctl(hw->fd, SNDRV_PCM_IOCTL_SW_PARAMS, sw_params) < 0) { + err = -errno; + SYSMSG("SNDRV_PCM_IOCTL_SW_PARAMS failed (%i)", err); + return err; + } + hw->prepare_reset_sw_params = false; + } if (ioctl(fd, SNDRV_PCM_IOCTL_PREPARE) < 0) { err = -errno; SYSMSG("SNDRV_PCM_IOCTL_PREPARE failed (%i)", err); @@ -718,7 +732,40 @@ static int snd_pcm_hw_drop(snd_pcm_t *pcm) static int snd_pcm_hw_drain(snd_pcm_t *pcm) { snd_pcm_hw_t *hw = pcm->private_data; + snd_pcm_sw_params_t sw_params; + snd_pcm_uframes_t silence_size; int err; + + if (pcm->stream != SND_PCM_STREAM_PLAYBACK) + goto __skip_silence; + /* compute end silence size, align to period size + extra time */ + snd_pcm_sw_params_current_no_lock(pcm, &sw_params); + if ((pcm->boundary % pcm->period_size) == 0) { + silence_size = pcm->period_size - (*pcm->appl.ptr % pcm->period_size); + if (silence_size == pcm->period_size) + silence_size = 0; + } else { + /* it not not easy to compute the period cross point + * in this case because period is not aligned to the boundary + * - use the full range (one period) in this case + */ + silence_size = pcm->period_size; + } + silence_size += pcm->rate / 10; /* 1/10th of second */ + if (sw_params.silence_size < silence_size) { + /* fill the silence soon as possible (in the bellow ioctl + * or the next period wake up) + */ + sw_params.silence_threshold = pcm->buffer_size; + sw_params.silence_size = silence_size; + if (ioctl(hw->fd, SNDRV_PCM_IOCTL_SW_PARAMS, &sw_params) < 0) { + err = -errno; + SYSMSG("SNDRV_PCM_IOCTL_SW_PARAMS failed (%i)", err); + return err; + } + hw->prepare_reset_sw_params = true; + } +__skip_silence: if (ioctl(hw->fd, SNDRV_PCM_IOCTL_DRAIN) < 0) { err = -errno; SYSMSG("SNDRV_PCM_IOCTL_DRAIN failed (%i)", err); diff --git a/src/pcm/pcm_local.h b/src/pcm/pcm_local.h index ae0c44bf..4a859cd1 100644 --- a/src/pcm/pcm_local.h +++ b/src/pcm/pcm_local.h @@ -366,6 +366,8 @@ struct _snd_pcm { snd1_pcm_hw_param_get_max #define snd_pcm_hw_param_name \ snd1_pcm_hw_param_name +#define snd_pcm_sw_params_current_no_lock \ + snd1_pcm_sw_params_current_no_lock int snd_pcm_new(snd_pcm_t **pcmp, snd_pcm_type_t type, const char *name, snd_pcm_stream_t stream, int mode); @@ -390,6 +392,8 @@ void snd_pcm_mmap_appl_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames); void snd_pcm_mmap_hw_backward(snd_pcm_t *pcm, snd_pcm_uframes_t frames); void snd_pcm_mmap_hw_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames); +void snd_pcm_sw_params_current_no_lock(snd_pcm_t *pcm, snd_pcm_sw_params_t *params); + snd_pcm_sframes_t snd_pcm_mmap_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size); snd_pcm_sframes_t snd_pcm_mmap_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size); snd_pcm_sframes_t snd_pcm_mmap_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size); From patchwork Tue May 2 11:50:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jaroslav Kysela X-Patchwork-Id: 13228814 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 08920C77B73 for ; Tue, 2 May 2023 11:52:35 +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 AAD51164D; Tue, 2 May 2023 13:51:43 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz AAD51164D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1683028353; bh=8r9KVwgJHm0edxCaCjnDsec4ZCPA7600wNcyVgj4/E8=; h=From:To:Subject:Date:In-Reply-To:References:List-Id:List-Archive: List-Help:List-Owner:List-Post:List-Subscribe:List-Unsubscribe: From; b=a6wlpxyGNaNUgR3Xh2wWfR1KkJEdiG1FWwmmKyHorYZKiCIwP61BNjjDd19Q0cpEH fWb3FwJt/+sRu4PLtdN0h3N2azO2bCUozkboEuV8PpWvSaqbbfTBO3NKlx3Ie3PVxQ 1q7XhZjFGtgnuORAqIZyXgkbdU7t0JjpsCLUeVk0= Received: from mailman-core.alsa-project.org (mailman-core.alsa-project.org [10.254.200.10]) by alsa1.perex.cz (Postfix) with ESMTP id 7E8B1F804FE; Tue, 2 May 2023 13:50:55 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 1C063F8052E; Tue, 2 May 2023 13:50:52 +0200 (CEST) Received: from mail1.perex.cz (mail1.perex.cz [77.48.224.245]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 2D58AF8049E for ; Tue, 2 May 2023 13:50:43 +0200 (CEST) Received: from mail1.perex.cz (localhost [127.0.0.1]) by smtp1.perex.cz (Perex's E-mail Delivery System) with ESMTP id 62F3311E2; Tue, 2 May 2023 13:50:42 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.perex.cz 62F3311E2 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=perex.cz; s=default; t=1683028242; bh=6cGUh0bloQTppsRGccGwlyiMZGz5IOCyZIiqwAJwx50=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=GGP6uuZAC+IFdPWUgcJ3DKLwDp6tWuxBN9I+tR7qomg3m4eenTVtMciknUlDy8K0v qqfxsGMCYA7x5/uyThFX+Ecp3269Ot0j4Ezyow8Te+us98CmYZvli+evMgdF0Vw3IO kF+KiEBRJZYNmbv+iCB6JgiUz0D96263AyDQnKm8= Received: from p1gen2.perex-int.cz (unknown [192.168.100.98]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: perex) by mail1.perex.cz (Perex's E-mail Delivery System) with ESMTPSA; Tue, 2 May 2023 13:50:40 +0200 (CEST) From: Jaroslav Kysela To: ALSA development Subject: [PATCH alsa-lib 2/4] pcm: hw: add drain_silence configuration keyword Date: Tue, 2 May 2023 13:50:08 +0200 Message-Id: <20230502115010.986325-3-perex@perex.cz> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230502115010.986325-1-perex@perex.cz> References: <20230502115010.986325-1-perex@perex.cz> MIME-Version: 1.0 Message-ID-Hash: W32T4EET5AD6FMD5GISI2T6VOE3PBI4J X-Message-ID-Hash: W32T4EET5AD6FMD5GISI2T6VOE3PBI4J X-MailFrom: perex@perex.cz 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: # Add silence in drain (-1 = auto /default/, 0 = off, > 0 silenced frames) [drain_silence INT] Signed-off-by: Jaroslav Kysela --- src/pcm/pcm_hw.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c index d8f32bd9..30ff843c 100644 --- a/src/pcm/pcm_hw.c +++ b/src/pcm/pcm_hw.c @@ -111,6 +111,7 @@ typedef struct { int max; } rates; int channels; + int drain_silence; /* for chmap */ unsigned int chmap_caps; snd_pcm_chmap_query_t **chmap_override; @@ -738,8 +739,16 @@ static int snd_pcm_hw_drain(snd_pcm_t *pcm) if (pcm->stream != SND_PCM_STREAM_PLAYBACK) goto __skip_silence; - /* compute end silence size, align to period size + extra time */ + if (hw->drain_silence == 0) + goto __skip_silence; snd_pcm_sw_params_current_no_lock(pcm, &sw_params); + if (hw->drain_silence > 0) { + silence_size = hw->drain_silence; + if (silence_size > pcm->buffer_size) + silence_size = pcm->buffer_size; + goto __manual_silence; + } + /* compute end silence size, align to period size + extra time */ if ((pcm->boundary % pcm->period_size) == 0) { silence_size = pcm->period_size - (*pcm->appl.ptr % pcm->period_size); if (silence_size == pcm->period_size) @@ -752,6 +761,7 @@ static int snd_pcm_hw_drain(snd_pcm_t *pcm) silence_size = pcm->period_size; } silence_size += pcm->rate / 10; /* 1/10th of second */ +__manual_silence: if (sw_params.silence_size < silence_size) { /* fill the silence soon as possible (in the bellow ioctl * or the next period wake up) @@ -1818,6 +1828,7 @@ pcm.name { [rate INT] # Restrict only to the given rate or [rate [INT INT]] # Restrict only to the given rate range (min max) [chmap MAP] # Override channel maps; MAP is a string array + [drain_silence INT] # Add silence in drain (-1 = auto /default/, 0 = off, > 0 silenced frames) } \endcode @@ -1850,7 +1861,7 @@ int _snd_pcm_hw_open(snd_pcm_t **pcmp, const char *name, long card = -1, device = 0, subdevice = -1; const char *str; int err, sync_ptr_ioctl = 0; - int min_rate = 0, max_rate = 0, channels = 0; + int min_rate = 0, max_rate = 0, channels = 0, drain_silence = -1; snd_pcm_format_t format = SND_PCM_FORMAT_UNKNOWN; snd_config_t *n; int nonblock = 1; /* non-block per default */ @@ -1991,6 +2002,16 @@ int _snd_pcm_hw_open(snd_pcm_t **pcmp, const char *name, } continue; } + if (strcmp(id, "drain_silence") == 0) { + long val; + err = snd_config_get_integer(n, &val); + if (err < 0) { + SNDERR("Invalid type for %s", id); + goto fail; + } + drain_silence = val; + continue; + } SNDERR("Unknown field %s", id); err = -EINVAL; goto fail; @@ -2033,6 +2054,7 @@ int _snd_pcm_hw_open(snd_pcm_t **pcmp, const char *name, } if (chmap) hw->chmap_override = chmap; + hw->drain_silence = drain_silence; return 0; From patchwork Tue May 2 11:50:09 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jaroslav Kysela X-Patchwork-Id: 13228815 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 8D0FCC77B7E for ; Tue, 2 May 2023 11:52:42 +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 AFF14168C; Tue, 2 May 2023 13:51:50 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz AFF14168C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1683028360; bh=E9oxnn98MhxBrsOvH7dJKh/YD38RYN+ixTHn36N/Jpc=; h=From:To:Subject:Date:In-Reply-To:References:List-Id:List-Archive: List-Help:List-Owner:List-Post:List-Subscribe:List-Unsubscribe: From; b=El/pVPZOQsi2/zVw00A0HVGWCMMMtzt3Snf7zXfM7xQ1zvh5dhi0iSQaKU2GYZF3f Ye7HOys0M6YAb73cQ8PN1c900NQ5Az0zInCjANFwT4mT+gsl4SsZvkdEj+a59Xnspu ypkPDFnPT/hMqZ2gzu7SNYjTWllerCqbKkgDFjy4= Received: from mailman-core.alsa-project.org (mailman-core.alsa-project.org [10.254.200.10]) by alsa1.perex.cz (Postfix) with ESMTP id 6FCB9F80534; Tue, 2 May 2023 13:51:01 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 6A97FF8053B; Tue, 2 May 2023 13:50:56 +0200 (CEST) Received: from mail1.perex.cz (mail1.perex.cz [77.48.224.245]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 691B9F8032B for ; Tue, 2 May 2023 13:50:45 +0200 (CEST) Received: from mail1.perex.cz (localhost [127.0.0.1]) by smtp1.perex.cz (Perex's E-mail Delivery System) with ESMTP id DA97211E2; Tue, 2 May 2023 13:50:44 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.perex.cz DA97211E2 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=perex.cz; s=default; t=1683028244; bh=zdatYxiN0/vkMvubX7YbUgDZwqJ8pQoC3Hjq3XlYSPY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=H1rg/zNlDisHofMotsvy3dSeg05WOxYoX2w4LTt3BOU7hLO8TIGDZ7MFJXoEBGqdh exSwZNA3rYPC01BMNmO9C+c6QBV7zRIEKVnWW+8M1yKo4BlaazUJIpI6aUqC/s81Kh X37UQLspsY/K9InafqMaMapRcHdncEYA7yY+74+0= Received: from p1gen2.perex-int.cz (unknown [192.168.100.98]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: perex) by mail1.perex.cz (Perex's E-mail Delivery System) with ESMTPSA; Tue, 2 May 2023 13:50:42 +0200 (CEST) From: Jaroslav Kysela To: ALSA development Subject: [PATCH alsa-lib 3/4] pcm: hw: introduce SNDRV_PCM_INFO_PERFECT_DRAIN Date: Tue, 2 May 2023 13:50:09 +0200 Message-Id: <20230502115010.986325-4-perex@perex.cz> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230502115010.986325-1-perex@perex.cz> References: <20230502115010.986325-1-perex@perex.cz> MIME-Version: 1.0 Message-ID-Hash: DUYQJWBDPUHTXGTM5NSYF2VEAGXMJ4UX X-Message-ID-Hash: DUYQJWBDPUHTXGTM5NSYF2VEAGXMJ4UX X-MailFrom: perex@perex.cz 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 driver may not require to touch the sample stream for the drain operation at all. Handle this situation in alsa-lib. Signed-off-by: Jaroslav Kysela --- include/pcm.h | 1 + include/sound/uapi/asound.h | 1 + src/pcm/pcm.c | 23 +++++++++++++++++++++++ src/pcm/pcm_hw.c | 4 +++- src/pcm/pcm_local.h | 2 ++ 5 files changed, 30 insertions(+), 1 deletion(-) diff --git a/include/pcm.h b/include/pcm.h index b5a514fa..f15462d9 100644 --- a/include/pcm.h +++ b/include/pcm.h @@ -722,6 +722,7 @@ int snd_pcm_hw_params_is_half_duplex(const snd_pcm_hw_params_t *params); int snd_pcm_hw_params_is_joint_duplex(const snd_pcm_hw_params_t *params); int snd_pcm_hw_params_can_sync_start(const snd_pcm_hw_params_t *params); int snd_pcm_hw_params_can_disable_period_wakeup(const snd_pcm_hw_params_t *params); +int snd_pcm_hw_params_does_perfect_drain(const snd_pcm_hw_params_t *params); int snd_pcm_hw_params_supports_audio_wallclock_ts(const snd_pcm_hw_params_t *params); /* deprecated, use audio_ts_type */ int snd_pcm_hw_params_supports_audio_ts_type(const snd_pcm_hw_params_t *params, int type); int snd_pcm_hw_params_get_rate_numden(const snd_pcm_hw_params_t *params, diff --git a/include/sound/uapi/asound.h b/include/sound/uapi/asound.h index fc18c024..0b8834f2 100644 --- a/include/sound/uapi/asound.h +++ b/include/sound/uapi/asound.h @@ -281,6 +281,7 @@ typedef int __bitwise snd_pcm_subformat_t; #define SNDRV_PCM_INFO_DOUBLE 0x00000004 /* Double buffering needed for PCM start/stop */ #define SNDRV_PCM_INFO_BATCH 0x00000010 /* double buffering */ #define SNDRV_PCM_INFO_SYNC_APPLPTR 0x00000020 /* need the explicit sync of appl_ptr update */ +#define SNDRV_PCM_INFO_PERFECT_DRAIN 0x00000040 /* silencing at the end of stream is not required */ #define SNDRV_PCM_INFO_INTERLEAVED 0x00000100 /* channels are interleaved */ #define SNDRV_PCM_INFO_NONINTERLEAVED 0x00000200 /* channels are not interleaved */ #define SNDRV_PCM_INFO_COMPLEX 0x00000400 /* complex frame organization (mmap only) */ diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c index 88b13ed4..099d83ee 100644 --- a/src/pcm/pcm.c +++ b/src/pcm/pcm.c @@ -3707,6 +3707,29 @@ int snd_pcm_hw_params_can_disable_period_wakeup(const snd_pcm_hw_params_t *param return !!(params->info & SNDRV_PCM_INFO_NO_PERIOD_WAKEUP); } +/** + * \brief Check if hardware does perfect drain + * \param params Configuration space + * \retval 0 Hardware doesn't do perfect drain + * \retval 1 Hardware does perfect drain + * + * This function should only be called when the configuration space + * contains a single configuration. Call #snd_pcm_hw_params to choose + * a single configuration from the configuration space. + * + * The perfect drain means that the hardware does not use samples + * beyond the stream application pointer. + */ +int snd_pcm_hw_params_does_perfect_drain(const snd_pcm_hw_params_t *params) +{ + assert(params); + if (CHECK_SANITY(params->info == ~0U)) { + SNDMSG("invalid PCM info field"); + return 0; /* FIXME: should be a negative error? */ + } + return !!(params->info & SNDRV_PCM_INFO_PERFECT_DRAIN); +} + /** * \brief Check if hardware supports audio wallclock timestamps * \param params Configuration space diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c index 30ff843c..ea0c2ef2 100644 --- a/src/pcm/pcm_hw.c +++ b/src/pcm/pcm_hw.c @@ -99,6 +99,7 @@ typedef struct { struct snd_pcm_sync_ptr *sync_ptr; bool prepare_reset_sw_params; + bool perfect_drain; int period_event; snd_timer_t *period_timer; @@ -398,6 +399,7 @@ static int snd_pcm_hw_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params) params->info &= ~0xf0000000; if (pcm->tstamp_type != SND_PCM_TSTAMP_TYPE_GETTIMEOFDAY) params->info |= SND_PCM_INFO_MONOTONIC; + hw->perfect_drain = !!(params->info & SND_PCM_INFO_PERFECT_DRAIN); return query_status_data(hw); } @@ -739,7 +741,7 @@ static int snd_pcm_hw_drain(snd_pcm_t *pcm) if (pcm->stream != SND_PCM_STREAM_PLAYBACK) goto __skip_silence; - if (hw->drain_silence == 0) + if (hw->drain_silence == 0 || hw->perfect_drain) goto __skip_silence; snd_pcm_sw_params_current_no_lock(pcm, &sw_params); if (hw->drain_silence > 0) { diff --git a/src/pcm/pcm_local.h b/src/pcm/pcm_local.h index 4a859cd1..b039dda0 100644 --- a/src/pcm/pcm_local.h +++ b/src/pcm/pcm_local.h @@ -79,6 +79,8 @@ #define SND_PCM_INFO_DOUBLE SNDRV_PCM_INFO_DOUBLE /** device transfers samples in batch */ #define SND_PCM_INFO_BATCH SNDRV_PCM_INFO_BATCH +/** device does perfect drain (silencing not required) */ +#define SND_PCM_INFO_PERFECT_DRAIN SNDRV_PCM_INFO_PERFECT_DRAIN /** device accepts interleaved samples */ #define SND_PCM_INFO_INTERLEAVED SNDRV_PCM_INFO_INTERLEAVED /** device accepts non-interleaved samples */ From patchwork Tue May 2 11:50:10 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jaroslav Kysela X-Patchwork-Id: 13228816 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 509CBC77B73 for ; Tue, 2 May 2023 11:53:03 +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 08DE91699; Tue, 2 May 2023 13:52:11 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 08DE91699 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1683028381; bh=a55i5xQCKVDhq49Hwsr9Hl1rbgYZ+SaMu7ysELZdFNY=; h=From:To:Subject:Date:In-Reply-To:References:List-Id:List-Archive: List-Help:List-Owner:List-Post:List-Subscribe:List-Unsubscribe: From; b=hwTYj91QsT4qEo6ZaoO85ZB2WoXWcidXCTAbUmyn4DmjatV95zCwRZibiv5DmJjv0 1Zme+8bYkCdVjAsK+gsWT1+yLMr9IeIFtZ0l6YRM9Fy6KOqUXEnrXfgPzQQAeIqas6 uRluPiohsMc6de/top0qHOVOyW+a+hPjw899lmcY= Received: from mailman-core.alsa-project.org (mailman-core.alsa-project.org [10.254.200.10]) by alsa1.perex.cz (Postfix) with ESMTP id E113CF80544; Tue, 2 May 2023 13:51:02 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id D8D5FF80534; Tue, 2 May 2023 13:50:57 +0200 (CEST) Received: from mail1.perex.cz (mail1.perex.cz [77.48.224.245]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id C4C64F800EC for ; Tue, 2 May 2023 13:50:47 +0200 (CEST) Received: from mail1.perex.cz (localhost [127.0.0.1]) by smtp1.perex.cz (Perex's E-mail Delivery System) with ESMTP id 2048511E2; Tue, 2 May 2023 13:50:47 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.perex.cz 2048511E2 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=perex.cz; s=default; t=1683028247; bh=B2JnqXaCj+89DG6MIJGGwdqgmQDuDA13yykR1w13exw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZdEIcIwIdCBXCoYyrJv22l+stcfQXgnFvl964rZrY6SMNTVAfKjpCAyIvB9SZjNV/ uPjWxHU4rWbMtmaF8CFq0GkpObbvB9B2sAjdxQRYoNGoRW9eelOYpbHkix6e2oNrpP KTPbVOVKnbZdxMB7UKHlrrZlbKX37IbqAygTEYo8= Received: from p1gen2.perex-int.cz (unknown [192.168.100.98]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: perex) by mail1.perex.cz (Perex's E-mail Delivery System) with ESMTPSA; Tue, 2 May 2023 13:50:45 +0200 (CEST) From: Jaroslav Kysela To: ALSA development Subject: [PATCH alsa-lib 4/4] pcm: hw: introduce SNDRV_PCM_HW_PARAMS_DRAIN_SILENCE Date: Tue, 2 May 2023 13:50:10 +0200 Message-Id: <20230502115010.986325-5-perex@perex.cz> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230502115010.986325-1-perex@perex.cz> References: <20230502115010.986325-1-perex@perex.cz> MIME-Version: 1.0 Message-ID-Hash: ZSWK6HDXP2CRRURSSEXFOMSEM3TFLMR2 X-Message-ID-Hash: ZSWK6HDXP2CRRURSSEXFOMSEM3TFLMR2 X-MailFrom: perex@perex.cz 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 application may not require to touch the sample stream for the drain operation at all. Handle this situation in alsa-lib. Signed-off-by: Jaroslav Kysela --- include/sound/uapi/asound.h | 3 +++ src/pcm/pcm.c | 32 ++++++++++++++++++++++++++++++++ src/pcm/pcm_hw.c | 3 ++- src/pcm/pcm_local.h | 1 + 4 files changed, 38 insertions(+), 1 deletion(-) diff --git a/include/sound/uapi/asound.h b/include/sound/uapi/asound.h index 0b8834f2..f970179e 100644 --- a/include/sound/uapi/asound.h +++ b/include/sound/uapi/asound.h @@ -390,6 +390,9 @@ typedef int snd_pcm_hw_param_t; #define SNDRV_PCM_HW_PARAMS_NORESAMPLE (1<<0) /* avoid rate resampling */ #define SNDRV_PCM_HW_PARAMS_EXPORT_BUFFER (1<<1) /* export buffer */ #define SNDRV_PCM_HW_PARAMS_NO_PERIOD_WAKEUP (1<<2) /* disable period wakeups */ +#define SNDRV_PCM_HW_PARAMS_NO_DRAIN_SILENCE (1<<3) /* supress drain with the filling + * of the silence samples + */ struct snd_interval { unsigned int min, max; diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c index 099d83ee..5872ee6f 100644 --- a/src/pcm/pcm.c +++ b/src/pcm/pcm.c @@ -4958,6 +4958,38 @@ int snd_pcm_hw_params_get_period_wakeup(snd_pcm_t *pcm, snd_pcm_hw_params_t *par return 0; } +/** + * \brief Restrict a configuration space to allow the drain with the filling of silence samples + * \param pcm PCM handle + * \param params Configuration space + * \param val 0 = disable, 1 = enable (default) drain with the filling of silence samples + * \return 0 otherwise a negative error code + */ +int snd_pcm_hw_params_set_drain_silence(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val) +{ + assert(pcm && params); + if (val) + params->flags &= ~SND_PCM_HW_PARAMS_NO_DRAIN_SILENCE; + else + params->flags |= SND_PCM_HW_PARAMS_NO_DRAIN_SILENCE; + params->rmask = ~0; + return snd_pcm_hw_refine(pcm, params); +} + +/** + * \brief Extract drain with the filling of silence samples from a configuration space + * \param pcm PCM handle + * \param params Configuration space + * \param val 0 = disable, 1 = enable + * \return 0 otherwise a negative error code + */ +int snd_pcm_hw_params_get_drain_silence(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val) +{ + assert(pcm && params && val); + *val = params->flags & SND_PCM_HW_PARAMS_NO_DRAIN_SILENCE ? 0 : 1; + return 0; +} + /** * \brief Extract period time from a configuration space * \param params Configuration space diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c index ea0c2ef2..90d5d07a 100644 --- a/src/pcm/pcm_hw.c +++ b/src/pcm/pcm_hw.c @@ -399,7 +399,8 @@ static int snd_pcm_hw_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params) params->info &= ~0xf0000000; if (pcm->tstamp_type != SND_PCM_TSTAMP_TYPE_GETTIMEOFDAY) params->info |= SND_PCM_INFO_MONOTONIC; - hw->perfect_drain = !!(params->info & SND_PCM_INFO_PERFECT_DRAIN); + hw->perfect_drain = !!(params->info & SND_PCM_INFO_PERFECT_DRAIN) || + !!(params->flags & SND_PCM_HW_PARAMS_NO_DRAIN_SILENCE); return query_status_data(hw); } diff --git a/src/pcm/pcm_local.h b/src/pcm/pcm_local.h index b039dda0..abea6654 100644 --- a/src/pcm/pcm_local.h +++ b/src/pcm/pcm_local.h @@ -107,6 +107,7 @@ #define SND_PCM_HW_PARAMS_NORESAMPLE SNDRV_PCM_HW_PARAMS_NORESAMPLE #define SND_PCM_HW_PARAMS_EXPORT_BUFFER SNDRV_PCM_HW_PARAMS_EXPORT_BUFFER #define SND_PCM_HW_PARAMS_NO_PERIOD_WAKEUP SNDRV_PCM_HW_PARAMS_NO_PERIOD_WAKEUP +#define SND_PCM_HW_PARAMS_NO_DRAIN_SILENCE SNDRV_PCM_HW_PARAMS_NO_DRAIN_SILENCE #define SND_PCM_INFO_MONOTONIC 0x80000000