44ca83
From 1b436862ed6253629d79edc2e09826efd4e0f4e3 Mon Sep 17 00:00:00 2001
44ca83
From: Jaroslav Kysela <perex@perex.cz>
44ca83
Date: Wed, 2 Nov 2022 15:01:56 +0100
44ca83
Subject: [PATCH 01/20] ucm: fix enhanced ID parsing in
44ca83
 snd_use_case_parse_ctl_elem_id()
44ca83
44ca83
Reported-by: Takashi Iwai <tiwai@suse.de>
44ca83
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
44ca83
---
44ca83
 src/ucm/main.c | 2 +-
44ca83
 1 file changed, 1 insertion(+), 1 deletion(-)
44ca83
44ca83
diff --git a/src/ucm/main.c b/src/ucm/main.c
44ca83
index 30ab1e41..28c60565 100644
44ca83
--- a/src/ucm/main.c
44ca83
+++ b/src/ucm/main.c
44ca83
@@ -2793,7 +2793,7 @@ int snd_use_case_parse_ctl_elem_id(snd_ctl_elem_id_t *dst,
44ca83
 	    strcmp(ucm_id, "CaptureSwitch"))
44ca83
 		return -EINVAL;
44ca83
 	snd_ctl_elem_id_clear(dst);
44ca83
-	if (strcasestr(ucm_id, "name="))
44ca83
+	if (strcasestr(value, "name="))
44ca83
 		return __snd_ctl_ascii_elem_id_parse(dst, value, NULL);
44ca83
 	iface = SND_CTL_ELEM_IFACE_MIXER;
44ca83
 	if (jack_control)
44ca83
-- 
44ca83
2.39.0
44ca83
44ca83
44ca83
From aa4f56c3c952269c36464cc0da9db5a1381648fa Mon Sep 17 00:00:00 2001
44ca83
From: Jaroslav Kysela <perex@perex.cz>
44ca83
Date: Wed, 9 Nov 2022 08:11:42 +0100
44ca83
Subject: [PATCH 02/20] pcm: rate - fix the crash in
44ca83
 snd_pcm_rate_may_wait_for_avail_min()
44ca83
44ca83
The pcm argument passed to the conversion function in
44ca83
snd_pcm_plugin_may_wait_for_avail_min_conv() should be
44ca83
pcm->fast_op_arg.
44ca83
44ca83
Test command: arecord -Dplughw:x -r12000 -c2 -fS16_LE -M temp.wav
44ca83
44ca83
Fixes: d9dbb57b ("pcm: rate - rewrite the may_wait_for_avail_min callback for the rate plugin")
44ca83
44ca83
BugLink: https://lore.kernel.org/alsa-devel/1667793912-18957-1-git-send-email-shengjiu.wang@nxp.com/
44ca83
Fixes: https://github.com/alsa-project/alsa-lib/issues/282
44ca83
Reported-by: Shengjiu Wang <shengjiu.wang@nxp.com>
44ca83
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
44ca83
---
44ca83
 src/pcm/pcm_plugin.c | 2 +-
44ca83
 1 file changed, 1 insertion(+), 1 deletion(-)
