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>
This commit is contained in:
Takashi Iwai 2013-11-26 11:44:40 +01:00
parent 7d0c2801b3
commit d2d9b6fc8d
4 changed files with 86 additions and 2 deletions

View file

@ -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

View file

@ -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

View file

@ -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;

75
alsactl/monitor.c Normal file
View file

@ -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;
}