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;
}