|
|
@@ -2,44 +2,108 @@ |
|
|
|
#include <fcntl.h> |
|
|
|
#include <stdio.h> |
|
|
|
#include <string.h> |
|
|
|
#if defined(__OpenBSD__) |
|
|
|
#include <soundcard.h> |
|
|
|
#else |
|
|
|
#include <sys/soundcard.h> |
|
|
|
#endif |
|
|
|
#include <sys/ioctl.h> |
|
|
|
#include <unistd.h> |
|
|
|
|
|
|
|
#include "../util.h" |
|
|
|
|
|
|
|
const char * |
|
|
|
vol_perc(const char *card) |
|
|
|
{ |
|
|
|
size_t i; |
|
|
|
int v, afd, devmask; |
|
|
|
char *vnames[] = SOUND_DEVICE_NAMES; |
|
|
|
#if defined(__OpenBSD__) |
|
|
|
#include <sys/audioio.h> |
|
|
|
|
|
|
|
if ((afd = open(card, O_RDONLY | O_NONBLOCK)) < 0) { |
|
|
|
warn("open '%s':", card); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
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 (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); |
|
|
|
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; |
|
|
|
|
|
|
|
close(afd); |
|
|
|
if ((afd = open(card, O_RDONLY | O_NONBLOCK)) < 0) { |
|
|
|
warn("open '%s':", card); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|
|
|
|
return bprintf("%d", v & 0xff); |
|
|
|
} |
|
|
|
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 |