Okay, this version of setvol (Empeg executable is attached, source is below) now restores the previous "saved" volume level (AC or DC) when run without any arguments. Otherwise, it takes a parameter 0..100 as before.
Enjoy!
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/soundcard.h>
#define MIXER "/dev/mixer"
#define STATE "/dev/empeg_state"
#define POWER "/proc/empeg_power"
static int Open (const char *path, int mode)
{
int fd = open(path, mode);
if (fd == -1) {
perror(path);
exit(errno);
}
return fd;
}
int main(int argc, char *argv[])
{
int fd;
int vol = -1;
if (argc == 1) {
unsigned char state[128], on_dc;
// restore previous level for this powermode
fd = Open(STATE, O_RDONLY);
if (sizeof(state) != read(fd, state, sizeof(state))) {
perror(STATE);
exit(errno);
}
close(fd);
fd = Open(POWER, O_RDONLY);
if (1 != read(fd, &on_dc, 1)) {
perror(POWER);
exit(errno);
}
close(fd);
on_dc &= 1;
if (on_dc)
vol = (state[0x0d] >> 1);
else
vol = ((state[0x0d] & 1) << 6) | (state[0xc] >> 2);
printf("Saved %s volume was %u\n", on_dc ? "DC" : "AC", vol);
} else if (argc != 2 || (vol = atoi(argv[1])) < 0 || vol > 100) {
fprintf(stderr, "Usage: %s volume (where 0 <= volume <= 100)\n", argv[0]);
exit(-1);
}
fd = Open(MIXER, O_WRONLY);
vol |= (vol << 8);
if (ioctl(fd, SOUND_MIXER_WRITE_VOLUME, &vol) == -1) {
perror("SOUND_MIXER_WRITE_VOLUME");
exit(errno);
}
close(fd);
printf("Volume=%d\n", vol & 0xff);
exit(0);
}