/* See LICENSE file for copyright and license details. */ #include #include #include #include #include #include "../util.h" #if defined(__OpenBSD__) #include 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 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