44ca83
44ca83
diff --git a/src/pcm/pcm_plugin.c b/src/pcm/pcm_plugin.c
44ca83
index 6bb90b8b..ec64604c 100644
44ca83
--- a/src/pcm/pcm_plugin.c
44ca83
+++ b/src/pcm/pcm_plugin.c
44ca83
@@ -622,7 +622,7 @@ int snd_pcm_plugin_may_wait_for_avail_min_conv(
44ca83
 		 * This code is also used by extplug, but extplug does not allow to alter the sampling rate.
44ca83
 		 */
44ca83
 		if (conv)
44ca83
-			needed_slave_avail_min = conv(pcm, needed_slave_avail_min);
44ca83
+			needed_slave_avail_min = conv(pcm->fast_op_arg, needed_slave_avail_min);
44ca83
 
44ca83
 		if (slave->avail_min != needed_slave_avail_min) {
44ca83
 			snd_pcm_sw_params_t *swparams;
44ca83
-- 
44ca83
2.39.0
44ca83
44ca83
44ca83
From 39060852d810461dc8cd1464cfb2ffe84da42d56 Mon Sep 17 00:00:00 2001
44ca83
From: Jaroslav Kysela <perex@perex.cz>
44ca83
Date: Wed, 9 Nov 2022 09:31:34 +0100
44ca83
Subject: [PATCH 03/20] pcm: rate - correct the previous fix for
44ca83
 snd_pcm_rate_may_wait_for_avail_min()
44ca83
44ca83
The previous fix in aa4f56c3 was not correct. The root of the cause is
44ca83
implementation in snd_pcm_may_wait_for_avail_min() inline function
44ca83
where the improper pcm argument is passed to the fast_ops function.
44ca83
44ca83
Fixes: aa4f56c3 ("pcm: rate - fix the crash in snd_pcm_rate_may_wait_for_avail_min()")
44ca83
Fixes: d9dbb57b ("pcm: rate - rewrite the may_wait_for_avail_min callback for the rate plugin")
44ca83
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
44ca83
---
44ca83
 src/pcm/pcm_local.h  |  2 +-
44ca83
 src/pcm/pcm_plugin.c | 10 +++++++---
44ca83
 2 files changed, 8 insertions(+), 4 deletions(-)
44ca83
44ca83
diff --git a/src/pcm/pcm_local.h b/src/pcm/pcm_local.h
44ca83
index 8d25971f..ae0c44bf 100644
44ca83
--- a/src/pcm/pcm_local.h
44ca83
+++ b/src/pcm/pcm_local.h
44ca83
@@ -1144,7 +1144,7 @@ static inline int snd_pcm_may_wait_for_avail_min(snd_pcm_t *pcm, snd_pcm_uframes
44ca83
 	if (avail >= pcm->avail_min)
44ca83
 		return 0;
44ca83
 	if (pcm->fast_ops->may_wait_for_avail_min)
44ca83
-		return pcm->fast_ops->may_wait_for_avail_min(pcm, avail);
44ca83
+		return pcm->fast_ops->may_wait_for_avail_min(pcm->fast_op_arg, avail);
44ca83
 	return 1;
44ca83
 }
44ca83
 
44ca83
diff --git a/src/pcm/pcm_plugin.c b/src/pcm/pcm_plugin.c
44ca83
index ec64604c..b3af1fb7 100644
44ca83
--- a/src/pcm/pcm_plugin.c
44ca83
+++ b/src/pcm/pcm_plugin.c
44ca83
@@ -597,8 +597,12 @@ int snd_pcm_plugin_may_wait_for_avail_min_conv(
44ca83
 		 * a) the slave can provide contineous hw_ptr between periods
44ca83
 		 * b) avail_min does not match one slave_period
44ca83
 		 */
44ca83
-		snd_pcm_plugin_t *plugin = pcm->private_data;
44ca83
-		snd_pcm_t *slave = plugin->gen.slave;
44ca83
+		snd_pcm_generic_t *generic = pcm->private_data;
44ca83
+		/*
44ca83
+		 * do not use snd_pcm_plugin_t pointer here
44ca83
+		 * this code is used from the generic plugins, too
44ca83
+		 */
44ca83
+		snd_pcm_t *slave = generic->slave;
44ca83
 		snd_pcm_uframes_t needed_slave_avail_min;
44ca83
 		snd_pcm_sframes_t available;
44ca83
 
44ca83
@@ -622,7 +626,7 @@ int snd_pcm_plugin_may_wait_for_avail_min_conv(
44ca83
 		 * This code is also used by extplug, but extplug does not allow to alter the sampling rate.
44ca83
 		 */
44ca83
 		if (conv)
44ca83
-			needed_slave_avail_min = conv(pcm->fast_op_arg, needed_slave_avail_min);
44ca83
+			needed_slave_avail_min = conv(pcm, needed_slave_avail_min);
44ca83
 
44ca83
 		if (slave->avail_min != needed_slave_avail_min) {
44ca83
 			snd_pcm_sw_params_t *swparams;
44ca83
-- 
44ca83
2.39.0
44ca83
44ca83
44ca83
From 161f47da5f196c291ac0e11d066fa5ff5f79fa04 Mon Sep 17 00:00:00 2001
44ca83
From: Jaroslav Kysela <perex@perex.cz>
44ca83
Date: Wed, 9 Nov 2022 14:37:45 +0100
44ca83
Subject: [PATCH 04/20] include: pcm_old.h - use a macro for the symbol
44ca83
 versioning
44ca83
44ca83
Make the header file more readable and error prone.
44ca83
44ca83
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
44ca83
---
44ca83
 include/pcm_old.h | 133 ++++++++++++++++++++++++----------------------
44ca83
 1 file changed, 68 insertions(+), 65 deletions(-)
44ca83
44ca83
diff --git a/include/pcm_old.h b/include/pcm_old.h
44ca83
index e6e050fc..a9f5308f 100644
44ca83
--- a/include/pcm_old.h
44ca83
+++ b/include/pcm_old.h
44ca83
@@ -2,11 +2,14 @@
44ca83
  * Old ALSA 0.9.x API
44ca83
  */
44ca83
 
44ca83
+#define ___symbol_version(name, version) \
44ca83
+	__asm__ (".symver " #name "," #name "@" version)
44ca83
+
44ca83
 #ifdef ALSA_PCM_OLD_HW_PARAMS_API
44ca83
 
44ca83
-asm(".symver snd_pcm_hw_params_get_access,snd_pcm_hw_params_get_access@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_set_access_first,snd_pcm_hw_params_set_access_first@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_set_access_last,snd_pcm_hw_params_set_access_last@ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_get_access, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_set_access_first, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_set_access_last, "ALSA_0.9");
44ca83
 
44ca83
 int snd_pcm_hw_params_get_access(const snd_pcm_hw_params_t *params);
44ca83
 int snd_pcm_hw_params_test_access(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t val);
44ca83
@@ -16,9 +19,9 @@ snd_pcm_access_t snd_pcm_hw_params_set_access_last(snd_pcm_t *pcm, snd_pcm_hw_pa
44ca83
 int snd_pcm_hw_params_set_access_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_mask_t *mask);
44ca83
 void snd_pcm_hw_params_get_access_mask(snd_pcm_hw_params_t *params, snd_pcm_access_mask_t *mask);
44ca83
 
44ca83
-asm(".symver snd_pcm_hw_params_get_format,snd_pcm_hw_params_get_format@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_set_format_first,snd_pcm_hw_params_set_format_first@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_set_format_last,snd_pcm_hw_params_set_format_last@ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_get_format, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_set_format_first, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_set_format_last, "ALSA_0.9");
44ca83
 
44ca83
 int snd_pcm_hw_params_get_format(const snd_pcm_hw_params_t *params);
44ca83
 int snd_pcm_hw_params_test_format(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t val);
44ca83
@@ -28,9 +31,9 @@ snd_pcm_format_t snd_pcm_hw_params_set_format_last(snd_pcm_t *pcm, snd_pcm_hw_pa
44ca83
 int snd_pcm_hw_params_set_format_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_mask_t *mask);
44ca83
 void snd_pcm_hw_params_get_format_mask(snd_pcm_hw_params_t *params, snd_pcm_format_mask_t *mask);
44ca83
 
44ca83
-asm(".symver snd_pcm_hw_params_get_subformat,snd_pcm_hw_params_get_subformat@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_set_subformat_first,snd_pcm_hw_params_set_subformat_first@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_set_subformat_last,snd_pcm_hw_params_set_subformat_last@ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_get_subformat, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_set_subformat_first, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_set_subformat_last, "ALSA_0.9");
44ca83
 
44ca83
 int snd_pcm_hw_params_test_subformat(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t val);
44ca83
 int snd_pcm_hw_params_get_subformat(const snd_pcm_hw_params_t *params);
44ca83
@@ -40,12 +43,12 @@ snd_pcm_subformat_t snd_pcm_hw_params_set_subformat_last(snd_pcm_t *pcm, snd_pcm
44ca83
 int snd_pcm_hw_params_set_subformat_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_mask_t *mask);
44ca83
 void snd_pcm_hw_params_get_subformat_mask(snd_pcm_hw_params_t *params, snd_pcm_subformat_mask_t *mask);
44ca83
 
44ca83
-asm(".symver snd_pcm_hw_params_get_channels,snd_pcm_hw_params_get_channels@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_get_channels_min,snd_pcm_hw_params_get_channels_min@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_get_channels_max,snd_pcm_hw_params_get_channels_max@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_set_channels_near,snd_pcm_hw_params_set_channels_near@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_set_channels_first,snd_pcm_hw_params_set_channels_first@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_set_channels_last,snd_pcm_hw_params_set_channels_last@ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_get_channels, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_get_channels_min, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_get_channels_max, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_set_channels_near, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_set_channels_first, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_set_channels_last, "ALSA_0.9");
44ca83
 
44ca83
 int snd_pcm_hw_params_get_channels(const snd_pcm_hw_params_t *params);
44ca83
 unsigned int snd_pcm_hw_params_get_channels_min(const snd_pcm_hw_params_t *params);
44ca83
@@ -59,12 +62,12 @@ unsigned int snd_pcm_hw_params_set_channels_near(snd_pcm_t *pcm, snd_pcm_hw_para
44ca83
 unsigned int snd_pcm_hw_params_set_channels_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
44ca83
 unsigned int snd_pcm_hw_params_set_channels_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
44ca83
 
44ca83
-asm(".symver snd_pcm_hw_params_get_rate,snd_pcm_hw_params_get_rate@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_get_rate_min,snd_pcm_hw_params_get_rate_min@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_get_rate_max,snd_pcm_hw_params_get_rate_max@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_set_rate_near,snd_pcm_hw_params_set_rate_near@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_set_rate_first,snd_pcm_hw_params_set_rate_first@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_set_rate_last,snd_pcm_hw_params_set_rate_last@ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_get_rate, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_get_rate_min, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_get_rate_max, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_set_rate_near, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_set_rate_first, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_set_rate_last, "ALSA_0.9");
44ca83
 
44ca83
 int snd_pcm_hw_params_get_rate(const snd_pcm_hw_params_t *params, int *dir);
44ca83
 unsigned int snd_pcm_hw_params_get_rate_min(const snd_pcm_hw_params_t *params, int *dir);
44ca83
@@ -80,12 +83,12 @@ unsigned int snd_pcm_hw_params_set_rate_last(snd_pcm_t *pcm, snd_pcm_hw_params_t
44ca83
 int snd_pcm_hw_params_set_rate_resample(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val);
44ca83
 int snd_pcm_hw_params_get_rate_resample(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val);
44ca83
 
44ca83
-asm(".symver snd_pcm_hw_params_get_period_time,snd_pcm_hw_params_get_period_time@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_get_period_time_min,snd_pcm_hw_params_get_period_time_min@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_get_period_time_max,snd_pcm_hw_params_get_period_time_max@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_set_period_time_near,snd_pcm_hw_params_set_period_time_near@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_set_period_time_first,snd_pcm_hw_params_set_period_time_first@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_set_period_time_last,snd_pcm_hw_params_set_period_time_last@ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_get_period_time, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_get_period_time_min, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_get_period_time_max, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_set_period_time_near, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_set_period_time_first, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_set_period_time_last, "ALSA_0.9");
44ca83
 
44ca83
 int snd_pcm_hw_params_get_period_time(const snd_pcm_hw_params_t *params, int *dir);
44ca83
 unsigned int snd_pcm_hw_params_get_period_time_min(const snd_pcm_hw_params_t *params, int *dir);
44ca83
@@ -99,12 +102,12 @@ unsigned int snd_pcm_hw_params_set_period_time_near(snd_pcm_t *pcm, snd_pcm_hw_p
44ca83
 unsigned int snd_pcm_hw_params_set_period_time_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir);
44ca83
 unsigned int snd_pcm_hw_params_set_period_time_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir);
44ca83
 
44ca83
-asm(".symver snd_pcm_hw_params_get_period_size,snd_pcm_hw_params_get_period_size@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_get_period_size_min,snd_pcm_hw_params_get_period_size_min@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_get_period_size_max,snd_pcm_hw_params_get_period_size_max@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_set_period_size_near,snd_pcm_hw_params_set_period_size_near@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_set_period_size_first,snd_pcm_hw_params_set_period_size_first@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_set_period_size_last,snd_pcm_hw_params_set_period_size_last@ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_get_period_size, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_get_period_size_min, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_get_period_size_max, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_set_period_size_near, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_set_period_size_first, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_set_period_size_last, "ALSA_0.9");
44ca83
 
44ca83
 snd_pcm_sframes_t snd_pcm_hw_params_get_period_size(const snd_pcm_hw_params_t *params, int *dir);
44ca83
 snd_pcm_uframes_t snd_pcm_hw_params_get_period_size_min(const snd_pcm_hw_params_t *params, int *dir);
44ca83
@@ -119,12 +122,12 @@ snd_pcm_uframes_t snd_pcm_hw_params_set_period_size_first(snd_pcm_t *pcm, snd_pc
44ca83
 snd_pcm_uframes_t snd_pcm_hw_params_set_period_size_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir);
44ca83
 int snd_pcm_hw_params_set_period_size_integer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
44ca83
 
44ca83
-asm(".symver snd_pcm_hw_params_get_periods,snd_pcm_hw_params_get_periods@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_get_periods_min,snd_pcm_hw_params_get_periods_min@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_get_periods_max,snd_pcm_hw_params_get_periods_max@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_set_periods_near,snd_pcm_hw_params_set_periods_near@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_set_periods_first,snd_pcm_hw_params_set_periods_first@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_set_periods_last,snd_pcm_hw_params_set_periods_last@ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_get_periods, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_get_periods_min, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_get_periods_max, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_set_periods_near, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_set_periods_first, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_set_periods_last, "ALSA_0.9");
44ca83
 
44ca83
 int snd_pcm_hw_params_get_periods(const snd_pcm_hw_params_t *params, int *dir);
44ca83
 unsigned int snd_pcm_hw_params_get_periods_min(const snd_pcm_hw_params_t *params, int *dir);
44ca83
@@ -139,12 +142,12 @@ unsigned int snd_pcm_hw_params_set_periods_first(snd_pcm_t *pcm, snd_pcm_hw_para
44ca83
 unsigned int snd_pcm_hw_params_set_periods_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir);
44ca83
 int snd_pcm_hw_params_set_periods_integer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
44ca83
 
44ca83
-asm(".symver snd_pcm_hw_params_get_buffer_time,snd_pcm_hw_params_get_buffer_time@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_get_buffer_time_min,snd_pcm_hw_params_get_buffer_time_min@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_get_buffer_time_max,snd_pcm_hw_params_get_buffer_time_max@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_set_buffer_time_near,snd_pcm_hw_params_set_buffer_time_near@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_set_buffer_time_first,snd_pcm_hw_params_set_buffer_time_first@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_set_buffer_time_last,snd_pcm_hw_params_set_buffer_time_last@ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_get_buffer_time, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_get_buffer_time_min, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_get_buffer_time_max, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_set_buffer_time_near, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_set_buffer_time_first, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_set_buffer_time_last, "ALSA_0.9");
44ca83
 
44ca83
 int snd_pcm_hw_params_get_buffer_time(const snd_pcm_hw_params_t *params, int *dir);
44ca83
 unsigned int snd_pcm_hw_params_get_buffer_time_min(const snd_pcm_hw_params_t *params, int *dir);
44ca83
@@ -158,12 +161,12 @@ unsigned int snd_pcm_hw_params_set_buffer_time_near(snd_pcm_t *pcm, snd_pcm_hw_p
44ca83
 unsigned int snd_pcm_hw_params_set_buffer_time_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir);
44ca83
 unsigned int snd_pcm_hw_params_set_buffer_time_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir);
44ca83
 
44ca83
-asm(".symver snd_pcm_hw_params_get_buffer_size,snd_pcm_hw_params_get_buffer_size@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_get_buffer_size_min,snd_pcm_hw_params_get_buffer_size_min@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_get_buffer_size_max,snd_pcm_hw_params_get_buffer_size_max@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_set_buffer_size_near,snd_pcm_hw_params_set_buffer_size_near@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_set_buffer_size_first,snd_pcm_hw_params_set_buffer_size_first@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_set_buffer_size_last,snd_pcm_hw_params_set_buffer_size_last@ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_get_buffer_size, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_get_buffer_size_min, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_get_buffer_size_max, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_set_buffer_size_near, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_set_buffer_size_first, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_set_buffer_size_last, "ALSA_0.9");
44ca83
 
44ca83
 snd_pcm_sframes_t snd_pcm_hw_params_get_buffer_size(const snd_pcm_hw_params_t *params);
44ca83
 snd_pcm_uframes_t snd_pcm_hw_params_get_buffer_size_min(const snd_pcm_hw_params_t *params);
44ca83
@@ -177,12 +180,12 @@ snd_pcm_uframes_t snd_pcm_hw_params_set_buffer_size_near(snd_pcm_t *pcm, snd_pcm
44ca83
 snd_pcm_uframes_t snd_pcm_hw_params_set_buffer_size_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
44ca83
 snd_pcm_uframes_t snd_pcm_hw_params_set_buffer_size_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
44ca83
 
44ca83
-asm(".symver snd_pcm_hw_params_get_tick_time,snd_pcm_hw_params_get_tick_time@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_get_tick_time_min,snd_pcm_hw_params_get_tick_time_min@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_get_tick_time_max,snd_pcm_hw_params_get_tick_time_max@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_set_tick_time_near,snd_pcm_hw_params_set_tick_time_near@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_set_tick_time_first,snd_pcm_hw_params_set_tick_time_first@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_hw_params_set_tick_time_last,snd_pcm_hw_params_set_tick_time_last@ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_get_tick_time, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_get_tick_time_min, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_get_tick_time_max, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_set_tick_time_near, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_set_tick_time_first, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_hw_params_set_tick_time_last, "ALSA_0.9");
44ca83
 
44ca83
 int snd_pcm_hw_params_get_tick_time(const snd_pcm_hw_params_t *params, int *dir);
44ca83
 unsigned int snd_pcm_hw_params_get_tick_time_min(const snd_pcm_hw_params_t *params, int *dir);
44ca83
@@ -201,14 +204,14 @@ unsigned int snd_pcm_hw_params_set_tick_time_last(snd_pcm_t *pcm, snd_pcm_hw_par
44ca83
 
44ca83
 #ifdef ALSA_PCM_OLD_SW_PARAMS_API
44ca83
 
44ca83
-asm(".symver snd_pcm_sw_params_get_tstamp_mode,snd_pcm_sw_params_get_tstamp_mode@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_sw_params_get_sleep_min,snd_pcm_sw_params_get_sleep_min@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_sw_params_get_avail_min,snd_pcm_sw_params_get_avail_min@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_sw_params_get_xfer_align,snd_pcm_sw_params_get_xfer_align@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_sw_params_get_start_threshold,snd_pcm_sw_params_get_start_threshold@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_sw_params_get_stop_threshold,snd_pcm_sw_params_get_stop_threshold@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_sw_params_get_silence_threshold,snd_pcm_sw_params_get_silence_threshold@ALSA_0.9");
44ca83
-asm(".symver snd_pcm_sw_params_get_silence_size,snd_pcm_sw_params_get_silence_size@ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_sw_params_get_tstamp_mode, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_sw_params_get_sleep_min, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_sw_params_get_avail_min, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_sw_params_get_xfer_align, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_sw_params_get_start_threshold, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_sw_params_get_stop_threshold, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_sw_params_get_silence_threshold, "ALSA_0.9");
44ca83
+___symbol_version(snd_pcm_sw_params_get_silence_size, "ALSA_0.9");
44ca83
 
44ca83
 int snd_pcm_sw_params_set_tstamp_mode(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_tstamp_t val);
44ca83
 snd_pcm_tstamp_t snd_pcm_sw_params_get_tstamp_mode(const snd_pcm_sw_params_t *params);
44ca83
-- 
44ca83
2.39.0
44ca83
44ca83
44ca83
From 152983f01b0bc1178ea0d461ebf66e2d2a8e2e02 Mon Sep 17 00:00:00 2001
44ca83
From: Jaroslav Kysela <perex@perex.cz>
44ca83
Date: Wed, 9 Nov 2022 15:04:06 +0100
44ca83
Subject: [PATCH 05/20] include: alsa-symbols.h - use newer gcc symver function
44ca83
 attribute
44ca83
44ca83
Use the symver function attribute for newer gccs (version 11+).
44ca83
The symver function attribute was introduced probably earlier
44ca83
(gcc-10). We can fix that on demand later.
44ca83
44ca83
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
44ca83
---
44ca83
 include/alsa-symbols.h | 7 +++++++
44ca83
 1 file changed, 7 insertions(+)
44ca83
44ca83
diff --git a/include/alsa-symbols.h b/include/alsa-symbols.h
44ca83
index 344f021a..f8c49103 100644
44ca83
--- a/include/alsa-symbols.h
44ca83
+++ b/include/alsa-symbols.h
44ca83
@@ -29,10 +29,17 @@
44ca83
 #define INTERNAL_CONCAT2_2(Pre, Post) Pre##Post
44ca83
 #define INTERNAL(Name) INTERNAL_CONCAT2_2(__, Name)
44ca83
 
44ca83
+#if __GNUC__ > 10
44ca83
+#define symbol_version(real, name, version) \
44ca83
+	extern __typeof (real) real __attribute__((symver (#name "@" #version)))
44ca83
+#define default_symbol_version(real, name, version) \
44ca83
+	extern __typeof (real) real __attribute__((symver (#name "@@" #version)))
44ca83
+#else
44ca83
 #define symbol_version(real, name, version) \
44ca83
 	__asm__ (".symver " ASM_NAME(#real) "," ASM_NAME(#name) "@" #version)
44ca83
 #define default_symbol_version(real, name, version) \
44ca83
 	__asm__ (".symver " ASM_NAME(#real) "," ASM_NAME(#name) "@@" #version)
44ca83
+#endif
44ca83
 
44ca83
 #ifdef __clang__
44ca83
 #define EXPORT_SYMBOL __attribute__((visibility("default")))
44ca83
-- 
44ca83
2.39.0
44ca83
44ca83
44ca83
From 78b20e3caa7bba930095e05f3f8cbe665204fcfd Mon Sep 17 00:00:00 2001
44ca83
From: Jaroslav Kysela <perex@perex.cz>
44ca83
Date: Mon, 14 Nov 2022 12:36:04 +0100
44ca83
Subject: [PATCH 06/20] test: latency - use snd_pcm_format_physical_width()
44ca83
44ca83
We need to allocate frames using the physical size not
44ca83
the sample bit size.
44ca83
44ca83
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
44ca83
---
44ca83
 src/topology/ctl.c | 7 ++++++-
44ca83
 test/latency.c     | 6 +++---
44ca83
 2 files changed, 9 insertions(+), 4 deletions(-)
44ca83
44ca83
diff --git a/src/topology/ctl.c b/src/topology/ctl.c
44ca83
index dd05424d..2c500ffc 100644
44ca83
--- a/src/topology/ctl.c
44ca83
+++ b/src/topology/ctl.c
44ca83
@@ -17,9 +17,13 @@
44ca83
            Liam Girdwood <liam.r.girdwood@linux.intel.com>
44ca83
 */
44ca83
 
44ca83
+#define ALSA_PCM_OLD_HW_PARAMS_API 1
44ca83
+#define ALSA_PCM_OLD_SW_PARAMS_API 1
44ca83
+#include "../../include/asoundlib.h"
44ca83
 #include "list.h"
44ca83
 #include "tplg_local.h"
44ca83
 
44ca83
+
44ca83
 #define ENUM_VAL_SIZE 	(SNDRV_CTL_ELEM_ID_NAME_MAXLEN >> 2)
44ca83
 
44ca83
 struct ctl_access_elem {
44ca83
@@ -71,7 +75,8 @@ static int parse_access_values(snd_config_t *cfg,
44ca83
 			}
44ca83
 		}
44ca83
 	}
44ca83
-
44ca83
+	return snd_pcm_hw_params_get_channels(NULL);
44ca83
+	//return snd_pcm_hw_params_get_access(NULL);
44ca83
 	return 0;
44ca83
 }
44ca83
 
44ca83
diff --git a/test/latency.c b/test/latency.c
44ca83
index 298bab8a..95b3c0ee 100644
44ca83
--- a/test/latency.c
44ca83
+++ b/test/latency.c
44ca83
@@ -354,7 +354,7 @@ long readbuf(snd_pcm_t *handle, char *buf, long len, size_t *frames, size_t *max
44ca83
 		}
44ca83
 		// printf("read = %li\n", r);
44ca83
 	} else {
44ca83
-		int frame_bytes = (snd_pcm_format_width(format) / 8) * channels;
44ca83
+		int frame_bytes = (snd_pcm_format_physical_width(format) / 8) * channels;
44ca83
 		do {
44ca83
 			r = snd_pcm_readi(handle, buf, len);
44ca83
 			if (r > 0) {
44ca83
@@ -374,7 +374,7 @@ long readbuf(snd_pcm_t *handle, char *buf, long len, size_t *frames, size_t *max
44ca83
 long writebuf(snd_pcm_t *handle, char *buf, long len, size_t *frames)
44ca83
 {
44ca83
 	long r;
44ca83
-	int frame_bytes = (snd_pcm_format_width(format) / 8) * channels;
44ca83
+	int frame_bytes = (snd_pcm_format_physical_width(format) / 8) * channels;
44ca83
 
44ca83
 	while (len > 0) {
44ca83
 		r = snd_pcm_writei(handle, buf, len);
44ca83
@@ -579,7 +579,7 @@ int main(int argc, char *argv[])
44ca83
 
44ca83
 	loop_limit = loop_sec * rate;
44ca83
 	latency = latency_min - 4;
44ca83
-	buffer = malloc((latency_max * snd_pcm_format_width(format) / 8) * 2);
44ca83
+	buffer = malloc((latency_max * snd_pcm_format_physical_width(format) / 8) * 2);
44ca83
 
44ca83
 	setscheduler();
44ca83
 
44ca83
-- 
44ca83
2.39.0
44ca83
44ca83
44ca83
From 425e4d1fbea4965ea0fb7529b1ee6cbb47eb7227 Mon Sep 17 00:00:00 2001
44ca83
From: Jaroslav Kysela <perex@perex.cz>
44ca83
Date: Mon, 14 Nov 2022 14:34:46 +0100
44ca83
Subject: [PATCH 07/20] pcm: fix the fast_ops pcm argument for fast_ops
44ca83
44ca83
The fast_ops callback invocation must always pass the fast_op_arg
44ca83
as the pcm argument. Plugins expect that.
44ca83
44ca83
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
44ca83
---
44ca83
 src/pcm/pcm.c        | 4 ++--
44ca83
 src/pcm/pcm_direct.c | 2 +-
44ca83
 src/pcm/pcm_hw.c     | 2 +-
44ca83
 src/pcm/pcm_multi.c  | 5 +++--
44ca83
 4 files changed, 7 insertions(+), 6 deletions(-)
44ca83
44ca83
diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c
44ca83
index 927aa055..2b966d44 100644
44ca83
--- a/src/pcm/pcm.c
44ca83
+++ b/src/pcm/pcm.c
44ca83
@@ -1705,7 +1705,7 @@ int snd_pcm_link(snd_pcm_t *pcm1, snd_pcm_t *pcm2)
44ca83
 	assert(pcm1);
44ca83
 	assert(pcm2);
44ca83
 	if (pcm1->fast_ops->link)
44ca83
-		err = pcm1->fast_ops->link(pcm1, pcm2);
44ca83
+		err = pcm1->fast_ops->link(pcm1->fast_op_arg, pcm2);
44ca83
 	else
44ca83
 		err = -ENOSYS;
44ca83
 	return err;
44ca83
@@ -1722,7 +1722,7 @@ int snd_pcm_unlink(snd_pcm_t *pcm)
44ca83
 
44ca83
 	assert(pcm);
44ca83
 	if (pcm->fast_ops->unlink)
44ca83
-		err = pcm->fast_ops->unlink(pcm);
44ca83
+		err = pcm->fast_ops->unlink(pcm->fast_op_arg);
44ca83
 	else
44ca83
 		err = -ENOSYS;
44ca83
 	return err;
44ca83
diff --git a/src/pcm/pcm_direct.c b/src/pcm/pcm_direct.c
44ca83
index 4803b81b..3cc5305f 100644
44ca83
--- a/src/pcm/pcm_direct.c
44ca83
+++ b/src/pcm/pcm_direct.c
44ca83
@@ -688,7 +688,7 @@ int snd_pcm_direct_check_xrun(snd_pcm_direct_t *direct, snd_pcm_t *pcm)
44ca83
 		 * so don't increment but just update to actual counter
44ca83
 		 */
44ca83
 		direct->recoveries = direct->shmptr->s.recoveries;
44ca83
-		pcm->fast_ops->drop(pcm);
44ca83
+		pcm->fast_ops->drop(pcm->fast_op_arg);
44ca83
 		/* trigger_tstamp update is missing in drop callbacks */
44ca83
 		gettimestamp(&direct->trigger_tstamp, pcm->tstamp_type);
44ca83
 		/* no timer clear:
44ca83
diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c
44ca83
index 5dfe32ee..0588ce5e 100644
44ca83
--- a/src/pcm/pcm_hw.c
44ca83
+++ b/src/pcm/pcm_hw.c
44ca83
@@ -838,7 +838,7 @@ static int snd_pcm_hw_link(snd_pcm_t *pcm1, snd_pcm_t *pcm2)
44ca83
 {
44ca83
 	if (pcm2->type != SND_PCM_TYPE_HW) {
44ca83
 		if (pcm2->fast_ops->link_slaves)
44ca83
-			return pcm2->fast_ops->link_slaves(pcm2, pcm1);
44ca83
+			return pcm2->fast_ops->link_slaves(pcm2->fast_op_arg, pcm1);
44ca83
 		return -ENOSYS;
44ca83
 	}
44ca83
 	return hw_link(pcm1, pcm2);
44ca83
diff --git a/src/pcm/pcm_multi.c b/src/pcm/pcm_multi.c
44ca83
index bec6d06f..3e7ce82c 100644
44ca83
--- a/src/pcm/pcm_multi.c
44ca83
+++ b/src/pcm/pcm_multi.c
44ca83
@@ -759,8 +759,9 @@ static int snd_pcm_multi_link_slaves(snd_pcm_t *pcm, snd_pcm_t *master)
44ca83
 static int snd_pcm_multi_link(snd_pcm_t *pcm1, snd_pcm_t *pcm2)
44ca83
 {
44ca83
 	snd_pcm_multi_t *multi = pcm1->private_data;
44ca83
-	if (multi->slaves[0].pcm->fast_ops->link)
44ca83
-		return multi->slaves[0].pcm->fast_ops->link(multi->slaves[0].pcm, pcm2);
44ca83
+	snd_pcm_t *main_pcm = multi->slaves[0].pcm;
44ca83
+	if (main_pcm->fast_ops->link)
44ca83
+		return main_pcm->fast_ops->link(main_pcm->fast_op_arg, pcm2);
44ca83
 	return -ENOSYS;
44ca83
 }
44ca83
 
44ca83
-- 
44ca83
2.39.0
44ca83
44ca83
44ca83
From 3e4aeba25bf4a4808183c4b64270f7321b436c13 Mon Sep 17 00:00:00 2001
44ca83
From: Jaroslav Kysela <perex@perex.cz>
44ca83
Date: Mon, 14 Nov 2022 20:42:10 +0100
44ca83
Subject: [PATCH 08/20] test: latency - add more realtime tests
44ca83
44ca83
Add '-x' and '-X' tests and '-U' - I/O update mode based
44ca83
on the system timing.
44ca83
44ca83
It may be required to check the position updates for the specific hardware.
44ca83
Print the real time / stream time differences.
44ca83
44ca83
Also include code to make valgrind happy (including the wrong memory
44ca83
llocation for the stream buffer).
44ca83
44ca83
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
44ca83
---
44ca83
 test/latency.c | 163 +++++++++++++++++++++++++++++++++++++++++++++----
44ca83
 1 file changed, 151 insertions(+), 12 deletions(-)
44ca83
44ca83
diff --git a/test/latency.c b/test/latency.c
44ca83
index 95b3c0ee..91bef1a1 100644
44ca83
--- a/test/latency.c
44ca83
+++ b/test/latency.c
44ca83
@@ -33,10 +33,13 @@
44ca83
 #include <sched.h>
44ca83
 #include <errno.h>
44ca83
 #include <getopt.h>
44ca83
+#include <time.h>
44ca83
 #include "../include/asoundlib.h"
44ca83
 #include <sys/time.h>
44ca83
 #include <math.h>
44ca83
 
44ca83
+typedef struct timespec timestamp_t;
44ca83
+
44ca83
 char *pdevice = "hw:0,0";
44ca83
 char *cdevice = "hw:0,0";
44ca83
 snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE;
44ca83
@@ -50,10 +53,40 @@ int loop_sec = 30;		/* seconds */
44ca83
 int block = 0;			/* block mode */
44ca83
 int use_poll = 0;
44ca83
 int resample = 1;
44ca83
+int sys_latency = 0;		/* data I/O: use system timings instead driver wakeups */
44ca83
+int pos_dump = 0;		/* dump positions */
44ca83
+int realtime_check = 0;
44ca83
 unsigned long loop_limit;
44ca83
+snd_pcm_uframes_t playback_buffer_size;
44ca83
 
44ca83
 snd_output_t *output = NULL;
44ca83
 
44ca83
+static inline long long frames_to_micro(size_t frames)
44ca83
+{
44ca83
+	return (long long)((frames * 1000000LL) + (rate / 2)) / rate;
44ca83
+}
44ca83
+
44ca83
+void timestamp_now(timestamp_t *tstamp)
44ca83
+{
44ca83
+	if (clock_gettime(CLOCK_MONOTONIC_RAW, tstamp))
44ca83
+		printf("clock_gettime() failed\n");
44ca83
+}
44ca83
+
44ca83
+long long timestamp_diff_micro(timestamp_t *tstamp)
44ca83
+{
44ca83
+	timestamp_t now, diff;
44ca83
+	timestamp_now(&now;;
44ca83
+	if (tstamp->tv_nsec > now.tv_nsec) {
44ca83
+		diff.tv_sec = now.tv_sec - tstamp->tv_sec - 1;
44ca83
+		diff.tv_nsec = (now.tv_nsec + 1000000000L) - tstamp->tv_nsec;
44ca83
+	} else {
44ca83
+		diff.tv_sec = now.tv_sec - tstamp->tv_sec;
44ca83
+		diff.tv_nsec = now.tv_nsec - tstamp->tv_nsec;
44ca83
+	}
44ca83
+	/* microseconds */
44ca83
+	return (diff.tv_sec * 1000000) + ((diff.tv_nsec + 500L) / 1000L);
44ca83
+}
44ca83
+
44ca83
 int setparams_stream(snd_pcm_t *handle,
44ca83
 		     snd_pcm_hw_params_t *params,
44ca83
 		     const char *id)
44ca83
@@ -96,6 +129,14 @@ int setparams_stream(snd_pcm_t *handle,
44ca83
 		printf("Rate doesn't match (requested %iHz, get %iHz)\n", rate, err);
44ca83
 		return -EINVAL;
44ca83
 	}
44ca83
+	/* we do not want driver wakeups */
44ca83
+	if (sys_latency > 0 && snd_pcm_hw_params_can_disable_period_wakeup(params)) {
44ca83
+		err = snd_pcm_hw_params_set_period_wakeup(handle, params, 0);
44ca83
+		if (err < 0) {
44ca83
+			printf("Cannot disable period wakeups for %s\n", id);
44ca83
+			return err;
44ca83
+		}
44ca83
+	}
44ca83
 	return 0;
44ca83
 }
44ca83
 
44ca83
@@ -227,6 +268,7 @@ int setparams(snd_pcm_t *phandle, snd_pcm_t *chandle, int *bufsize)
44ca83
 		goto __again;
44ca83
 
44ca83
 	snd_pcm_hw_params_get_buffer_size(p_params, &p_size);
44ca83
+	playback_buffer_size = p_size;
44ca83
 	if (p_psize * 2 < p_size) {
44ca83
                 snd_pcm_hw_params_get_periods_min(p_params, &val, NULL);
44ca83
                 if (val > 2) {
44ca83
@@ -390,7 +432,7 @@ long writebuf(snd_pcm_t *handle, char *buf, long len, size_t *frames)
44ca83
 	}
44ca83
 	return 0;
44ca83
 }
44ca83
-			
44ca83
+
44ca83
 #define FILTERSWEEP_LFO_CENTER 2000.
44ca83
 #define FILTERSWEEP_LFO_DEPTH 1800.
44ca83
 #define FILTERSWEEP_LFO_FREQ 0.2
44ca83
@@ -434,6 +476,19 @@ void applyeffect(char* buffer,int r)
44ca83
 	}
44ca83
 }
44ca83
 
44ca83
+static ssize_t get_avail(snd_pcm_t *pcm)
44ca83
+{
44ca83
+	ssize_t avail;
44ca83
+
44ca83
+	while (1) {
44ca83
+		avail = snd_pcm_avail(pcm);
44ca83
+		if (avail == -EAGAIN)
44ca83
+			continue;
44ca83
+		break;
44ca83
+	}
44ca83
+	return avail;
44ca83
+}
44ca83
+
44ca83
 void help(void)
44ca83
 {
44ca83
 	int k;
44ca83
@@ -444,6 +499,7 @@ void help(void)
44ca83
 "-C,--cdevice   capture device\n"
44ca83
 "-m,--min       minimum latency in frames\n"
44ca83
 "-M,--max       maximum latency in frames\n"
44ca83
+"-U,--updates   I/O updates in milliseconds (0 = off)\n"
44ca83
 "-F,--frames    frames to transfer\n"
44ca83
 "-f,--format    sample format\n"
44ca83
 "-c,--channels  channels\n"
44ca83
@@ -454,6 +510,8 @@ void help(void)
44ca83
 "-b,--block     block mode\n"
44ca83
 "-p,--poll      use poll (wait for event - reduces CPU usage)\n"
44ca83
 "-e,--effect    apply an effect (bandpass filter sweep)\n"
44ca83
+"-x,--posdump   dump buffer positions\n"
44ca83
+"-X,--realtime  do a realtime check (buffering)\n"
44ca83
 );
44ca83
         printf("Recognized sample formats are:");
44ca83
         for (k = 0; k < SND_PCM_FORMAT_LAST; ++k) {
44ca83
@@ -480,6 +538,7 @@ int main(int argc, char *argv[])
44ca83
 		{"cdevice", 1, NULL, 'C'},
44ca83
 		{"min", 1, NULL, 'm'},
44ca83
 		{"max", 1, NULL, 'M'},
44ca83
+		{"updates", 1, NULL, 'U'},
44ca83
 		{"frames", 1, NULL, 'F'},
44ca83
 		{"format", 1, NULL, 'f'},
44ca83
 		{"channels", 1, NULL, 'c'},
44ca83
@@ -490,20 +549,23 @@ int main(int argc, char *argv[])
44ca83
 		{"block", 0, NULL, 'b'},
44ca83
 		{"poll", 0, NULL, 'p'},
44ca83
 		{"effect", 0, NULL, 'e'},
44ca83
+		{"posdump", 0, NULL, 'x'},
44ca83
+		{"realtime", 0, NULL, 'X'},
44ca83
 		{NULL, 0, NULL, 0},
44ca83
 	};
44ca83
 	snd_pcm_t *phandle, *chandle;
44ca83
 	char *buffer;
44ca83
 	int err, latency, morehelp;
44ca83
-	int ok;
44ca83
+	int ok, first_avail;
44ca83
 	snd_timestamp_t p_tstamp, c_tstamp;
44ca83
-	ssize_t r;
44ca83
+	ssize_t r, cap_avail, cap_avail_max, pbk_fill, pbk_fill_min;
44ca83
 	size_t frames_in, frames_out, in_max;
44ca83
+	timestamp_t tstamp_start;
44ca83
 	int effect = 0;
44ca83
 	morehelp = 0;
44ca83
 	while (1) {
44ca83
 		int c;
44ca83
-		if ((c = getopt_long(argc, argv, "hP:C:m:M:F:f:c:r:B:E:s:bpen", long_option, NULL)) < 0)
44ca83
+		if ((c = getopt_long(argc, argv, "hP:C:m:M:U:F:f:c:r:B:E:s:bpenxX", long_option, NULL)) < 0)
44ca83
 			break;
44ca83
 		switch (c) {
44ca83
 		case 'h':
44ca83
@@ -525,6 +587,10 @@ int main(int argc, char *argv[])
44ca83
 			err = atoi(optarg) / 2;
44ca83
 			latency_max = latency_min > err ? latency_min : err;
44ca83
 			break;
44ca83
+		case 'U':
44ca83
+			err = atoi(optarg);
44ca83
+			sys_latency = err <= 0 ? 0 : err;
44ca83
+			break;
44ca83
 		case 'f':
44ca83
 			format = snd_pcm_format_value(optarg);
44ca83
 			if (format == SND_PCM_FORMAT_UNKNOWN) {
44ca83
@@ -564,6 +630,12 @@ int main(int argc, char *argv[])
44ca83
 		case 'n':
44ca83
 			resample = 0;
44ca83
 			break;
44ca83
+		case 'x':
44ca83
+			pos_dump = 1;
44ca83
+			break;
44ca83
+		case 'X':
44ca83
+			realtime_check = 1;
44ca83
+			break;
44ca83
 		}
44ca83
 	}
44ca83
 
44ca83
@@ -579,15 +651,27 @@ int main(int argc, char *argv[])
44ca83
 
44ca83
 	loop_limit = loop_sec * rate;
44ca83
 	latency = latency_min - 4;
44ca83
-	buffer = malloc((latency_max * snd_pcm_format_physical_width(format) / 8) * 2);
44ca83
+	buffer = malloc((latency_max * 2 * snd_pcm_format_physical_width(format) / 8) * channels);
44ca83
+
44ca83
+	/* I/O updates based on a system timer */
44ca83
+	if (sys_latency > 0) {
44ca83
+		block = 0;
44ca83
+		use_poll = 0;
44ca83
+	}
44ca83
 
44ca83
 	setscheduler();
44ca83
 
44ca83
 	printf("Playback device is %s\n", pdevice);
44ca83
 	printf("Capture device is %s\n", cdevice);
44ca83
-	printf("Parameters are %iHz, %s, %i channels, %s mode\n", rate, snd_pcm_format_name(format), channels, block ? "blocking" : "non-blocking");
44ca83
-	printf("Poll mode: %s\n", use_poll ? "yes" : "no");
44ca83
-	printf("Loop limit is %lu frames, minimum latency = %i, maximum latency = %i\n", loop_limit, latency_min * 2, latency_max * 2);
44ca83
+	printf("Parameters are %iHz, %s, %i channels, %s mode, use poll %s\n",
44ca83
+			rate, snd_pcm_format_name(format),
44ca83
+			channels, block ? "blocking" : "non-blocking",
44ca83
+			use_poll ? "yes" : "no");
44ca83
+	printf("Loop limit is %lu frames, minimum latency = %i, maximum latency = %i",
44ca83
+			loop_limit, latency_min * 2, latency_max * 2);
44ca83
+	if (sys_latency > 0)
44ca83
+		printf(", I/O updates %ims", sys_latency);
44ca83
+	printf("\n");
44ca83
 
44ca83
 	if ((err = snd_pcm_open(&phandle, pdevice, SND_PCM_STREAM_PLAYBACK, block ? 0 : SND_PCM_NONBLOCK)) < 0) {
44ca83
 		printf("Playback open error: %s\n", snd_strerror(err));
44ca83
@@ -613,6 +697,9 @@ int main(int argc, char *argv[])
44ca83
 		y[1] = (float*) malloc(channels*sizeof(float));		
44ca83
 		y[2] = (float*) malloc(channels*sizeof(float));		
44ca83
 	}
44ca83
+
44ca83
+	cap_avail_max = 0;
44ca83
+	pbk_fill_min = latency * 2;
44ca83
 			  
44ca83
 	while (1) {
44ca83
 		frames_in = frames_out = 0;
44ca83
@@ -623,7 +710,7 @@ int main(int argc, char *argv[])
44ca83
 			printf("Streams link error: %s\n", snd_strerror(err));
44ca83
 			exit(0);
44ca83
 		}
44ca83
-		if (snd_pcm_format_set_silence(format, buffer, latency*channels) < 0) {
44ca83
+		if (snd_pcm_format_set_silence(format, buffer, latency * channels) < 0) {
44ca83
 			fprintf(stderr, "silence error\n");
44ca83
 			break;
44ca83
 		}
44ca83
@@ -640,6 +727,8 @@ int main(int argc, char *argv[])
44ca83
 			printf("Go error: %s\n", snd_strerror(err));
44ca83
 			exit(0);
44ca83
 		}
44ca83
+		if (realtime_check)
44ca83
+			timestamp_now(&tstamp_start);
44ca83
 		gettimestamp(phandle, &p_tstamp);
44ca83
 		gettimestamp(chandle, &c_tstamp);
44ca83
 #if 0
44ca83
@@ -651,16 +740,54 @@ int main(int argc, char *argv[])
44ca83
 
44ca83
 		ok = 1;
44ca83
 		in_max = 0;
44ca83
+		first_avail = 1;
44ca83
 		while (ok && frames_in < loop_limit) {
44ca83
-			if (use_poll) {
44ca83
+			cap_avail = latency;
44ca83
+			if (sys_latency > 0) {
44ca83
+				poll(NULL, 0, sys_latency);
44ca83
+				cap_avail = get_avail(chandle);
44ca83
+				if (cap_avail < 0) {
44ca83
+					printf("Avail failed: %s\n", snd_strerror(cap_avail));
44ca83
+					ok = 0;
44ca83
+					break;
44ca83
+				}
44ca83
+				if (first_avail && realtime_check) {
44ca83
+					long long diff = timestamp_diff_micro(&tstamp_start);
44ca83
+					long long pos = frames_to_micro(cap_avail);
44ca83
+					printf("POS FIRST CHECK: c=%zd (rt=%lldus)\n", cap_avail, pos - diff);
44ca83
+					first_avail = 0;
44ca83
+				}
44ca83
+			} else if (use_poll) {
44ca83
 				/* use poll to wait for next event */
44ca83
 				snd_pcm_wait(chandle, 1000);
44ca83
 			}
44ca83
-			if ((r = readbuf(chandle, buffer, latency, &frames_in, &in_max)) < 0)
44ca83
+			if (pos_dump || realtime_check) {
44ca83
+				if (sys_latency <= 0)
44ca83
+					cap_avail = get_avail(chandle);
44ca83
+				pbk_fill = get_avail(phandle);
44ca83
+				if (pbk_fill >= 0)
44ca83
+					pbk_fill = playback_buffer_size - pbk_fill;
44ca83
+				if (cap_avail > cap_avail_max)
44ca83
+					cap_avail_max = cap_avail;
44ca83
+				if (pbk_fill >= 0 && pbk_fill < pbk_fill_min)
44ca83
+					pbk_fill_min = pbk_fill;
44ca83
+				if (realtime_check) {
44ca83
+					long long diff = timestamp_diff_micro(&tstamp_start);
44ca83
+					long long cap_pos = frames_to_micro(frames_in + cap_avail);
44ca83
+					long long pbk_pos = frames_to_micro(frames_out - pbk_fill);
44ca83
+					printf("POS: p=%zd (min=%zd, rt=%lldus) c=%zd (max=%zd, rt=%lldus)\n",
44ca83
+							pbk_fill, pbk_fill_min, pbk_pos - diff,
44ca83
+							cap_avail, cap_avail_max, cap_pos - diff);
44ca83
+				} else if (pos_dump) {
44ca83
+					printf("POS: p=%zd (min=%zd), c=%zd (max=%zd)\n",
44ca83
+							pbk_fill, pbk_fill_min, cap_avail, cap_avail_max);
44ca83
+				}
44ca83
+			}
44ca83
+			if ((r = readbuf(chandle, buffer, cap_avail, &frames_in, &in_max)) < 0)
44ca83
 				ok = 0;
44ca83
 			else {
44ca83
 				if (effect)
44ca83
-					applyeffect(buffer,r);
44ca83
+					applyeffect(buffer, r);
44ca83
 			 	if (writebuf(phandle, buffer, r, &frames_out) < 0)
44ca83
 					ok = 0;
44ca83
 			}
44ca83
@@ -677,6 +804,13 @@ int main(int argc, char *argv[])
44ca83
 		if (p_tstamp.tv_sec == c_tstamp.tv_sec &&
44ca83
 		    p_tstamp.tv_usec == c_tstamp.tv_usec)
44ca83
 			printf("Hardware sync\n");
44ca83
+		if (realtime_check) {
44ca83
+			long long diff = timestamp_diff_micro(&tstamp_start);
44ca83
+			long long mtime = frames_to_micro(frames_in);
44ca83
+			printf("Elapsed real time: %lldus\n", diff);
44ca83
+			printf("Elapsed device time: %lldus\n", mtime);
44ca83
+			printf("Test time diff (device - real): %lldus\n", mtime - diff);
44ca83
+		}
44ca83
 		snd_pcm_drop(chandle);
44ca83
 		snd_pcm_nonblock(phandle, 0);
44ca83
 		snd_pcm_drain(phandle);
44ca83
@@ -698,5 +832,10 @@ int main(int argc, char *argv[])
44ca83
 	}
44ca83
 	snd_pcm_close(phandle);
44ca83
 	snd_pcm_close(chandle);
44ca83
+	snd_output_close(output);
44ca83
+	snd_config_update_free_global();
44ca83
+	free(buffer);
44ca83
+	free(pdevice);
44ca83
+	free(cdevice);
44ca83
 	return 0;
44ca83
 }
44ca83
-- 
44ca83
2.39.0
44ca83
44ca83
44ca83
From a0836e2af1f2c37b66e723d8caf399e80b76825b Mon Sep 17 00:00:00 2001
44ca83
From: Jaroslav Kysela <perex@perex.cz>
44ca83
Date: Mon, 14 Nov 2022 21:26:39 +0100
44ca83
Subject: [PATCH 09/20] latency: add timestamps to the POS lines
44ca83
44ca83
- remove first capture pos line
44ca83
- measure the snd_pcm_start() call, too
44ca83
44ca83
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
44ca83
---
44ca83
 test/latency.c | 17 ++++++-----------
44ca83
 1 file changed, 6 insertions(+), 11 deletions(-)
44ca83
44ca83
diff --git a/test/latency.c b/test/latency.c
44ca83
index 91bef1a1..3aff37c1 100644
44ca83
--- a/test/latency.c
44ca83
+++ b/test/latency.c
44ca83
@@ -556,7 +556,7 @@ int main(int argc, char *argv[])
44ca83
 	snd_pcm_t *phandle, *chandle;
44ca83
 	char *buffer;
44ca83
 	int err, latency, morehelp;
44ca83
-	int ok, first_avail;
44ca83
+	int ok;
44ca83
 	snd_timestamp_t p_tstamp, c_tstamp;
44ca83
 	ssize_t r, cap_avail, cap_avail_max, pbk_fill, pbk_fill_min;
44ca83
 	size_t frames_in, frames_out, in_max;
44ca83
@@ -723,12 +723,14 @@ int main(int argc, char *argv[])
44ca83
 			break;
44ca83
 		}
44ca83
 
44ca83
+		if (realtime_check)
44ca83
+			timestamp_now(&tstamp_start);
44ca83
 		if ((err = snd_pcm_start(chandle)) < 0) {
44ca83
 			printf("Go error: %s\n", snd_strerror(err));
44ca83
 			exit(0);
44ca83
 		}
44ca83
 		if (realtime_check)
44ca83
-			timestamp_now(&tstamp_start);
44ca83
+			printf("[%lldus] Stream start\n", timestamp_diff_micro(&tstamp_start));
44ca83
 		gettimestamp(phandle, &p_tstamp);
44ca83
 		gettimestamp(chandle, &c_tstamp);
44ca83
 #if 0
44ca83
@@ -740,7 +742,6 @@ int main(int argc, char *argv[])
44ca83
 
44ca83
 		ok = 1;
44ca83
 		in_max = 0;
44ca83
-		first_avail = 1;
44ca83
 		while (ok && frames_in < loop_limit) {
44ca83
 			cap_avail = latency;
44ca83
 			if (sys_latency > 0) {
44ca83
@@ -751,12 +752,6 @@ int main(int argc, char *argv[])
44ca83
 					ok = 0;
44ca83
 					break;
44ca83
 				}
44ca83
-				if (first_avail && realtime_check) {
44ca83
-					long long diff = timestamp_diff_micro(&tstamp_start);
44ca83
-					long long pos = frames_to_micro(cap_avail);
44ca83
-					printf("POS FIRST CHECK: c=%zd (rt=%lldus)\n", cap_avail, pos - diff);
44ca83
-					first_avail = 0;
44ca83
-				}
44ca83
 			} else if (use_poll) {
44ca83
 				/* use poll to wait for next event */
44ca83
 				snd_pcm_wait(chandle, 1000);
44ca83
@@ -775,8 +770,8 @@ int main(int argc, char *argv[])
44ca83
 					long long diff = timestamp_diff_micro(&tstamp_start);
44ca83
 					long long cap_pos = frames_to_micro(frames_in + cap_avail);
44ca83
 					long long pbk_pos = frames_to_micro(frames_out - pbk_fill);
44ca83
-					printf("POS: p=%zd (min=%zd, rt=%lldus) c=%zd (max=%zd, rt=%lldus)\n",
44ca83
-							pbk_fill, pbk_fill_min, pbk_pos - diff,
44ca83
+					printf("[%lldus] POS: p=%zd (min=%zd, rt=%lldus) c=%zd (max=%zd, rt=%lldus)\n",
44ca83
+							diff, pbk_fill, pbk_fill_min, pbk_pos - diff,
44ca83
 							cap_avail, cap_avail_max, cap_pos - diff);
44ca83
 				} else if (pos_dump) {
44ca83
 					printf("POS: p=%zd (min=%zd), c=%zd (max=%zd)\n",
44ca83
-- 
44ca83
2.39.0
44ca83
44ca83
44ca83
From 8b64f22459b6c55ec54f985f35ff701e18800616 Mon Sep 17 00:00:00 2001
44ca83
From: Jaroslav Kysela <perex@perex.cz>
44ca83
Date: Tue, 15 Nov 2022 17:25:59 +0100
44ca83
Subject: [PATCH 10/20] ucm: clarify set_defaults calls
44ca83
44ca83
- do full reset in snd_use_case_mgr_reload
44ca83
44ca83
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
44ca83
---
44ca83
 src/ucm/main.c | 36 +++++++++++++++++++++++++-----------
44ca83
 1 file changed, 25 insertions(+), 11 deletions(-)
44ca83
44ca83
diff --git a/src/ucm/main.c b/src/ucm/main.c
44ca83
index 28c60565..4f36648c 100644
44ca83
--- a/src/ucm/main.c
44ca83
+++ b/src/ucm/main.c
44ca83
@@ -998,13 +998,14 @@ static int add_auto_values(snd_use_case_mgr_t *uc_mgr)
44ca83
 /**
44ca83
  * \brief execute default commands
44ca83
  * \param uc_mgr Use case manager
44ca83
+ * \param force Force run
44ca83
  * \return zero on success, otherwise a negative error code
44ca83
  */
44ca83
-static int set_defaults(snd_use_case_mgr_t *uc_mgr)
44ca83
+static int set_defaults(snd_use_case_mgr_t *uc_mgr, bool force)
44ca83
 {
44ca83
 	int err;
44ca83
 
44ca83
-	if (uc_mgr->default_list_executed)
44ca83
+	if (!force && uc_mgr->default_list_executed)
44ca83
 		return 0;
44ca83
 	err = execute_sequence(uc_mgr, NULL, &uc_mgr->default_list,
44ca83
 			       &uc_mgr->value_list, NULL, NULL);
44ca83
@@ -1351,7 +1352,7 @@ static int set_verb(snd_use_case_mgr_t *uc_mgr,
44ca83
 	int err;
44ca83
 
44ca83
 	if (enable) {
44ca83
-		err = set_defaults(uc_mgr);
44ca83
+		err = set_defaults(uc_mgr, false);
44ca83
 		if (err < 0)
44ca83
 			return err;
44ca83
 		seq = &verb->enable_list;
44ca83
@@ -1435,6 +1436,22 @@ static int set_device(snd_use_case_mgr_t *uc_mgr,
44ca83
 	return err;
44ca83
 }
44ca83
 
44ca83
+/**
44ca83
+ * \brief Do the full reset
44ca83
+ * \param uc_mgr Use case manager
44ca83
+ * \return zero on success, otherwise a negative error code
44ca83
+ */
44ca83
+static int do_reset(snd_use_case_mgr_t *uc_mgr)
44ca83
+{
44ca83
+	int err;
44ca83
+
44ca83
+	err = set_defaults(uc_mgr, true);
44ca83
+	INIT_LIST_HEAD(&uc_mgr->active_modifiers);
44ca83
+	INIT_LIST_HEAD(&uc_mgr->active_devices);
44ca83
+	uc_mgr->active_verb = NULL;
44ca83
+	return err;
44ca83
+}
44ca83
+
44ca83
 /**
44ca83
  * \brief Parse open arguments
44ca83
  * \param uc_mgr Use case manager
44ca83
@@ -1569,6 +1586,8 @@ int snd_use_case_mgr_reload(snd_use_case_mgr_t *uc_mgr)
44ca83
 
44ca83
 	pthread_mutex_lock(&uc_mgr->mutex);
44ca83
 
44ca83
+	do_reset(uc_mgr);
44ca83
+
44ca83
 	uc_mgr_free_verb(uc_mgr);
44ca83
 
44ca83
 	uc_mgr->default_list_executed = 0;
44ca83
@@ -1633,8 +1652,7 @@ static int dismantle_use_case(snd_use_case_mgr_t *uc_mgr)
44ca83
 	}
44ca83
 	uc_mgr->active_verb = NULL;
44ca83
 
44ca83
-	err = execute_sequence(uc_mgr, NULL, &uc_mgr->default_list,
44ca83
-			       &uc_mgr->value_list, NULL, NULL);
44ca83
+	err = set_defaults(uc_mgr, true);
44ca83
 	
44ca83
 	return err;
44ca83
 }
44ca83
@@ -1649,11 +1667,7 @@ int snd_use_case_mgr_reset(snd_use_case_mgr_t *uc_mgr)
44ca83
 	int err;
44ca83
 
44ca83
 	pthread_mutex_lock(&uc_mgr->mutex);
44ca83
-	err = execute_sequence(uc_mgr, NULL, &uc_mgr->default_list,
44ca83
-			       &uc_mgr->value_list, NULL, NULL);
44ca83
-	INIT_LIST_HEAD(&uc_mgr->active_modifiers);
44ca83
-	INIT_LIST_HEAD(&uc_mgr->active_devices);
44ca83
-	uc_mgr->active_verb = NULL;
44ca83
+	err = do_reset(uc_mgr);
44ca83
 	pthread_mutex_unlock(&uc_mgr->mutex);
44ca83
 	return err;
44ca83
 }
44ca83
@@ -2512,7 +2526,7 @@ static int set_defaults_user(snd_use_case_mgr_t *uc_mgr,
44ca83
 		uc_error("error: wrong value for _defaults (%s)", value);
44ca83
 		return -EINVAL;
44ca83
 	}
44ca83
-	return set_defaults(uc_mgr);
44ca83
+	return set_defaults(uc_mgr, false);
44ca83
 }
44ca83
 
44ca83
 static int handle_transition_verb(snd_use_case_mgr_t *uc_mgr,
44ca83
-- 
44ca83
2.39.0
44ca83
44ca83
44ca83
From 9649b64c6f72984c53f469dad8dd4221d307e06d Mon Sep 17 00:00:00 2001
44ca83
From: Jaroslav Kysela <perex@perex.cz>
44ca83
Date: Tue, 22 Nov 2022 09:59:04 +0100
44ca83
Subject: [PATCH 11/20] ucm: handle empty string also for ${env:} substitution
44ca83
44ca83
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
44ca83
---
44ca83
 src/ucm/ucm_subs.c | 8 +++++++-
44ca83
 1 file changed, 7 insertions(+), 1 deletion(-)
44ca83
44ca83
diff --git a/src/ucm/ucm_subs.c b/src/ucm/ucm_subs.c
44ca83
index 2261bdc2..e62290ea 100644
44ca83
--- a/src/ucm/ucm_subs.c
44ca83
+++ b/src/ucm/ucm_subs.c
44ca83
@@ -490,7 +490,13 @@ static char *rval_env(snd_use_case_mgr_t *uc_mgr ATTRIBUTE_UNUSED, const char *i
44ca83
 {
44ca83
 	char *e;
44ca83
 
44ca83
-	e = getenv(id);
44ca83
+	if (*id == '-') {
44ca83
+		e = getenv(id + 1);
44ca83
+		if (e == NULL)
44ca83
+			e = "";
44ca83
+	} else {
44ca83
+		e = getenv(id);
44ca83
+	}
44ca83
 	if (e)
44ca83
 		return strdup(e);
44ca83
 	return NULL;
44ca83
-- 
44ca83
2.39.0
44ca83
44ca83
44ca83
From f0f054517c05ff4ef7a1615851a686a3a202b9ff Mon Sep 17 00:00:00 2001
44ca83
From: Jaroslav Kysela <perex@perex.cz>
44ca83
Date: Wed, 23 Nov 2022 17:56:20 +0100
44ca83
Subject: [PATCH 12/20] test: latency - add -y option (I/O usleep)
44ca83
44ca83
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
44ca83
---
44ca83
 test/latency.c | 13 ++++++++++++-
44ca83
 1 file changed, 12 insertions(+), 1 deletion(-)
44ca83
44ca83
diff --git a/test/latency.c b/test/latency.c
44ca83
index 3aff37c1..161d1f68 100644
44ca83
--- a/test/latency.c
44ca83
+++ b/test/latency.c
44ca83
@@ -52,6 +52,7 @@ int latency_max = 2048;		/* in frames / 2 */
44ca83
 int loop_sec = 30;		/* seconds */
44ca83
 int block = 0;			/* block mode */
44ca83
 int use_poll = 0;
44ca83
+int usleep_val = 0;
44ca83
 int resample = 1;
44ca83
 int sys_latency = 0;		/* data I/O: use system timings instead driver wakeups */
44ca83
 int pos_dump = 0;		/* dump positions */
44ca83
@@ -509,6 +510,8 @@ void help(void)
44ca83
 "-s,--seconds   duration of test in seconds\n"
44ca83
 "-b,--block     block mode\n"
44ca83
 "-p,--poll      use poll (wait for event - reduces CPU usage)\n"
44ca83
+"-y,--usleep    sleep for the specified amount of microseconds between\n"
44ca83
+"               stream updates (default 0 - off)\n"
44ca83
 "-e,--effect    apply an effect (bandpass filter sweep)\n"
44ca83
 "-x,--posdump   dump buffer positions\n"
44ca83
 "-X,--realtime  do a realtime check (buffering)\n"
44ca83
@@ -548,6 +551,7 @@ int main(int argc, char *argv[])
44ca83
 		{"seconds", 1, NULL, 's'},
44ca83
 		{"block", 0, NULL, 'b'},
44ca83
 		{"poll", 0, NULL, 'p'},
44ca83
+		{"usleep", 1, NULL, 'y'},
44ca83
 		{"effect", 0, NULL, 'e'},
44ca83
 		{"posdump", 0, NULL, 'x'},
44ca83
 		{"realtime", 0, NULL, 'X'},
44ca83
@@ -565,7 +569,7 @@ int main(int argc, char *argv[])
44ca83
 	morehelp = 0;
44ca83
 	while (1) {
44ca83
 		int c;
44ca83
-		if ((c = getopt_long(argc, argv, "hP:C:m:M:U:F:f:c:r:B:E:s:bpenxX", long_option, NULL)) < 0)
44ca83
+		if ((c = getopt_long(argc, argv, "hP:C:m:M:U:F:f:c:r:B:E:s:y:bpenxX", long_option, NULL)) < 0)
44ca83
 			break;
44ca83
 		switch (c) {
44ca83
 		case 'h':
44ca83
@@ -624,6 +628,9 @@ int main(int argc, char *argv[])
44ca83
 		case 'p':
44ca83
 			use_poll = 1;
44ca83
 			break;
44ca83
+		case 'y':
44ca83
+			usleep_val = atoi(optarg);
44ca83
+			break;
44ca83
 		case 'e':
44ca83
 			effect = 1;
44ca83
 			break;
44ca83
@@ -671,6 +678,8 @@ int main(int argc, char *argv[])
44ca83
 			loop_limit, latency_min * 2, latency_max * 2);
44ca83
 	if (sys_latency > 0)
44ca83
 		printf(", I/O updates %ims", sys_latency);
44ca83
+	else if (!block)
44ca83
+		printf(", I/O usleep %ius", usleep_val);
44ca83
 	printf("\n");
44ca83
 
44ca83
 	if ((err = snd_pcm_open(&phandle, pdevice, SND_PCM_STREAM_PLAYBACK, block ? 0 : SND_PCM_NONBLOCK)) < 0) {
44ca83
@@ -755,6 +764,8 @@ int main(int argc, char *argv[])
44ca83
 			} else if (use_poll) {
44ca83
 				/* use poll to wait for next event */
44ca83
 				snd_pcm_wait(chandle, 1000);
44ca83
+			} else if (usleep_val > 0) {
44ca83
+				usleep(usleep_val);
44ca83
 			}
44ca83
 			if (pos_dump || realtime_check) {
44ca83
 				if (sys_latency <= 0)
44ca83
-- 
44ca83
2.39.0
44ca83
44ca83
44ca83
From 536c93928bc57d941a7cd146dbcbd62df0be2d83 Mon Sep 17 00:00:00 2001
44ca83
From: Jaroslav Kysela <perex@perex.cz>
44ca83
Date: Wed, 23 Nov 2022 19:45:15 +0100
44ca83
Subject: [PATCH 13/20] test: latency - usleep should not be used in the block
44ca83
 mode
44ca83
44ca83
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
44ca83
---
44ca83
 test/latency.c | 4 ++--
44ca83
 1 file changed, 2 insertions(+), 2 deletions(-)
44ca83
44ca83
diff --git a/test/latency.c b/test/latency.c
44ca83
index 161d1f68..1b4848d6 100644
44ca83
--- a/test/latency.c
44ca83
+++ b/test/latency.c
44ca83
@@ -678,7 +678,7 @@ int main(int argc, char *argv[])
44ca83
 			loop_limit, latency_min * 2, latency_max * 2);
44ca83
 	if (sys_latency > 0)
44ca83
 		printf(", I/O updates %ims", sys_latency);
44ca83
-	else if (!block)
44ca83
+	else if (!block && !use_poll)
44ca83
 		printf(", I/O usleep %ius", usleep_val);
44ca83
 	printf("\n");
44ca83
 
44ca83
@@ -764,7 +764,7 @@ int main(int argc, char *argv[])
44ca83
 			} else if (use_poll) {
44ca83
 				/* use poll to wait for next event */
44ca83
 				snd_pcm_wait(chandle, 1000);
44ca83
-			} else if (usleep_val > 0) {
44ca83
+			} else if (!block && usleep_val > 0) {
44ca83
 				usleep(usleep_val);
44ca83
 			}
44ca83
 			if (pos_dump || realtime_check) {
44ca83
-- 
44ca83
2.39.0
44ca83
44ca83
44ca83
From ea0850f3f3780652869c2b4550576894bc21684f Mon Sep 17 00:00:00 2001
44ca83
From: Jaroslav Kysela <perex@perex.cz>
44ca83
Date: Thu, 24 Nov 2022 08:33:47 +0100
44ca83
Subject: [PATCH 14/20] test: latency - add --policy option to allow using
44ca83
 SCHED_FIFO
44ca83
44ca83
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
44ca83
---
44ca83
 test/latency.c | 22 +++++++++++++++++-----
44ca83
 1 file changed, 17 insertions(+), 5 deletions(-)
44ca83
44ca83
diff --git a/test/latency.c b/test/latency.c
44ca83
index 1b4848d6..3b20e1c1 100644
44ca83
--- a/test/latency.c
44ca83
+++ b/test/latency.c
44ca83
@@ -40,6 +40,7 @@
44ca83
 
44ca83
 typedef struct timespec timestamp_t;
44ca83
 
44ca83
+char *sched_policy = "rr";
44ca83
 char *pdevice = "hw:0,0";
44ca83
 char *cdevice = "hw:0,0";
44ca83
 snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE;
44ca83
@@ -354,18 +355,24 @@ void gettimestamp(snd_pcm_t *handle, snd_timestamp_t *timestamp)
44ca83
 void setscheduler(void)
44ca83
 {
44ca83
 	struct sched_param sched_param;
44ca83
+	int policy = SCHED_RR;
44ca83
+	const char *spolicy = "Round Robin";
44ca83
 
44ca83
+	if (strcasecmp(sched_policy, "fifo") == 0) {
44ca83
+		policy = SCHED_FIFO;
44ca83
+		spolicy = "FIFO";
44ca83
+	}
44ca83
 	if (sched_getparam(0, &sched_param) < 0) {
44ca83
 		printf("Scheduler getparam failed...\n");
44ca83
 		return;
44ca83
 	}
44ca83
-	sched_param.sched_priority = sched_get_priority_max(SCHED_RR);
44ca83
-	if (!sched_setscheduler(0, SCHED_RR, &sched_param)) {
44ca83
-		printf("Scheduler set to Round Robin with priority %i...\n", sched_param.sched_priority);
44ca83
+	sched_param.sched_priority = sched_get_priority_max(policy);
44ca83
+	if (!sched_setscheduler(0, policy, &sched_param)) {
44ca83
+		printf("Scheduler set to %s with priority %i...\n", spolicy, sched_param.sched_priority);
44ca83
 		fflush(stdout);
44ca83
 		return;
44ca83
 	}
44ca83
-	printf("!!!Scheduler set to Round Robin with priority %i FAILED!!!\n", sched_param.sched_priority);
44ca83
+	printf("!!!Scheduler set to %s with priority %i FAILED!!!\n", spolicy, sched_param.sched_priority);
44ca83
 }
44ca83
 
44ca83
 long timediff(snd_timestamp_t t1, snd_timestamp_t t2)
44ca83
@@ -515,6 +522,7 @@ void help(void)
44ca83
 "-e,--effect    apply an effect (bandpass filter sweep)\n"
44ca83
 "-x,--posdump   dump buffer positions\n"
44ca83
 "-X,--realtime  do a realtime check (buffering)\n"
44ca83
+"-O,--policy    set scheduler policy (RR or FIFO)\n"
44ca83
 );
44ca83
         printf("Recognized sample formats are:");
44ca83
         for (k = 0; k < SND_PCM_FORMAT_LAST; ++k) {
44ca83
@@ -555,6 +563,7 @@ int main(int argc, char *argv[])
44ca83
 		{"effect", 0, NULL, 'e'},
44ca83
 		{"posdump", 0, NULL, 'x'},
44ca83
 		{"realtime", 0, NULL, 'X'},
44ca83
+		{"policy", 1, NULL, 'O'},
44ca83
 		{NULL, 0, NULL, 0},
44ca83
 	};
44ca83
 	snd_pcm_t *phandle, *chandle;
44ca83
@@ -569,7 +578,7 @@ int main(int argc, char *argv[])
44ca83
 	morehelp = 0;
44ca83
 	while (1) {
44ca83
 		int c;
44ca83
-		if ((c = getopt_long(argc, argv, "hP:C:m:M:U:F:f:c:r:B:E:s:y:bpenxX", long_option, NULL)) < 0)
44ca83
+		if ((c = getopt_long(argc, argv, "hP:C:m:M:U:F:f:c:r:B:E:s:y:O:bpenxX", long_option, NULL)) < 0)
44ca83
 			break;
44ca83
 		switch (c) {
44ca83
 		case 'h':
44ca83
@@ -643,6 +652,9 @@ int main(int argc, char *argv[])
44ca83
 		case 'X':
44ca83
 			realtime_check = 1;
44ca83
 			break;
44ca83
+		case 'O':
44ca83
+			sched_policy = optarg;
44ca83
+			break;
44ca83
 		}
44ca83
 	}
44ca83
 
44ca83
-- 
44ca83
2.39.0
44ca83
44ca83
44ca83
From 75f8e2e73e03f628a4f2ba55ca8aa3e9f50cdbd9 Mon Sep 17 00:00:00 2001
44ca83
From: Jaroslav Kysela <perex@perex.cz>
44ca83
Date: Thu, 24 Nov 2022 10:55:32 +0100
44ca83
Subject: [PATCH 15/20] test: latency - --policy option - allow using
44ca83
 SCHED_OTHER
44ca83
44ca83
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
44ca83
---
44ca83
 test/latency.c | 5 ++++-
44ca83
 1 file changed, 4 insertions(+), 1 deletion(-)
44ca83
44ca83
diff --git a/test/latency.c b/test/latency.c
44ca83
index 3b20e1c1..5e67015c 100644
44ca83
--- a/test/latency.c
44ca83
+++ b/test/latency.c
44ca83
@@ -361,6 +361,9 @@ void setscheduler(void)
44ca83
 	if (strcasecmp(sched_policy, "fifo") == 0) {
44ca83
 		policy = SCHED_FIFO;
44ca83
 		spolicy = "FIFO";
44ca83
+	} else if (strcasecmp(sched_policy, "other") == 0) {
44ca83
+		policy = SCHED_OTHER;
44ca83
+		spolicy = "OTHER";
44ca83
 	}
44ca83
 	if (sched_getparam(0, &sched_param) < 0) {
44ca83
 		printf("Scheduler getparam failed...\n");
44ca83
@@ -522,7 +525,7 @@ void help(void)
44ca83
 "-e,--effect    apply an effect (bandpass filter sweep)\n"
44ca83
 "-x,--posdump   dump buffer positions\n"
44ca83
 "-X,--realtime  do a realtime check (buffering)\n"
44ca83
-"-O,--policy    set scheduler policy (RR or FIFO)\n"
44ca83
+"-O,--policy    set scheduler policy (RR, FIFO or OTHER)\n"
44ca83
 );
44ca83
         printf("Recognized sample formats are:");
44ca83
         for (k = 0; k < SND_PCM_FORMAT_LAST; ++k) {
44ca83
-- 
44ca83
2.39.0
44ca83
44ca83
44ca83
From d28e8cb29485cc93f741b01dc65893c798359963 Mon Sep 17 00:00:00 2001
44ca83
From: Jaroslav Kysela <perex@perex.cz>
44ca83
Date: Tue, 29 Nov 2022 19:42:13 +0100
44ca83
Subject: [PATCH 16/20] topology: ctl - remove the wrong (debug) code
44ca83
44ca83
This code was commited by mistake. It was used for testing
44ca83
of ALSA_PCM_OLD_HW/SW_PARAMS_API.
44ca83
44ca83
BugLink: https://github.com/thesofproject/sof/issues/6667
44ca83
Related-to: 78b20e3c ("test: latency - use snd_pcm_format_physical_width()")
44ca83
Reported-by: Jaska Uimonen <jaska.uimonen@linux.intel.com>
44ca83
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
44ca83
---
44ca83
 src/topology/ctl.c | 7 +------
44ca83
 1 file changed, 1 insertion(+), 6 deletions(-)
44ca83
44ca83
diff --git a/src/topology/ctl.c b/src/topology/ctl.c
44ca83
index 2c500ffc..dd05424d 100644
44ca83
--- a/src/topology/ctl.c
44ca83
+++ b/src/topology/ctl.c
44ca83
@@ -17,13 +17,9 @@
44ca83
            Liam Girdwood <liam.r.girdwood@linux.intel.com>
44ca83
 */
44ca83
 
44ca83
-#define ALSA_PCM_OLD_HW_PARAMS_API 1
44ca83
-#define ALSA_PCM_OLD_SW_PARAMS_API 1
44ca83
-#include "../../include/asoundlib.h"
44ca83
 #include "list.h"
44ca83
 #include "tplg_local.h"
44ca83
 
44ca83
-
44ca83
 #define ENUM_VAL_SIZE 	(SNDRV_CTL_ELEM_ID_NAME_MAXLEN >> 2)
44ca83
 
44ca83
 struct ctl_access_elem {
44ca83
@@ -75,8 +71,7 @@ static int parse_access_values(snd_config_t *cfg,
44ca83
 			}
44ca83
 		}
44ca83
 	}
44ca83
-	return snd_pcm_hw_params_get_channels(NULL);
44ca83
-	//return snd_pcm_hw_params_get_access(NULL);
44ca83
+
44ca83
 	return 0;
44ca83
 }
44ca83
 
44ca83
-- 
44ca83
2.39.0
44ca83
44ca83
44ca83
From e29413a2205099b2bffe584210d7a2b59f531f90 Mon Sep 17 00:00:00 2001
44ca83
From: Jaroslav Kysela <perex@perex.cz>
44ca83
Date: Wed, 7 Dec 2022 14:49:48 +0100
44ca83
Subject: [PATCH 17/20] ucm: execute_sysw - fix possible use-after-free
44ca83
44ca83
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
44ca83
---
44ca83
 src/ucm/main.c | 5 +++--
44ca83
 1 file changed, 3 insertions(+), 2 deletions(-)
44ca83
44ca83
diff --git a/src/ucm/main.c b/src/ucm/main.c
44ca83
index 4f36648c..2ff4d3f3 100644
44ca83
--- a/src/ucm/main.c
44ca83
+++ b/src/ucm/main.c
44ca83
@@ -572,16 +572,17 @@ static int execute_sysw(const char *sysw)
44ca83
 	wlen = write(fd, value, len);
44ca83
 	myerrno = errno;
44ca83
 	close(fd);
44ca83
-	free(s);
44ca83
 
44ca83
 	if (ignore_error)
44ca83
-		return 0;
44ca83
+		goto __end;
44ca83
 
44ca83
 	if (wlen != (ssize_t)len) {
44ca83
 		uc_error("unable to write '%s' to '%s': %s", value, path, strerror(myerrno));
44ca83
 		return -EINVAL;
44ca83
 	}
44ca83
 
44ca83
+__end:
44ca83
+	free(s);
44ca83
 	return 0;
44ca83
 }
44ca83
 
44ca83
-- 
44ca83
2.39.0
44ca83
44ca83
44ca83
From 13e31fb1ecd5f666ffda09e87ef1aa53b4fae022 Mon Sep 17 00:00:00 2001
44ca83
From: Jaroslav Kysela <perex@perex.cz>
44ca83
Date: Wed, 7 Dec 2022 14:54:30 +0100
44ca83
Subject: [PATCH 18/20] alsa-lib: conf - fix possible use-after-free in
44ca83
 get_char_skip_comments
44ca83
44ca83
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
44ca83
---
44ca83
 src/conf.c | 3 ++-
44ca83
 1 file changed, 2 insertions(+), 1 deletion(-)
44ca83
44ca83
diff --git a/src/conf.c b/src/conf.c
44ca83
index eb38c344..65f2e1a7 100644
44ca83
--- a/src/conf.c
44ca83
+++ b/src/conf.c
44ca83
@@ -814,11 +814,12 @@ static int get_char_skip_comments(input_t *input)
44ca83
 				closedir(dirp);
44ca83
 
44ca83
 				err = add_include_path(input->current, str);
44ca83
-				free(str);
44ca83
 				if (err < 0) {
44ca83
 					SNDERR("Cannot add search dir %s", str);
44ca83
+					free(str);
44ca83
 					return err;
44ca83
 				}
44ca83
+				free(str);
44ca83
 				continue;
44ca83
 			}
44ca83
 
44ca83
-- 
44ca83
2.39.0
44ca83
44ca83
44ca83
From 9f2c68cef716aa45942b502a42d94b84289f23bc Mon Sep 17 00:00:00 2001
44ca83
From: Jaroslav Kysela <perex@perex.cz>
44ca83
Date: Tue, 13 Dec 2022 10:31:32 +0100
44ca83
Subject: [PATCH 19/20] pcm: route/softvol use snd_config_get_ireal vs get_real
44ca83
 to handle also integers
44ca83
44ca83
Link: https://lore.kernel.org/alsa-devel/f9a7ad6a256d4ad7a31642dcf875d436@axis.com/
44ca83
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
44ca83
---
44ca83
 src/pcm/pcm_route.c   | 11 +++--------
44ca83
 src/pcm/pcm_softvol.c |  4 ++--
44ca83
 2 files changed, 5 insertions(+), 10 deletions(-)
44ca83
44ca83
diff --git a/src/pcm/pcm_route.c b/src/pcm/pcm_route.c
44ca83
index d3e5f3ff..21b869cc 100644
44ca83
--- a/src/pcm/pcm_route.c
44ca83
+++ b/src/pcm/pcm_route.c
44ca83
@@ -1182,15 +1182,10 @@ static int _snd_pcm_route_load_ttable(snd_config_t *tt, snd_pcm_route_ttable_ent
44ca83
 				return -EINVAL;
44ca83
 			}
44ca83
 
44ca83
-			err = snd_config_get_real(jnode, &value);
44ca83
+			err = snd_config_get_ireal(jnode, &value);
44ca83
 			if (err < 0) {
44ca83
-				long v;
44ca83
-				err = snd_config_get_integer(jnode, &v);
44ca83
-				if (err < 0) {
44ca83
-					SNDERR("Invalid type for %s", id);
44ca83
-					return -EINVAL;
44ca83
-				}
44ca83
-				value = v;
44ca83
+				SNDERR("Invalid type for %s", id);
44ca83
+				return -EINVAL;
44ca83
 			}
44ca83
 
44ca83
 			for (k = 0; (int) k < ss; k++) {
44ca83
diff --git a/src/pcm/pcm_softvol.c b/src/pcm/pcm_softvol.c
44ca83
index 99d0d32e..3e3dbc79 100644
44ca83
--- a/src/pcm/pcm_softvol.c
44ca83
+++ b/src/pcm/pcm_softvol.c
44ca83
@@ -1190,7 +1190,7 @@ int _snd_pcm_softvol_open(snd_pcm_t **pcmp, const char *name,
44ca83
 			continue;
44ca83
 		}
44ca83
 		if (strcmp(id, "min_dB") == 0) {
44ca83
-			err = snd_config_get_real(n, &min_dB);
44ca83
+			err = snd_config_get_ireal(n, &min_dB);
44ca83
 			if (err < 0) {
44ca83
 				SNDERR("Invalid min_dB value");
44ca83
 				return err;
44ca83
@@ -1198,7 +1198,7 @@ int _snd_pcm_softvol_open(snd_pcm_t **pcmp, const char *name,
44ca83
 			continue;
44ca83
 		}
44ca83
 		if (strcmp(id, "max_dB") == 0) {
44ca83
-			err = snd_config_get_real(n, &max_dB);
44ca83
+			err = snd_config_get_ireal(n, &max_dB);
44ca83
 			if (err < 0) {
44ca83
 				SNDERR("Invalid max_dB value");
44ca83
 				return err;
44ca83
-- 
44ca83
2.39.0
44ca83
44ca83
44ca83
From 2e82060ebcd68f5ea1fe3dccc5a6518008132a54 Mon Sep 17 00:00:00 2001
44ca83
From: Alan Young <consult.awy@gmail.com>
44ca83
Date: Fri, 30 Dec 2022 16:48:14 +0000
44ca83
Subject: [PATCH 20/20] pcm: rate: fix last_commit_ptr boundary wrapping
44ca83
44ca83
Wrap last_commit_ptr using boundary. Was just wrapped to 0, which is
44ca83
correct only if the buffer size, and hence the boundary, is an integer
44ca83
multiple of the period size.
44ca83
44ca83
Fixes: 467d69c5bc1 ("Fix CPU hog with combination of rate plugin")
44ca83
Fixes: 29041c52207 ("fix infinite draining of the rate plugin in SND_PCM_NONBLOCK mode")
44ca83
Link: https://lore.kernel.org/alsa-devel/20221230164814.901457-1-consult.awy@gmail.com/
44ca83
Signed-off-by: Alan Young <consult.awy@gmail.com>
44ca83
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
44ca83
---
44ca83
 src/pcm/pcm_rate.c | 4 ++--
44ca83
 1 file changed, 2 insertions(+), 2 deletions(-)
44ca83
44ca83
diff --git a/src/pcm/pcm_rate.c b/src/pcm/pcm_rate.c
44ca83
index e5d8eddd..c8076859 100644
44ca83
--- a/src/pcm/pcm_rate.c
44ca83
+++ b/src/pcm/pcm_rate.c
44ca83
@@ -1018,7 +1018,7 @@ static int snd_pcm_rate_sync_playback_area(snd_pcm_t *pcm, snd_pcm_uframes_t app
44ca83
 		slave_size -= rate->gen.slave->period_size;
44ca83
 		rate->last_commit_ptr += pcm->period_size;
44ca83
 		if (rate->last_commit_ptr >= pcm->boundary)
44ca83
-			rate->last_commit_ptr = 0;
44ca83
+			rate->last_commit_ptr -= pcm->boundary;
44ca83
 	}
44ca83
 	return 0;
44ca83
 }
44ca83
@@ -1163,7 +1163,7 @@ static int snd_pcm_rate_drain(snd_pcm_t *pcm)
44ca83
 			if (commit_err == 1) {
44ca83
 				rate->last_commit_ptr += psize;
44ca83
 				if (rate->last_commit_ptr >= pcm->boundary)
44ca83
-					rate->last_commit_ptr = 0;
44ca83
+					rate->last_commit_ptr -= pcm->boundary;
44ca83
 			} else if (commit_err == 0) {
44ca83
 				if (pcm->mode & SND_PCM_NONBLOCK) {
44ca83
 					commit_err = -EAGAIN;
44ca83
-- 
44ca83
2.39.0
44ca83