File 0016-alsactl-monitor-all-cards-as-default.patch of Package alsa-utils.948

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

openSUSE Build Service is sponsored by