Accepting request 47041 from multimedia:libs

Copy from multimedia:libs/alsa based on submit request 47041 from user tiwai

OBS-URL: https://build.opensuse.org/request/show/47041
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/alsa?expand=0&rev=91
This commit is contained in:
OBS User autobuild 2010-09-03 14:40:54 +00:00 committed by Git OBS Bridge
commit 74b4b5a228
23 changed files with 1743 additions and 1 deletions

View File

@ -0,0 +1,29 @@
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

@ -0,0 +1,66 @@
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

@ -0,0 +1,35 @@
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

@ -0,0 +1,52 @@
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

@ -0,0 +1,26 @@
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

@ -0,0 +1,49 @@
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

@ -0,0 +1,76 @@
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

@ -0,0 +1,31 @@
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

@ -0,0 +1,30 @@
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

@ -0,0 +1,26 @@
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

@ -0,0 +1,27 @@
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

@ -0,0 +1,26 @@
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

@ -0,0 +1,166 @@
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

@ -0,0 +1,98 @@
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

@ -0,0 +1,91 @@
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

@ -0,0 +1,25 @@
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

@ -0,0 +1,112 @@
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

@ -0,0 +1,59 @@
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

@ -0,0 +1,40 @@
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

@ -0,0 +1,516 @@
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

@ -0,0 +1,94 @@
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,3 +1,29 @@
-------------------------------------------------------------------
Thu Sep 2 15:52:04 CEST 2010 - tiwai@suse.de
- Backport patches from GIT:
* 0001-Check-for-thread-specific-locale-support.patch
* 0002-Use-thread-safe-locale-functions-if-available.patch
* 0003-seq-Fix-for-snd_seq_parse_address.patch
* 0004-control-tlv-Check-dB-range-only-within-the-control-s.patch
* 0005-alisp-Fix-a-string-format-ambiguity.patch
* 0006-tlv-Check-out-of-range-dB-with-SND_CTL_TLVT_DB_RANGE.patch
* 0007-tlv-Handle-holes-in-SND_CTL_TLVT_DB_RANGE-array.patch
* 0008-tlv-Remove-tailing-tab-after-snd_ctl_get_dB_range-fu.patch
* 0009-Memory-leak-in-namehint.c.patch
* 0010-pcm-ladspa-fix-small-memory-leak-in-snd_pcm_ladspa_f.patch
* 0011-pcm_plug-fix-comparison-always-true.patch
* 0012-test-latency-fix-timediff-calculation.patch
* 0013-HDA-Intel-present-all-4-HDMI-outputs-instead-of-just.patch
* 0014-pcm-add-defaults.pcm.minperiodtime-parsing.patch
* 0015-pcm-introduce-defaults.pcm.compat-to-change-the-para.patch
* 0016-pcm-Fixed-typo-wrong-deleted-line-instroduced-in-the.patch
* 0017-Add-missing-support-for-3-byte-formats-for-16bit-put.patch
* 0018-namehint-Evaluate-more-possibilities-for-hw-devices.patch
* 0019-HDA-Intel-do-not-lock-IEC958-Playback-switch.patch
* 0020-general-recoded-snd_dlobj_-functions.patch
* 0021-Add-Loopback.conf-to-define-standard-PCM-devices-for.patch
-------------------------------------------------------------------
Thu May 6 16:27:19 CEST 2010 - tiwai@suse.de

View File

@ -34,7 +34,7 @@ Obsoletes: alsa-64bit
#
Summary: Advanced Linux Sound Architecture
Version: 1.0.23
Release: 5
Release: 6
Source: ftp://ftp.alsa-project.org/pub/lib/alsa-lib-%{package_version}.tar.bz2
Source2: baselibs.conf
Source8: 40-alsa.rules
@ -52,6 +52,27 @@ 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
Url: http://www.alsa-project.org/
BuildRoot: %{_tmppath}/%{name}-%{version}-build
@ -127,6 +148,27 @@ Authors:
%prep
%setup -q -n alsa-lib-%{package_version}
# %patch -p1
%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
# hack to fix build on older distros
%if %suse_version < 1100
%ifarch %ix86