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