Accepting request 59786 from multimedia:libs

Accepted submit request 59786 from user tiwai

OBS-URL: https://build.opensuse.org/request/show/59786
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/alsa?expand=0&rev=96
This commit is contained in:
Ruediger Oertel 2011-02-03 00:25:55 +00:00 committed by Git OBS Bridge
commit 56214dc5f1
41 changed files with 39 additions and 2772 deletions

View File

@ -1,29 +0,0 @@
From 51ef640cee37f73d771e784e81196ff7c15f53ff Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Denis-Courmont?= <remi@remlab.net>
Date: Wed, 21 Apr 2010 18:37:47 +0200
Subject: [PATCH 01/21] Check for thread-specific locale support
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Rémi Denis-Courmont <remi@remlab.net>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
configure.in | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/configure.in b/configure.in
index f6df502..abc4687 100644
--- a/configure.in
+++ b/configure.in
@@ -64,6 +64,7 @@ dnl Checks for library functions.
AC_PROG_GCC_TRADITIONAL
AC_CHECK_FUNC([hsearch_r], [HAVE_HSEARCH_R=yes])
AM_CONDITIONAL(ALSA_HSEARCH_R, [test "x$HAVE_HSEARCH_R" != xyes])
+AC_CHECK_FUNCS([uselocale])
SAVE_LIBRARY_VERSION
AC_SUBST(LIBTOOL_VERSION_INFO)
--
1.7.2.1

View File

