Accepting request 208682 from multimedia:libs

- Backport upstream fixes: a few fixes for chmap support, alsaconf
  updates, a new monitor command for alsactl, etc:
  0006-amixer-fix-indentation-when-printing-container-TLV-c.patch
  0007-alsaloop-pcmjob.c-use-portable-way-to-initialize-rec.patch
  0008-speaker-test-Fix-chmapped-channel-selection-without-.patch
  0009-speaker-test-Always-show-chmap-channel-names-if-avai.patch
  0010-speaker-test-Show-out-of-chmap-channels-as-Unknown.patch
  0011-alsaconf-support-newer-m-i-t-and-kmod.patch
  0012-alsaconf-update-gentoo-to-use-modprobe.d-method-as-e.patch
  0013-configure-detect-udevdir-via-pkg-config-fallback-to-.patch
  0014-alsactl-Add-monitor-command.patch
  0015-alsactl-Fix-REMOVE-event-handling-in-monitor-command.patch
  0016-alsactl-monitor-all-cards-as-default.patch (forwarded request 208681 from tiwai)

OBS-URL: https://build.opensuse.org/request/show/208682
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/alsa-utils?expand=0&rev=86
This commit is contained in:
Stephan Kulow 2013-11-28 06:14:04 +00:00 committed by Git OBS Bridge
commit f41a2a5a7d
13 changed files with 951 additions and 0 deletions

View File

