/* audio_setdevice (version 1)
 *     by Brad Thompson
 * This is a program for playing with the audio device from the command line
 * It seems to work under NetBSD and Solaris and will probably work under
 * SunOS and *BSD.  This code is in the public domain.
 */

#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/audioio.h>

void fail(const char *err);
#define usage() (fprintf(stderr,"Usage: audio_setdevice [-out lineout|headphones|speaker]\n                       [-in linein|microphone|cd]\n                       [-volume 1...100]\n"),exit(1));
char *argv0;

int main(int argc, char **argv)
{
    int fd, r, i, new_input=-1, new_output=-1, new_volume=-1;
    struct audio_info info;

    argv0 = argv[0];
    errno = 0;

    if ((argc % 2)==0) usage();
    for (i=1; i<argc; i+=2)
    {
	if (i+1==argc) usage();

	if (strcasecmp(argv[i], "-out")==0)
	{
	    if (strcasecmp(argv[i+1], "lineout")==0)
		new_output = AUDIO_LINE_OUT;
	    else if (strcasecmp(argv[i+1], "headphones")==0)
		new_output = AUDIO_HEADPHONE;
	    else if (strcasecmp(argv[i+1], "speaker")==0)
		new_output = AUDIO_SPEAKER;
	    else
		usage();
	}
	if (strcasecmp(argv[i], "-in")==0)
	{
	    if (strcasecmp(argv[i+1], "linein")==0)
		new_input = AUDIO_LINE_IN;
	    else if (strcasecmp(argv[i+1], "microphone")==0)
		new_input = AUDIO_MICROPHONE;
	    else if (strcasecmp(argv[i+1], "cd")==0)
		new_input = AUDIO_CD;
	    else
		usage();
	}
	if (strcasecmp(argv[i], "-volume")==0)
	{
	    int v;

	    v = atoi(argv[i+1]);
	    if (v>=0 && v<=100) new_volume = v;
	    else usage();
	}
    }

    fd = open("/dev/audioctl", O_RDWR, 0);
    if (fd==-1) fail("can't open /dev/audioctl");

    r = ioctl(fd, AUDIO_GETINFO, &info); 
    if (r==-1) fail("can't get audio info");

    if (new_output!=-1) info.play.port = new_output;
    if (new_input!=-1) info.record.port = new_output;
    if (new_volume!=-1) info.play.gain = (AUDIO_MAX_GAIN * new_volume)/100;

    r = ioctl(fd, AUDIO_SETINFO, &info); 
    if (r==-1) fail("can't set audio info");

    r = close(fd);
    if (r==-1) fail("can't close /dev/audioctl");

    exit(0);
}

void fail(const char *err)
{
    fprintf(stderr, "%s: %s (%d: %s)\n", argv0, err, errno,
	    errno?strerror(errno):"unknown error");
    exit(1);
}

