volume.c (1330B)
1 /* See LICENSE for license details. */ 2 #include <alsa/asoundlib.h> 3 #include <alsa/mixer.h> 4 #include <limits.h> 5 6 struct vol_arg { 7 const char *card; 8 const char *sink; 9 }; 10 11 static size_t 12 volume(struct Block *b) 13 { 14 snd_mixer_t *handle; 15 snd_mixer_selem_id_t *sid; 16 snd_mixer_elem_t *elem; 17 struct vol_arg *va = b->arg; 18 const char *str = "muted"; 19 20 int notmuted; 21 long vol = 0, min, max; 22 23 snd_mixer_open(&handle, 0); 24 snd_mixer_attach(handle, va->card); 25 snd_mixer_selem_register(handle, NULL, NULL); 26 snd_mixer_load(handle); 27 28 snd_mixer_selem_id_malloc(&sid); 29 snd_mixer_selem_id_set_index(sid, 0); 30 snd_mixer_selem_id_set_name(sid, va->sink); 31 elem = snd_mixer_find_selem(handle, sid); 32 33 snd_mixer_selem_get_playback_switch(elem, 0, ¬muted); 34 35 if (snd_mixer_selem_has_playback_volume(elem)) { 36 snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_MONO, &vol); 37 snd_mixer_selem_get_playback_volume_range(elem, &min, &max); 38 39 /* covert from raw value to percent */ 40 vol = (double)(vol - min) / (double)(max - min) * 100; 41 } 42 43 /* don't change to snd_mixer_elem_free() it leaks memory */ 44 snd_mixer_close(handle); 45 snd_mixer_selem_id_free(sid); 46 47 if (notmuted) { 48 if (vol) { 49 snprintf(buf, sizeof(buf), "%ld%%", vol); 50 str = buf; 51 } else 52 str = "on"; 53 } 54 55 return snprintf(b->curstr, LEN(b->curstr), b->fmt, str); 56 }