@ -0,0 +1,42 @@
From f1e991e81350e9388ab6cf04a64ac4b4389a588c Mon Sep 17 00:00:00 2001
From: Anssi Hannula <anssi.hannula@iki.fi>
Date: Tue, 1 Oct 2013 23:46:53 +0300
Subject: [PATCH] amixer: fix indentation when printing container TLV contents
decode_tlv() adds indentation in the beginning, with the expectation
that the TLV will be printed on the line afterwards in a switch-case.
However, in the case of a container TLV the switch-case simply adds
another level of indentation and calls decode_tlv() for the inner TLVs.
This causes the first inner TLV to be printed with too much indentation
and double '|'.
Fix that by printing "container" and a newline for container TLVs, so
that the result is as follows:
: values=0,0,0,0,0,0,0,0
| container
| chmap-variable=FL,FR
| chmap-variable=FL,FR,LFE
| chmap-variable=FL,FR,FC
Signed-off-by: Anssi Hannula <anssi.hannula@iki.fi>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
amixer/amixer.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/amixer/amixer.c b/amixer/amixer.c
index b83b0c356474..cf82892bfa2f 100644
--- a/amixer/amixer.c
+++ b/amixer/amixer.c
@@ -460,6 +460,7 @@ static void decode_tlv(unsigned int spaces, unsigned int *tlv, unsigned int tlv_
}
switch (type) {
case SND_CTL_TLVT_CONTAINER:
+ printf("container\n");
size += sizeof(unsigned int) -1;
size /= sizeof(unsigned int);
while (idx < size) {
--
1.8.4.3

View File

@ -0,0 +1,55 @@
From 0616d87fbaae1d4a558104051cb5369504eb2068 Mon Sep 17 00:00:00 2001
From: John Spencer <maillist-alsa@barfooze.de>
Date: Fri, 8 Nov 2013 13:59:41 +0100
Subject: [PATCH] alsaloop: pcmjob.c: use portable way to initialize recursive
mutex
PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP is not in POSIX, as _NP
(non-portable) suggests.
exposing such a symbol in musl libc would lock in the ABI for all
times and makes it impossible to do future changes to the under-
lying struct without hideous symbol versioning hacks.
use the portable way instead: pthread_once was designed for such
cases.
Signed-off-by: John Spencer <maillist-alsa@barfooze.de>
Tested-by: John Spencer <maillist-alsa@barfooze.de>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
alsaloop/pcmjob.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/alsaloop/pcmjob.c b/alsaloop/pcmjob.c
index 139b6fdf087e..f32180c8e8cd 100644
--- a/alsaloop/pcmjob.c
+++ b/alsaloop/pcmjob.c
@@ -62,11 +62,22 @@ static const char *src_types[] = {
};
#endif
-static pthread_mutex_t pcm_open_mutex =
- PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+static pthread_once_t pcm_open_mutex_once = PTHREAD_ONCE_INIT;
+static pthread_mutex_t pcm_open_mutex;
+
+static void pcm_open_init_mutex(void)
+{
+ pthread_mutexattr_t attr;
+
+ pthread_mutexattr_init(&attr);
+ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+ pthread_mutex_init(&pcm_open_mutex, &attr);
+ pthread_mutexattr_destroy(&attr);
+}
static inline void pcm_open_lock(void)
{
+ pthread_once(&pcm_open_mutex_once, pcm_open_init_mutex);
if (workarounds & WORKAROUND_SERIALOPEN)
pthread_mutex_lock(&pcm_open_mutex);
}
--
1.8.4.3

View File

@ -0,0 +1,232 @@
From a1992044d5813371ce71f5252187942f943b198d Mon Sep 17 00:00:00 2001
From: Anssi Hannula <anssi.hannula@iki.fi>
Date: Tue, 12 Nov 2013 00:04:02 +0200
Subject: [PATCH] speaker-test: Fix chmapped channel selection without
specified chmap
The channel selection currently does not work properly when there is a
driver-provided non-ALSA-traditional channel map but no manual channel
map was explicitely requested with "-m".
For example, the CEA/HDMI 8ch map is FL,FR,RLC,RRC,FC,LFE,RL,RR. Note
that it is otherwise the same as the traditional ALSA channel map,
except that the traditional rear speakers are considered
rear-center speakers and the traditional side speakers are considered
rear speakers.
Speaker-test tries to play back channels in this following order:
0, /* Front Left */
4, /* Center */
1, /* Front Right */
7, /* Side Right */
3, /* Rear Right */
2, /* Rear Left */
6, /* Side Left */
5, /* LFE */
When it is the time to play back Side Left/Right, speaker-test tries to
look for SL/SR in the chmap, but doesn't find it, so it just plays back
channels 6/7 (which indeed are the side speakers, or RL/RR in this
channel map - so the correct channels are selected).
When it becomes the time to playback Rear Left/Right, speaker-test again
tries to find RL/RR in the chmap, and this time it does find them in the
chmap positions 6/7.
So the channels 6/7 are tested twice and 2/3 are never tested.
To fix this, define a generic playback order channel_order[] to be used
when the channel map is present (but not user-defined) and generate a
(speaker/playback number => channel number) mapping with the channels
ordered in the following order:
1. regular channels found in channel_order[] in the defined order,
2. channels not found in channel_order[] ordered by channel number.
3. UNKNOWN channels ordered by channel number.
4. NA channels ordered by channel number.
For channels outside the channel map just use their channel numbers (so
they will be last after all of the above).
For example, if the playback device has a fictional default channel map
of FR,FL,UNKNOWN1,FOO,BAR,RR,RL,UNKNOWN2, the playback order will be
FL,FR,RR,RL,FOO,BAR,UNKNOWN1,UNKNOWN2(,any_extra_channels).
When the channel mapping is specified manually, the specified order is
used for playback as before.
Signed-off-by: Anssi Hannula <anssi.hannula@iki.fi>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
speaker-test/speaker-test.c | 113 +++++++++++++++++++++++++++++++++++---------
1 file changed, 91 insertions(+), 22 deletions(-)
diff --git a/speaker-test/speaker-test.c b/speaker-test/speaker-test.c
index d35065f73a7a..25b08dcee70b 100644
--- a/speaker-test/speaker-test.c
+++ b/speaker-test/speaker-test.c
@@ -88,6 +88,8 @@ enum {
#define BE_INT(v) (v)
#endif
+#define ARRAY_SIZE(x) (int)(sizeof(x)/sizeof(x[0]))
+
static char *device = "default"; /* playback device */
static snd_pcm_format_t format = SND_PCM_FORMAT_S16; /* sample format */
static unsigned int rate = 48000; /* stream rate */
@@ -110,6 +112,7 @@ static snd_pcm_t *pcm_handle = NULL;
#ifdef CONFIG_SUPPORT_CHMAP
static snd_pcm_chmap_t *channel_map;
static int channel_map_set;
+static unsigned int *ordered_channels;
#endif
static const char *const channel_name[MAX_CHANNELS] = {
@@ -156,36 +159,94 @@ static const int channels8[] = {
5, /* LFE */
};
-static int get_mapped_channel(int chn)
-{
#ifdef CONFIG_SUPPORT_CHMAP
- static const int maps[MAX_CHANNELS] = {
- SND_CHMAP_FL,
- SND_CHMAP_FR,
- SND_CHMAP_RL,
- SND_CHMAP_RR,
- SND_CHMAP_FC,
- SND_CHMAP_LFE,
- SND_CHMAP_SL,
- SND_CHMAP_SR,
- };
+/* circular clockwise and bottom-to-top order */
+static const int channel_order[] = {
+ [SND_CHMAP_FLW] = 10,
+ [SND_CHMAP_FL] = 20,
+ [SND_CHMAP_TFL] = 30,
+ [SND_CHMAP_FLC] = 40,
+ [SND_CHMAP_TFLC] = 50,
+ [SND_CHMAP_FC] = 60,
+ [SND_CHMAP_TFC] = 70,
+ [SND_CHMAP_FRC] = 80,
+ [SND_CHMAP_TFRC] = 90,
+ [SND_CHMAP_FR] = 100,
+ [SND_CHMAP_TFR] = 110,
+ [SND_CHMAP_FRW] = 120,
+ [SND_CHMAP_SR] = 130,
+ [SND_CHMAP_TSR] = 140,
+ [SND_CHMAP_RR] = 150,
+ [SND_CHMAP_TRR] = 160,
+ [SND_CHMAP_RRC] = 170,
+ [SND_CHMAP_RC] = 180,
+ [SND_CHMAP_TRC] = 190,
+ [SND_CHMAP_RLC] = 200,
+ [SND_CHMAP_RL] = 210,
+ [SND_CHMAP_TRL] = 220,
+ [SND_CHMAP_SL] = 230,
+ [SND_CHMAP_TSL] = 240,
+ [SND_CHMAP_BC] = 250,
+ [SND_CHMAP_TC] = 260,
+ [SND_CHMAP_LLFE] = 270,
+ [SND_CHMAP_LFE] = 280,
+ [SND_CHMAP_RLFE] = 290,
+ /* not in table = 10000 */
+ [SND_CHMAP_UNKNOWN] = 20000,
+ [SND_CHMAP_NA] = 30000,
+};
- if (channel_map && maps[chn]) {
- int i;
- for (i = 0; i < channel_map->channels; i++) {
- if (channel_map->pos[i] == maps[chn])
- return i;
- }
+static int chpos_cmp(const void *chnum1p, const void *chnum2p)
+{
+ int chnum1 = *(int *)chnum1p;
+ int chnum2 = *(int *)chnum2p;
+ int chpos1 = channel_map->pos[chnum1];
+ int chpos2 = channel_map->pos[chnum2];
+ int weight1 = 10000;
+ int weight2 = 10000;
+
+ if (chpos1 < ARRAY_SIZE(channel_order) && channel_order[chpos1])
+ weight1 = channel_order[chpos1];
+ if (chpos2 < ARRAY_SIZE(channel_order) && channel_order[chpos2])
+ weight2 = channel_order[chpos2];
+
+ if (weight1 == weight2) {
+ /* order by channel number if both have the same position (e.g. UNKNOWN)
+ * or if neither is in channel_order[] */
+ return chnum1 - chnum2;
}
-#endif
- return chn;
+
+ /* order according to channel_order[] */
+ return weight1 - weight2;
+}
+
+static int *order_channels(void)
+{
+ /* create a (playback order => channel number) table with channels ordered
+ * according to channel_order[] values */
+ int i;
+ int *ordered_chs;
+
+ ordered_chs = calloc(channel_map->channels, sizeof(*ordered_chs));
+ if (!ordered_chs)
+ return NULL;
+
+ for (i = 0; i < channel_map->channels; i++)
+ ordered_chs[i] = i;
+
+ qsort(ordered_chs, channel_map->channels, sizeof(*ordered_chs), chpos_cmp);
+
+ return ordered_chs;
}
+#endif
static int get_speaker_channel(int chn)
{
#ifdef CONFIG_SUPPORT_CHMAP
- if (channel_map_set)
+ if (channel_map_set || (ordered_channels && chn >= channel_map->channels))
return chn;
+ if (ordered_channels)
+ return ordered_channels[chn];
#endif
switch (channels) {
@@ -200,7 +261,7 @@ static int get_speaker_channel(int chn)
break;
}
- return get_mapped_channel(chn);
+ return chn;
}
static const char *get_channel_name(int chn)
@@ -611,6 +672,11 @@ static int config_chmap(snd_pcm_t *handle, const char *mapstr)
}
channel_map = snd_pcm_get_chmap(handle);
+
+ /* create a channel order table for default layouts */
+ if (channel_map)
+ ordered_channels = order_channels();
+
return 0;
}
#endif
@@ -1230,6 +1296,9 @@ int main(int argc, char *argv[]) {
free(frames);
+#ifdef CONFIG_SUPPORT_CHMAP
+ free(ordered_channels);
+#endif
return prg_exit(EXIT_SUCCESS);
}
--
1.8.4.3

View File

@ -0,0 +1,44 @@
From 5b0c6da0d8166cd404379740c5f75fda44ca5806 Mon Sep 17 00:00:00 2001
From: Anssi Hannula <anssi.hannula@iki.fi>
Date: Sun, 10 Nov 2013 20:29:18 +0200
Subject: [PATCH] speaker-test: Always show chmap channel names if available
Currently speaker-test only uses channel names retrieved by
snd_pcm_chmap_long_name() when a channel map has been manually set.
However, the device may provide a default (or fixed) channel map that
differs from the traditional ALSA map, in which case wrong channel names
are shown.
Fix that by always using the name from the channel map when a channel
map is present.
Note that the names retrieved by snd_pcm_chmap_long_name() are not
currently localized via gettext.
Also note that Linux kernel HDMI driver reported wrong default channel
maps before 56cac413dd6d43af8355f5d1f90a199b540f73fc ("ALSA: hda - hdmi:
Fix reported channel map on common default layouts").
Signed-off-by: Anssi Hannula <anssi.hannula@iki.fi>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
speaker-test/speaker-test.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/speaker-test/speaker-test.c b/speaker-test/speaker-test.c
index 25b08dcee70b..101bb0d390ee 100644
--- a/speaker-test/speaker-test.c
+++ b/speaker-test/speaker-test.c
@@ -267,7 +267,7 @@ static int get_speaker_channel(int chn)
static const char *get_channel_name(int chn)
{
#ifdef CONFIG_SUPPORT_CHMAP
- if (channel_map_set && chn < channel_map->channels) {
+ if (channel_map && chn < channel_map->channels) {
const char *name = snd_pcm_chmap_long_name(channel_map->pos[chn]);
return name ? name : "Unknown";
}
--
1.8.4.3

View File

@ -0,0 +1,41 @@
From 58752c3ae32e03d676fa225c99c9a8dde9de39ed Mon Sep 17 00:00:00 2001
From: Anssi Hannula <anssi.hannula@iki.fi>
Date: Sun, 10 Nov 2013 20:29:19 +0200
Subject: [PATCH] speaker-test: Show out-of-chmap channels as Unknown
Currently speaker-test falls back to ALSA default channel names for
channels out-of-chmap.
This causes e.g. the 4th channel of
$ speaker-test -c4 -Dhdmi -m "FR,FL,FC"
to be shown as "Rear Right".
Change the code to show such channels as Unknown instead, similar to
when snd_pcm_chmap_long_name() does not know the name.
Signed-off-by: Anssi Hannula <anssi.hannula@iki.fi>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
speaker-test/speaker-test.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/speaker-test/speaker-test.c b/speaker-test/speaker-test.c
index 101bb0d390ee..261f399067e9 100644
--- a/speaker-test/speaker-test.c
+++ b/speaker-test/speaker-test.c
@@ -267,8 +267,10 @@ static int get_speaker_channel(int chn)
static const char *get_channel_name(int chn)
{
#ifdef CONFIG_SUPPORT_CHMAP
- if (channel_map && chn < channel_map->channels) {
- const char *name = snd_pcm_chmap_long_name(channel_map->pos[chn]);
+ if (channel_map) {
+ const char *name = NULL;
+ if (chn < channel_map->channels)
+ name = snd_pcm_chmap_long_name(channel_map->pos[chn]);
return name ? name : "Unknown";
}
#endif
--
1.8.4.3

View File

@ -0,0 +1,39 @@
From df875c6e8f1a26ccba8a9d864bcff85b633df244 Mon Sep 17 00:00:00 2001
From: Mike Frysinger <vapier@gentoo.org>
Date: Wed, 13 Nov 2013 13:23:47 -0500
Subject: [PATCH] alsaconf: support newer m-i-t and kmod
The m-i-t package made it up to 3.10 versions before ending, so update
the glob to handle those too.
Most distros are moving on to kmod, so we also want to handle the version
string that package outputs.
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
alsaconf/alsaconf.in | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/alsaconf/alsaconf.in b/alsaconf/alsaconf.in
index 5c23787742f1..59f25d1ee1d9 100644
--- a/alsaconf/alsaconf.in
+++ b/alsaconf/alsaconf.in
@@ -308,9 +308,11 @@ elif [ "$kernel" = "new" ]; then
cfgout="/etc/modprobe.d/50-sound.conf"
cfgoldout="/etc/modprobe.d/sound"
if [ ! -f $cfgout ]; then
- modver=$(modprobe -V | sed -e's/^module-init-tools version //')
- case "$modver" in
- 3.[789]*)
+ case "$(modprobe -V)" in
+ "module-init-tools version "3.[789]*|\
+ "module-init-tools version "3.1[0-9]*)
+ ;;
+ "kmod version "*)
;;
*)
cfgout="/etc/modprobe.d/sound"
--
1.8.4.3

View File

@ -0,0 +1,32 @@
From 54a459a884ea7e8fe7f80ed9bf84b0417205c5d4 Mon Sep 17 00:00:00 2001
From: Mike Frysinger <vapier@gentoo.org>
Date: Wed, 13 Nov 2013 13:23:48 -0500
Subject: [PATCH] alsaconf: update gentoo to use modprobe.d method as everyone
else
We migrated off modules.d a long time ago.
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
alsaconf/alsaconf.in | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/alsaconf/alsaconf.in b/alsaconf/alsaconf.in
index 59f25d1ee1d9..3d6adca8b0bd 100644
--- a/alsaconf/alsaconf.in
+++ b/alsaconf/alsaconf.in
@@ -300,9 +300,7 @@ if [ -n "$cfgfile" ]; then
exit 1
fi
else
-if [ "$distribution" = "gentoo" ]; then
- cfgfile="/etc/modules.d/alsa"
-elif [ "$kernel" = "new" ]; then
+if [ "$kernel" = "new" ]; then
cfgfile="/etc/modprobe.conf"
if [ -d /etc/modprobe.d ]; then
cfgout="/etc/modprobe.d/50-sound.conf"
--
1.8.4.3

View File

@ -0,0 +1,36 @@
From 7d0c2801b3395d8dd4d46e9a1eb2491dde8a053c Mon Sep 17 00:00:00 2001
From: Ivailo Monev <xakepa10@gmail.com>
Date: Sat, 16 Nov 2013 14:00:19 +0000
Subject: [PATCH] configure: detect udevdir via pkg-config, fallback to
/lib/udev/rules.d
Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
configure.in | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/configure.in b/configure.in
index 3ae320926a1c..60da1fa680ba 100644
--- a/configure.in
+++ b/configure.in
@@ -120,8 +120,14 @@ AM_CONDITIONAL(USE_XMLTO, test x"$xmlto" = xyes)
AC_ARG_WITH(
[udev-rules-dir],
- AS_HELP_STRING([--with-udev-rules-dir],[Directory where to install udev rules to (defaults to /lib/udev/rules.d)]),
- [udevrulesdir=$withval], [udevrulesdir="/lib/udev/rules.d"])
+ AS_HELP_STRING([--with-udev-rules-dir=DIR],[Directory where to install udev rules to (default=auto)]),
+ [udevrulesdir="$withval"],
+ [udevdir=$($PKG_CONFIG udev --variable=udevdir)
+ if test "x$udevdir" = "x"; then
+ udevrulesdir="/lib/udev/rules.d"
+ else
+ udevrulesdir="$udevdir/rules.d"
+ fi])
AC_SUBST(udevrulesdir)
dnl Checks for header files.
--
1.8.4.3

View File

@ -0,0 +1,162 @@
From d2d9b6fc8d20fca1e06fc261ac20fd6cfd8a8d1b Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai@suse.de>
Date: Tue, 26 Nov 2013 11:44:40 +0100
Subject: [PATCH] alsactl: Add monitor command
With monitor command, you can monitor the events received from the
given control device.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
alsactl/Makefile.am | 2 +-
alsactl/alsactl.1 | 8 +++++-
alsactl/alsactl.c | 3 +++
alsactl/monitor.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 86 insertions(+), 2 deletions(-)
create mode 100644 alsactl/monitor.c
diff --git a/alsactl/Makefile.am b/alsactl/Makefile.am
index bac84eb079dc..b05b09ce287f 100644
--- a/alsactl/Makefile.am
+++ b/alsactl/Makefile.am
@@ -7,7 +7,7 @@ man_MANS += alsactl_init.7
endif
EXTRA_DIST=alsactl.1 alsactl_init.xml
-alsactl_SOURCES=alsactl.c state.c lock.c utils.c init_parse.c daemon.c
+alsactl_SOURCES=alsactl.c state.c lock.c utils.c init_parse.c daemon.c monitor.c
alsactl_CFLAGS=$(AM_CFLAGS) -D__USE_GNU -DSYS_ASOUNDRC=\"$(ASOUND_STATE_DIR)/asound.state\" -DSYS_PIDFILE=\"$(ALSACTL_PIDFILE_DIR)/alsactl.pid\"
noinst_HEADERS=alsactl.h list.h init_sysdeps.c init_utils_string.c init_utils_run.c init_sysfs.c
diff --git a/alsactl/alsactl.1 b/alsactl/alsactl.1
index 45ac8a68f4a8..a11c17cb59e1 100644
--- a/alsactl/alsactl.1
+++ b/alsactl/alsactl.1
@@ -6,6 +6,8 @@ alsactl \- advanced controls for ALSA soundcard driver
\fBalsactl\fP [\fIoptions\fP] [\fIstore\fP|\fIrestore\fP|\fIinit\fP] <card # or id or device>
+\fBalsactl\fP \fImonitor\fP <card # or id>
+
.SH DESCRIPTION
\fBalsactl\fP is used to control advanced settings for the ALSA
soundcard drivers. It supports multiple soundcards. If your card has
@@ -34,8 +36,12 @@ is not known, error code 99 is returned.
\fIkill\fP notifies the daemon to do the specified operation (quit,
rescan, save_and_quit).
+\fImonitor\fP is for monitoring the events received from the given
+control device.
+
If no soundcards are specified, setup for all cards will be saved or
-loaded.
+loaded (except for \fImonitor\fP command that can handle only a single
+card; it selects the card "default" when unspecified).
.SH OPTIONS
diff --git a/alsactl/alsactl.c b/alsactl/alsactl.c
index 75baad856b5d..6bc013f467d0 100644
--- a/alsactl/alsactl.c
+++ b/alsactl/alsactl.c
@@ -100,6 +100,7 @@ static struct arg args[] = {
{ CARDCMD, "daemon", "store state periodically for one or each soundcards" },
{ CARDCMD, "rdaemon", "like daemon but do the state restore at first" },
{ KILLCMD, "kill", "notify daemon to quit, rescan or save_and_quit" },
+{ CARDCMD, "monitor", "monitor control events" },
{ 0, NULL, NULL }
};
@@ -363,6 +364,8 @@ int main(int argc, char *argv[])
res = state_daemon(cfgfile, cardname, period, pidfile);
} else if (!strcmp(cmd, "kill")) {
res = state_daemon_kill(pidfile, cardname);
+ } else if (!strcmp(cmd, "monitor")) {
+ res = monitor(cardname);
} else {
fprintf(stderr, "alsactl: Unknown command '%s'...\n", cmd);
res = -ENODEV;
diff --git a/alsactl/monitor.c b/alsactl/monitor.c
new file mode 100644
index 000000000000..12d24504264b
--- /dev/null
+++ b/alsactl/monitor.c
@@ -0,0 +1,75 @@
+/*
+ * Advanced Linux Sound Architecture Control Program
+ * Copyright (c) by Takashi Iwai <tiwai@suse.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "aconfig.h"
+#include "version.h"
+#include <stdio.h>
+#include <alsa/asoundlib.h>
+
+int monitor(const char *name)
+{
+ snd_ctl_t *ctl;
+ snd_ctl_event_t *event;
+ int err;
+
+ if (!name)
+ name = "default";
+
+ err = snd_ctl_open(&ctl, name, SND_CTL_READONLY);
+ if (err < 0) {
+ fprintf(stderr, "Cannot open ctl %s\n", name);
+ return err;
+ }
+ err = snd_ctl_subscribe_events(ctl, 1);
+ if (err < 0) {
+ fprintf(stderr, "Cannot open subscribe events to ctl %s\n", name);
+ snd_ctl_close(ctl);
+ return err;
+ }
+ snd_ctl_event_alloca(&event);
+ while (snd_ctl_read(ctl, event) > 0) {
+ unsigned int mask;
+
+ if (snd_ctl_event_get_type(event) != SND_CTL_EVENT_ELEM)
+ continue;
+
+ printf("#%d (%i,%i,%i,%s,%i)",
+ snd_ctl_event_elem_get_numid(event),
+ snd_ctl_event_elem_get_interface(event),
+ snd_ctl_event_elem_get_device(event),
+ snd_ctl_event_elem_get_subdevice(event),
+ snd_ctl_event_elem_get_name(event),
+ snd_ctl_event_elem_get_index(event));
+
+ mask = snd_ctl_event_elem_get_mask(event);
+ if (mask & SND_CTL_EVENT_MASK_VALUE)
+ printf(" VALUE");
+ if (mask & SND_CTL_EVENT_MASK_INFO)
+ printf(" INFO");
+ if (mask & SND_CTL_EVENT_MASK_ADD)
+ printf(" ADD");
+ if (mask & SND_CTL_EVENT_MASK_TLV)
+ printf(" TLV");
+ if (mask == SND_CTL_EVENT_MASK_REMOVE)
+ printf(" REMOVE");
+ printf("\n");
+ }
+ snd_ctl_close(ctl);
+ return 0;
+}
--
1.8.4.3

View File

@ -0,0 +1,40 @@
From bb3293c76e6a1a130196ccb86e78aea3322ed735 Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai@suse.de>
Date: Tue, 26 Nov 2013 13:59:19 +0100
Subject: [PATCH] alsactl: Fix REMOVE event handling in monitor command
SND_CTL_EVENT_MASK_REMOVE has to be checked at first and ignore the
rest if it matches. Suggested by Clemens.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
alsactl/monitor.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/alsactl/monitor.c b/alsactl/monitor.c
index 12d24504264b..1c0246849c62 100644
--- a/alsactl/monitor.c
+++ b/alsactl/monitor.c
@@ -58,6 +58,10 @@ int monitor(const char *name)
snd_ctl_event_elem_get_index(event));
mask = snd_ctl_event_elem_get_mask(event);
+ if (mask == SND_CTL_EVENT_MASK_REMOVE) {
+ printf(" REMOVE\n");
+ continue;
+ }
if (mask & SND_CTL_EVENT_MASK_VALUE)
printf(" VALUE");
if (mask & SND_CTL_EVENT_MASK_INFO)
@@ -66,8 +70,6 @@ int monitor(const char *name)
printf(" ADD");
if (mask & SND_CTL_EVENT_MASK_TLV)
printf(" TLV");
- if (mask == SND_CTL_EVENT_MASK_REMOVE)
- printf(" REMOVE");
printf("\n");
}
snd_ctl_close(ctl);
--
1.8.4.3

View File

@ -0,0 +1,189 @@
From 5dfc232a9dde5bd6b36ef6782039f4437fc04dd3 Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai@suse.de>
Date: Tue, 26 Nov 2013 14:27:30 +0100
Subject: [PATCH] alsactl: monitor all cards as default
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
alsactl/alsactl.1 | 5 +-
alsactl/monitor.c | 136 ++++++++++++++++++++++++++++++++++++++++--------------
2 files changed, 104 insertions(+), 37 deletions(-)
diff --git a/alsactl/alsactl.1 b/alsactl/alsactl.1
index a11c17cb59e1..b1e17945c2fb 100644
--- a/alsactl/alsactl.1
+++ b/alsactl/alsactl.1
@@ -39,9 +39,8 @@ rescan, save_and_quit).
\fImonitor\fP is for monitoring the events received from the given
control device.
-If no soundcards are specified, setup for all cards will be saved or
-loaded (except for \fImonitor\fP command that can handle only a single
-card; it selects the card "default" when unspecified).
+If no soundcards are specified, setup for all cards will be saved,
+loaded or monitored.
.SH OPTIONS
diff --git a/alsactl/monitor.c b/alsactl/monitor.c
index 1c0246849c62..536176d0e7cb 100644
--- a/alsactl/monitor.c
+++ b/alsactl/monitor.c
@@ -22,15 +22,11 @@
#include <stdio.h>
#include <alsa/asoundlib.h>
-int monitor(const char *name)
+static int open_ctl(const char *name, snd_ctl_t **ctlp)
{
snd_ctl_t *ctl;
- snd_ctl_event_t *event;
int err;
- if (!name)
- name = "default";
-
err = snd_ctl_open(&ctl, name, SND_CTL_READONLY);
if (err < 0) {
fprintf(stderr, "Cannot open ctl %s\n", name);
@@ -42,36 +38,108 @@ int monitor(const char *name)
snd_ctl_close(ctl);
return err;
}
+ *ctlp = ctl;
+ return 0;
+}
+
+static int print_event(int card, snd_ctl_t *ctl)
+{
+ snd_ctl_event_t *event;
+ unsigned int mask;
+ int err;
+
snd_ctl_event_alloca(&event);
- while (snd_ctl_read(ctl, event) > 0) {
- unsigned int mask;
-
- if (snd_ctl_event_get_type(event) != SND_CTL_EVENT_ELEM)
- continue;
-
- printf("#%d (%i,%i,%i,%s,%i)",
- snd_ctl_event_elem_get_numid(event),
- snd_ctl_event_elem_get_interface(event),
- snd_ctl_event_elem_get_device(event),
- snd_ctl_event_elem_get_subdevice(event),
- snd_ctl_event_elem_get_name(event),
- snd_ctl_event_elem_get_index(event));
-
- mask = snd_ctl_event_elem_get_mask(event);
- if (mask == SND_CTL_EVENT_MASK_REMOVE) {
- printf(" REMOVE\n");
- continue;
- }
- if (mask & SND_CTL_EVENT_MASK_VALUE)
- printf(" VALUE");
- if (mask & SND_CTL_EVENT_MASK_INFO)
- printf(" INFO");
- if (mask & SND_CTL_EVENT_MASK_ADD)
- printf(" ADD");
- if (mask & SND_CTL_EVENT_MASK_TLV)
- printf(" TLV");
- printf("\n");
+ err = snd_ctl_read(ctl, event);
+ if (err < 0)
+ return err;
+
+ if (snd_ctl_event_get_type(event) != SND_CTL_EVENT_ELEM)
+ return 0;
+
+ if (card >= 0)
+ printf("card %d, ", card);
+ printf("#%d (%i,%i,%i,%s,%i)",
+ snd_ctl_event_elem_get_numid(event),
+ snd_ctl_event_elem_get_interface(event),
+ snd_ctl_event_elem_get_device(event),
+ snd_ctl_event_elem_get_subdevice(event),
+ snd_ctl_event_elem_get_name(event),
+ snd_ctl_event_elem_get_index(event));
+
+ mask = snd_ctl_event_elem_get_mask(event);
+ if (mask == SND_CTL_EVENT_MASK_REMOVE) {
+ printf(" REMOVE\n");
+ return 0;
}
- snd_ctl_close(ctl);
+
+ if (mask & SND_CTL_EVENT_MASK_VALUE)
+ printf(" VALUE");
+ if (mask & SND_CTL_EVENT_MASK_INFO)
+ printf(" INFO");
+ if (mask & SND_CTL_EVENT_MASK_ADD)
+ printf(" ADD");
+ if (mask & SND_CTL_EVENT_MASK_TLV)
+ printf(" TLV");
+ printf("\n");
return 0;
}
+
+#define MAX_CARDS 256
+
+int monitor(const char *name)
+{
+ snd_ctl_t *ctls[MAX_CARDS];
+ int ncards = 0;
+ int show_cards;
+ int i, err;
+
+ if (!name) {
+ int card = -1;
+ while (snd_card_next(&card) >= 0 && card >= 0) {
+ char cardname[16];
+ if (ncards >= MAX_CARDS) {
+ fprintf(stderr, "alsactl: too many cards\n");
+ err = -E2BIG;
+ goto error;
+ }
+ sprintf(cardname, "hw:%d", card);
+ err = open_ctl(cardname, &ctls[ncards]);
+ if (err < 0)
+ goto error;
+ ncards++;
+ }
+ show_cards = 1;
+ } else {
+ err = open_ctl(name, &ctls[0]);
+ if (err < 0)
+ goto error;
+ ncards++;
+ show_cards = 0;
+ }
+
+ for (;;) {
+ struct pollfd fds[ncards];
+
+ for (i = 0; i < ncards; i++)
+ snd_ctl_poll_descriptors(ctls[i], &fds[i], 1);
+
+ err = poll(fds, ncards, -1);
+ if (err <= 0) {
+ err = 0;
+ break;
+ }
+
+ for (i = 0; i < ncards; i++) {
+ unsigned short revents;
+ snd_ctl_poll_descriptors_revents(ctls[i], &fds[i], 1,
+ &revents);
+ if (revents & POLLIN)
+ print_event(show_cards ? i : -1, ctls[i]);
+ }
+ }
+
+ error:
+ for (i = 0; i < ncards; i++)
+ snd_ctl_close(ctls[i]);
+ return err;
+}
--
1.8.4.3

View File

@ -1,3 +1,20 @@
-------------------------------------------------------------------
Wed Nov 27 09:54:23 CET 2013 - tiwai@suse.de
- Backport upstream fixes: a few fixes for chmap support, alsaconf
updates, a new monitor command for alsactl, etc:
0006-amixer-fix-indentation-when-printing-container-TLV-c.patch
0007-alsaloop-pcmjob.c-use-portable-way-to-initialize-rec.patch
0008-speaker-test-Fix-chmapped-channel-selection-without-.patch
0009-speaker-test-Always-show-chmap-channel-names-if-avai.patch
0010-speaker-test-Show-out-of-chmap-channels-as-Unknown.patch
0011-alsaconf-support-newer-m-i-t-and-kmod.patch
0012-alsaconf-update-gentoo-to-use-modprobe.d-method-as-e.patch
0013-configure-detect-udevdir-via-pkg-config-fallback-to-.patch
0014-alsactl-Add-monitor-command.patch
0015-alsactl-Fix-REMOVE-event-handling-in-monitor-command.patch
0016-alsactl-monitor-all-cards-as-default.patch
-------------------------------------------------------------------
Tue Oct 1 12:30:28 CEST 2013 - tiwai@suse.de

View File

@ -63,6 +63,17 @@ Patch2: 0002-alsaloop-fix-wrong-alias-for-signal.h.patch
Patch3: 0003-aplay-fix-two-off-by-one-errors.patch
Patch4: 0004-alsaloop-add-z-syslog-option-to-use-syslog-for-error.patch
Patch5: 0005-amixer-actually-print-all-TLVs-in-a-container-TLV.patch
Patch6: 0006-amixer-fix-indentation-when-printing-container-TLV-c.patch
Patch7: 0007-alsaloop-pcmjob.c-use-portable-way-to-initialize-rec.patch
Patch8: 0008-speaker-test-Fix-chmapped-channel-selection-without-.patch
Patch9: 0009-speaker-test-Always-show-chmap-channel-names-if-avai.patch
Patch10: 0010-speaker-test-Show-out-of-chmap-channels-as-Unknown.patch
Patch11: 0011-alsaconf-support-newer-m-i-t-and-kmod.patch
Patch12: 0012-alsaconf-update-gentoo-to-use-modprobe.d-method-as-e.patch
Patch13: 0013-configure-detect-udevdir-via-pkg-config-fallback-to-.patch
Patch14: 0014-alsactl-Add-monitor-command.patch
Patch15: 0015-alsactl-Fix-REMOVE-event-handling-in-monitor-command.patch
Patch16: 0016-alsactl-monitor-all-cards-as-default.patch
#
Patch99: alsa-utils-gettext-version-removal.diff
Url: http://www.alsa-project.org/
@ -83,6 +94,17 @@ sed -i -e's/EXTRA_DIST= config.rpath /EXTRA_DIST=/' Makefile.am
%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
#
%if %suse_version < 1020
%patch99 -p1