@ -1,66 +0,0 @@
From 8d80d5f344ae5e32d24122cbf8e759fdd1e1a60d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Denis-Courmont?= <remi@remlab.net>
Date: Wed, 21 Apr 2010 18:37:48 +0200
Subject: [PATCH 02/21] Use thread-safe locale functions if available
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
setlocale() is not thread-safe. It can actually trigger a crash if
another thread uses locale informations at the same time in the process.
Library code should use POSIX newlocale/duplocale/uselocale/freelocale
instead. Those functions only change the locale data for the calling
thread.
Signed-off-by: Rémi Denis-Courmont <remi@remlab.net>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
src/conf.c | 16 ++++++++++++++++
1 files changed, 16 insertions(+), 0 deletions(-)
diff --git a/src/conf.c b/src/conf.c
index 570c90f..5d8c5c9 100644
--- a/src/conf.c
+++ b/src/conf.c
@@ -499,22 +499,38 @@ static int safe_strtod(const char *str, double *val)
{
char *end;
double v;
+#ifdef HAVE_USELOCALE
+ locale_t saved_locale, c_locale;
+#else
char *saved_locale;
char locstr[64]; /* enough? */
+#endif
int err;
if (!*str)
return -EINVAL;
+#ifdef HAVE_USELOCALE
+ c_locale = newlocale(LC_NUMERIC_MASK, "C", 0);
+ saved_locale = uselocale(c_locale);
+#else
saved_locale = setlocale(LC_NUMERIC, NULL);
if (saved_locale) {
snprintf(locstr, sizeof(locstr), "%s", saved_locale);
setlocale(LC_NUMERIC, "C");
}
+#endif
errno = 0;
v = strtod(str, &end);
err = -errno;
+#ifdef HAVE_USELOCALE
+ if (c_locale != (locale_t)0) {
+ uselocale(saved_locale);
+ freelocale(c_locale);
+ }
+#else
if (saved_locale)
setlocale(LC_NUMERIC, locstr);
+#endif
if (err)
return err;
if (*end)
--
1.7.2.1

View File

@ -1,35 +0,0 @@
From 19892334499ed21ed4dc30084ad8700253f9cb2f Mon Sep 17 00:00:00 2001
From: Pedro Lopez-Cabanillas <pedro.lopez.cabanillas@gmail.com>
Date: Thu, 22 Apr 2010 15:42:20 +0200
Subject: [PATCH 03/21] seq: Fix for snd_seq_parse_address()
snd_seq_parse_address() uses strncmp() to compare the client name
in the string argument with the existing clients, until it finds one
name matching the same leading characters. This may produce wrong
results when there are two sequencer clients with similar names.
Example: "KMidimon" : "Kmid"
Signed-off-by: Pedro Lopez-Cabanillas <pedro.lopez.cabanillas@gmail.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
src/seq/seqmid.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/src/seq/seqmid.c b/src/seq/seqmid.c
index 86a4970..894c3a2 100644
--- a/src/seq/seqmid.c
+++ b/src/seq/seqmid.c
@@ -414,7 +414,8 @@ int snd_seq_parse_address(snd_seq_t *seq, snd_seq_addr_t *addr, const char *arg)
return -EINVAL;
cinfo.client = -1;
while (snd_seq_query_next_client(seq, &cinfo) >= 0) {
- if (! strncmp(arg, cinfo.name, len)) {
+ if ((strlen(cinfo.name) == len) &&
+ ! strncmp(arg, cinfo.name, len)) {
addr->client = cinfo.client;
return 0;
}
--
1.7.2.1

View File

@ -1,52 +0,0 @@
From 30ad5ed04017f7e77b25cf40f18c26396903cd23 Mon Sep 17 00:00:00 2001
From: Peter Ujfalusi <peter.ujfalusi@nokia.com>
Date: Wed, 19 May 2010 08:19:26 +0200
Subject: [PATCH 04/21] control: tlv: Check dB range only within the control's volume range
The DB_RANGE need to be used on some HW, since the gain on
volume control is not continuous, and has to be divided into
several sub DB_SCALE ranges.
ASoC has a feature to override the HW default volume range,
and in this case when the volume range is less than the
HW maximum we do not need to go through the whole DB_RANGE,
but we need to stop where the kcontrol's maximum tell us.
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@nokia.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
src/control/tlv.c | 11 ++++++++---
1 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/src/control/tlv.c b/src/control/tlv.c
index cfd9b97..0ff052e 100644
--- a/src/control/tlv.c
+++ b/src/control/tlv.c
@@ -140,10 +140,13 @@ int snd_tlv_get_dB_range(unsigned int *tlv, long rangemin, long rangemax,
pos = 2;
while (pos + 4 <= len) {
long rmin, rmax;
- rangemin = (int)tlv[pos];
- rangemax = (int)tlv[pos + 1];
+ long submin, submax;
+ submin = (int)tlv[pos];
+ submax = (int)tlv[pos + 1];
+ if (rangemax < submax)
+ submax = rangemax;
err = snd_tlv_get_dB_range(tlv + pos + 2,
- rangemin, rangemax,
+ submin, submax,
&rmin, &rmax);
if (err < 0)
return err;
@@ -156,6 +159,8 @@ int snd_tlv_get_dB_range(unsigned int *tlv, long rangemin, long rangemax,
*min = rmin;
*max = rmax;
}
+ if (rangemax == submax)
+ return 0;
pos += int_index(tlv[pos + 3]) + 4;
}
return 0;
--
1.7.2.1

View File

@ -1,26 +0,0 @@
From 191c57805a791925ab5992f127a1cb5f4ab56c9c Mon Sep 17 00:00:00 2001
From: Colin Guthrie <cguthrie@mandriva.org>
Date: Sun, 28 Feb 2010 22:25:26 +0000
Subject: [PATCH 05/21] alisp - Fix a string format ambiguity
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
src/alisp/alisp.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/alisp/alisp.c b/src/alisp/alisp.c
index f3580f9..7575f55 100644
--- a/src/alisp/alisp.c
+++ b/src/alisp/alisp.c
@@ -1712,7 +1712,7 @@ static struct alisp_object * F_princ(struct alisp_instance *instance, struct ali
delete_tree(instance, p1);
p1 = eval(instance, car(p));
if (alisp_compare_type(p1, ALISP_OBJ_STRING))
- snd_output_printf(instance->out, p1->value.s);
+ snd_output_printf(instance->out, "%s", p1->value.s);
else
princ_object(instance->out, p1);
n = cdr(p);
--
1.7.2.1

View File

@ -1,49 +0,0 @@
From 16a2cad39b7ee29e34b92d39d72eebfc88f8dc22 Mon Sep 17 00:00:00 2001
From: Peter Ujfalusi <peter.ujfalusi@nokia.com>
Date: Tue, 20 Jul 2010 10:34:52 +0300
Subject: [PATCH 06/21] tlv: Check out of range dB with SND_CTL_TLVT_DB_RANGE
When converting from dB value to raw value, the control's
full range was not checked in case of SND_CTL_TLVT_DB_RANGE.
Check out of range dB values, and return apropriate raw
value for the caller.
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@nokia.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
src/control/tlv.c | 12 +++++++++++-
1 files changed, 11 insertions(+), 1 deletions(-)
diff --git a/src/control/tlv.c b/src/control/tlv.c
index 0ff052e..9f26f35 100644
--- a/src/control/tlv.c
+++ b/src/control/tlv.c
@@ -285,13 +285,23 @@ int snd_tlv_convert_from_dB(unsigned int *tlv, long rangemin, long rangemax,
{
switch (tlv[0]) {
case SND_CTL_TLVT_DB_RANGE: {
+ long dbmin, dbmax;
unsigned int pos, len;
len = int_index(tlv[1]);
if (len > MAX_TLV_RANGE_SIZE)
return -EINVAL;
+ if (snd_tlv_get_dB_range(tlv, rangemin, rangemax,
+ &dbmin, &dbmax))
+ return -EINVAL;
+ if (db_gain <= dbmin) {
+ *value = rangemin;
+ return 0;
+ } else if (db_gain >= dbmax) {
+ *value = rangemax;
+ return 0;
+ }
pos = 2;
while (pos + 4 <= len) {
- long dbmin, dbmax;
rangemin = (int)tlv[pos];
rangemax = (int)tlv[pos + 1];
if (!snd_tlv_get_dB_range(tlv + pos + 2,
--
1.7.2.1

View File

@ -1,76 +0,0 @@
From d81ce4ea7af917f992aa0529c29db590d566ae7a Mon Sep 17 00:00:00 2001
From: Peter Ujfalusi <peter.ujfalusi@nokia.com>
Date: Tue, 20 Jul 2010 10:34:53 +0300
Subject: [PATCH 07/21] tlv: Handle 'holes' in SND_CTL_TLVT_DB_RANGE array
When converting from dB to raw value, and DB_RANGE is
used with non overlapping map, dB value in between the
sub ranges will be not found.
For example, if the control has the following:
0: -10dB
1: -5dB
2: 0dB
3: 2dB
4: 4dB
static const unsigned int nonoverlapping_tlv[] = {
TLV_DB_RANGE_HEAD(2),
0, 2, TLV_DB_SCALE_ITEM(-1000, 500, 0),
3, 4, TLV_DB_SCALE_ITEM(200, 200, 0),
};
Range 1: -10 .. 0dB
Range 2: 2 .. 4dB
If user asks for 1dB the snd_tlv_convert_from_dB will not find
the raw value, since the 1dB is not part of either range.
To fix this, we will store the previous non maching range's
maximum raw value. If the dB value is not found in the next range,
we will check, if the requested dB value is in between the current
and the previous range, and if it is than pick the apropriate raw
value based on the xdir (up or down rounding).
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@nokia.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
src/control/tlv.c | 8 +++++++-
1 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/src/control/tlv.c b/src/control/tlv.c
index 9f26f35..49f9afe 100644
--- a/src/control/tlv.c
+++ b/src/control/tlv.c
@@ -285,7 +285,7 @@ int snd_tlv_convert_from_dB(unsigned int *tlv, long rangemin, long rangemax,
{
switch (tlv[0]) {
case SND_CTL_TLVT_DB_RANGE: {
- long dbmin, dbmax;
+ long dbmin, dbmax, prev_rangemax;
unsigned int pos, len;
len = int_index(tlv[1]);
if (len > MAX_TLV_RANGE_SIZE)
@@ -301,6 +301,7 @@ int snd_tlv_convert_from_dB(unsigned int *tlv, long rangemin, long rangemax,
return 0;
}
pos = 2;
+ prev_rangemax = 0;
while (pos + 4 <= len) {
rangemin = (int)tlv[pos];
rangemax = (int)tlv[pos + 1];
@@ -311,6 +312,11 @@ int snd_tlv_convert_from_dB(unsigned int *tlv, long rangemin, long rangemax,
return snd_tlv_convert_from_dB(tlv + pos + 2,
rangemin, rangemax,
db_gain, value, xdir);
+ else if (db_gain < dbmin) {
+ *value = xdir ? rangemin : prev_rangemax;
+ return 0;
+ }
+ prev_rangemax = rangemax;
pos += int_index(tlv[pos + 3]) + 4;
}
return -EINVAL;
--
1.7.2.1

View File

@ -1,31 +0,0 @@
From 2a94d80407f620c256021707503b14377d4701d1 Mon Sep 17 00:00:00 2001
From: Peter Ujfalusi <peter.ujfalusi@nokia.com>
Date: Tue, 20 Jul 2010 10:34:54 +0300
Subject: [PATCH 08/21] tlv: Remove tailing tab after snd_ctl_get_dB_range function
Cosmetic fix.
There was a tab instead of new line after snd_ctl_get_dB_range
function.
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@nokia.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
src/control/tlv.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/control/tlv.c b/src/control/tlv.c
index 49f9afe..ba52752 100644
--- a/src/control/tlv.c
+++ b/src/control/tlv.c
@@ -442,7 +442,7 @@ int snd_ctl_get_dB_range(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id,
return snd_tlv_get_dB_range(info.tlv, info.minval, info.maxval,
min, max);
}
-
+
/**
* \brief Convert the volume value to dB on the given control element
* \param ctl the control handler
--
1.7.2.1

View File

@ -1,30 +0,0 @@
From 8dde984237d9bce99236355b85df9c438badb59f Mon Sep 17 00:00:00 2001
From: John Lindgren <john.lindgren@tds.net>
Date: Wed, 21 Jul 2010 00:38:37 +0200
Subject: [PATCH 09/21] Memory leak in namehint.c
Get_card_name() can be called more than once on the same list, so it
must free the previous list->cardname before replacing it.
Signed-off-by: John Lindgren <john.lindgren@tds.net>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
src/control/namehint.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/src/control/namehint.c b/src/control/namehint.c
index 78572d8..1819292 100644
--- a/src/control/namehint.c
+++ b/src/control/namehint.c
@@ -471,6 +471,8 @@ static int get_card_name(struct hint_list *list, int card)
char scard[16], *s;
int err;
+ free(list->cardname);
+ list->cardname = NULL;
err = snd_card_get_name(card, &list->cardname);
if (err <= 0)
return 0;
--
1.7.2.1

View File

@ -1,26 +0,0 @@
From 3f589c9369a7514850e2f5afe4e9d486708f12ef Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Thu, 22 Jul 2010 11:33:20 +0200
Subject: [PATCH 10/21] pcm - ladspa: fix small memory leak in snd_pcm_ladspa_free_instances()
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
src/pcm/pcm_ladspa.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/src/pcm/pcm_ladspa.c b/src/pcm/pcm_ladspa.c
index 5161820..c413c10 100644
--- a/src/pcm/pcm_ladspa.c
+++ b/src/pcm/pcm_ladspa.c
@@ -341,6 +341,8 @@ static void snd_pcm_ladspa_free_instances(snd_pcm_t *pcm, snd_pcm_ladspa_t *lads
free(instance->output.m_data[idx]);
free(instance->output.m_data);
}
+ free(instance->input.data);
+ free(instance->output.data);
list_del(&(instance->list));
snd_pcm_ladspa_free_eps(&instance->input);
snd_pcm_ladspa_free_eps(&instance->output);
--
1.7.2.1

View File

@ -1,27 +0,0 @@
From db7545a077eecee0a8c32759ee77340f9e7c9d15 Mon Sep 17 00:00:00 2001
From: Anssi Hannula <anssi.hannula@iki.fi>
Date: Mon, 2 Aug 2010 18:50:08 +0300
Subject: [PATCH 11/21] pcm_plug: fix comparison always true
Signed-off-by: Anssi Hannula <anssi.hannula@iki.fi>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
src/pcm/pcm_plug.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/pcm/pcm_plug.c b/src/pcm/pcm_plug.c
index 967cf46..e9d2923 100644
--- a/src/pcm/pcm_plug.c
+++ b/src/pcm/pcm_plug.c
@@ -485,7 +485,7 @@ static int snd_pcm_plug_change_format(snd_pcm_t *pcm, snd_pcm_t **new, snd_pcm_p
/* No conversion is needed */
if (clt->format == slv->format &&
clt->rate == slv->rate &&
- clt->channels == clt->channels)
+ clt->channels == slv->channels)
return 0;
if (snd_pcm_format_linear(slv->format)) {
--
1.7.2.1

View File

@ -1,26 +0,0 @@
From eb3768563a29189156b7117d975930aee8133586 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Wed, 4 Aug 2010 19:47:01 +0200
Subject: [PATCH 12/21] test/latency: fix timediff calculation
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
test/latency.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/test/latency.c b/test/latency.c
index 304e012..03d65a2 100644
--- a/test/latency.c
+++ b/test/latency.c
@@ -321,7 +321,7 @@ long timediff(snd_timestamp_t t1, snd_timestamp_t t2)
l = (signed long) t1.tv_usec - (signed long) t2.tv_usec;
if (l < 0) {
t1.tv_sec--;
- l = -l;
+ l = 1000000 + l;
l %= 1000000;
}
return (t1.tv_sec * 1000000) + l;
--
1.7.2.1

View File

@ -1,166 +0,0 @@
From e6d5dcf1f625984605d362338d71162de45a6c60 Mon Sep 17 00:00:00 2001
From: Anssi Hannula <anssi.hannula@iki.fi>
Date: Tue, 3 Aug 2010 20:27:49 +0300
Subject: [PATCH 13/21] HDA-Intel: present all 4 HDMI outputs instead of just the first one
Commit 92608badc519a8c1f65d93743396517aaa582b53 in linux kernel added
the possibility of 3 additional HDMI devices on indexes 7-9.
Present all those additional devices using the "hdmi" alias as well.
Signed-off-by: Anssi Hannula <anssi.hannula@iki.fi>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
src/conf/cards/HDA-Intel.conf | 108 +++++++++++++++++++++++++++++++++++++++--
1 files changed, 104 insertions(+), 4 deletions(-)
diff --git a/src/conf/cards/HDA-Intel.conf b/src/conf/cards/HDA-Intel.conf
index d3ac002..726e8c9 100644
--- a/src/conf/cards/HDA-Intel.conf
+++ b/src/conf/cards/HDA-Intel.conf
@@ -142,11 +142,17 @@ HDA-Intel.pcm.iec958.0 {
<confdir:pcm/hdmi.conf>
-HDA-Intel.pcm.hdmi.0 {
- @args [ CARD AES0 AES1 AES2 AES3 ]
+HDA-Intel.pcm.hdmi.common {
+ @args [ CARD DEVICE CTLINDEX AES0 AES1 AES2 AES3 ]
@args.CARD {
type string
}
+ @args.DEVICE {
+ type integer
+ }
+ @args.CTLINDEX {
+ type integer
+ }
@args.AES0 {
type integer
}
@@ -163,26 +169,120 @@ HDA-Intel.pcm.hdmi.0 {
slave.pcm {
type hw
card $CARD
- device 3
+ device $DEVICE
}
hooks.0 {
type ctl_elems
hook_args [
{
name "IEC958 Playback Default"
+ index $CTLINDEX
lock true
preserve true
value [ $AES0 $AES1 $AES2 $AES3 ]
}
{
name "IEC958 Playback Switch"
+ index $CTLINDEX
lock true
preserve true
value true
}
]
}
- hint.device 3
+ hint.device $DEVICE
+}
+
+HDA-Intel.pcm.hdmi.0 {
+ @args [ CARD AES0 AES1 AES2 AES3 ]
+ @args.CARD { type string }
+ @args.AES0 { type integer }
+ @args.AES1 { type integer }
+ @args.AES2 { type integer }
+ @args.AES3 { type integer }
+ @func refer
+ name {
+ @func concat
+ strings [
+ "cards.HDA-Intel.pcm.hdmi.common:"
+ "CARD=" $CARD ","
+ "DEVICE=3,"
+ "CTLINDEX=0,"
+ "AES0=" $AES0 ","
+ "AES1=" $AES1 ","
+ "AES2=" $AES2 ","
+ "AES3=" $AES3
+ ]
+ }
+}
+
+HDA-Intel.pcm.hdmi.1 {
+ @args [ CARD AES0 AES1 AES2 AES3 ]
+ @args.CARD { type string }
+ @args.AES0 { type integer }
+ @args.AES1 { type integer }
+ @args.AES2 { type integer }
+ @args.AES3 { type integer }
+ @func refer
+ name {
+ @func concat
+ strings [
+ "cards.HDA-Intel.pcm.hdmi.common:"
+ "CARD=" $CARD ","
+ "DEVICE=7,"
+ "CTLINDEX=1,"
+ "AES0=" $AES0 ","
+ "AES1=" $AES1 ","
+ "AES2=" $AES2 ","
+ "AES3=" $AES3
+ ]
+ }
+}
+
+HDA-Intel.pcm.hdmi.2 {
+ @args [ CARD AES0 AES1 AES2 AES3 ]
+ @args.CARD { type string }
+ @args.AES0 { type integer }
+ @args.AES1 { type integer }
+ @args.AES2 { type integer }
+ @args.AES3 { type integer }
+ @func refer
+ name {
+ @func concat
+ strings [
+ "cards.HDA-Intel.pcm.hdmi.common:"
+ "CARD=" $CARD ","
+ "DEVICE=8,"
+ "CTLINDEX=2,"
+ "AES0=" $AES0 ","
+ "AES1=" $AES1 ","
+ "AES2=" $AES2 ","
+ "AES3=" $AES3
+ ]
+ }
+}
+
+HDA-Intel.pcm.hdmi.3 {
+ @args [ CARD AES0 AES1 AES2 AES3 ]
+ @args.CARD { type string }
+ @args.AES0 { type integer }
+ @args.AES1 { type integer }
+ @args.AES2 { type integer }
+ @args.AES3 { type integer }
+ @func refer
+ name {
+ @func concat
+ strings [
+ "cards.HDA-Intel.pcm.hdmi.common:"
+ "CARD=" $CARD ","
+ "DEVICE=9,"
+ "CTLINDEX=3,"
+ "AES0=" $AES0 ","
+ "AES1=" $AES1 ","
+ "AES2=" $AES2 ","
+ "AES3=" $AES3
+ ]
+ }
}
<confdir:pcm/modem.conf>
--
1.7.2.1

View File

@ -1,98 +0,0 @@
From 09879a4bb58199f64abcb8df506f917c8efc2383 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Wed, 11 Aug 2010 19:45:40 +0200
Subject: [PATCH 14/21] 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.1

View File

@ -1,91 +0,0 @@
From de606e9c256f5a776c1625b174600a539007f38d Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Wed, 11 Aug 2010 20:20:40 +0200
Subject: [PATCH 15/21] pcm: introduce defaults.pcm.compat to change the params choose behaviour
Having getenv directly in the function is not a good idea. Allow
configuration of the behaviour change in snd_pcm_param_choose() function
using alsa.conf. Use the environment variable LIBASOUND_COMPAT only
as fallback.
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
src/conf/alsa.conf | 1 +
src/pcm/pcm.c | 12 ++++++++++++
src/pcm/pcm_local.h | 3 ++-
src/pcm/pcm_params.c | 3 +--
4 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/src/conf/alsa.conf b/src/conf/alsa.conf
index 5160529..1889f01 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.compat 0
defaults.pcm.minperiodtime 5000 # in us
defaults.pcm.ipc_key 5678293
defaults.pcm.ipc_gid audio
diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c
index f3c2f74..8a4bc6a 100644
--- a/src/pcm/pcm.c
+++ b/src/pcm/pcm.c
@@ -2192,6 +2192,18 @@ static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name,
}
}
if (err >= 0) {
+ err = snd_config_search(pcm_root, "defaults.pcm.compat", &tmp);
+ if (err >= 0) {
+ long i;
+ if (snd_config_get_integer(tmp, &i) >= 0) {
+ if (i > 0)
+ (*pcmp)->compat = 1;
+ }
+ } else {
+ char *str = getenv("LIBASOUND_COMPAT");
+ if (str && *str)
+ (*pcmp)->compat = 1;
+ }
err = snd_config_search(pcm_root, "defaults.pcm.minperiodtime", &tmp);
if (err >= 0)
snd_config_get_integer(tmp, &(*pcmp)->minperiodtime);
diff --git a/src/pcm/pcm_local.h b/src/pcm/pcm_local.h
index dda970c..16069b6 100644
--- a/src/pcm/pcm_local.h
+++ b/src/pcm/pcm_local.h
@@ -184,7 +184,8 @@ struct _snd_pcm {
int poll_fd;
unsigned short poll_events;
int setup: 1,
- monotonic: 1;
+ monotonic: 1,
+ compat: 1;
snd_pcm_access_t access; /* access mode */
snd_pcm_format_t format; /* SND_PCM_FORMAT_* */
snd_pcm_subformat_t subformat; /* subformat */
diff --git a/src/pcm/pcm_params.c b/src/pcm/pcm_params.c
index 6120677..c7c3b97 100644
--- a/src/pcm/pcm_params.c
+++ b/src/pcm/pcm_params.c
@@ -1081,7 +1081,6 @@ int snd_pcm_hw_param_never_eq(const snd_pcm_hw_params_t *params,
static int snd_pcm_hw_params_choose(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
{
int err;
- const char *compat = getenv("LIBASOUND_COMPAT");
#ifdef CHOOSE_DEBUG
snd_output_t *log;
snd_output_stdio_attach(&log, stderr, 0);
@@ -1115,7 +1114,7 @@ static int snd_pcm_hw_params_choose(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
snd_pcm_hw_param_set_min(pcm, params, SND_CHANGE, SND_PCM_HW_PARAM_PERIOD_TIME, &min, &dir);
}
}
- if (compat && *compat) {
+ if (pcm->compat) {
/* old mode */
err = snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_PERIOD_TIME, NULL, 0);
if (err < 0)
--
1.7.2.1

View File

@ -1,25 +0,0 @@
From 0633a966362ce231392ff6283c99142c5bccc1c8 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Thu, 12 Aug 2010 08:21:26 +0200
Subject: [PATCH 16/21] pcm: Fixed typo (wrong deleted line) instroduced in the minperiodsize patch
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
src/pcm/pcm_params.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/src/pcm/pcm_params.c b/src/pcm/pcm_params.c
index c7c3b97..3a90bcd 100644
--- a/src/pcm/pcm_params.c
+++ b/src/pcm/pcm_params.c
@@ -1101,6 +1101,7 @@ 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;
--
1.7.2.1

View File

@ -1,112 +0,0 @@
From 18b377dec2aa728d52dae55a19bbea35e231a1ef Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai@suse.de>
Date: Fri, 13 Aug 2010 16:11:36 +0200
Subject: [PATCH 17/21] Add missing support for 3-byte formats for 16bit put conversion
In the put conversion, the support for 3-byte formats was missing.
This resulted in inaudible volume with rate plugin & co.
Typos fixed by Mark Hills <mark@pogo.org.uk>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
src/pcm/pcm_linear.c | 21 ++++++++++++++++++---
src/pcm/plugin_ops.h | 27 ++++++++++++++++++++++++++-
2 files changed, 44 insertions(+), 4 deletions(-)
diff --git a/src/pcm/pcm_linear.c b/src/pcm/pcm_linear.c
index 12e2e7f..e85dfaa 100644
--- a/src/pcm/pcm_linear.c
+++ b/src/pcm/pcm_linear.c
@@ -114,10 +114,9 @@ int snd_pcm_linear_get32_index(snd_pcm_format_t src_format, snd_pcm_format_t dst
int snd_pcm_linear_put_index(snd_pcm_format_t src_format, snd_pcm_format_t dst_format)
{
- int sign, width, endian;
+ int sign, width, pwidth, endian;
sign = (snd_pcm_format_signed(src_format) !=
snd_pcm_format_signed(dst_format));
- width = snd_pcm_format_width(dst_format) / 8 - 1;
#ifdef SND_LITTLE_ENDIAN
endian = snd_pcm_format_big_endian(dst_format);
#else
@@ -125,7 +124,23 @@ int snd_pcm_linear_put_index(snd_pcm_format_t src_format, snd_pcm_format_t dst_f
#endif
if (endian < 0)
endian = 0;
- return width * 4 + endian * 2 + sign;
+ pwidth = snd_pcm_format_physical_width(dst_format);
+ width = snd_pcm_format_width(dst_format);
+ if (pwidth == 24) {
+ switch (width) {
+ case 24:
+ width = 0; break;
+ case 20:
+ width = 1; break;
+ case 18:
+ default:
+ width = 2; break;
+ }
+ return width * 4 + endian * 2 + sign + 16;
+ } else {
+ width = width / 8 - 1;
+ return width * 4 + endian * 2 + sign;
+ }
}
int snd_pcm_linear_put32_index(snd_pcm_format_t src_format, snd_pcm_format_t dst_format)
diff --git a/src/pcm/plugin_ops.h b/src/pcm/plugin_ops.h
index 04220d6..21535c9 100644
--- a/src/pcm/plugin_ops.h
+++ b/src/pcm/plugin_ops.h
@@ -407,7 +407,7 @@ get16_123_B2_18: sample = (_get_triple_s(src) >> 2) ^ 0x8000; goto GET16_END;
#ifdef PUT16_LABELS
/* dst_wid dst_endswap sign_toggle */
-static void *const put16_labels[4 * 2 * 2] = {
+static void *const put16_labels[4 * 2 * 2 + 4 * 3] = {
&&put16_12_1, /* 16h -> 8h */
&&put16_12_9, /* 16h ^> 8h */
&&put16_12_1, /* 16h -> 8s */
@@ -424,6 +424,19 @@ static void *const put16_labels[4 * 2 * 2] = {
&&put16_12_9200, /* 16h ^> 32h */
&&put16_12_0021, /* 16h -> 32s */
&&put16_12_0029, /* 16h ^> 32s */
+ /* 3bytes format */
+ &&put16_12_120, /* 16h -> 24h */
+ &&put16_12_920, /* 16h ^> 24h */
+ &&put16_12_021, /* 16h -> 24s */
+ &&put16_12_029, /* 16h ^> 24s */
+ &&put16_12_120_20, /* 16h -> 20h */
+ &&put16_12_920_20, /* 16h ^> 20h */
+ &&put16_12_021_20, /* 16h -> 20s */
+ &&put16_12_029_20, /* 16h ^> 20s */
+ &&put16_12_120_18, /* 16h -> 18h */
+ &&put16_12_920_18, /* 16h ^> 18h */
+ &&put16_12_021_18, /* 16h -> 18s */
+ &&put16_12_029_18, /* 16h ^> 18s */
};
#endif
@@ -443,6 +456,18 @@ put16_12_1200: as_u32(dst) = (u_int32_t)sample << 16; goto PUT16_END;
put16_12_9200: as_u32(dst) = (u_int32_t)(sample ^ 0x8000) << 16; goto PUT16_END;
put16_12_0021: as_u32(dst) = (u_int32_t)bswap_16(sample); goto PUT16_END;
put16_12_0029: as_u32(dst) = (u_int32_t)bswap_16(sample) ^ 0x80; goto PUT16_END;
+put16_12_120: _put_triple(dst, (u_int32_t)sample << 8); goto PUT16_END;
+put16_12_920: _put_triple(dst, (u_int32_t)(sample ^ 0x8000) << 8); goto PUT16_END;
+put16_12_021: _put_triple_s(dst, (u_int32_t)sample << 8); goto PUT16_END;
+put16_12_029: _put_triple_s(dst, (u_int32_t)(sample ^ 0x8000) << 8); goto PUT16_END;
+put16_12_120_20: _put_triple(dst, (u_int32_t)sample << 4); goto PUT16_END;
+put16_12_920_20: _put_triple(dst, (u_int32_t)(sample ^ 0x8000) << 4); goto PUT16_END;
+put16_12_021_20: _put_triple_s(dst, (u_int32_t)sample << 4); goto PUT16_END;
+put16_12_029_20: _put_triple_s(dst, (u_int32_t)(sample ^ 0x8000) << 4); goto PUT16_END;
+put16_12_120_18: _put_triple(dst, (u_int32_t)sample << 2); goto PUT16_END;
+put16_12_920_18: _put_triple(dst, (u_int32_t)(sample ^ 0x8000) << 2); goto PUT16_END;
+put16_12_021_18: _put_triple_s(dst, (u_int32_t)sample << 2); goto PUT16_END;
+put16_12_029_18: _put_triple_s(dst, (u_int32_t)(sample ^ 0x8000) << 2); goto PUT16_END;
}
#endif
--
1.7.2.1

View File

@ -1,59 +0,0 @@
From 97d25c0766405453d3c298bd51dd4916121a4f6a Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Fri, 20 Aug 2010 10:31:17 +0200
Subject: [PATCH 18/21] namehint: Evaluate more possibilities for hw devices
This tries to fix the issue when logical device indexes does not match the
hardware device indexes (like hdmi -> 0:3, 1:7, 2:8, 3:9).
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
src/control/namehint.c | 18 +++++++++++++-----
1 files changed, 13 insertions(+), 5 deletions(-)
diff --git a/src/control/namehint.c b/src/control/namehint.c
index 1819292..e06d240 100644
--- a/src/control/namehint.c
+++ b/src/control/namehint.c
@@ -414,6 +414,7 @@ static int add_card(struct hint_list *list, int card)
const char *str;
char ctl_name[16];
snd_ctl_card_info_t *info;
+ int device, max_device = 0;
snd_ctl_card_info_alloca(&info);
list->info = info;
@@ -431,18 +432,25 @@ static int add_card(struct hint_list *list, int card)
n = snd_config_iterator_entry(i);
if (snd_config_get_id(n, &str) < 0)
continue;
+
if (next_devices[list->iface] != NULL) {
list->card = card;
- list->device = -1;
- err = next_devices[list->iface](list->ctl, &list->device);
- if (list->device < 0)
+ device = max_device = -1;
+ err = next_devices[list->iface](list->ctl, &device);
+ if (device < 0)
err = -EINVAL;
+ while (err >= 0 && device >= 0) {
+ err = next_devices[list->iface](list->ctl, &device);
+ if (device > max_device)
+ max_device = device;
+ ok++;
+ }
ok = 0;
- while (err >= 0 && list->device >= 0) {
+ for (device = 0; err >= 0 && device < max_device; device++) {
+ list->device = device;
err = try_config(list, list->siface, str);
if (err < 0)
break;
- err = next_devices[list->iface](list->ctl, &list->device);
ok++;
}
if (ok)
--
1.7.2.1

View File

@ -1,40 +0,0 @@
From be06ab3ee7266c6ca7d2475d45b42cc4f47a20f8 Mon Sep 17 00:00:00 2001
From: Pierre-Louis Bossart <pierre-louis.bossart@intel.com>
Date: Thu, 19 Aug 2010 20:42:30 -0500
Subject: [PATCH 19/21] HDA-Intel: do not lock IEC958 Playback switch
As discussed with Takashi, removing the lock allows apps to mute
the output using the mixer interface.
Other AES controls remain locked.
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
src/conf/cards/HDA-Intel.conf | 4 ----
1 files changed, 0 insertions(+), 4 deletions(-)
diff --git a/src/conf/cards/HDA-Intel.conf b/src/conf/cards/HDA-Intel.conf
index 726e8c9..f7eecb4 100644
--- a/src/conf/cards/HDA-Intel.conf
+++ b/src/conf/cards/HDA-Intel.conf
@@ -111,8 +111,6 @@ HDA-Intel.pcm.iec958.0 {
}
{
name "IEC958 Playback Switch"
- lock true
- preserve true
value true
}
]
@@ -184,8 +182,6 @@ HDA-Intel.pcm.hdmi.common {
{
name "IEC958 Playback Switch"
index $CTLINDEX
- lock true
- preserve true
value true
}
]
--
1.7.2.1

View File

@ -1,516 +0,0 @@
From 91c9c8f1b85e69b4bdc94a777d2767c4906c3f47 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Mon, 23 Aug 2010 17:05:36 +0200
Subject: [PATCH 20/21] general: recoded snd_dlobj_ functions
- changed logic to get/put blocks
- added mutex locking of the symbol list
- added reference counting (do not free used dl handles)
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
include/local.h | 12 ++--
src/control/control.c | 40 +++----------
src/control/control_local.h | 2 +-
src/dlmisc.c | 132 +++++++++++++++++++++++++++++++++---------
src/pcm/pcm.c | 38 +++----------
src/pcm/pcm_local.h | 2 +-
src/pcm/pcm_rate.c | 46 +++++++--------
7 files changed, 151 insertions(+), 121 deletions(-)
diff --git a/include/local.h b/include/local.h
index fa3f0b7..4dc6562 100644
--- a/include/local.h
+++ b/include/local.h
@@ -254,10 +254,10 @@ static inline int snd_open_device(const char *filename, int fmode)
}
/* make local functions really local */
-#define snd_dlobj_cache_lookup \
- snd1_dlobj_cache_lookup
-#define snd_dlobj_cache_add \
- snd1_dlobj_cache_add
+#define snd_dlobj_cache_get \
+ snd1_dlobj_cache_get
+#define snd_dlobj_cache_put \
+ snd1_dlobj_cache_put
#define snd_dlobj_cache_cleanup \
snd1_dlobj_cache_cleanup
#define snd_config_set_hop \
@@ -268,8 +268,8 @@ static inline int snd_open_device(const char *filename, int fmode)
snd1_config_search_alias_hooks
/* dlobj cache */
-void *snd_dlobj_cache_lookup(const char *name);
-int snd_dlobj_cache_add(const char *name, void *dlobj, void *open_func);
+void *snd_dlobj_cache_get(const char *lib, const char *name, const char *version, int verbose);
+int snd_dlobj_cache_put(void *open_func);
void snd_dlobj_cache_cleanup(void);
/* for recursive checks */
diff --git a/src/control/control.c b/src/control/control.c
index b63a28c..19e9389 100644
--- a/src/control/control.c
+++ b/src/control/control.c
@@ -94,8 +94,7 @@ int snd_ctl_close(snd_ctl_t *ctl)
}
err = ctl->ops->close(ctl);
free(ctl->name);
- if (ctl->dl_handle)
- snd_dlclose(ctl->dl_handle);
+ snd_dlobj_cache_put(ctl->open_func);
free(ctl);
return err;
}
@@ -768,7 +767,6 @@ static int snd_ctl_open_conf(snd_ctl_t **ctlp, const char *name,
#ifndef PIC
extern void *snd_control_open_symbols(void);
#endif
- void *h = NULL;
if (snd_config_get_type(ctl_conf) != SND_CONFIG_TYPE_COMPOUND) {
if (name)
SNDERR("Invalid type for CTL %s definition", name);
@@ -854,40 +852,22 @@ static int snd_ctl_open_conf(snd_ctl_t **ctlp, const char *name,
#ifndef PIC
snd_control_open_symbols();
#endif
- open_func = snd_dlobj_cache_lookup(open_name);
+ open_func = snd_dlobj_cache_get(lib, open_name,
+ SND_DLSYM_VERSION(SND_CONTROL_DLSYM_VERSION), 1);
if (open_func) {
- err = 0;
- goto _err;
- }
- h = snd_dlopen(lib, RTLD_NOW);
- if (h)
- open_func = snd_dlsym(h, open_name, SND_DLSYM_VERSION(SND_CONTROL_DLSYM_VERSION));
- err = 0;
- if (!h) {
- SNDERR("Cannot open shared library %s", lib);
- err = -ENOENT;
- } else if (!open_func) {
- SNDERR("symbol %s is not defined inside %s", open_name, lib);
- snd_dlclose(h);
- err = -ENXIO;
- }
- _err:
- if (type_conf)
- snd_config_delete(type_conf);
- if (err >= 0) {
err = open_func(ctlp, name, ctl_root, ctl_conf, mode);
if (err >= 0) {
- if (h /*&& (mode & SND_CTL_KEEP_ALIVE)*/) {
- snd_dlobj_cache_add(open_name, h, open_func);
- h = NULL;
- }
- (*ctlp)->dl_handle = h;
+ (*ctlp)->open_func = open_func;
err = 0;
} else {
- if (h)
- snd_dlclose(h);
+ snd_dlobj_cache_put(open_func);
}
+ } else {
+ err = -ENXIO;
}
+ _err:
+ if (type_conf)
+ snd_config_delete(type_conf);
free(buf);
free(buf1);
return err;
diff --git a/src/control/control_local.h b/src/control/control_local.h
index fd9f941..49150d8 100644
--- a/src/control/control_local.h
+++ b/src/control/control_local.h
@@ -56,7 +56,7 @@ typedef struct _snd_ctl_ops {
struct _snd_ctl {
- void *dl_handle;
+ void *open_func;
char *name;
snd_ctl_type_t type;
const snd_ctl_ops_t *ops;
diff --git a/src/dlmisc.c b/src/dlmisc.c
index a0d62d3..ecbbe8d 100644
--- a/src/dlmisc.c
+++ b/src/dlmisc.c
@@ -29,6 +29,9 @@
#include "list.h"
#include "local.h"
+#ifdef HAVE_LIBPTHREAD
+#include <pthread.h>
+#endif
#ifndef DOC_HIDDEN
#ifndef PIC
@@ -169,69 +172,140 @@ void *snd_dlsym(void *handle, const char *name, const char *version)
/*
* dlobj cache
- *
- * FIXME: add reference counter and proper locking
*/
#ifndef DOC_HIDDEN
struct dlobj_cache {
+ const char *lib;
const char *name;
- void *obj;
+ void *dlobj;
void *func;
+ unsigned int refcnt;
struct list_head list;
};
-static LIST_HEAD(pcm_dlobj_list);
+#ifdef HAVE_LIBPTHREAD
+static pthread_mutex_t snd_dlobj_mutex = PTHREAD_MUTEX_INITIALIZER;
-void *snd_dlobj_cache_lookup(const char *name)
+static inline void snd_dlobj_lock(void)
{
- struct list_head *p;
- struct dlobj_cache *c;
+ pthread_mutex_lock(&snd_dlobj_mutex);
+}
- list_for_each(p, &pcm_dlobj_list) {
- c = list_entry(p, struct dlobj_cache, list);
- if (strcmp(c->name, name) == 0)
- return c->func;
- }
- return NULL;
+static inline void snd_dlobj_unlock(void)
+{
+ pthread_mutex_unlock(&snd_dlobj_mutex);
}
+#else
+static inline void snd_dlobj_lock(void) {}
+static inline void snd_dlobj_unlock(void) {}
+#endif
+
+static LIST_HEAD(pcm_dlobj_list);
-int snd_dlobj_cache_add(const char *name, void *dlobj, void *open_func)
+void *snd_dlobj_cache_get(const char *lib, const char *name,
+ const char *version, int verbose)
{
struct list_head *p;
struct dlobj_cache *c;
+ void *func, *dlobj = NULL;
+ int dlobj_close = 0;
+ snd_dlobj_lock();
list_for_each(p, &pcm_dlobj_list) {
c = list_entry(p, struct dlobj_cache, list);
- if (strcmp(c->name, name) == 0)
- return 0; /* already exists */
+ if (c->lib && lib && strcmp(c->lib, lib) != 0)
+ continue;
+ if (!c->lib && lib)
+ continue;
+ if (!lib && c->lib)
+ continue;
+ dlobj = c->dlobj;
+ if (strcmp(c->name, name) == 0) {
+ c->refcnt++;
+ func = c->func;
+ snd_dlobj_unlock();
+ return func;
+ }
+ }
+ if (dlobj == NULL) {
+ dlobj = snd_dlopen(lib, RTLD_NOW);
+ if (dlobj == NULL) {
+ if (verbose)
+ SNDERR("Cannot open shared library %s",
+ lib ? lib : "[builtin]");
+ snd_dlobj_unlock();
+ return NULL;
+ }
+ dlobj_close = 1;
+ }
+ func = snd_dlsym(dlobj, name, version);
+ if (func == NULL) {
+ if (verbose)
+ SNDERR("symbol %s is not defined inside %s",
+ name, lib ? lib : "[builtin]");
+ goto __err;
}
c = malloc(sizeof(*c));
if (! c)
- return -ENOMEM;
+ goto __err;
+ c->refcnt = 1;
+ c->lib = lib ? strdup(lib) : NULL;
c->name = strdup(name);
- if (! c->name) {
+ if ((lib && ! c->lib) || ! c->name) {
+ free((void *)c->name);
+ free((void *)c->lib);
free(c);
- return -ENOMEM;
+ __err:
+ if (dlobj_close)
+ snd_dlclose(dlobj);
+ snd_dlobj_unlock();
+ return NULL;
}
- c->obj = dlobj;
- c->func = open_func;
+ c->dlobj = dlobj;
+ c->func = func;
list_add_tail(&c->list, &pcm_dlobj_list);
- return 0;
+ snd_dlobj_unlock();
+ return func;
}
-void snd_dlobj_cache_cleanup(void)
+int snd_dlobj_cache_put(void *func)
{
struct list_head *p;
struct dlobj_cache *c;
+ unsigned int refcnt;
- while (! list_empty(&pcm_dlobj_list)) {
- p = pcm_dlobj_list.next;
+ snd_dlobj_lock();
+ list_for_each(p, &pcm_dlobj_list) {
c = list_entry(p, struct dlobj_cache, list);
- list_del(p);
- snd_dlclose(c->obj);
- free((void *)c->name); /* shut up gcc warning */
- free(c);
+ if (c->func == func) {
+ refcnt = c->refcnt;
+ if (c->refcnt > 0)
+ c->refcnt--;
+ snd_dlobj_unlock();
+ return refcnt == 1 ? 0 : -EINVAL;
+ }
+ }
+ snd_dlobj_unlock();
+ return -ENOENT;
+}
+
+void snd_dlobj_cache_cleanup(void)
+{
+ struct list_head *p, *npos;
+ struct dlobj_cache *c;
+
+ snd_dlobj_lock();
+ list_for_each_safe(p, npos, &pcm_dlobj_list) {
+ c = list_entry(p, struct dlobj_cache, list);
+ if (c->refcnt == 0) {
+ list_del(p);
+ snd_dlclose(c->dlobj);
+ free((void *)c->name); /* shut up gcc warning */
+ free((void *)c->lib); /* shut up gcc warning */
+ free(c);
+ }
}
+ snd_dlobj_unlock();
}
#endif
diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c
index 8a4bc6a..a49b5b9 100644
--- a/src/pcm/pcm.c
+++ b/src/pcm/pcm.c
@@ -2068,7 +2068,6 @@ static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name,
#ifndef PIC
extern void *snd_pcm_open_symbols(void);
#endif
- void *h = NULL;
if (snd_config_get_type(pcm_conf) != SND_CONFIG_TYPE_COMPOUND) {
char *val;
id = NULL;
@@ -2157,39 +2156,18 @@ static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name,
#ifndef PIC
snd_pcm_open_symbols(); /* this call is for static linking only */
#endif
- open_func = snd_dlobj_cache_lookup(open_name);
+ open_func = snd_dlobj_cache_get(lib, open_name,
+ SND_DLSYM_VERSION(SND_PCM_DLSYM_VERSION), 1);
if (open_func) {
- err = 0;
- goto _err;
- }
- h = snd_dlopen(lib, RTLD_NOW);
- if (h)
- open_func = snd_dlsym(h, open_name, SND_DLSYM_VERSION(SND_PCM_DLSYM_VERSION));
- err = 0;
- if (!h) {
- SNDERR("Cannot open shared library %s",
- lib ? lib : "[builtin]");
- err = -ENOENT;
- } else if (!open_func) {
- SNDERR("symbol %s is not defined inside %s", open_name,
- lib ? lib : "[builtin]");
- snd_dlclose(h);
- err = -ENXIO;
- }
- _err:
- if (err >= 0) {
err = open_func(pcmp, name, pcm_root, pcm_conf, stream, mode);
if (err >= 0) {
- if (h /*&& (mode & SND_PCM_KEEP_ALIVE)*/) {
- snd_dlobj_cache_add(open_name, h, open_func);
- h = NULL;
- }
- (*pcmp)->dl_handle = h;
+ (*pcmp)->open_func = open_func;
err = 0;
} else {
- if (h)
- snd_dlclose(h);
+ snd_dlobj_cache_put(open_func);
}
+ } else {
+ err = -ENXIO;
}
if (err >= 0) {
err = snd_config_search(pcm_root, "defaults.pcm.compat", &tmp);
@@ -2209,6 +2187,7 @@ static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name,
snd_config_get_integer(tmp, &(*pcmp)->minperiodtime);
err = 0;
}
+ _err:
if (type_conf)
snd_config_delete(type_conf);
free(buf);
@@ -2304,8 +2283,7 @@ int snd_pcm_free(snd_pcm_t *pcm)
free(pcm->name);
free(pcm->hw.link_dst);
free(pcm->appl.link_dst);
- if (pcm->dl_handle)
- snd_dlclose(pcm->dl_handle);
+ snd_dlobj_cache_put(pcm->open_func);
free(pcm);
return 0;
}
diff --git a/src/pcm/pcm_local.h b/src/pcm/pcm_local.h
index 16069b6..2f6fcd2 100644
--- a/src/pcm/pcm_local.h
+++ b/src/pcm/pcm_local.h
@@ -174,7 +174,7 @@ typedef struct {
} snd_pcm_fast_ops_t;
struct _snd_pcm {
- void *dl_handle;
+ void *open_func;
char *name;
snd_pcm_type_t type;
snd_pcm_stream_t stream;
diff --git a/src/pcm/pcm_rate.c b/src/pcm/pcm_rate.c
index ecf0022..70e30e5 100644
--- a/src/pcm/pcm_rate.c
+++ b/src/pcm/pcm_rate.c
@@ -61,6 +61,7 @@ struct _snd_pcm_rate {
snd_pcm_channel_area_t *pareas; /* areas for splitted period (rate pcm) */
snd_pcm_channel_area_t *sareas; /* areas for splitted period (slave pcm) */
snd_pcm_rate_info_t info;
+ void *open_func;
void *obj;
snd_pcm_rate_ops_t ops;
unsigned int get_idx;
@@ -1204,6 +1205,8 @@ static int snd_pcm_rate_close(snd_pcm_t *pcm)
if (rate->ops.close)
rate->ops.close(rate->obj);
+ if (rate->open_func)
+ snd_dlobj_cache_put(rate->open_func);
return snd_pcm_generic_close(pcm);
}
@@ -1272,33 +1275,23 @@ static const char *const default_rate_plugins[] = {
"speexrate", "linear", NULL
};
-static int rate_open_func(snd_pcm_rate_t *rate, const char *type)
+static int rate_open_func(snd_pcm_rate_t *rate, const char *type, int verbose)
{
- char open_name[64];
+ char open_name[64], lib_name[128], *lib = NULL;
snd_pcm_rate_open_func_t open_func;
int err;
snprintf(open_name, sizeof(open_name), "_snd_pcm_rate_%s_open", type);
- open_func = snd_dlobj_cache_lookup(open_name);
- if (!open_func) {
- void *h;
- char lib_name[128], *lib = NULL;
- if (!is_builtin_plugin(type)) {
- snprintf(lib_name, sizeof(lib_name),
+ if (!is_builtin_plugin(type)) {
+ snprintf(lib_name, sizeof(lib_name),
"%s/libasound_module_rate_%s.so", ALSA_PLUGIN_DIR, type);
- lib = lib_name;
- }
- h = snd_dlopen(lib, RTLD_NOW);
- if (!h)
- return -ENOENT;
- open_func = snd_dlsym(h, open_name, NULL);
- if (!open_func) {
- snd_dlclose(h);
- return -ENOENT;
- }
- snd_dlobj_cache_add(open_name, h, open_func);
+ lib = lib_name;
}
+ open_func = snd_dlobj_cache_get(lib, open_name, NULL, verbose);
+ if (!open_func)
+ return -ENOENT;
+ rate->open_func = open_func;
rate->rate_min = SND_PCM_PLUGIN_RATE_MIN;
rate->rate_max = SND_PCM_PLUGIN_RATE_MAX;
rate->plugin_version = SND_PCM_RATE_PLUGIN_VERSION;
@@ -1315,8 +1308,13 @@ static int rate_open_func(snd_pcm_rate_t *rate, const char *type)
/* try to open with the old protocol version */
rate->plugin_version = SND_PCM_RATE_PLUGIN_VERSION_OLD;
- return open_func(SND_PCM_RATE_PLUGIN_VERSION_OLD,
- &rate->obj, &rate->ops);
+ err = open_func(SND_PCM_RATE_PLUGIN_VERSION_OLD,
+ &rate->obj, &rate->ops);
+ if (err) {
+ snd_dlobj_cache_put(open_func);
+ rate->open_func = NULL;
+ }
+ return err;
}
#endif
@@ -1373,21 +1371,21 @@ int snd_pcm_rate_open(snd_pcm_t **pcmp, const char *name,
if (!converter) {
const char *const *types;
for (types = default_rate_plugins; *types; types++) {
- err = rate_open_func(rate, *types);
+ err = rate_open_func(rate, *types, 0);
if (!err) {
type = *types;
break;
}
}
} else if (!snd_config_get_string(converter, &type))
- err = rate_open_func(rate, type);
+ err = rate_open_func(rate, type, 1);
else if (snd_config_get_type(converter) == SND_CONFIG_TYPE_COMPOUND) {
snd_config_iterator_t i, next;
snd_config_for_each(i, next, converter) {
snd_config_t *n = snd_config_iterator_entry(i);
if (snd_config_get_string(n, &type) < 0)
break;
- err = rate_open_func(rate, type);
+ err = rate_open_func(rate, type, 0);
if (!err)
break;
}
--
1.7.2.1

View File

@ -1,94 +0,0 @@
From 72c7260ce624adcb40377bc2093cd4d965b9b22e Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Wed, 25 Aug 2010 09:04:51 +0200
Subject: [PATCH 21/21] Add Loopback.conf to define standard PCM devices for snd-aloop driver
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
src/conf/cards/Loopback.conf | 74 ++++++++++++++++++++++++++++++++++++++++++
1 files changed, 74 insertions(+), 0 deletions(-)
create mode 100644 src/conf/cards/Loopback.conf
diff --git a/src/conf/cards/Loopback.conf b/src/conf/cards/Loopback.conf
new file mode 100644
index 0000000..05c48c6
--- /dev/null
+++ b/src/conf/cards/Loopback.conf
@@ -0,0 +1,74 @@
+#
+# Configuration for the Intel HD audio (ICH6/ICH7)
+#
+
+<confdir:pcm/front.conf>
+
+Loopback.pcm.front.0 {
+ @args [ CARD ]
+ @args.CARD {
+ type string
+ }
+ type softvol
+ slave.pcm {
+ type hw
+ card $CARD
+ }
+ control {
+ name "PCM Playback Volume"
+ card $CARD
+ }
+}
+
+# default with dmix+softvol & dsnoop
+Loopback.pcm.default {
+ @args [ CARD ]
+ @args.CARD {
+ type string
+ }
+ type asym
+ playback.pcm {
+ type plug
+ slave.pcm {
+ type softvol
+ slave.pcm {
+ @func concat
+ strings [ "dmix:" $CARD ]
+ }
+ control {
+ name "PCM Playback Volume"
+ card $CARD
+ }
+ }
+ }
+ capture.pcm {
+ type plug
+ slave.pcm {
+ type softvol
+ slave.pcm {
+ @func concat
+ strings [ "dsnoop:" $CARD ]
+ }
+ control {
+ name "Digital Capture Volume"
+ card $CARD
+ }
+ min_dB -30.0
+ max_dB 30.0
+ resolution 121
+ }
+ # to avoid possible phase inversions with digital mics
+ route_policy copy
+ }
+ hint.device 0
+}
+
+<confdir:pcm/surround40.conf>
+<confdir:pcm/surround41.conf>
+<confdir:pcm/surround50.conf>
+<confdir:pcm/surround51.conf>
+<confdir:pcm/surround71.conf>
+
+Loopback.pcm.surround40.0 cards.HDA-Intel.pcm.front.0
+Loopback.pcm.surround51.0 cards.HDA-Intel.pcm.front.0
+Loopback.pcm.surround71.0 cards.HDA-Intel.pcm.front.0
--
1.7.2.1

View File

@ -1,27 +0,0 @@
From 9ce25165dd14722cf9ca9e25d486bf79824ea606 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Wed, 15 Sep 2010 08:11:42 +0200
Subject: [PATCH] Fix typo for surround PCMs in src/conf/cards/Loopback.conf
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
src/conf/cards/Loopback.conf | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/conf/cards/Loopback.conf b/src/conf/cards/Loopback.conf
index 05c48c6..5365fa1 100644
--- a/src/conf/cards/Loopback.conf
+++ b/src/conf/cards/Loopback.conf
@@ -69,6 +69,6 @@ Loopback.pcm.default {
<confdir:pcm/surround51.conf>
<confdir:pcm/surround71.conf>
-Loopback.pcm.surround40.0 cards.HDA-Intel.pcm.front.0
-Loopback.pcm.surround51.0 cards.HDA-Intel.pcm.front.0
-Loopback.pcm.surround71.0 cards.HDA-Intel.pcm.front.0
+Loopback.pcm.surround40.0 cards.Loopback.pcm.front.0
+Loopback.pcm.surround51.0 cards.Loopback.pcm.front.0
+Loopback.pcm.surround71.0 cards.Loopback.pcm.front.0
--
1.7.3.1

View File

@ -1,26 +0,0 @@
From 0244370be695372a05344ac760d624e0b40ec9ea Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Fri, 1 Oct 2010 13:31:45 +0200
Subject: [PATCH] namehint: Fix hw device evaluation (missing last device)
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
src/control/namehint.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/control/namehint.c b/src/control/namehint.c
index e06d240..ab3525e 100644
--- a/src/control/namehint.c
+++ b/src/control/namehint.c
@@ -446,7 +446,7 @@ static int add_card(struct hint_list *list, int card)
ok++;
}
ok = 0;
- for (device = 0; err >= 0 && device < max_device; device++) {
+ for (device = 0; err >= 0 && device <= max_device; device++) {
list->device = device;
err = try_config(list, list->siface, str);
if (err < 0)
--
1.7.3.1

View File

@ -1,32 +0,0 @@
From c049d48407ff0459ff15e466edeeee6ecff67fcd Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Fri, 1 Oct 2010 14:08:03 +0200
Subject: [PATCH] namehint: Another fix to properly evaluate hw devices
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
src/control/namehint.c | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/control/namehint.c b/src/control/namehint.c
index ab3525e..faaa5d5 100644
--- a/src/control/namehint.c
+++ b/src/control/namehint.c
@@ -439,11 +439,12 @@ static int add_card(struct hint_list *list, int card)
err = next_devices[list->iface](list->ctl, &device);
if (device < 0)
err = -EINVAL;
+ else
+ max_device = device;
while (err >= 0 && device >= 0) {
err = next_devices[list->iface](list->ctl, &device);
- if (device > max_device)
+ if (err >= 0 && device > max_device)
max_device = device;
- ok++;
}
ok = 0;
for (device = 0; err >= 0 && device <= max_device; device++) {
--
1.7.3.1

View File

@ -1,159 +0,0 @@
From c6a81e21c0f566c2cf62ff345eefea857925afa7 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Mon, 11 Oct 2010 10:34:12 +0200
Subject: [PATCH] config file processing: rewrite the locking - use one recursive mutex
Avoid configuration file processing races when multiple threads call
the *open() functions together (for example using alsaloop with
multiple -T jobs can reproduce this issue).
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
src/conf.c | 59 +++++++++++++++++++++++++++++++++++++++--------------------
1 files changed, 39 insertions(+), 20 deletions(-)
diff --git a/src/conf.c b/src/conf.c
index 5d8c5c9..8939d62 100644
--- a/src/conf.c
+++ b/src/conf.c
@@ -425,6 +425,11 @@ beginning:</P>
#ifndef DOC_HIDDEN
+#ifdef HAVE_LIBPTHREAD
+static pthread_mutex_t snd_config_update_mutex =
+ PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+#endif
+
struct _snd_config {
char *id;
snd_config_type_t type;
@@ -464,6 +469,25 @@ typedef struct {
int ch;
} input_t;
+#ifdef HAVE_LIBPTHREAD
+
+static inline void snd_config_lock(void)
+{
+ pthread_mutex_lock(&snd_config_update_mutex);
+}
+
+static inline void snd_config_unlock(void)
+{
+ pthread_mutex_unlock(&snd_config_update_mutex);
+}
+
+#else
+
+static inline void snd_config_lock(void) { }
+static inline void snd_config_unlock(void) { }
+
+#endif
+
static int safe_strtoll(const char *str, long long *val)
{
long long v;
@@ -3318,6 +3342,7 @@ static int snd_config_hooks(snd_config_t *config, snd_config_t *private_data)
if ((err = snd_config_search(config, "@hooks", &n)) < 0)
return 0;
+ snd_config_lock();
snd_config_remove(n);
do {
hit = 0;
@@ -3334,7 +3359,7 @@ static int snd_config_hooks(snd_config_t *config, snd_config_t *private_data)
if (i == idx) {
err = snd_config_hooks_call(config, n, private_data);
if (err < 0)
- return err;
+ goto _err;
idx++;
hit = 1;
}
@@ -3343,6 +3368,7 @@ static int snd_config_hooks(snd_config_t *config, snd_config_t *private_data)
err = 0;
_err:
snd_config_delete(n);
+ snd_config_unlock();
return err;
}
@@ -3692,10 +3718,6 @@ int snd_config_update_r(snd_config_t **_top, snd_config_update_t **_update, cons
return 1;
}
-#ifdef HAVE_LIBPTHREAD
-static pthread_mutex_t snd_config_update_mutex = PTHREAD_MUTEX_INITIALIZER;
-#endif
-
/**
* \brief Updates #snd_config by rereading the global configuration files (if needed).
* \return 0 if #snd_config was up to date, 1 if #snd_config was
@@ -3716,13 +3738,9 @@ int snd_config_update(void)
{
int err;
-#ifdef HAVE_LIBPTHREAD
- pthread_mutex_lock(&snd_config_update_mutex);
-#endif
+ snd_config_lock();
err = snd_config_update_r(&snd_config, &snd_config_global_update, NULL);
-#ifdef HAVE_LIBPTHREAD
- pthread_mutex_unlock(&snd_config_update_mutex);
-#endif
+ snd_config_unlock();
return err;
}
@@ -3755,18 +3773,14 @@ int snd_config_update_free(snd_config_update_t *update)
*/
int snd_config_update_free_global(void)
{
-#ifdef HAVE_LIBPTHREAD
- pthread_mutex_lock(&snd_config_update_mutex);
-#endif
+ snd_config_lock();
if (snd_config)
snd_config_delete(snd_config);
snd_config = NULL;
if (snd_config_global_update)
snd_config_update_free(snd_config_global_update);
snd_config_global_update = NULL;
-#ifdef HAVE_LIBPTHREAD
- pthread_mutex_unlock(&snd_config_update_mutex);
-#endif
+ snd_config_unlock();
/* FIXME: better to place this in another place... */
snd_dlobj_cache_cleanup();
@@ -4657,7 +4671,7 @@ int snd_config_expand(snd_config_t *config, snd_config_t *root, const char *args
snd_config_delete(subs);
return err;
}
-
+
/**
* \brief Searches for a definition in a configuration tree, using
* aliases and expanding hooks and arguments.
@@ -4707,10 +4721,15 @@ int snd_config_search_definition(snd_config_t *config,
* if key contains dot (.), the implicit base is ignored
* and the key starts from root given by the 'config' parameter
*/
+ snd_config_lock();
err = snd_config_search_alias_hooks(config, strchr(key, '.') ? NULL : base, key, &conf);
- if (err < 0)
+ if (err < 0) {
+ snd_config_unlock();
return err;
- return snd_config_expand(conf, config, args, NULL, result);
+ }
+ err = snd_config_expand(conf, config, args, NULL, result);
+ snd_config_unlock();
+ return err;
}
#ifndef DOC_HIDDEN
--
1.7.3.1

View File

@ -1,85 +0,0 @@
From 2f6206da0c1ff88235e6eca0077343f22a4b43ee Mon Sep 17 00:00:00 2001
From: Clemens Ladisch <clemens@ladisch.de>
Date: Fri, 15 Oct 2010 10:33:20 +0200
Subject: [PATCH] tlv: fix returned dB information for min-is-mute controls
For TLV information that indicates that the minimum value is actually
muted, the returned range used the wrong minimum dB value, and
converting dB values to raw control values did not round up correctly
near the minimum.
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
src/control/tlv.c | 26 ++++++++++++++++++++------
1 files changed, 20 insertions(+), 6 deletions(-)
diff --git a/src/control/tlv.c b/src/control/tlv.c
index ba52752..f7c9976 100644
--- a/src/control/tlv.c
+++ b/src/control/tlv.c
@@ -167,17 +167,23 @@ int snd_tlv_get_dB_range(unsigned int *tlv, long rangemin, long rangemax,
}
case SND_CTL_TLVT_DB_SCALE: {
int step;
- *min = (int)tlv[2];
+ if (tlv[3] & 0x10000)
+ *min = SND_CTL_TLV_DB_GAIN_MUTE;
+ else
+ *min = (int)tlv[2];
step = (tlv[3] & 0xffff);
- *max = *min + (long)(step * (rangemax - rangemin));
+ *max = (int)tlv[2] + step * (rangemax - rangemin);
return 0;
}
case SND_CTL_TLVT_DB_MINMAX:
- case SND_CTL_TLVT_DB_MINMAX_MUTE:
case SND_CTL_TLVT_DB_LINEAR:
*min = (int)tlv[2];
*max = (int)tlv[3];
return 0;
+ case SND_CTL_TLVT_DB_MINMAX_MUTE:
+ *min = SND_CTL_TLV_DB_GAIN_MUTE;
+ *max = (int)tlv[3];
+ return 0;
}
return -EINVAL;
}
@@ -217,7 +223,7 @@ int snd_tlv_convert_to_dB(unsigned int *tlv, long rangemin, long rangemax,
min = tlv[2];
step = (tlv[3] & 0xffff);
mute = (tlv[3] >> 16) & 1;
- if (mute && volume == rangemin)
+ if (mute && volume <= rangemin)
*db_gain = SND_CTL_TLV_DB_GAIN_MUTE;
else
*db_gain = (volume - rangemin) * step + min;
@@ -327,7 +333,11 @@ int snd_tlv_convert_from_dB(unsigned int *tlv, long rangemin, long rangemax,
step = (tlv[3] & 0xffff);
max = min + (int)(step * (rangemax - rangemin));
if (db_gain <= min)
- *value = rangemin;
+ if (db_gain > SND_CTL_TLV_DB_GAIN_MUTE && xdir > 0 &&
+ (tlv[3] & 0x10000))
+ *value = rangemin + 1;
+ else
+ *value = rangemin;
else if (db_gain >= max)
*value = rangemax;
else {
@@ -345,7 +355,11 @@ int snd_tlv_convert_from_dB(unsigned int *tlv, long rangemin, long rangemax,
min = tlv[2];
max = tlv[3];
if (db_gain <= min)
- *value = rangemin;
+ if (db_gain > SND_CTL_TLV_DB_GAIN_MUTE && xdir > 0 &&
+ tlv[0] == SND_CTL_TLVT_DB_MINMAX_MUTE)
+ *value = rangemin + 1;
+ else
+ *value = rangemin;
else if (db_gain >= max)
*value = rangemax;
else {
--
1.7.3.1

View File

@ -1,32 +0,0 @@
From 443c1057379f167639acad5dc197bd50a915b5ab Mon Sep 17 00:00:00 2001
From: Simon McVittie <smcv@debian.org>
Date: Fri, 8 Oct 2010 09:06:29 +0100
Subject: [PATCH 01/10] Version-check libtool correctly when doing an out-of-tree build
libtool is only created at the end of ./configure, so it doesn't make
sense to grep it in ./configure (the check would always fail the first
time). However, ltmain.sh is copied into the ${srcdir} by libtoolize and
should be safe to check at any time that configure can be run.
Signed-off-by: Simon McVittie <smcv@debian.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
configure.in | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/configure.in b/configure.in
index abc4687..e904956 100644
--- a/configure.in
+++ b/configure.in
@@ -115,7 +115,7 @@ AC_ARG_WITH(versioned,
versioned="$withval", versioned="yes")
if test "$versioned" = "yes"; then
# it seems that GNU ld versions since 2.10 are not broken
- xres=`grep '^VERSION=' libtool | cut -d = -f 2 | cut -d \" -f 2`
+ xres=`grep '^VERSION=' ${srcdir}/ltmain.sh | cut -d = -f 2 | cut -d \" -f 2`
major=`echo $xres | cut -d . -f 1`
minor=`echo $xres | cut -d . -f 2`
pass=0
--
1.7.3.1

View File

@ -1,28 +0,0 @@
From 5cfa03d2f3a9e6bc62f740640d20bd137b4e3bb5 Mon Sep 17 00:00:00 2001
From: Simon McVittie <smcv@debian.org>
Date: Fri, 8 Oct 2010 09:06:58 +0100
Subject: [PATCH 02/10] configure.in: don't rely on test -a, not all shells support it
Notably, /bin/sh in older Debian and Ubuntu is dash, which doesn't.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
configure.in | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/configure.in b/configure.in
index e904956..c353759 100644
--- a/configure.in
+++ b/configure.in
@@ -119,7 +119,7 @@ if test "$versioned" = "yes"; then
major=`echo $xres | cut -d . -f 1`
minor=`echo $xres | cut -d . -f 2`
pass=0
- if test $major -eq 1 -a $minor -gt 3; then
+ if test $major -eq 1 && test $minor -gt 3; then
pass=1
else
if test $major -gt 1; then
--
1.7.3.1

View File

@ -1,137 +0,0 @@
From 13b5d972d2e7a5f0e6f3c066684dbb01fafd5121 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Fri, 29 Oct 2010 17:36:41 +0200
Subject: [PATCH 03/10] pcm direct plugins: change timestamping in dsnoop
Do not use own timestamps, try to sync hw.ptr with real timestamp.
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
src/pcm/pcm_direct.h | 1 +
src/pcm/pcm_dmix.c | 2 +-
src/pcm/pcm_dshare.c | 2 +-
src/pcm/pcm_dsnoop.c | 31 +++++++++++++++++++++++++------
4 files changed, 28 insertions(+), 8 deletions(-)
diff --git a/src/pcm/pcm_direct.h b/src/pcm/pcm_direct.h
index 132c281..7f16481 100644
--- a/src/pcm/pcm_direct.h
+++ b/src/pcm/pcm_direct.h
@@ -137,6 +137,7 @@ struct snd_pcm_direct {
int (*sync_ptr)(snd_pcm_t *pcm);
snd_pcm_state_t state;
snd_htimestamp_t trigger_tstamp;
+ snd_htimestamp_t update_tstamp;
int server, client;
int comm_fd; /* communication file descriptor (socket) */
int hw_fd; /* hardware file descriptor */
diff --git a/src/pcm/pcm_dmix.c b/src/pcm/pcm_dmix.c
index cb62de9..434fc65 100644
--- a/src/pcm/pcm_dmix.c
+++ b/src/pcm/pcm_dmix.c
@@ -852,7 +852,7 @@ static int snd_pcm_dmix_htimestamp(snd_pcm_t *pcm,
if (ok && *avail == avail1)
break;
*avail = avail1;
- *tstamp = snd_pcm_hw_fast_tstamp(pcm);
+ *tstamp = snd_pcm_hw_fast_tstamp(dmix->spcm);
}
return 0;
}
diff --git a/src/pcm/pcm_dshare.c b/src/pcm/pcm_dshare.c
index 02782a7..77789a5 100644
--- a/src/pcm/pcm_dshare.c
+++ b/src/pcm/pcm_dshare.c
@@ -542,7 +542,7 @@ static int snd_pcm_dshare_htimestamp(snd_pcm_t *pcm,
if (ok && *avail == avail1)
break;
*avail = avail1;
- *tstamp = snd_pcm_hw_fast_tstamp(pcm);
+ *tstamp = snd_pcm_hw_fast_tstamp(dshare->spcm);
}
return 0;
}
diff --git a/src/pcm/pcm_dsnoop.c b/src/pcm/pcm_dsnoop.c
index 15c727a..988f1f4 100644
--- a/src/pcm/pcm_dsnoop.c
+++ b/src/pcm/pcm_dsnoop.c
@@ -54,6 +54,23 @@ const char *_snd_module_pcm_dsnoop = "";
*
*/
+static int snoop_timestamp(snd_pcm_t *pcm)
+{
+ snd_pcm_direct_t *dsnoop = pcm->private_data;
+ snd_pcm_uframes_t ptr1 = -2LL /* invalid value */, ptr2;
+
+ /* loop is required to sync hw.ptr with timestamp */
+ while (1) {
+ ptr2 = *dsnoop->spcm->hw.ptr;
+ if (ptr1 == ptr2)
+ break;
+ ptr1 = ptr2;
+ dsnoop->update_tstamp = snd_pcm_hw_fast_tstamp(dsnoop->spcm);
+ }
+ dsnoop->slave_hw_ptr = ptr1;
+ return 0;
+}
+
static void snoop_areas(snd_pcm_direct_t *dsnoop,
const snd_pcm_channel_area_t *src_areas,
const snd_pcm_channel_area_t *dst_areas,
@@ -126,7 +143,8 @@ static int snd_pcm_dsnoop_sync_ptr(snd_pcm_t *pcm)
if (dsnoop->slowptr)
snd_pcm_hwsync(dsnoop->spcm);
old_slave_hw_ptr = dsnoop->slave_hw_ptr;
- slave_hw_ptr = dsnoop->slave_hw_ptr = *dsnoop->spcm->hw.ptr;
+ snoop_timestamp(pcm);
+ slave_hw_ptr = dsnoop->slave_hw_ptr;
diff = slave_hw_ptr - old_slave_hw_ptr;
if (diff == 0) /* fast path */
return 0;
@@ -172,7 +190,7 @@ static int snd_pcm_dsnoop_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
state = snd_pcm_state(dsnoop->spcm);
status->state = state == SND_PCM_STATE_RUNNING ? dsnoop->state : state;
status->trigger_tstamp = dsnoop->trigger_tstamp;
- gettimestamp(&status->tstamp, pcm->monotonic);
+ status->tstamp = dsnoop->update_tstamp;
status->avail = snd_pcm_mmap_capture_avail(pcm);
status->avail_max = status->avail > dsnoop->avail_max ? status->avail : dsnoop->avail_max;
dsnoop->avail_max = 0;
@@ -254,7 +272,7 @@ static int snd_pcm_dsnoop_reset(snd_pcm_t *pcm)
snd_pcm_direct_t *dsnoop = pcm->private_data;
dsnoop->hw_ptr %= pcm->period_size;
dsnoop->appl_ptr = dsnoop->hw_ptr;
- dsnoop->slave_appl_ptr = dsnoop->slave_hw_ptr = *dsnoop->spcm->hw.ptr;
+ dsnoop->slave_appl_ptr = dsnoop->slave_hw_ptr;
return 0;
}
@@ -266,12 +284,13 @@ static int snd_pcm_dsnoop_start(snd_pcm_t *pcm)
if (dsnoop->state != SND_PCM_STATE_PREPARED)
return -EBADFD;
snd_pcm_hwsync(dsnoop->spcm);
- dsnoop->slave_appl_ptr = dsnoop->slave_hw_ptr = *dsnoop->spcm->hw.ptr;
+ snoop_timestamp(pcm);
+ dsnoop->slave_appl_ptr = dsnoop->slave_hw_ptr;
err = snd_timer_start(dsnoop->timer);
if (err < 0)
return err;
dsnoop->state = SND_PCM_STATE_RUNNING;
- gettimestamp(&dsnoop->trigger_tstamp, pcm->monotonic);
+ dsnoop->trigger_tstamp = dsnoop->update_tstamp;
return 0;
}
@@ -437,7 +456,7 @@ static int snd_pcm_dsnoop_htimestamp(snd_pcm_t *pcm,
if (ok && *avail == avail1)
break;
*avail = avail1;
- *tstamp = snd_pcm_hw_fast_tstamp(pcm);
+ *tstamp = snd_pcm_hw_fast_tstamp(dsnoop->spcm);
}
return 0;
}
--
1.7.3.1

View File

@ -1,56 +0,0 @@
From ab6df229015f46bc2c7b50f5278480d996b232c0 Mon Sep 17 00:00:00 2001
From: Clemens Ladisch <clemens@ladisch.de>
Date: Wed, 10 Nov 2010 10:11:51 +0100
Subject: [PATCH 04/10] USB-Audio.conf: fix Audiophile USB card name
The device name of the M-Audio AudioPhile USB is actually "Audiophile USB (tm)".
Also keep the old string, just to be sure.
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
---
src/conf/cards/USB-Audio.conf | 8 ++++++--
1 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/src/conf/cards/USB-Audio.conf b/src/conf/cards/USB-Audio.conf
index 5849e3f..0726c34 100644
--- a/src/conf/cards/USB-Audio.conf
+++ b/src/conf/cards/USB-Audio.conf
@@ -16,6 +16,7 @@
# here.
USB-Audio.pcm.use_dmix {
"AudioPhile" no # uses big-endian 24-bit samples
+ "Audiophile USB (tm)" no
}
# If a device does not have a four-channel mode for the front/rear outputs,
@@ -25,6 +26,7 @@ USB-Audio.pcm.use_dmix {
# two_stereo_devices - for devices that have two stereo audio interfaces
USB-Audio.pcm.surround40_type {
"AudioPhile" two_stereo_devices
+ "Audiophile USB (tm)" two_stereo_devices
"OmniStudio" two_stereo_devices
"Quattro" two_stereo_devices
"SB Audigy 2 NX" six_channels
@@ -43,7 +45,8 @@ USB-Audio.pcm.iec958_device {
# M-Audio AudioPhile USB:
# device 0: analog output, digital input
# device 1: digital output, analog input
-USB-Audio."AudioPhile".pcm.default {
+USB-Audio."AudioPhile".pcm.default "cards.USB-Audio.Audiophile USB (tm).pcm.default"
+USB-Audio."Audiophile USB (tm)".pcm.default {
@args [ CARD ]
@args.CARD { type string }
type asym
@@ -63,7 +66,8 @@ USB-Audio."AudioPhile".pcm.default {
}
}
}
-USB-Audio."AudioPhile".pcm.iec958 {
+USB-Audio."AudioPhile".pcm.iec958 "cards.USB-Audio.Audiophile USB (tm).pcm.iec958"
+USB-Audio."Audiophile USB (tm)".pcm.iec958 {
@args [ CARD AES0 AES1 AES2 AES3 ]
@args.CARD { type string }
@args.AES0 { type integer }
--
1.7.3.1

View File

@ -1,30 +0,0 @@
From 70dded6aba653b5f70b48fda22f9b322fd3ae2c9 Mon Sep 17 00:00:00 2001
From: Clemens Ladisch <clemens@ladisch.de>
Date: Mon, 15 Nov 2010 10:33:35 +0100
Subject: [PATCH 05/10] pcm: pass hw_params flags to slave
Fix required before interrupt disabling routines patch can be applied.
Without this fix, the interrupts are only disabled when directly
accessing hw devices.
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@intel.com>
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
---
src/pcm/pcm_params.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/src/pcm/pcm_params.c b/src/pcm/pcm_params.c
index 3a90bcd..b085d42 100644
--- a/src/pcm/pcm_params.c
+++ b/src/pcm/pcm_params.c
@@ -2126,6 +2126,7 @@ int _snd_pcm_hw_params_refine(snd_pcm_hw_params_t *params,
err = changed;
}
params->info &= src->info;
+ params->flags = src->flags; /* propagate all flags to slave */
return err;
}
--
1.7.3.1

View File

@ -1,175 +0,0 @@
From 7c99bd24bcf6852d55e90e0f42f7ac5ea8f14fbb Mon Sep 17 00:00:00 2001
From: Clemens Ladisch <clemens@ladisch.de>
Date: Mon, 15 Nov 2010 10:43:13 +0100
Subject: [PATCH 06/10] support for period wakeup disabling
Add API to disable period wakeups.
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@intel.com>
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
---
include/pcm.h | 3 ++
include/sound/asound.h | 2 +
src/pcm/pcm.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++-
src/pcm/pcm_local.h | 3 ++
4 files changed, 79 insertions(+), 1 deletions(-)
diff --git a/include/pcm.h b/include/pcm.h
index f3618c3..7243ffb 100644
--- a/include/pcm.h
+++ b/include/pcm.h
@@ -531,6 +531,7 @@ int snd_pcm_hw_params_can_resume(const snd_pcm_hw_params_t *params);
int snd_pcm_hw_params_is_half_duplex(const snd_pcm_hw_params_t *params);
int snd_pcm_hw_params_is_joint_duplex(const snd_pcm_hw_params_t *params);
int snd_pcm_hw_params_can_sync_start(const snd_pcm_hw_params_t *params);
+int snd_pcm_hw_params_can_disable_period_wakeup(const snd_pcm_hw_params_t *params);
int snd_pcm_hw_params_get_rate_numden(const snd_pcm_hw_params_t *params,
unsigned int *rate_num,
unsigned int *rate_den);
@@ -626,6 +627,8 @@ int snd_pcm_hw_params_set_rate_resample(snd_pcm_t *pcm, snd_pcm_hw_params_t *par
int snd_pcm_hw_params_get_rate_resample(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val);
int snd_pcm_hw_params_set_export_buffer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val);
int snd_pcm_hw_params_get_export_buffer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val);
+int snd_pcm_hw_params_set_period_wakeup(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val);
+int snd_pcm_hw_params_get_period_wakeup(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val);
int snd_pcm_hw_params_get_period_time(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
int snd_pcm_hw_params_get_period_time_min(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
diff --git a/include/sound/asound.h b/include/sound/asound.h
index fa88938..17dfe8f 100644
--- a/include/sound/asound.h
+++ b/include/sound/asound.h
@@ -278,6 +278,7 @@ enum sndrv_pcm_subformat {
#define SNDRV_PCM_INFO_HALF_DUPLEX 0x00100000 /* only half duplex */
#define SNDRV_PCM_INFO_JOINT_DUPLEX 0x00200000 /* playback and capture stream are somewhat correlated */
#define SNDRV_PCM_INFO_SYNC_START 0x00400000 /* pcm support some kind of sync go */
+#define SNDRV_PCM_INFO_NO_PERIOD_WAKEUP 0x00800000 /* period wakeup can be disabled */
enum sndrv_pcm_state {
SNDRV_PCM_STATE_OPEN = 0, /* stream is open */
@@ -346,6 +347,7 @@ enum sndrv_pcm_hw_param {
#define SNDRV_PCM_HW_PARAMS_NORESAMPLE (1<<0) /* avoid rate resampling */
#define SNDRV_PCM_HW_PARAMS_EXPORT_BUFFER (1<<1) /* export buffer */
+#define SNDRV_PCM_HW_PARAMS_NO_PERIOD_WAKEUP (1<<2) /* disable period wakeups */
struct sndrv_interval {
unsigned int min, max;
diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c
index a49b5b9..f378779 100644
--- a/src/pcm/pcm.c
+++ b/src/pcm/pcm.c
@@ -726,8 +726,11 @@ int snd_pcm_nonblock(snd_pcm_t *pcm, int nonblock)
return err;
if (nonblock)
pcm->mode |= SND_PCM_NONBLOCK;
- else
+ else {
+ if (pcm->hw_flags & SND_PCM_HW_PARAMS_NO_PERIOD_WAKEUP)
+ return -EINVAL;
pcm->mode &= ~SND_PCM_NONBLOCK;
+ }
return 0;
}
@@ -3081,6 +3084,23 @@ int snd_pcm_hw_params_can_sync_start(const snd_pcm_hw_params_t *params)
}
/**
+ * \brief Check if hardware can disable period wakeups
+ * \param params Configuration space
+ * \return Boolean value
+ * \retval 0 Hardware cannot disable period wakeups
+ * \retval 1 Hardware can disable period wakeups
+ */
+int snd_pcm_hw_params_can_disable_period_wakeup(const snd_pcm_hw_params_t *params)
+{
+ assert(params);
+ if (CHECK_SANITY(params->info == ~0U)) {
+ SNDMSG("invalid PCM info field");
+ return 0; /* FIXME: should be a negative error? */
+ }
+ return !!(params->info & SNDRV_PCM_INFO_NO_PERIOD_WAKEUP);
+}
+
+/**
* \brief Get rate exact info from a configuration space
* \param params Configuration space
* \param rate_num Pointer to returned rate numerator
@@ -4200,6 +4220,56 @@ int snd_pcm_hw_params_get_export_buffer(snd_pcm_t *pcm, snd_pcm_hw_params_t *par
}
/**
+ * \brief Restrict a configuration space to settings without period wakeups
+ * \param pcm PCM handle
+ * \param params Configuration space
+ * \param val 0 = disable, 1 = enable (default) period wakeup
+ * \return Zero on success, otherwise a negative error code.
+ *
+ * This function must be called only on devices where non-blocking mode is
+ * enabled.
+ *
+ * To check whether the hardware does support disabling period wakeups, call
+ * #snd_pcm_hw_params_can_disable_period_wakeup(). If the hardware does not
+ * support this mode, standard period wakeups will be generated.
+ *
+ * Even with disabled period wakeups, the period size/time/count parameters
+ * are valid; it is suggested to use #snd_pcm_hw_params_set_period_size_last().
+ *
+ * When period wakeups are disabled, the application must not use any functions
+ * that could block on this device. The use of poll should be limited to error
+ * cases. The application needs to use an external event or a timer to
+ * check the state of the ring buffer and refill it apropriately.
+ */
+int snd_pcm_hw_params_set_period_wakeup(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val)
+{
+ assert(pcm && params);
+
+ if (!val) {
+ if (!(pcm->mode & SND_PCM_NONBLOCK))
+ return -EINVAL;
+ params->flags |= SND_PCM_HW_PARAMS_NO_PERIOD_WAKEUP;
+ } else
+ params->flags &= ~SND_PCM_HW_PARAMS_NO_PERIOD_WAKEUP;
+
+ return snd_pcm_hw_refine(pcm, params);
+}
+
+/**
+ * \brief Extract period wakeup flag from a configuration space
+ * \param pcm PCM handle
+ * \param params Configuration space
+ * \param val 0 = disabled, 1 = enabled period wakeups
+ * \return Zero on success, otherwise a negative error code.
+ */
+int snd_pcm_hw_params_get_period_wakeup(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)
+{
+ assert(pcm && params && val);
+ *val = params->flags & SND_PCM_HW_PARAMS_NO_PERIOD_WAKEUP ? 0 : 1;
+ return 0;
+}
+
+/**
* \brief Extract period time from a configuration space
* \param params Configuration space
* \param val Returned approximate period duration in us
diff --git a/src/pcm/pcm_local.h b/src/pcm/pcm_local.h
index 2f6fcd2..2e901d5 100644
--- a/src/pcm/pcm_local.h
+++ b/src/pcm/pcm_local.h
@@ -91,9 +91,12 @@ typedef enum sndrv_pcm_hw_param snd_pcm_hw_param_t;
#define SND_PCM_INFO_JOINT_DUPLEX SNDRV_PCM_INFO_JOINT_DUPLEX
/** device can do a kind of synchronized start */
#define SND_PCM_INFO_SYNC_START SNDRV_PCM_INFO_SYNC_START
+/** device can disable period wakeups */
+#define SND_PCM_INFO_NO_PERIOD_WAKEUP SNDRV_PCM_INFO_NO_PERIOD_WAKEUP
#define SND_PCM_HW_PARAMS_NORESAMPLE SNDRV_PCM_HW_PARAMS_NORESAMPLE
#define SND_PCM_HW_PARAMS_EXPORT_BUFFER SNDRV_PCM_HW_PARAMS_EXPORT_BUFFER
+#define SND_PCM_HW_PARAMS_NO_PERIOD_WAKEUP SNDRV_PCM_HW_PARAMS_NO_PERIOD_WAKEUP
#define SND_PCM_INFO_MONOTONIC 0x80000000
--
1.7.3.1

View File

@ -1,47 +0,0 @@
From ba9332e9192814a5431a3a2505d25d74a9232124 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Thu, 18 Nov 2010 09:27:07 +0100
Subject: [PATCH 07/10] pcm: fix snd_pcm_avail_delay() function
For capture stream, the delay must be obtained as last, but we need to
update the ring buffer pointers for the avail_update call. So, rearrange
the code a bit and add hwsync call as first.
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
src/pcm/pcm.c | 10 +++++++---
1 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c
index f378779..7409943 100644
--- a/src/pcm/pcm.c
+++ b/src/pcm/pcm.c
@@ -2470,18 +2470,22 @@ int snd_pcm_avail_delay(snd_pcm_t *pcm,
snd_pcm_sframes_t *delayp)
{
snd_pcm_sframes_t sf;
+ int err;
assert(pcm && availp && delayp);
if (CHECK_SANITY(! pcm->setup)) {
SNDMSG("PCM not set up");
return -EIO;
}
- sf = pcm->fast_ops->delay(pcm->fast_op_arg, delayp);
- if (sf < 0)
- return (int)sf;
+ err = pcm->fast_ops->hwsync(pcm->fast_op_arg);
+ if (err < 0)
+ return err;
sf = pcm->fast_ops->avail_update(pcm->fast_op_arg);
if (sf < 0)
return (int)sf;
+ err = pcm->fast_ops->delay(pcm->fast_op_arg, delayp);
+ if (err < 0)
+ return err;
*availp = sf;
return 0;
}
--
1.7.3.1

View File

@ -1,119 +0,0 @@
From ade3efbd865967bf78d7f0ae6a2fe9809ea90719 Mon Sep 17 00:00:00 2001
From: Pierre-Louis Bossart <pierre-louis.bossart@intel.com>
Date: Fri, 19 Nov 2010 10:35:31 -0600
Subject: [PATCH 08/10] pcm_plugin: remove unused client_frames and slave_frames routines
plug->client_frames and plug->slave_frames are not used by
any plugin, remove dead code.
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@intel.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
src/pcm/pcm_plugin.c | 33 ++++-----------------------------
src/pcm/pcm_plugin.h | 2 --
2 files changed, 4 insertions(+), 31 deletions(-)
diff --git a/src/pcm/pcm_plugin.c b/src/pcm/pcm_plugin.c
index 0ef394a..19d0dee 100644
--- a/src/pcm/pcm_plugin.c
+++ b/src/pcm/pcm_plugin.c
@@ -144,8 +144,6 @@ static int snd_pcm_plugin_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
int err = snd_pcm_delay(plugin->gen.slave, &sd);
if (err < 0)
return err;
- if (plugin->client_frames)
- sd = plugin->client_frames(pcm, sd);
*delayp = sd;
return 0;
}
@@ -208,18 +206,13 @@ static snd_pcm_sframes_t snd_pcm_plugin_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t
if (frames == 0)
return 0;
- if (plugin->slave_frames)
- sframes = plugin->slave_frames(pcm, (snd_pcm_sframes_t) frames);
- else
- sframes = frames;
+ sframes = frames;
snd_atomic_write_begin(&plugin->watom);
sframes = snd_pcm_rewind(plugin->gen.slave, sframes);
if (sframes < 0) {
snd_atomic_write_end(&plugin->watom);
return sframes;
}
- if (plugin->client_frames)
- frames = plugin->client_frames(pcm, sframes);
snd_pcm_mmap_appl_backward(pcm, (snd_pcm_uframes_t) frames);
snd_atomic_write_end(&plugin->watom);
return (snd_pcm_sframes_t) frames;
@@ -241,18 +234,13 @@ static snd_pcm_sframes_t snd_pcm_plugin_forward(snd_pcm_t *pcm, snd_pcm_uframes_
if (frames == 0)
return 0;
- if (plugin->slave_frames)
- sframes = plugin->slave_frames(pcm, (snd_pcm_sframes_t) frames);
- else
- sframes = frames;
+ sframes = frames;
snd_atomic_write_begin(&plugin->watom);
sframes = INTERNAL(snd_pcm_forward)(plugin->gen.slave, sframes);
if (sframes < 0) {
snd_atomic_write_end(&plugin->watom);
return sframes;
}
- if (plugin->client_frames)
- frames = plugin->client_frames(pcm, sframes);
snd_pcm_mmap_appl_forward(pcm, (snd_pcm_uframes_t) frames);
snd_atomic_write_end(&plugin->watom);
return (snd_pcm_sframes_t) frames;
@@ -469,15 +457,8 @@ static snd_pcm_sframes_t snd_pcm_plugin_avail_update(snd_pcm_t *pcm)
pcm->access != SND_PCM_ACCESS_RW_INTERLEAVED &&
pcm->access != SND_PCM_ACCESS_RW_NONINTERLEAVED)
goto _capture;
- if (plugin->client_frames) {
- *pcm->hw.ptr = plugin->client_frames(pcm, *slave->hw.ptr);
- if (slave_size <= 0)
- return slave_size;
- return plugin->client_frames(pcm, slave_size);
- } else {
- *pcm->hw.ptr = *slave->hw.ptr;
- return slave_size;
- }
+ *pcm->hw.ptr = *slave->hw.ptr;
+ return slave_size;
_capture:
{
const snd_pcm_channel_area_t *areas;
@@ -547,16 +528,10 @@ static int snd_pcm_plugin_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
}
status->appl_ptr = *pcm->appl.ptr;
status->hw_ptr = *pcm->hw.ptr;
- if (plugin->client_frames) {
- status->delay = plugin->client_frames(pcm, status->delay);
- status->avail = plugin->client_frames(pcm, status->avail);
- }
if (!snd_atomic_read_ok(&ratom)) {
snd_atomic_read_wait(&ratom);
goto _again;
}
- if (plugin->client_frames)
- status->avail_max = plugin->client_frames(pcm, (snd_pcm_sframes_t) status->avail_max);
return 0;
}
diff --git a/src/pcm/pcm_plugin.h b/src/pcm/pcm_plugin.h
index dfcf6de..7ee7c7f 100644
--- a/src/pcm/pcm_plugin.h
+++ b/src/pcm/pcm_plugin.h
@@ -44,8 +44,6 @@ typedef struct {
snd_pcm_slave_xfer_areas_func_t write;
snd_pcm_slave_xfer_areas_undo_func_t undo_read;
snd_pcm_slave_xfer_areas_undo_func_t undo_write;
- snd_pcm_sframes_t (*client_frames)(snd_pcm_t *pcm, snd_pcm_sframes_t frames);
- snd_pcm_sframes_t (*slave_frames)(snd_pcm_t *pcm, snd_pcm_sframes_t frames);
int (*init)(snd_pcm_t *pcm);
snd_pcm_uframes_t appl_ptr, hw_ptr;
snd_atomic_write_t watom;
--
1.7.3.1

View File

@ -1,29 +0,0 @@
From a4f71b19407fde8d5fd4f35850543173636b3ee0 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Tue, 23 Nov 2010 13:40:25 +0100
Subject: [PATCH 09/10] pcm: add MMAP_EMUL to type names
If we try to print this then it causes a read past the end of the array
in snd_pcm_type_name().
From: Dan Carpenter <error27@gmail.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
src/pcm/pcm.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c
index 7409943..906b502 100644
--- a/src/pcm/pcm.c
+++ b/src/pcm/pcm.c
@@ -1633,6 +1633,7 @@ static const char *const snd_pcm_type_names[] = {
PCMTYPE(SOFTVOL),
PCMTYPE(IOPLUG),
PCMTYPE(EXTPLUG),
+ PCMTYPE(MMAP_EMUL),
};
static const char *const snd_pcm_subformat_names[] = {
--
1.7.3.1

View File

@ -1,38 +0,0 @@
From aba87e509898ec9ddb3e319267d7c267409ff100 Mon Sep 17 00:00:00 2001
From: Pierre-Louis Bossart <pierre-louis.bossart@intel.com>
Date: Tue, 23 Nov 2010 08:47:08 -0600
Subject: [PATCH 10/10] pcm_plugin: fix delay
PulseAudio ALSA modules report errors after calling
snd_pcm_avail_delay(), with a delay lower than the number of samples
available.
Correct delay using Jaroslav's recommendation:
"the result should be 'delay(slave) + mmap_capture_avail(pcm)"
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@intel.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
src/pcm/pcm_plugin.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/src/pcm/pcm_plugin.c b/src/pcm/pcm_plugin.c
index 19d0dee..d88e117 100644
--- a/src/pcm/pcm_plugin.c
+++ b/src/pcm/pcm_plugin.c
@@ -144,6 +144,12 @@ static int snd_pcm_plugin_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
int err = snd_pcm_delay(plugin->gen.slave, &sd);
if (err < 0)
return err;
+ if (pcm->stream == SND_PCM_STREAM_CAPTURE &&
+ pcm->access != SND_PCM_ACCESS_RW_INTERLEAVED &&
+ pcm->access != SND_PCM_ACCESS_RW_NONINTERLEAVED) {
+ sd += snd_pcm_mmap_capture_avail(pcm);
+ }
+
*delayp = sd;
return 0;
}
--
1.7.3.1

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b4238ecaba5e4a1383af06180611a57ef29f9bf47bc177136dba1bb5b70ff423
size 808271

View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a32f7c21015b6c71f9a80ff70a2b6a50e4ff4d5c77c744ff0793dea7ba7a2517
size 832555

View File

@ -0,0 +1,21 @@
diff --git a/doc/doxygen.cfg.in b/doc/doxygen.cfg.in
index f4499d6..6bd6486 100644
--- a/doc/doxygen.cfg.in
+++ b/doc/doxygen.cfg.in
@@ -77,7 +77,6 @@ INPUT = @top_srcdir@/doc/index.doxygen \
@top_srcdir@/src/rawmidi \
@top_srcdir@/src/timer \
@top_srcdir@/src/hwdep \
- @top_srcdir@/src/seq \
@top_srcdir@/src/ucm
EXCLUDE = @top_srcdir@/src/control/control_local.h \
@top_srcdir@/src/pcm/atomic.h \
@@ -94,7 +93,7 @@ EXCLUDE = @top_srcdir@/src/control/control_local.h \
@top_srcdir@/src/mixer/mixer_local.h \
@top_srcdir@/src/rawmidi/rawmidi_local.h \
@top_srcdir@/src/seq/seq_local.h \
- @top_srcdir@/src/seq/ucm_local.h
+ @top_srcdir@/src/ucm/ucm_local.h
RECURSIVE = YES
FILE_PATTERNS = *.c *.h
EXAMPLE_PATH = @top_srcdir@/test

View File

@ -1,3 +1,11 @@
-------------------------------------------------------------------
Mon Jan 31 17:14:35 CET 2011 - tiwai@suse.de
- updated to version 1.0.24.1:
* including previous fix patches
* add the UCM (Use Cas Manager) framework
- Add a hack to avoid crash of doxygen on 11.3 builds
-------------------------------------------------------------------
Fri Nov 26 09:29:58 CET 2010 - tiwai@suse.de

View File

@ -1,5 +1,5 @@
#
# spec file for package alsa (Version 1.0.23)
# spec file for package alsa (Version 1.0.24.1)
#
# Copyright (c) 2010 SUSE LINUX Products GmbH, Nuernberg, Germany.
#
@ -20,7 +20,7 @@
Name: alsa
BuildRequires: doxygen pkg-config
%define package_version 1.0.23
%define package_version 1.0.24.1
License: LGPLv2.1+
Group: System/Libraries
Requires: alsa-utils
@ -33,8 +33,8 @@ Obsoletes: alsa-64bit
%endif
#
Summary: Advanced Linux Sound Architecture
Version: 1.0.23
Release: 8
Version: 1.0.24.1
Release: 1
Source: ftp://ftp.alsa-project.org/pub/lib/alsa-lib-%{package_version}.tar.bz2
Source2: baselibs.conf
Source8: 40-alsa.rules
@ -52,42 +52,7 @@ Source32: all_notes_off.mid
Source33: alsa-info.sh
Source34: alsa-init.sh
# Patch: alsa-lib-git-fixes.diff
Patch1: 0001-Check-for-thread-specific-locale-support.patch
Patch2: 0002-Use-thread-safe-locale-functions-if-available.patch
Patch3: 0003-seq-Fix-for-snd_seq_parse_address.patch
Patch4: 0004-control-tlv-Check-dB-range-only-within-the-control-s.patch
Patch5: 0005-alisp-Fix-a-string-format-ambiguity.patch
Patch6: 0006-tlv-Check-out-of-range-dB-with-SND_CTL_TLVT_DB_RANGE.patch
Patch7: 0007-tlv-Handle-holes-in-SND_CTL_TLVT_DB_RANGE-array.patch
Patch8: 0008-tlv-Remove-tailing-tab-after-snd_ctl_get_dB_range-fu.patch
Patch9: 0009-Memory-leak-in-namehint.c.patch
Patch10: 0010-pcm-ladspa-fix-small-memory-leak-in-snd_pcm_ladspa_f.patch
Patch11: 0011-pcm_plug-fix-comparison-always-true.patch
Patch12: 0012-test-latency-fix-timediff-calculation.patch
Patch13: 0013-HDA-Intel-present-all-4-HDMI-outputs-instead-of-just.patch
Patch14: 0014-pcm-add-defaults.pcm.minperiodtime-parsing.patch
Patch15: 0015-pcm-introduce-defaults.pcm.compat-to-change-the-para.patch
Patch16: 0016-pcm-Fixed-typo-wrong-deleted-line-instroduced-in-the.patch
Patch17: 0017-Add-missing-support-for-3-byte-formats-for-16bit-put.patch
Patch18: 0018-namehint-Evaluate-more-possibilities-for-hw-devices.patch
Patch19: 0019-HDA-Intel-do-not-lock-IEC958-Playback-switch.patch
Patch20: 0020-general-recoded-snd_dlobj_-functions.patch
Patch21: 0021-Add-Loopback.conf-to-define-standard-PCM-devices-for.patch
Patch22: 0022-Fix-typo-for-surround-PCMs-in-src-conf-cards-Loopbac.patch
Patch23: 0023-namehint-Fix-hw-device-evaluation-missing-last-devic.patch
Patch24: 0024-namehint-Another-fix-to-properly-evaluate-hw-devices.patch
Patch25: 0025-config-file-processing-rewrite-the-locking-use-one-r.patch
Patch26: 0026-tlv-fix-returned-dB-information-for-min-is-mute-cont.patch
Patch27: 0027-Version-check-libtool-correctly-when-doing-an-out-of.patch
Patch28: 0028-configure.in-don-t-rely-on-test-a-not-all-shells-sup.patch
Patch29: 0029-pcm-direct-plugins-change-timestamping-in-dsnoop.patch
Patch30: 0030-USB-Audio.conf-fix-Audiophile-USB-card-name.patch
Patch31: 0031-pcm-pass-hw_params-flags-to-slave.patch
Patch32: 0032-support-for-period-wakeup-disabling.patch
Patch33: 0033-pcm-fix-snd_pcm_avail_delay-function.patch
Patch34: 0034-pcm_plugin-remove-unused-client_frames-and-slave_fra.patch
Patch35: 0035-pcm-add-MMAP_EMUL-to-type-names.patch
Patch36: 0036-pcm_plugin-fix-delay.patch
Patch1: alsa-lib-doxygen-avoid-crash-for-11.3.diff
Url: http://www.alsa-project.org/
BuildRoot: %{_tmppath}/%{name}-%{version}-build
@ -163,42 +128,9 @@ Authors:
%prep
%setup -q -n alsa-lib-%{package_version}
# %patch -p1
%if %suse_version == 1130
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch4 -p1
%patch5 -p1
%patch6 -p1
%patch7 -p1
%patch8 -p1
%patch9 -p1
%patch10 -p1
%patch11 -p1
%patch12 -p1
%patch13 -p1
%patch14 -p1
%patch15 -p1
%patch16 -p1
%patch17 -p1
%patch18 -p1
%patch19 -p1
%patch20 -p1
%patch21 -p1
%patch22 -p1
%patch23 -p1
%patch24 -p1
%patch25 -p1
%patch26 -p1
%patch27 -p1
%patch28 -p1
%patch29 -p1
%patch30 -p1
%patch31 -p1
%patch32 -p1
%patch33 -p1
%patch34 -p1
%patch35 -p1
%patch36 -p1
%endif
# hack to fix build on older distros
%if %suse_version < 1100
%ifarch %ix86