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