File:  [DragonFly] / src / usr.sbin / mixer / mixer.c
Revision 1.4: download - view: text, annotated - select for diffs
Thu Apr 15 12:38:02 2004 UTC (10 years, 3 months ago) by joerg
Branches: MAIN
CVS tags: HEAD
Don't print the recording sources to stderr, the manpage doesn't indicate
this and it doesn't seem sensible.

Print the recording source in parameter format, if mixer is called with -s.

    1: /*
    2:  *	This is an example of a mixer program for Linux
    3:  *
    4:  *	updated 1/1/93 to add stereo, level query, broken
    5:  *      	devmask kludge - cmetz@thor.tjhsst.edu
    6:  *
    7:  * (C) Craig Metz and Hannu Savolainen 1993.
    8:  *
    9:  * You may do anything you wish with this program.
   10:  *
   11:  * ditto for my modifications (John-Mark Gurney, 1997)
   12:  *
   13:  * $FreeBSD: src/usr.sbin/mixer/mixer.c,v 1.11.2.6 2001/07/30 10:22:58 dd Exp $
   14:  * $DragonFly: src/usr.sbin/mixer/mixer.c,v 1.4 2004/04/15 12:38:02 joerg Exp $
   15:  */
   16: 
   17: #include <err.h>
   18: #include <fcntl.h>
   19: #include <stdio.h>
   20: #include <string.h>
   21: #include <stdlib.h>
   22: #include <unistd.h>
   23: #include <sys/soundcard.h>
   24: 
   25: #define LEFT(vol) (vol & 0x7f)
   26: #define RIGHT(vol) ((vol >> 8) & 0x7f)
   27: 
   28: const char *names[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_NAMES;
   29: const char *defaultdev = "/dev/mixer";
   30: 
   31: void usage(int devmask, int recmask);
   32: int res_name(const char *name, int mask);
   33: void print_recsrc(int recsrc);
   34: void print_recsrc_short(int recsrc);
   35: 
   36: void
   37: usage(int devmask, int recmask)
   38: {
   39: 	int i, n;
   40: 
   41: 	printf("usage: mixer [-f device] [-s] [dev [+|-][voll[:[+|-]volr]] ...\n"
   42: 	       "       mixer [-f device] [-s] recsrc ...\n"
   43: 	       "       mixer [-f device] [-s] {^|+|-|=}rec recdev ...\n"
   44: 	       "       mixer -h\n");
   45: 	printf(" devices: ");
   46: 	for (i = 0, n = 0; i < SOUND_MIXER_NRDEVICES; i++)
   47: 		if ((1 << i) & devmask)  {
   48: 			if (n)
   49: 				printf(", ");
   50: 			printf("%s", names[i]);
   51: 			n = 1;
   52: 		}
   53: 	printf("\n rec devices: ");
   54: 	for (i = 0, n = 0; i < SOUND_MIXER_NRDEVICES; i++)
   55: 		if ((1 << i) & recmask)  {
   56: 			if (n)
   57: 				printf(", ");
   58: 			printf("%s", names[i]);
   59: 			n = 1;
   60: 		}
   61: 	printf("\n");
   62: 	exit(1);
   63: }
   64: 
   65: int
   66: res_name(const char *name, int mask)
   67: {
   68: 	int i;
   69: 
   70: 	for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
   71: 		if ((1 << i) & mask && !strcmp(names[i], name))
   72: 			break;
   73: 
   74: 	return i == SOUND_MIXER_NRDEVICES ? -1 : i;
   75: }
   76: 
   77: void
   78: print_recsrc(int recsrc)
   79: {
   80: 	int i, n = 0;
   81: 	printf("Recording source: ");
   82: 
   83: 	for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
   84: 		if ((1 << i) & recsrc) {
   85: 			if (n)
   86: 				printf(", ");
   87: 			printf("%s", names[i]);
   88: 			n = 1;
   89: 		}
   90: 	printf("\n");
   91: }
   92: 
   93: void print_recsrc_short(int recsrc)
   94: {
   95: 	int i, first;
   96: 
   97: 	first = 1;
   98: 
   99: 	for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
  100: 		if ((1 << i) & recsrc) {
  101: 			if (first) {
  102: 				printf("=%s ", names[i]);
  103: 				first = 0;
  104: 			} else 
  105: 				printf("+%s ", names[i]);
  106: 		}
  107: 	}
  108: }
  109: 
  110: int
  111: main(int argc, char *argv[])
  112: {
  113: 	int i, mset, fd, dev;
  114: 	int devmask = 0, recmask = 0, recsrc = 0, orecsrc;
  115: 	int dusage = 0, drecsrc = 0, shortflag = 0;
  116: 	int l = 0, r = 0, t = 0;
  117: 	int n = 0, lrel = 0, rrel = 0;
  118: 	char lstr[8], rstr[8];
  119: 	char ch;
  120: 
  121: 	const char *name = defaultdev;
  122: 
  123: 	while ((ch = getopt(argc, argv, "f:sh")) != -1)
  124: 		switch (ch) {
  125: 			case 'f':
  126: 				name = optarg;
  127: 				break;
  128: 			case 's':
  129: 				shortflag = 1;
  130: 				break;
  131: 			case 'h': /* Fall through */
  132: 			default:
  133: 				dusage = 1;
  134: 		}
  135: 	argc -= optind;
  136: 	argv += optind;
  137: 
  138: 	if ((fd = open(name, O_RDWR)) < 0)
  139: 		err(1, "%s", name);
  140: 	if (ioctl(fd, SOUND_MIXER_READ_DEVMASK, &devmask) == -1)
  141: 		err(1, "SOUND_MIXER_READ_DEVMASK");
  142: 	if (ioctl(fd, SOUND_MIXER_READ_RECMASK, &recmask) == -1)
  143: 		err(1, "SOUND_MIXER_READ_RECMASK");
  144: 	if (ioctl(fd, SOUND_MIXER_READ_RECSRC, &recsrc) == -1)
  145: 		err(1, "SOUND_MIXER_READ_RECSRC");
  146: 	orecsrc = recsrc;
  147: 
  148: 	if (dusage) {
  149: 		close(fd);
  150: 		usage(devmask, recmask); /* Does not return */
  151: 	}
  152: 
  153: 	if (argc == 0) {
  154: 		for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
  155: 			if (!((1 << i) & devmask)) 
  156: 				continue;
  157: 			if (ioctl(fd, MIXER_READ(i),&mset)== -1) {
  158: 			   	warn("MIXER_READ");
  159: 				continue;
  160: 			}
  161: 			if (shortflag)
  162: 				printf("%s %d:%d ", names[i], LEFT(mset), 
  163: 						RIGHT(mset));
  164: 			else
  165: 				printf("Mixer %-8s is currently set to %3d:%d\n", 
  166: 						names[i], LEFT(mset), RIGHT(mset));
  167: 		}
  168: 		if (ioctl(fd, SOUND_MIXER_READ_RECSRC, &recsrc) == -1)
  169: 			err(1, "SOUND_MIXER_READ_RECSRC");
  170: 		if (shortflag) {
  171: 			print_recsrc_short(recsrc);
  172: 			if (isatty(STDOUT_FILENO))
  173: 				printf("\n");
  174: 		} else
  175: 			print_recsrc(recsrc);
  176: 		exit(0);
  177: 	}
  178: 
  179: 
  180: 
  181: 	while (argc > 0) {
  182: 		if (!strcmp("recsrc", *argv)) {
  183: 			drecsrc = 1;
  184: 			argc--; argv++;
  185: 			continue;
  186: 		} else if (argc > 1 && !strcmp("rec", *argv + 1)) {
  187: 			if (**argv != '+' && **argv != '-' &&
  188: 			    **argv != '=' && **argv != '^') {
  189: 				warnx("unknown modifier: %c", **argv);
  190: 				dusage = 1;
  191: 				break;
  192: 			}
  193: 			if ((dev = res_name(argv[1], recmask)) == -1) {
  194: 				warnx("unknown recording device: %s", argv[1]);
  195: 				dusage = 1;
  196: 				break;
  197: 			}
  198: 			switch(**argv) {
  199: 			case '+':
  200: 				recsrc |= (1 << dev);
  201: 				break;
  202: 			case '-':
  203: 				recsrc &= ~(1 << dev);
  204: 				break;
  205: 			case '=':
  206: 				recsrc = (1 << dev);
  207: 				break;
  208: 			case '^':
  209: 				recsrc ^= (1 << dev);
  210: 				break;
  211: 			}
  212: 			drecsrc = 1;
  213: 			argc -= 2; argv += 2;
  214: 			continue;
  215: 		}
  216: 
  217: 		if ((t = sscanf(*argv, "%d:%d", &l, &r)) > 0) {
  218: 			dev = 0;
  219: 		}
  220: 		else if((dev = res_name(*argv, devmask)) == -1) {
  221: 			warnx("unknown device: %s", *argv);
  222: 			dusage = 1;
  223: 			break;
  224: 		}
  225: 
  226: #define	issign(c)	(((c) == '+') || ((c) == '-'))
  227: 
  228: 		if (argc > 1) {
  229: 			n = sscanf(argv[1], "%7[^:]:%7s", lstr, rstr);
  230: 			if (n > 0) {
  231: 				if (issign(lstr[0]))
  232: 					lrel = rrel = 1;
  233: 				l = atoi(lstr);
  234: 			}
  235: 			if (n > 1) {
  236: 				rrel = 0;
  237: 				if (issign(rstr[0]))
  238: 					rrel = 1;
  239: 				r = atoi(rstr);
  240: 			}
  241: 		}
  242: 
  243: 		switch(argc > 1 ? n : t) {
  244: 		case 0:
  245: 			if (ioctl(fd, MIXER_READ(dev),&mset)== -1) {
  246: 				warn("MIXER_READ");
  247: 				argc--; argv++;
  248: 				continue;
  249: 			}
  250: 			if (shortflag)
  251: 				printf("%s %d:%d ", names[dev], LEFT(mset), RIGHT(mset));
  252: 			else
  253: 				printf("Mixer %-8s is currently set to %3d:%d\n",
  254: 				  names[dev], LEFT(mset), RIGHT(mset));
  255: 
  256: 			argc--; argv++;
  257: 			break;
  258: 		case 1:
  259: 			r = l;
  260: 		case 2:
  261: 			if (ioctl(fd, MIXER_READ(dev),&mset)== -1) {
  262: 				warn("MIXER_READ");
  263: 				argc--; argv++;
  264: 				continue;
  265: 			}
  266: 
  267: 			if (lrel)
  268: 				l += LEFT(mset);
  269: 			if (rrel)
  270: 				r += RIGHT(mset);
  271: 
  272: 			if (l < 0)
  273: 				l = 0;
  274: 			else if (l > 100)
  275: 				l = 100;
  276: 			if (r < 0)
  277: 				r = 0;
  278: 			else if (r > 100)
  279: 				r = 100;
  280: 
  281: 			printf("Setting the mixer %s to %d:%d.\n", names[dev],
  282: 			    l, r);
  283: 
  284: 			l |= r << 8;
  285: 			if (ioctl(fd, MIXER_WRITE(dev), &l) == -1)
  286: 				warn("WRITE_MIXER");
  287: 
  288: 			argc -= 2; argv += 2;
  289:  			break;
  290: 		}
  291: 	}
  292: 
  293: 	if (orecsrc != recsrc)
  294: 		if (ioctl(fd, SOUND_MIXER_WRITE_RECSRC, &recsrc) == -1)
  295: 			err(1, "SOUND_MIXER_WRITE_RECSRC");
  296:  
  297: 	if (drecsrc) {
  298: 		if (ioctl(fd, SOUND_MIXER_READ_RECSRC, &recsrc) == -1)
  299: 			err(1, "SOUND_MIXER_READ_RECSRC");
  300: 		print_recsrc(recsrc);
  301: 	}
  302: 
  303: 	close(fd);
  304: 
  305: 	exit(0);
  306: }