components/volume.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/* See LICENSE file for copyright and license details. */ #include <fcntl.h> #include <stdio.h> #include <string.h> #include <sys/ioctl.h> #include <unistd.h> #include "../util.h" #if defined(__OpenBSD__) #include <sys/audioio.h> const char * vol_perc(const char *card) { static int cls = -1; mixer_devinfo_t mdi; mixer_ctrl_t mc; int afd = -1, m = -1, v = -1; if ((afd = open(card, O_RDONLY)) < 0) { warn("open '%s':", card); return NULL; } for (mdi.index = 0; cls == -1; mdi.index++) { if (ioctl(afd, AUDIO_MIXER_DEVINFO, &mdi) < 0) { warn("ioctl 'AUDIO_MIXER_DEVINFO':"); close(afd); return NULL; } if (mdi.type == AUDIO_MIXER_CLASS && !strncmp(mdi.label.name, AudioCoutputs, MAX_AUDIO_DEV_LEN)) cls = mdi.index; } for (mdi.index = 0; v == -1 || m == -1; mdi.index++) { if (ioctl(afd, AUDIO_MIXER_DEVINFO, &mdi) < 0) { warn("ioctl 'AUDIO_MIXER_DEVINFO':"); close(afd); return NULL; } if (mdi.mixer_class == cls && ((mdi.type == AUDIO_MIXER_VALUE && !strncmp(mdi.label.name, AudioNmaster, MAX_AUDIO_DEV_LEN)) || (mdi.type == AUDIO_MIXER_ENUM && !strncmp(mdi.label.name, AudioNmute, MAX_AUDIO_DEV_LEN)))) { mc.dev = mdi.index, mc.type = mdi.type; if (ioctl(afd, AUDIO_MIXER_READ, &mc) < 0) { warn("ioctl 'AUDIO_MIXER_READ':"); close(afd); return NULL; } if (mc.type == AUDIO_MIXER_VALUE) v = mc.un.value.num_channels == 1 ? mc.un.value.level[AUDIO_MIXER_LEVEL_MONO] : (mc.un.value.level[AUDIO_MIXER_LEVEL_LEFT] > mc.un.value.level[AUDIO_MIXER_LEVEL_RIGHT] ? mc.un.value.level[AUDIO_MIXER_LEVEL_LEFT] : mc.un.value.level[AUDIO_MIXER_LEVEL_RIGHT]); else if (mc.type == AUDIO_MIXER_ENUM) m = mc.un.ord; } } close(afd); return bprintf("%d", m ? 0 : v * 100 / 255); } #else #include <sys/soundcard.h> const char * vol_perc(const char *card) { size_t i; int v, afd, devmask; char *vnames[] = SOUND_DEVICE_NAMES; if ((afd = open(card, O_RDONLY | O_NONBLOCK)) < 0) { warn("open '%s':", card); return NULL; } if (ioctl(afd, (int)SOUND_MIXER_READ_DEVMASK, &devmask) < 0) { warn("ioctl 'SOUND_MIXER_READ_DEVMASK':"); close(afd); return NULL; } for (i = 0; i < LEN(vnames); i++) { if (devmask & (1 << i) && !strcmp("vol", vnames[i])) { if (ioctl(afd, MIXER_READ(i), &v) < 0) { warn("ioctl 'MIXER_READ(%ld)':", i); close(afd); return NULL; } } } close(afd); return bprintf("%d", v & 0xff); } #endif