Sophie

Sophie

distrib > Mandriva > 2010.1 > i586 > by-pkgid > 4ff5c7c7f42d365d2ec63adbf5a8dced > files > 1

libalsa2-1.0.23-2.0.2mdv2010.1.src.rpm

From 8cf0dd2021c9003e3a3dae96dad3ccb25ee38f12 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Wed, 11 Aug 2010 19:45:40 +0200
Subject: [PATCH 100/101] pcm: add defaults.pcm.minperiodtime parsing

Some broken applications like Audacious don't set any timing parameters.
While the alsa-lib behaviour is to select the smallest period size and
biggest buffer size, the result is the generation of thousands
interrupts per second.

The default value in alsa.conf is 5000usec.

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
 src/conf/alsa.conf   |    1 +
 src/pcm/pcm.c        |    8 +++++++-
 src/pcm/pcm_local.h  |    1 +
 src/pcm/pcm_params.c |   13 ++++++++++++-
 4 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/src/conf/alsa.conf b/src/conf/alsa.conf
index db64259..5160529 100644
--- a/src/conf/alsa.conf
+++ b/src/conf/alsa.conf
@@ -63,6 +63,7 @@ defaults.pcm.card 0
 defaults.pcm.device 0
 defaults.pcm.subdevice -1
 defaults.pcm.nonblock 1
+defaults.pcm.minperiodtime 5000		# in us
 defaults.pcm.ipc_key 5678293
 defaults.pcm.ipc_gid audio
 defaults.pcm.ipc_perm 0660
diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c
index f910189..f3c2f74 100644
--- a/src/pcm/pcm.c
+++ b/src/pcm/pcm.c
@@ -2058,7 +2058,7 @@ static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name,
 	const char *str;
 	char *buf = NULL, *buf1 = NULL;
 	int err;
-	snd_config_t *conf, *type_conf = NULL;
+	snd_config_t *conf, *type_conf = NULL, *tmp;
 	snd_config_iterator_t i, next;
 	const char *id;
 	const char *lib = NULL, *open_name = NULL;
@@ -2191,6 +2191,12 @@ static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name,
 				snd_dlclose(h);
 		}
 	}
+	if (err >= 0) {
+		err = snd_config_search(pcm_root, "defaults.pcm.minperiodtime", &tmp);
+		if (err >= 0)
+			snd_config_get_integer(tmp, &(*pcmp)->minperiodtime);
+		err = 0;
+	}
 	if (type_conf)
 		snd_config_delete(type_conf);
 	free(buf);
diff --git a/src/pcm/pcm_local.h b/src/pcm/pcm_local.h
index 9aa81e1..dda970c 100644
--- a/src/pcm/pcm_local.h
+++ b/src/pcm/pcm_local.h
@@ -179,6 +179,7 @@ struct _snd_pcm {
 	snd_pcm_type_t type;
 	snd_pcm_stream_t stream;
 	int mode;
+	long minperiodtime;		/* in us */
 	int poll_fd_count;
 	int poll_fd;
 	unsigned short poll_events;
diff --git a/src/pcm/pcm_params.c b/src/pcm/pcm_params.c
index 0e1c3fc..6120677 100644
--- a/src/pcm/pcm_params.c
+++ b/src/pcm/pcm_params.c
@@ -1102,8 +1102,19 @@ static int snd_pcm_hw_params_choose(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
 	if (err < 0)
 		return err;
 	err = snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_RATE, NULL, 0);
-	if (err < 0)
 		return err;
+	if (pcm->minperiodtime > 0) {
+		unsigned int min, max;
+		int dir = 1;
+		err = snd_pcm_hw_param_get_min(params, SND_PCM_HW_PARAM_PERIOD_TIME, &min, &dir);
+		if (err >= 0)
+			err = snd_pcm_hw_param_get_max(params, SND_PCM_HW_PARAM_PERIOD_TIME, &max, &dir);
+		if (err >= 0 && (long)min < pcm->minperiodtime &&
+			        (long)max > pcm->minperiodtime) {
+			min = pcm->minperiodtime; dir = 1;
+			snd_pcm_hw_param_set_min(pcm, params, SND_CHANGE, SND_PCM_HW_PARAM_PERIOD_TIME, &min, &dir);
+		}
+	}
 	if (compat && *compat) {
 		/* old mode */
 		err = snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_PERIOD_TIME, NULL, 0);
-- 
1.7.2.2