From d3edfd16ef6f4da0790c0f06dc9ea7f04967dbcac8b4d4fda6a88b11b29fab67 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 2 Sep 2010 13:55:02 +0000 Subject: [PATCH 1/3] backport fixes OBS-URL: https://build.opensuse.org/package/show/multimedia:libs/alsa?expand=0&rev=63 --- ...k-for-thread-specific-locale-support.patch | 29 + ...d-safe-locale-functions-if-available.patch | 66 +++ 0003-seq-Fix-for-snd_seq_parse_address.patch | 35 ++ ...k-dB-range-only-within-the-control-s.patch | 52 ++ ...-alisp-Fix-a-string-format-ambiguity.patch | 26 + ...-range-dB-with-SND_CTL_TLVT_DB_RANGE.patch | 49 ++ ...holes-in-SND_CTL_TLVT_DB_RANGE-array.patch | 76 +++ ...ng-tab-after-snd_ctl_get_dB_range-fu.patch | 31 ++ 0009-Memory-leak-in-namehint.c.patch | 30 + ...mall-memory-leak-in-snd_pcm_ladspa_f.patch | 26 + ...-pcm_plug-fix-comparison-always-true.patch | 27 + ...est-latency-fix-timediff-calculation.patch | 26 + ...t-all-4-HDMI-outputs-instead-of-just.patch | 166 ++++++ ...d-defaults.pcm.minperiodtime-parsing.patch | 98 ++++ ...faults.pcm.compat-to-change-the-para.patch | 91 +++ ...rong-deleted-line-instroduced-in-the.patch | 25 + ...ort-for-3-byte-formats-for-16bit-put.patch | 112 ++++ ...te-more-possibilities-for-hw-devices.patch | 59 ++ ...l-do-not-lock-IEC958-Playback-switch.patch | 40 ++ ...general-recoded-snd_dlobj_-functions.patch | 516 ++++++++++++++++++ ...f-to-define-standard-PCM-devices-for.patch | 94 ++++ alsa.changes | 26 + alsa.spec | 42 ++ 23 files changed, 1742 insertions(+) create mode 100644 0001-Check-for-thread-specific-locale-support.patch create mode 100644 0002-Use-thread-safe-locale-functions-if-available.patch create mode 100644 0003-seq-Fix-for-snd_seq_parse_address.patch create mode 100644 0004-control-tlv-Check-dB-range-only-within-the-control-s.patch create mode 100644 0005-alisp-Fix-a-string-format-ambiguity.patch create mode 100644 0006-tlv-Check-out-of-range-dB-with-SND_CTL_TLVT_DB_RANGE.patch create mode 100644 0007-tlv-Handle-holes-in-SND_CTL_TLVT_DB_RANGE-array.patch create mode 100644 0008-tlv-Remove-tailing-tab-after-snd_ctl_get_dB_range-fu.patch create mode 100644 0009-Memory-leak-in-namehint.c.patch create mode 100644 0010-pcm-ladspa-fix-small-memory-leak-in-snd_pcm_ladspa_f.patch create mode 100644 0011-pcm_plug-fix-comparison-always-true.patch create mode 100644 0012-test-latency-fix-timediff-calculation.patch create mode 100644 0013-HDA-Intel-present-all-4-HDMI-outputs-instead-of-just.patch create mode 100644 0014-pcm-add-defaults.pcm.minperiodtime-parsing.patch create mode 100644 0015-pcm-introduce-defaults.pcm.compat-to-change-the-para.patch create mode 100644 0016-pcm-Fixed-typo-wrong-deleted-line-instroduced-in-the.patch create mode 100644 0017-Add-missing-support-for-3-byte-formats-for-16bit-put.patch create mode 100644 0018-namehint-Evaluate-more-possibilities-for-hw-devices.patch create mode 100644 0019-HDA-Intel-do-not-lock-IEC958-Playback-switch.patch create mode 100644 0020-general-recoded-snd_dlobj_-functions.patch create mode 100644 0021-Add-Loopback.conf-to-define-standard-PCM-devices-for.patch diff --git a/0001-Check-for-thread-specific-locale-support.patch b/0001-Check-for-thread-specific-locale-support.patch new file mode 100644 index 0000000..55672ed --- /dev/null +++ b/0001-Check-for-thread-specific-locale-support.patch @@ -0,0 +1,29 @@ +From 51ef640cee37f73d771e784e81196ff7c15f53ff Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?R=C3=A9mi=20Denis-Courmont?= +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 +Signed-off-by: Jaroslav Kysela +--- + 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 + diff --git a/0002-Use-thread-safe-locale-functions-if-available.patch b/0002-Use-thread-safe-locale-functions-if-available.patch new file mode 100644 index 0000000..91ce510 --- /dev/null +++ b/0002-Use-thread-safe-locale-functions-if-available.patch @@ -0,0 +1,66 @@ +From 8d80d5f344ae5e32d24122cbf8e759fdd1e1a60d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?R=C3=A9mi=20Denis-Courmont?= +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 +Signed-off-by: Jaroslav Kysela +--- + 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 + diff --git a/0003-seq-Fix-for-snd_seq_parse_address.patch b/0003-seq-Fix-for-snd_seq_parse_address.patch new file mode 100644 index 0000000..0361909 --- /dev/null +++ b/0003-seq-Fix-for-snd_seq_parse_address.patch @@ -0,0 +1,35 @@ +From 19892334499ed21ed4dc30084ad8700253f9cb2f Mon Sep 17 00:00:00 2001 +From: Pedro Lopez-Cabanillas +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 +Signed-off-by: Jaroslav Kysela +--- + 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 + diff --git a/0004-control-tlv-Check-dB-range-only-within-the-control-s.patch b/0004-control-tlv-Check-dB-range-only-within-the-control-s.patch new file mode 100644 index 0000000..f38229e --- /dev/null +++ b/0004-control-tlv-Check-dB-range-only-within-the-control-s.patch @@ -0,0 +1,52 @@ +From 30ad5ed04017f7e77b25cf40f18c26396903cd23 Mon Sep 17 00:00:00 2001 +From: Peter Ujfalusi +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 +Signed-off-by: Jaroslav Kysela +--- + 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 + diff --git a/0005-alisp-Fix-a-string-format-ambiguity.patch b/0005-alisp-Fix-a-string-format-ambiguity.patch new file mode 100644 index 0000000..1da5526 --- /dev/null +++ b/0005-alisp-Fix-a-string-format-ambiguity.patch @@ -0,0 +1,26 @@ +From 191c57805a791925ab5992f127a1cb5f4ab56c9c Mon Sep 17 00:00:00 2001 +From: Colin Guthrie +Date: Sun, 28 Feb 2010 22:25:26 +0000 +Subject: [PATCH 05/21] alisp - Fix a string format ambiguity + +Signed-off-by: Takashi Iwai +--- + 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 + diff --git a/0006-tlv-Check-out-of-range-dB-with-SND_CTL_TLVT_DB_RANGE.patch b/0006-tlv-Check-out-of-range-dB-with-SND_CTL_TLVT_DB_RANGE.patch new file mode 100644 index 0000000..2353585 --- /dev/null +++ b/0006-tlv-Check-out-of-range-dB-with-SND_CTL_TLVT_DB_RANGE.patch @@ -0,0 +1,49 @@ +From 16a2cad39b7ee29e34b92d39d72eebfc88f8dc22 Mon Sep 17 00:00:00 2001 +From: Peter Ujfalusi +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 +Signed-off-by: Takashi Iwai +--- + 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 + diff --git a/0007-tlv-Handle-holes-in-SND_CTL_TLVT_DB_RANGE-array.patch b/0007-tlv-Handle-holes-in-SND_CTL_TLVT_DB_RANGE-array.patch new file mode 100644 index 0000000..06b2793 --- /dev/null +++ b/0007-tlv-Handle-holes-in-SND_CTL_TLVT_DB_RANGE-array.patch @@ -0,0 +1,76 @@ +From d81ce4ea7af917f992aa0529c29db590d566ae7a Mon Sep 17 00:00:00 2001 +From: Peter Ujfalusi +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 +Signed-off-by: Takashi Iwai +--- + 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 + diff --git a/0008-tlv-Remove-tailing-tab-after-snd_ctl_get_dB_range-fu.patch b/0008-tlv-Remove-tailing-tab-after-snd_ctl_get_dB_range-fu.patch new file mode 100644 index 0000000..7673d5d --- /dev/null +++ b/0008-tlv-Remove-tailing-tab-after-snd_ctl_get_dB_range-fu.patch @@ -0,0 +1,31 @@ +From 2a94d80407f620c256021707503b14377d4701d1 Mon Sep 17 00:00:00 2001 +From: Peter Ujfalusi +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 +Signed-off-by: Takashi Iwai +--- + 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 + diff --git a/0009-Memory-leak-in-namehint.c.patch b/0009-Memory-leak-in-namehint.c.patch new file mode 100644 index 0000000..8f10ae7 --- /dev/null +++ b/0009-Memory-leak-in-namehint.c.patch @@ -0,0 +1,30 @@ +From 8dde984237d9bce99236355b85df9c438badb59f Mon Sep 17 00:00:00 2001 +From: John Lindgren +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 +Signed-off-by: Jaroslav Kysela +--- + 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 + diff --git a/0010-pcm-ladspa-fix-small-memory-leak-in-snd_pcm_ladspa_f.patch b/0010-pcm-ladspa-fix-small-memory-leak-in-snd_pcm_ladspa_f.patch new file mode 100644 index 0000000..bca72e9 --- /dev/null +++ b/0010-pcm-ladspa-fix-small-memory-leak-in-snd_pcm_ladspa_f.patch @@ -0,0 +1,26 @@ +From 3f589c9369a7514850e2f5afe4e9d486708f12ef Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +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 +--- + 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 + diff --git a/0011-pcm_plug-fix-comparison-always-true.patch b/0011-pcm_plug-fix-comparison-always-true.patch new file mode 100644 index 0000000..c6b9c5e --- /dev/null +++ b/0011-pcm_plug-fix-comparison-always-true.patch @@ -0,0 +1,27 @@ +From db7545a077eecee0a8c32759ee77340f9e7c9d15 Mon Sep 17 00:00:00 2001 +From: Anssi Hannula +Date: Mon, 2 Aug 2010 18:50:08 +0300 +Subject: [PATCH 11/21] pcm_plug: fix comparison always true + +Signed-off-by: Anssi Hannula +Signed-off-by: Takashi Iwai +--- + 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 + diff --git a/0012-test-latency-fix-timediff-calculation.patch b/0012-test-latency-fix-timediff-calculation.patch new file mode 100644 index 0000000..4923630 --- /dev/null +++ b/0012-test-latency-fix-timediff-calculation.patch @@ -0,0 +1,26 @@ +From eb3768563a29189156b7117d975930aee8133586 Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Wed, 4 Aug 2010 19:47:01 +0200 +Subject: [PATCH 12/21] test/latency: fix timediff calculation + +Signed-off-by: Jaroslav Kysela +--- + 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 + diff --git a/0013-HDA-Intel-present-all-4-HDMI-outputs-instead-of-just.patch b/0013-HDA-Intel-present-all-4-HDMI-outputs-instead-of-just.patch new file mode 100644 index 0000000..c07338a --- /dev/null +++ b/0013-HDA-Intel-present-all-4-HDMI-outputs-instead-of-just.patch @@ -0,0 +1,166 @@ +From e6d5dcf1f625984605d362338d71162de45a6c60 Mon Sep 17 00:00:00 2001 +From: Anssi Hannula +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 +Signed-off-by: Takashi Iwai +--- + 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 { + + + +-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 ++ ] ++ } + } + + +-- +1.7.2.1 + diff --git a/0014-pcm-add-defaults.pcm.minperiodtime-parsing.patch b/0014-pcm-add-defaults.pcm.minperiodtime-parsing.patch new file mode 100644 index 0000000..db1ac3d --- /dev/null +++ b/0014-pcm-add-defaults.pcm.minperiodtime-parsing.patch @@ -0,0 +1,98 @@ +From 09879a4bb58199f64abcb8df506f917c8efc2383 Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +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 +--- + 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 + diff --git a/0015-pcm-introduce-defaults.pcm.compat-to-change-the-para.patch b/0015-pcm-introduce-defaults.pcm.compat-to-change-the-para.patch new file mode 100644 index 0000000..f3bb75c --- /dev/null +++ b/0015-pcm-introduce-defaults.pcm.compat-to-change-the-para.patch @@ -0,0 +1,91 @@ +From de606e9c256f5a776c1625b174600a539007f38d Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +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 +--- + 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 + diff --git a/0016-pcm-Fixed-typo-wrong-deleted-line-instroduced-in-the.patch b/0016-pcm-Fixed-typo-wrong-deleted-line-instroduced-in-the.patch new file mode 100644 index 0000000..d6e8f15 --- /dev/null +++ b/0016-pcm-Fixed-typo-wrong-deleted-line-instroduced-in-the.patch @@ -0,0 +1,25 @@ +From 0633a966362ce231392ff6283c99142c5bccc1c8 Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +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 +--- + 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 + diff --git a/0017-Add-missing-support-for-3-byte-formats-for-16bit-put.patch b/0017-Add-missing-support-for-3-byte-formats-for-16bit-put.patch new file mode 100644 index 0000000..e281b34 --- /dev/null +++ b/0017-Add-missing-support-for-3-byte-formats-for-16bit-put.patch @@ -0,0 +1,112 @@ +From 18b377dec2aa728d52dae55a19bbea35e231a1ef Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +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 + +Signed-off-by: Takashi Iwai +--- + 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 + diff --git a/0018-namehint-Evaluate-more-possibilities-for-hw-devices.patch b/0018-namehint-Evaluate-more-possibilities-for-hw-devices.patch new file mode 100644 index 0000000..dc38010 --- /dev/null +++ b/0018-namehint-Evaluate-more-possibilities-for-hw-devices.patch @@ -0,0 +1,59 @@ +From 97d25c0766405453d3c298bd51dd4916121a4f6a Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +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 +--- + 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 + diff --git a/0019-HDA-Intel-do-not-lock-IEC958-Playback-switch.patch b/0019-HDA-Intel-do-not-lock-IEC958-Playback-switch.patch new file mode 100644 index 0000000..57a68c8 --- /dev/null +++ b/0019-HDA-Intel-do-not-lock-IEC958-Playback-switch.patch @@ -0,0 +1,40 @@ +From be06ab3ee7266c6ca7d2475d45b42cc4f47a20f8 Mon Sep 17 00:00:00 2001 +From: Pierre-Louis Bossart +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 +Signed-off-by: Takashi Iwai +--- + 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 + diff --git a/0020-general-recoded-snd_dlobj_-functions.patch b/0020-general-recoded-snd_dlobj_-functions.patch new file mode 100644 index 0000000..ed84baa --- /dev/null +++ b/0020-general-recoded-snd_dlobj_-functions.patch @@ -0,0 +1,516 @@ +From 91c9c8f1b85e69b4bdc94a777d2767c4906c3f47 Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +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 +--- + 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 ++#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 + diff --git a/0021-Add-Loopback.conf-to-define-standard-PCM-devices-for.patch b/0021-Add-Loopback.conf-to-define-standard-PCM-devices-for.patch new file mode 100644 index 0000000..b3ac4b6 --- /dev/null +++ b/0021-Add-Loopback.conf-to-define-standard-PCM-devices-for.patch @@ -0,0 +1,94 @@ +From 72c7260ce624adcb40377bc2093cd4d965b9b22e Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +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 +--- + 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) ++# ++ ++ ++ ++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 ++} ++ ++ ++ ++ ++ ++ ++ ++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 + diff --git a/alsa.changes b/alsa.changes index 92b7715..1dc2415 100644 --- a/alsa.changes +++ b/alsa.changes @@ -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 diff --git a/alsa.spec b/alsa.spec index d035f79..e91ec2a 100644 --- a/alsa.spec +++ b/alsa.spec @@ -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 From 8fd890cf59d20c9e1c7d0b3c8d014d52533d51c43ab1763b69d5dec172401d3d Mon Sep 17 00:00:00 2001 From: OBS User autobuild Date: Fri, 3 Sep 2010 14:40:53 +0000 Subject: [PATCH 2/3] Accepting request 47041 from multimedia:libs checked in (request 47041) OBS-URL: https://build.opensuse.org/request/show/47041 OBS-URL: https://build.opensuse.org/package/show/multimedia:libs/alsa?expand=0&rev=64 --- ...k-for-thread-specific-locale-support.patch | 29 - ...d-safe-locale-functions-if-available.patch | 66 --- 0003-seq-Fix-for-snd_seq_parse_address.patch | 35 -- ...k-dB-range-only-within-the-control-s.patch | 52 -- ...-alisp-Fix-a-string-format-ambiguity.patch | 26 - ...-range-dB-with-SND_CTL_TLVT_DB_RANGE.patch | 49 -- ...holes-in-SND_CTL_TLVT_DB_RANGE-array.patch | 76 --- ...ng-tab-after-snd_ctl_get_dB_range-fu.patch | 31 -- 0009-Memory-leak-in-namehint.c.patch | 30 - ...mall-memory-leak-in-snd_pcm_ladspa_f.patch | 26 - ...-pcm_plug-fix-comparison-always-true.patch | 27 - ...est-latency-fix-timediff-calculation.patch | 26 - ...t-all-4-HDMI-outputs-instead-of-just.patch | 166 ------ ...d-defaults.pcm.minperiodtime-parsing.patch | 98 ---- ...faults.pcm.compat-to-change-the-para.patch | 91 --- ...rong-deleted-line-instroduced-in-the.patch | 25 - ...ort-for-3-byte-formats-for-16bit-put.patch | 112 ---- ...te-more-possibilities-for-hw-devices.patch | 59 -- ...l-do-not-lock-IEC958-Playback-switch.patch | 40 -- ...general-recoded-snd_dlobj_-functions.patch | 516 ------------------ ...f-to-define-standard-PCM-devices-for.patch | 94 ---- alsa.changes | 26 - alsa.spec | 42 -- 23 files changed, 1742 deletions(-) delete mode 100644 0001-Check-for-thread-specific-locale-support.patch delete mode 100644 0002-Use-thread-safe-locale-functions-if-available.patch delete mode 100644 0003-seq-Fix-for-snd_seq_parse_address.patch delete mode 100644 0004-control-tlv-Check-dB-range-only-within-the-control-s.patch delete mode 100644 0005-alisp-Fix-a-string-format-ambiguity.patch delete mode 100644 0006-tlv-Check-out-of-range-dB-with-SND_CTL_TLVT_DB_RANGE.patch delete mode 100644 0007-tlv-Handle-holes-in-SND_CTL_TLVT_DB_RANGE-array.patch delete mode 100644 0008-tlv-Remove-tailing-tab-after-snd_ctl_get_dB_range-fu.patch delete mode 100644 0009-Memory-leak-in-namehint.c.patch delete mode 100644 0010-pcm-ladspa-fix-small-memory-leak-in-snd_pcm_ladspa_f.patch delete mode 100644 0011-pcm_plug-fix-comparison-always-true.patch delete mode 100644 0012-test-latency-fix-timediff-calculation.patch delete mode 100644 0013-HDA-Intel-present-all-4-HDMI-outputs-instead-of-just.patch delete mode 100644 0014-pcm-add-defaults.pcm.minperiodtime-parsing.patch delete mode 100644 0015-pcm-introduce-defaults.pcm.compat-to-change-the-para.patch delete mode 100644 0016-pcm-Fixed-typo-wrong-deleted-line-instroduced-in-the.patch delete mode 100644 0017-Add-missing-support-for-3-byte-formats-for-16bit-put.patch delete mode 100644 0018-namehint-Evaluate-more-possibilities-for-hw-devices.patch delete mode 100644 0019-HDA-Intel-do-not-lock-IEC958-Playback-switch.patch delete mode 100644 0020-general-recoded-snd_dlobj_-functions.patch delete mode 100644 0021-Add-Loopback.conf-to-define-standard-PCM-devices-for.patch diff --git a/0001-Check-for-thread-specific-locale-support.patch b/0001-Check-for-thread-specific-locale-support.patch deleted file mode 100644 index 55672ed..0000000 --- a/0001-Check-for-thread-specific-locale-support.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 51ef640cee37f73d771e784e81196ff7c15f53ff Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Denis-Courmont?= -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 -Signed-off-by: Jaroslav Kysela ---- - 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 - diff --git a/0002-Use-thread-safe-locale-functions-if-available.patch b/0002-Use-thread-safe-locale-functions-if-available.patch deleted file mode 100644 index 91ce510..0000000 --- a/0002-Use-thread-safe-locale-functions-if-available.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 8d80d5f344ae5e32d24122cbf8e759fdd1e1a60d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Denis-Courmont?= -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 -Signed-off-by: Jaroslav Kysela ---- - 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 - diff --git a/0003-seq-Fix-for-snd_seq_parse_address.patch b/0003-seq-Fix-for-snd_seq_parse_address.patch deleted file mode 100644 index 0361909..0000000 --- a/0003-seq-Fix-for-snd_seq_parse_address.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 19892334499ed21ed4dc30084ad8700253f9cb2f Mon Sep 17 00:00:00 2001 -From: Pedro Lopez-Cabanillas -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 -Signed-off-by: Jaroslav Kysela ---- - 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 - diff --git a/0004-control-tlv-Check-dB-range-only-within-the-control-s.patch b/0004-control-tlv-Check-dB-range-only-within-the-control-s.patch deleted file mode 100644 index f38229e..0000000 --- a/0004-control-tlv-Check-dB-range-only-within-the-control-s.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 30ad5ed04017f7e77b25cf40f18c26396903cd23 Mon Sep 17 00:00:00 2001 -From: Peter Ujfalusi -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 -Signed-off-by: Jaroslav Kysela ---- - 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 - diff --git a/0005-alisp-Fix-a-string-format-ambiguity.patch b/0005-alisp-Fix-a-string-format-ambiguity.patch deleted file mode 100644 index 1da5526..0000000 --- a/0005-alisp-Fix-a-string-format-ambiguity.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 191c57805a791925ab5992f127a1cb5f4ab56c9c Mon Sep 17 00:00:00 2001 -From: Colin Guthrie -Date: Sun, 28 Feb 2010 22:25:26 +0000 -Subject: [PATCH 05/21] alisp - Fix a string format ambiguity - -Signed-off-by: Takashi Iwai ---- - 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 - diff --git a/0006-tlv-Check-out-of-range-dB-with-SND_CTL_TLVT_DB_RANGE.patch b/0006-tlv-Check-out-of-range-dB-with-SND_CTL_TLVT_DB_RANGE.patch deleted file mode 100644 index 2353585..0000000 --- a/0006-tlv-Check-out-of-range-dB-with-SND_CTL_TLVT_DB_RANGE.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 16a2cad39b7ee29e34b92d39d72eebfc88f8dc22 Mon Sep 17 00:00:00 2001 -From: Peter Ujfalusi -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 -Signed-off-by: Takashi Iwai ---- - 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 - diff --git a/0007-tlv-Handle-holes-in-SND_CTL_TLVT_DB_RANGE-array.patch b/0007-tlv-Handle-holes-in-SND_CTL_TLVT_DB_RANGE-array.patch deleted file mode 100644 index 06b2793..0000000 --- a/0007-tlv-Handle-holes-in-SND_CTL_TLVT_DB_RANGE-array.patch +++ /dev/null @@ -1,76 +0,0 @@ -From d81ce4ea7af917f992aa0529c29db590d566ae7a Mon Sep 17 00:00:00 2001 -From: Peter Ujfalusi -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 -Signed-off-by: Takashi Iwai ---- - 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 - diff --git a/0008-tlv-Remove-tailing-tab-after-snd_ctl_get_dB_range-fu.patch b/0008-tlv-Remove-tailing-tab-after-snd_ctl_get_dB_range-fu.patch deleted file mode 100644 index 7673d5d..0000000 --- a/0008-tlv-Remove-tailing-tab-after-snd_ctl_get_dB_range-fu.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 2a94d80407f620c256021707503b14377d4701d1 Mon Sep 17 00:00:00 2001 -From: Peter Ujfalusi -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 -Signed-off-by: Takashi Iwai ---- - 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 - diff --git a/0009-Memory-leak-in-namehint.c.patch b/0009-Memory-leak-in-namehint.c.patch deleted file mode 100644 index 8f10ae7..0000000 --- a/0009-Memory-leak-in-namehint.c.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 8dde984237d9bce99236355b85df9c438badb59f Mon Sep 17 00:00:00 2001 -From: John Lindgren -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 -Signed-off-by: Jaroslav Kysela ---- - 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 - diff --git a/0010-pcm-ladspa-fix-small-memory-leak-in-snd_pcm_ladspa_f.patch b/0010-pcm-ladspa-fix-small-memory-leak-in-snd_pcm_ladspa_f.patch deleted file mode 100644 index bca72e9..0000000 --- a/0010-pcm-ladspa-fix-small-memory-leak-in-snd_pcm_ladspa_f.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 3f589c9369a7514850e2f5afe4e9d486708f12ef Mon Sep 17 00:00:00 2001 -From: Jaroslav Kysela -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 ---- - 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 - diff --git a/0011-pcm_plug-fix-comparison-always-true.patch b/0011-pcm_plug-fix-comparison-always-true.patch deleted file mode 100644 index c6b9c5e..0000000 --- a/0011-pcm_plug-fix-comparison-always-true.patch +++ /dev/null @@ -1,27 +0,0 @@ -From db7545a077eecee0a8c32759ee77340f9e7c9d15 Mon Sep 17 00:00:00 2001 -From: Anssi Hannula -Date: Mon, 2 Aug 2010 18:50:08 +0300 -Subject: [PATCH 11/21] pcm_plug: fix comparison always true - -Signed-off-by: Anssi Hannula -Signed-off-by: Takashi Iwai ---- - 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 - diff --git a/0012-test-latency-fix-timediff-calculation.patch b/0012-test-latency-fix-timediff-calculation.patch deleted file mode 100644 index 4923630..0000000 --- a/0012-test-latency-fix-timediff-calculation.patch +++ /dev/null @@ -1,26 +0,0 @@ -From eb3768563a29189156b7117d975930aee8133586 Mon Sep 17 00:00:00 2001 -From: Jaroslav Kysela -Date: Wed, 4 Aug 2010 19:47:01 +0200 -Subject: [PATCH 12/21] test/latency: fix timediff calculation - -Signed-off-by: Jaroslav Kysela ---- - 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 - diff --git a/0013-HDA-Intel-present-all-4-HDMI-outputs-instead-of-just.patch b/0013-HDA-Intel-present-all-4-HDMI-outputs-instead-of-just.patch deleted file mode 100644 index c07338a..0000000 --- a/0013-HDA-Intel-present-all-4-HDMI-outputs-instead-of-just.patch +++ /dev/null @@ -1,166 +0,0 @@ -From e6d5dcf1f625984605d362338d71162de45a6c60 Mon Sep 17 00:00:00 2001 -From: Anssi Hannula -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 -Signed-off-by: Takashi Iwai ---- - 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 { - - - --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 -+ ] -+ } - } - - --- -1.7.2.1 - diff --git a/0014-pcm-add-defaults.pcm.minperiodtime-parsing.patch b/0014-pcm-add-defaults.pcm.minperiodtime-parsing.patch deleted file mode 100644 index db1ac3d..0000000 --- a/0014-pcm-add-defaults.pcm.minperiodtime-parsing.patch +++ /dev/null @@ -1,98 +0,0 @@ -From 09879a4bb58199f64abcb8df506f917c8efc2383 Mon Sep 17 00:00:00 2001 -From: Jaroslav Kysela -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 ---- - 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 - diff --git a/0015-pcm-introduce-defaults.pcm.compat-to-change-the-para.patch b/0015-pcm-introduce-defaults.pcm.compat-to-change-the-para.patch deleted file mode 100644 index f3bb75c..0000000 --- a/0015-pcm-introduce-defaults.pcm.compat-to-change-the-para.patch +++ /dev/null @@ -1,91 +0,0 @@ -From de606e9c256f5a776c1625b174600a539007f38d Mon Sep 17 00:00:00 2001 -From: Jaroslav Kysela -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 ---- - 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 - diff --git a/0016-pcm-Fixed-typo-wrong-deleted-line-instroduced-in-the.patch b/0016-pcm-Fixed-typo-wrong-deleted-line-instroduced-in-the.patch deleted file mode 100644 index d6e8f15..0000000 --- a/0016-pcm-Fixed-typo-wrong-deleted-line-instroduced-in-the.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 0633a966362ce231392ff6283c99142c5bccc1c8 Mon Sep 17 00:00:00 2001 -From: Jaroslav Kysela -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 ---- - 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 - diff --git a/0017-Add-missing-support-for-3-byte-formats-for-16bit-put.patch b/0017-Add-missing-support-for-3-byte-formats-for-16bit-put.patch deleted file mode 100644 index e281b34..0000000 --- a/0017-Add-missing-support-for-3-byte-formats-for-16bit-put.patch +++ /dev/null @@ -1,112 +0,0 @@ -From 18b377dec2aa728d52dae55a19bbea35e231a1ef Mon Sep 17 00:00:00 2001 -From: Takashi Iwai -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 - -Signed-off-by: Takashi Iwai ---- - 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 - diff --git a/0018-namehint-Evaluate-more-possibilities-for-hw-devices.patch b/0018-namehint-Evaluate-more-possibilities-for-hw-devices.patch deleted file mode 100644 index dc38010..0000000 --- a/0018-namehint-Evaluate-more-possibilities-for-hw-devices.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 97d25c0766405453d3c298bd51dd4916121a4f6a Mon Sep 17 00:00:00 2001 -From: Jaroslav Kysela -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 ---- - 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 - diff --git a/0019-HDA-Intel-do-not-lock-IEC958-Playback-switch.patch b/0019-HDA-Intel-do-not-lock-IEC958-Playback-switch.patch deleted file mode 100644 index 57a68c8..0000000 --- a/0019-HDA-Intel-do-not-lock-IEC958-Playback-switch.patch +++ /dev/null @@ -1,40 +0,0 @@ -From be06ab3ee7266c6ca7d2475d45b42cc4f47a20f8 Mon Sep 17 00:00:00 2001 -From: Pierre-Louis Bossart -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 -Signed-off-by: Takashi Iwai ---- - 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 - diff --git a/0020-general-recoded-snd_dlobj_-functions.patch b/0020-general-recoded-snd_dlobj_-functions.patch deleted file mode 100644 index ed84baa..0000000 --- a/0020-general-recoded-snd_dlobj_-functions.patch +++ /dev/null @@ -1,516 +0,0 @@ -From 91c9c8f1b85e69b4bdc94a777d2767c4906c3f47 Mon Sep 17 00:00:00 2001 -From: Jaroslav Kysela -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 ---- - 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 -+#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 - diff --git a/0021-Add-Loopback.conf-to-define-standard-PCM-devices-for.patch b/0021-Add-Loopback.conf-to-define-standard-PCM-devices-for.patch deleted file mode 100644 index b3ac4b6..0000000 --- a/0021-Add-Loopback.conf-to-define-standard-PCM-devices-for.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 72c7260ce624adcb40377bc2093cd4d965b9b22e Mon Sep 17 00:00:00 2001 -From: Jaroslav Kysela -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 ---- - 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) -+# -+ -+ -+ -+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 -+} -+ -+ -+ -+ -+ -+ -+ -+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 - diff --git a/alsa.changes b/alsa.changes index 1dc2415..92b7715 100644 --- a/alsa.changes +++ b/alsa.changes @@ -1,29 +1,3 @@ -------------------------------------------------------------------- -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 diff --git a/alsa.spec b/alsa.spec index e91ec2a..d035f79 100644 --- a/alsa.spec +++ b/alsa.spec @@ -52,27 +52,6 @@ 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 @@ -148,27 +127,6 @@ 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 From 78c3cb05aa4caba2ae084bbe39cc10b77ad91ae151c81651702df87f531eb9b8 Mon Sep 17 00:00:00 2001 From: OBS User buildservice-autocommit Date: Fri, 3 Sep 2010 14:40:54 +0000 Subject: [PATCH 3/3] Updating link to change in openSUSE:Factory/alsa revision 91.0 OBS-URL: https://build.opensuse.org/package/show/multimedia:libs/alsa?expand=0&rev=46b9aabbb1258be113505f7e4f6cbbe4 --- ...k-for-thread-specific-locale-support.patch | 29 + ...d-safe-locale-functions-if-available.patch | 66 +++ 0003-seq-Fix-for-snd_seq_parse_address.patch | 35 ++ ...k-dB-range-only-within-the-control-s.patch | 52 ++ ...-alisp-Fix-a-string-format-ambiguity.patch | 26 + ...-range-dB-with-SND_CTL_TLVT_DB_RANGE.patch | 49 ++ ...holes-in-SND_CTL_TLVT_DB_RANGE-array.patch | 76 +++ ...ng-tab-after-snd_ctl_get_dB_range-fu.patch | 31 ++ 0009-Memory-leak-in-namehint.c.patch | 30 + ...mall-memory-leak-in-snd_pcm_ladspa_f.patch | 26 + ...-pcm_plug-fix-comparison-always-true.patch | 27 + ...est-latency-fix-timediff-calculation.patch | 26 + ...t-all-4-HDMI-outputs-instead-of-just.patch | 166 ++++++ ...d-defaults.pcm.minperiodtime-parsing.patch | 98 ++++ ...faults.pcm.compat-to-change-the-para.patch | 91 +++ ...rong-deleted-line-instroduced-in-the.patch | 25 + ...ort-for-3-byte-formats-for-16bit-put.patch | 112 ++++ ...te-more-possibilities-for-hw-devices.patch | 59 ++ ...l-do-not-lock-IEC958-Playback-switch.patch | 40 ++ ...general-recoded-snd_dlobj_-functions.patch | 516 ++++++++++++++++++ ...f-to-define-standard-PCM-devices-for.patch | 94 ++++ alsa.changes | 26 + alsa.spec | 44 +- 23 files changed, 1743 insertions(+), 1 deletion(-) create mode 100644 0001-Check-for-thread-specific-locale-support.patch create mode 100644 0002-Use-thread-safe-locale-functions-if-available.patch create mode 100644 0003-seq-Fix-for-snd_seq_parse_address.patch create mode 100644 0004-control-tlv-Check-dB-range-only-within-the-control-s.patch create mode 100644 0005-alisp-Fix-a-string-format-ambiguity.patch create mode 100644 0006-tlv-Check-out-of-range-dB-with-SND_CTL_TLVT_DB_RANGE.patch create mode 100644 0007-tlv-Handle-holes-in-SND_CTL_TLVT_DB_RANGE-array.patch create mode 100644 0008-tlv-Remove-tailing-tab-after-snd_ctl_get_dB_range-fu.patch create mode 100644 0009-Memory-leak-in-namehint.c.patch create mode 100644 0010-pcm-ladspa-fix-small-memory-leak-in-snd_pcm_ladspa_f.patch create mode 100644 0011-pcm_plug-fix-comparison-always-true.patch create mode 100644 0012-test-latency-fix-timediff-calculation.patch create mode 100644 0013-HDA-Intel-present-all-4-HDMI-outputs-instead-of-just.patch create mode 100644 0014-pcm-add-defaults.pcm.minperiodtime-parsing.patch create mode 100644 0015-pcm-introduce-defaults.pcm.compat-to-change-the-para.patch create mode 100644 0016-pcm-Fixed-typo-wrong-deleted-line-instroduced-in-the.patch create mode 100644 0017-Add-missing-support-for-3-byte-formats-for-16bit-put.patch create mode 100644 0018-namehint-Evaluate-more-possibilities-for-hw-devices.patch create mode 100644 0019-HDA-Intel-do-not-lock-IEC958-Playback-switch.patch create mode 100644 0020-general-recoded-snd_dlobj_-functions.patch create mode 100644 0021-Add-Loopback.conf-to-define-standard-PCM-devices-for.patch diff --git a/0001-Check-for-thread-specific-locale-support.patch b/0001-Check-for-thread-specific-locale-support.patch new file mode 100644 index 0000000..55672ed --- /dev/null +++ b/0001-Check-for-thread-specific-locale-support.patch @@ -0,0 +1,29 @@ +From 51ef640cee37f73d771e784e81196ff7c15f53ff Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?R=C3=A9mi=20Denis-Courmont?= +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 +Signed-off-by: Jaroslav Kysela +--- + 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 + diff --git a/0002-Use-thread-safe-locale-functions-if-available.patch b/0002-Use-thread-safe-locale-functions-if-available.patch new file mode 100644 index 0000000..91ce510 --- /dev/null +++ b/0002-Use-thread-safe-locale-functions-if-available.patch @@ -0,0 +1,66 @@ +From 8d80d5f344ae5e32d24122cbf8e759fdd1e1a60d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?R=C3=A9mi=20Denis-Courmont?= +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 +Signed-off-by: Jaroslav Kysela +--- + 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 + diff --git a/0003-seq-Fix-for-snd_seq_parse_address.patch b/0003-seq-Fix-for-snd_seq_parse_address.patch new file mode 100644 index 0000000..0361909 --- /dev/null +++ b/0003-seq-Fix-for-snd_seq_parse_address.patch @@ -0,0 +1,35 @@ +From 19892334499ed21ed4dc30084ad8700253f9cb2f Mon Sep 17 00:00:00 2001 +From: Pedro Lopez-Cabanillas +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 +Signed-off-by: Jaroslav Kysela +--- + 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 + diff --git a/0004-control-tlv-Check-dB-range-only-within-the-control-s.patch b/0004-control-tlv-Check-dB-range-only-within-the-control-s.patch new file mode 100644 index 0000000..f38229e --- /dev/null +++ b/0004-control-tlv-Check-dB-range-only-within-the-control-s.patch @@ -0,0 +1,52 @@ +From 30ad5ed04017f7e77b25cf40f18c26396903cd23 Mon Sep 17 00:00:00 2001 +From: Peter Ujfalusi +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 +Signed-off-by: Jaroslav Kysela +--- + 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 + diff --git a/0005-alisp-Fix-a-string-format-ambiguity.patch b/0005-alisp-Fix-a-string-format-ambiguity.patch new file mode 100644 index 0000000..1da5526 --- /dev/null +++ b/0005-alisp-Fix-a-string-format-ambiguity.patch @@ -0,0 +1,26 @@ +From 191c57805a791925ab5992f127a1cb5f4ab56c9c Mon Sep 17 00:00:00 2001 +From: Colin Guthrie +Date: Sun, 28 Feb 2010 22:25:26 +0000 +Subject: [PATCH 05/21] alisp - Fix a string format ambiguity + +Signed-off-by: Takashi Iwai +--- + 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 + diff --git a/0006-tlv-Check-out-of-range-dB-with-SND_CTL_TLVT_DB_RANGE.patch b/0006-tlv-Check-out-of-range-dB-with-SND_CTL_TLVT_DB_RANGE.patch new file mode 100644 index 0000000..2353585 --- /dev/null +++ b/0006-tlv-Check-out-of-range-dB-with-SND_CTL_TLVT_DB_RANGE.patch @@ -0,0 +1,49 @@ +From 16a2cad39b7ee29e34b92d39d72eebfc88f8dc22 Mon Sep 17 00:00:00 2001 +From: Peter Ujfalusi +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 +Signed-off-by: Takashi Iwai +--- + 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 + diff --git a/0007-tlv-Handle-holes-in-SND_CTL_TLVT_DB_RANGE-array.patch b/0007-tlv-Handle-holes-in-SND_CTL_TLVT_DB_RANGE-array.patch new file mode 100644 index 0000000..06b2793 --- /dev/null +++ b/0007-tlv-Handle-holes-in-SND_CTL_TLVT_DB_RANGE-array.patch @@ -0,0 +1,76 @@ +From d81ce4ea7af917f992aa0529c29db590d566ae7a Mon Sep 17 00:00:00 2001 +From: Peter Ujfalusi +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 +Signed-off-by: Takashi Iwai +--- + 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 + diff --git a/0008-tlv-Remove-tailing-tab-after-snd_ctl_get_dB_range-fu.patch b/0008-tlv-Remove-tailing-tab-after-snd_ctl_get_dB_range-fu.patch new file mode 100644 index 0000000..7673d5d --- /dev/null +++ b/0008-tlv-Remove-tailing-tab-after-snd_ctl_get_dB_range-fu.patch @@ -0,0 +1,31 @@ +From 2a94d80407f620c256021707503b14377d4701d1 Mon Sep 17 00:00:00 2001 +From: Peter Ujfalusi +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 +Signed-off-by: Takashi Iwai +--- + 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 + diff --git a/0009-Memory-leak-in-namehint.c.patch b/0009-Memory-leak-in-namehint.c.patch new file mode 100644 index 0000000..8f10ae7 --- /dev/null +++ b/0009-Memory-leak-in-namehint.c.patch @@ -0,0 +1,30 @@ +From 8dde984237d9bce99236355b85df9c438badb59f Mon Sep 17 00:00:00 2001 +From: John Lindgren +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 +Signed-off-by: Jaroslav Kysela +--- + 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 + diff --git a/0010-pcm-ladspa-fix-small-memory-leak-in-snd_pcm_ladspa_f.patch b/0010-pcm-ladspa-fix-small-memory-leak-in-snd_pcm_ladspa_f.patch new file mode 100644 index 0000000..bca72e9 --- /dev/null +++ b/0010-pcm-ladspa-fix-small-memory-leak-in-snd_pcm_ladspa_f.patch @@ -0,0 +1,26 @@ +From 3f589c9369a7514850e2f5afe4e9d486708f12ef Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +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 +--- + 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 + diff --git a/0011-pcm_plug-fix-comparison-always-true.patch b/0011-pcm_plug-fix-comparison-always-true.patch new file mode 100644 index 0000000..c6b9c5e --- /dev/null +++ b/0011-pcm_plug-fix-comparison-always-true.patch @@ -0,0 +1,27 @@ +From db7545a077eecee0a8c32759ee77340f9e7c9d15 Mon Sep 17 00:00:00 2001 +From: Anssi Hannula +Date: Mon, 2 Aug 2010 18:50:08 +0300 +Subject: [PATCH 11/21] pcm_plug: fix comparison always true + +Signed-off-by: Anssi Hannula +Signed-off-by: Takashi Iwai +--- + 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 + diff --git a/0012-test-latency-fix-timediff-calculation.patch b/0012-test-latency-fix-timediff-calculation.patch new file mode 100644 index 0000000..4923630 --- /dev/null +++ b/0012-test-latency-fix-timediff-calculation.patch @@ -0,0 +1,26 @@ +From eb3768563a29189156b7117d975930aee8133586 Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Wed, 4 Aug 2010 19:47:01 +0200 +Subject: [PATCH 12/21] test/latency: fix timediff calculation + +Signed-off-by: Jaroslav Kysela +--- + 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 + diff --git a/0013-HDA-Intel-present-all-4-HDMI-outputs-instead-of-just.patch b/0013-HDA-Intel-present-all-4-HDMI-outputs-instead-of-just.patch new file mode 100644 index 0000000..c07338a --- /dev/null +++ b/0013-HDA-Intel-present-all-4-HDMI-outputs-instead-of-just.patch @@ -0,0 +1,166 @@ +From e6d5dcf1f625984605d362338d71162de45a6c60 Mon Sep 17 00:00:00 2001 +From: Anssi Hannula +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 +Signed-off-by: Takashi Iwai +--- + 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 { + + + +-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 ++ ] ++ } + } + + +-- +1.7.2.1 + diff --git a/0014-pcm-add-defaults.pcm.minperiodtime-parsing.patch b/0014-pcm-add-defaults.pcm.minperiodtime-parsing.patch new file mode 100644 index 0000000..db1ac3d --- /dev/null +++ b/0014-pcm-add-defaults.pcm.minperiodtime-parsing.patch @@ -0,0 +1,98 @@ +From 09879a4bb58199f64abcb8df506f917c8efc2383 Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +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 +--- + 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 + diff --git a/0015-pcm-introduce-defaults.pcm.compat-to-change-the-para.patch b/0015-pcm-introduce-defaults.pcm.compat-to-change-the-para.patch new file mode 100644 index 0000000..f3bb75c --- /dev/null +++ b/0015-pcm-introduce-defaults.pcm.compat-to-change-the-para.patch @@ -0,0 +1,91 @@ +From de606e9c256f5a776c1625b174600a539007f38d Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +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 +--- + 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 + diff --git a/0016-pcm-Fixed-typo-wrong-deleted-line-instroduced-in-the.patch b/0016-pcm-Fixed-typo-wrong-deleted-line-instroduced-in-the.patch new file mode 100644 index 0000000..d6e8f15 --- /dev/null +++ b/0016-pcm-Fixed-typo-wrong-deleted-line-instroduced-in-the.patch @@ -0,0 +1,25 @@ +From 0633a966362ce231392ff6283c99142c5bccc1c8 Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +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 +--- + 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 + diff --git a/0017-Add-missing-support-for-3-byte-formats-for-16bit-put.patch b/0017-Add-missing-support-for-3-byte-formats-for-16bit-put.patch new file mode 100644 index 0000000..e281b34 --- /dev/null +++ b/0017-Add-missing-support-for-3-byte-formats-for-16bit-put.patch @@ -0,0 +1,112 @@ +From 18b377dec2aa728d52dae55a19bbea35e231a1ef Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +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 + +Signed-off-by: Takashi Iwai +--- + 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 + diff --git a/0018-namehint-Evaluate-more-possibilities-for-hw-devices.patch b/0018-namehint-Evaluate-more-possibilities-for-hw-devices.patch new file mode 100644 index 0000000..dc38010 --- /dev/null +++ b/0018-namehint-Evaluate-more-possibilities-for-hw-devices.patch @@ -0,0 +1,59 @@ +From 97d25c0766405453d3c298bd51dd4916121a4f6a Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +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 +--- + 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 + diff --git a/0019-HDA-Intel-do-not-lock-IEC958-Playback-switch.patch b/0019-HDA-Intel-do-not-lock-IEC958-Playback-switch.patch new file mode 100644 index 0000000..57a68c8 --- /dev/null +++ b/0019-HDA-Intel-do-not-lock-IEC958-Playback-switch.patch @@ -0,0 +1,40 @@ +From be06ab3ee7266c6ca7d2475d45b42cc4f47a20f8 Mon Sep 17 00:00:00 2001 +From: Pierre-Louis Bossart +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 +Signed-off-by: Takashi Iwai +--- + 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 + diff --git a/0020-general-recoded-snd_dlobj_-functions.patch b/0020-general-recoded-snd_dlobj_-functions.patch new file mode 100644 index 0000000..ed84baa --- /dev/null +++ b/0020-general-recoded-snd_dlobj_-functions.patch @@ -0,0 +1,516 @@ +From 91c9c8f1b85e69b4bdc94a777d2767c4906c3f47 Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +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 +--- + 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 ++#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 + diff --git a/0021-Add-Loopback.conf-to-define-standard-PCM-devices-for.patch b/0021-Add-Loopback.conf-to-define-standard-PCM-devices-for.patch new file mode 100644 index 0000000..b3ac4b6 --- /dev/null +++ b/0021-Add-Loopback.conf-to-define-standard-PCM-devices-for.patch @@ -0,0 +1,94 @@ +From 72c7260ce624adcb40377bc2093cd4d965b9b22e Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +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 +--- + 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) ++# ++ ++ ++ ++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 ++} ++ ++ ++ ++ ++ ++ ++ ++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 + diff --git a/alsa.changes b/alsa.changes index 92b7715..1dc2415 100644 --- a/alsa.changes +++ b/alsa.changes @@ -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 diff --git a/alsa.spec b/alsa.spec index d035f79..e4ddc1f 100644 --- a/alsa.spec +++ b/alsa.spec @@ -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