Here's some untested code that might prove useful.
mute.c
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <fcntl.h> #include <sys/ioctl.h> #include <linux/soundcard.h> #include <errno.h> #include <string.h> #define EMPEG_MIXER_READ_FLAGS _IOR('m', 1, int) #define EMPEG_MIXER_WRITE_FLAGS _IOW('m', 1, int) #define EMPEG_MIXER_FLAG_MUTE (1<<0) int main(int ac, char *av[]) { int mute = -1; int flags = 0; int fd = -1; while (*++av) { if(av[0][0] == '-') { switch(av[0][1]) { case 'm': mute = 1; break; case 'u': mute = 0; break; default: fprintf(stderr, "Usage: mute [-u|-m]\n"); return 1; } } else { fprintf(stderr, "Usage: mute [-u|-m]\n"); return 1; } } fd = open("/dev/mixer", O_RDONLY); if (fd < 0) { fprintf(stderr, "Couldn't open /dev/mixer\n"); return 2; } if (mute >= 0) { if (mute) flags |= EMPEG_MIXER_FLAG_MUTE; if (ioctl(fd, EMPEG_MIXER_WRITE_FLAGS, &flags) < 0) printf("Write mute ioctl failed: %s (%d)\n", strerror(errno), errno); } if (ioctl(fd, EMPEG_MIXER_READ_FLAGS, &flags) < 0) printf("Read mute ioctl failed: %s (%d)\n", strerror(errno), errno); if (flags & EMPEG_MIXER_FLAG_MUTE) printf("Output is currently muted.\n"); else printf("Output is currently unmuted.\n"); return 0; }
The following code will view or change the input source (PCM, radio, or line.)
mixersrc.c
# include <stdio.h> # include <unistd.h> # include <fcntl.h> # include <sys/ioctl.h> # include <sys/soundcard.h> # define DEV_MIXER "/dev/mixer" /* The following definitions are from include/asm-arm/arch-sa1100/empeg.h in the beta9b kernel source */ # define EMPEG_MIXER_MAGIC 'm' # define EMPEG_MIXER_READ_SOURCE _IOR(EMPEG_MIXER_MAGIC, 0, int) # define EMPEG_MIXER_WRITE_SOURCE _IOW(EMPEG_MIXER_MAGIC, 0, int) int main(int argc, char *argv[]) { int fd, opt, source = 0; char *source_str; while ((opt = getopt(argc, argv, "prl")) != -1) { switch (opt) { case 'p': source = SOUND_MASK_PCM; break; case 'r': source = SOUND_MASK_RADIO; break; case 'l': source = SOUND_MASK_LINE; break; default: fprintf(stderr, "Usage: %s [-p|-r|-l]\n", argv[0]); return 1; } } fd = open(DEV_MIXER, O_RDONLY); if (fd == -1) { perror(DEV_MIXER); return 2; } if (source) { if (ioctl(fd, EMPEG_MIXER_WRITE_SOURCE, &source) == -1) { perror("ioctl(EMPEG_MIXER_WRITE_SOURCE)"); return 3; } } if (ioctl(fd, EMPEG_MIXER_READ_SOURCE, &source) == -1) { perror("ioctl(EMPEG_MIXER_READ_SOURCE)"); return 4; } if (source & SOUND_MASK_PCM) source_str = "PCM"; else if (source & SOUND_MASK_RADIO) source_str = "radio"; else if (source & SOUND_MASK_LINE) source_str = "line"; else source_str = "unknown"; printf("%s source selected\n", source_str); if (close(fd) == -1) { perror("close"); return 5; } return 0; }
An additional mute setting known as the Soft Audio Mute (SAM) can be toggled with the following code.
sam.c
# include <stdio.h> # include <unistd.h> # include <fcntl.h> # include <sys/ioctl.h> # include <sys/soundcard.h> # define DEV_MIXER "/dev/mixer" /* The following definitions are from include/asm-arm/arch-sa1100/empeg.h in the beta10a kernel source */ # define EMPEG_MIXER_MAGIC 'm' # define EMPEG_MIXER_SET_SAM _IOW(EMPEG_MIXER_MAGIC, 15, int) int main(int argc, char *argv[]) { int fd, opt, sam = -1; while ((opt = getopt(argc, argv, "mu")) != -1) { switch (opt) { case 'm': sam = 1; break; case 'u': sam = 0; break; default: return 1; } } if (sam == -1) { fprintf(stderr, "Usage: %s {-u|-m}\n", argv[0]); return 1; } fd = open(DEV_MIXER, O_RDONLY); if (fd == -1) { perror(DEV_MIXER); return 2; } if (ioctl(fd, EMPEG_MIXER_SET_SAM, &sam) == -1) { perror("ioctl(EMPEG_MIXER_SET_SAM)"); return 3; } printf("Soft Audio Mute %s\n", sam ? "enabled" : "disabled"); if (close(fd) == -1) { perror("close"); return 5; } return 0; }