tarina

git clone https://git.tarina.org/tarina
Log | Files | Refs | README | LICENSE

monitor.c (3475B)


      1 /*
      2  *  Advanced Linux Sound Architecture Control Program
      3  *  Copyright (c) by Takashi Iwai <tiwai@suse.de>
      4  *
      5  *   This program is free software; you can redistribute it and/or modify
      6  *   it under the terms of the GNU General Public License as published by
      7  *   the Free Software Foundation; either version 2 of the License, or
      8  *   (at your option) any later version.
      9  *
     10  *   This program is distributed in the hope that it will be useful,
     11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13  *   GNU General Public License for more details.
     14  *
     15  *   You should have received a copy of the GNU General Public License
     16  *   along with this program; if not, write to the Free Software
     17  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
     18  */
     19 
     20 #include "aconfig.h"
     21 #include "version.h"
     22 #include <stdio.h>
     23 #include <alsa/asoundlib.h>
     24 
     25 static int open_ctl(const char *name, snd_ctl_t **ctlp)
     26 {
     27 	snd_ctl_t *ctl;
     28 	int err;
     29 
     30 	err = snd_ctl_open(&ctl, name, SND_CTL_READONLY);
     31 	if (err < 0) {
     32 		fprintf(stderr, "Cannot open ctl %s\n", name);
     33 		return err;
     34 	}
     35 	err = snd_ctl_subscribe_events(ctl, 1);
     36 	if (err < 0) {
     37 		fprintf(stderr, "Cannot open subscribe events to ctl %s\n", name);
     38 		snd_ctl_close(ctl);
     39 		return err;
     40 	}
     41 	*ctlp = ctl;
     42 	return 0;
     43 }
     44 
     45 static int print_event(int card, snd_ctl_t *ctl)
     46 {
     47 	snd_ctl_event_t *event;
     48 	unsigned int mask;
     49 	int err;
     50 
     51 	snd_ctl_event_alloca(&event);
     52 	err = snd_ctl_read(ctl, event);
     53 	if (err < 0)
     54 		return err;
     55 
     56 	if (snd_ctl_event_get_type(event) != SND_CTL_EVENT_ELEM)
     57 		return 0;
     58 
     59 	if (card >= 0)
     60 		printf("card %d, ", card);
     61 	printf("#%d (%i,%i,%i,%s,%i)",
     62 	       snd_ctl_event_elem_get_numid(event),
     63 	       snd_ctl_event_elem_get_interface(event),
     64 	       snd_ctl_event_elem_get_device(event),
     65 	       snd_ctl_event_elem_get_subdevice(event),
     66 	       snd_ctl_event_elem_get_name(event),
     67 	       snd_ctl_event_elem_get_index(event));
     68 
     69 	mask = snd_ctl_event_elem_get_mask(event);
     70 	if (mask == SND_CTL_EVENT_MASK_REMOVE) {
     71 		printf(" REMOVE\n");
     72 		return 0;
     73 	}
     74 
     75 	if (mask & SND_CTL_EVENT_MASK_VALUE)
     76 		printf(" VALUE");
     77 	if (mask & SND_CTL_EVENT_MASK_INFO)
     78 		printf(" INFO");
     79 	if (mask & SND_CTL_EVENT_MASK_ADD)
     80 		printf(" ADD");
     81 	if (mask & SND_CTL_EVENT_MASK_TLV)
     82 		printf(" TLV");
     83 	printf("\n");
     84 	return 0;
     85 }
     86 
     87 #define MAX_CARDS	256
     88 
     89 int monitor(const char *name)
     90 {
     91 	snd_ctl_t *ctls[MAX_CARDS];
     92 	int ncards = 0;
     93 	int show_cards;
     94 	int i, err = 0;
     95 
     96 	if (!name) {
     97 		int card = -1;
     98 		while (snd_card_next(&card) >= 0 && card >= 0) {
     99 			char cardname[16];
    100 			if (ncards >= MAX_CARDS) {
    101 				fprintf(stderr, "alsactl: too many cards\n");
    102 				err = -E2BIG;
    103 				goto error;
    104 			}
    105 			sprintf(cardname, "hw:%d", card);
    106 			err = open_ctl(cardname, &ctls[ncards]);
    107 			if (err < 0)
    108 				goto error;
    109 			ncards++;
    110 		}
    111 		show_cards = 1;
    112 	} else {
    113 		err = open_ctl(name, &ctls[0]);
    114 		if (err < 0)
    115 			goto error;
    116 		ncards++;
    117 		show_cards = 0;
    118 	}
    119 
    120 	for (;ncards > 0;) {
    121 		struct pollfd fds[ncards];
    122 
    123 		for (i = 0; i < ncards; i++)
    124 			snd_ctl_poll_descriptors(ctls[i], &fds[i], 1);
    125 
    126 		err = poll(fds, ncards, -1);
    127 		if (err <= 0) {
    128 			err = 0;
    129 			break;
    130 		}
    131 
    132 		for (i = 0; i < ncards; i++) {
    133 			unsigned short revents;
    134 			snd_ctl_poll_descriptors_revents(ctls[i], &fds[i], 1,
    135 							 &revents);
    136 			if (revents & POLLIN)
    137 				print_event(show_cards ? i : -1, ctls[i]);
    138 		}
    139 	}
    140 
    141  error:
    142 	for (i = 0; i < ncards; i++)
    143 		snd_ctl_close(ctls[i]);
    144 	return err;
    145 }