/**
 * Turns off all the audio devices but the headphones
 *
 * Shamelessly ripped from the end of the audio(7I) manpage
 */


#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/audioio.h>
#include <sys/ddi.h>
#include <sys/types.h>
#include <unistd.h>

void help(void) {
	printf("Usage: \n");
	printf("\t-u\tVolume up\n");
	printf("\t-d\tVolume down\n");
	printf("\t-m\tMute on\n");
	printf("\t-o\tMute off\n");
	printf("\t-t\tToggle Mute\n");
	printf("\t-s value\tSet volume level (0-255)\n");
	printf("\t-h\thelp\n");
}

int main(int argc, char **argv) {
	audio_info_t info;
	int ret;

	/* open audio control device */
	int audio_fd=open("/dev/audioctl", O_RDWR);
	if(audio_fd==-1) {
		if(errno==EACCES) {
			fprintf(stderr, "Permission denied, are you root?\n");
		} else if(errno==ENOENT) {
			fprintf(stderr, "No audio device\n");
		} else {
			perror("open /dev/audioctl");
		}
		exit(EXIT_FAILURE);
	}
	
	/* get current settings */
	if(ioctl(audio_fd, AUDIO_GETINFO, &info)==-1) {
		perror("ioctl AUDIO_GETINFO");
		exit(EXIT_FAILURE);
	}

	while((ret=getopt(argc, argv, "udmohts:"))!=-1) {
		switch(ret) {
			case 'u': /* volume up */
				info.play.gain+=10;
				break;
			case 'd': /* volume down */
				info.play.gain-=10;
				break;
			case 'm': /* mute on */
				info.play.port=AUDIO_HEADPHONE;
				break;
			case 'o': /* mute off */
				info.play.port=AUDIO_HEADPHONE | AUDIO_SPEAKER;
				break;
			case 't': /* toggle mute */
				if(info.play.port==AUDIO_HEADPHONE || info.play.port==(AUDIO_HEADPHONE | AUDIO_LINE_OUT)) {
					info.play.port=AUDIO_HEADPHONE | AUDIO_SPEAKER;
				} else {
					info.play.port=AUDIO_HEADPHONE;
				}
				break;
			case 's': /* set volume to a certain level */
				info.play.gain=atoi(optarg);
				break;
			case 'h':
				help();
				exit(0);
				break;
		}
	}

	//check the bounds
	if(info.play.gain>(100*AUDIO_MAX_GAIN)) {
		info.play.gain=AUDIO_MIN_GAIN;
	}
	info.play.gain=min(info.play.gain, AUDIO_MAX_GAIN);
	
	/* set new settings */
	if(ioctl(audio_fd, AUDIO_SETINFO, &info)==-1) {
		perror("ioctl AUDIO_SETINFO");
		exit(EXIT_FAILURE);
	}
	
	/* close audio control device */
	if(close(audio_fd)==-1) {
		perror("close /dev/audioctl");
		exit(EXIT_FAILURE);
	}

	/* exit */
	return EXIT_SUCCESS;
}
