alsa-utils/0016-alsactl-monitor-all-cards-as-default.patch
Takashi Iwai f84c139643 Accepting request 208681 from home:tiwai:branches: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

OBS-URL: https://build.opensuse.org/request/show/208681
OBS-URL: https://build.opensuse.org/package/show/multimedia:libs/alsa-utils?expand=0&rev=94
2013-11-27 13:18:04 +00:00

190 lines
4.6 KiB
Diff

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