mixer.c revision 29963
16448Sache/* 26448Sache * This is an example of a mixer program for Linux 36448Sache * 46448Sache * updated 1/1/93 to add stereo, level query, broken 58857Srgrimes * devmask kludge - cmetz@thor.tjhsst.edu 66448Sache * 76448Sache * (C) Craig Metz and Hannu Savolainen 1993. 86448Sache * 96448Sache * You may do anything you wish with this program. 1029612Sjmg * 1129612Sjmg * ditto for my modifications (John-Mark Gurney, 1997) 126448Sache */ 136448Sache 1429963Scharnier#ifndef lint 1529963Scharnierstatic const char rcsid[] = 1629963Scharnier "$Id$"; 1729963Scharnier#endif /* not lint */ 1829963Scharnier 1929963Scharnier#include <err.h> 2029963Scharnier#include <fcntl.h> 216448Sache#include <stdio.h> 226448Sache#include <string.h> 2329612Sjmg#include <stdlib.h> 2429612Sjmg#include <unistd.h> 256448Sache#ifdef __FreeBSD__ 266448Sache#include <machine/soundcard.h> 276448Sache#else 286448Sache#include <sys/soundcard.h> 296448Sache#endif 306448Sache 316448Sachechar *names[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_NAMES; 326448Sache 3329612Sjmgvoid usage(int devmask, int recmask); 3429612Sjmgint res_name(const char *name, int mask); 3529612Sjmgvoid print_recsrc(int recsrc); 366448Sache 3729612Sjmgvoid 3829612Sjmgusage(int devmask, int recmask) 396448Sache{ 4029612Sjmg int i, n; 416448Sache 4229963Scharnier printf("usage: mixer [[dev [voll[:volr]] | recsrc | {^|+|-|=}rec recdev] ... ]\n"); 4329753Sache printf(" devices: "); 4429612Sjmg for (i = 0, n = 0; i < SOUND_MIXER_NRDEVICES; i++) 456448Sache if ((1 << i) & devmask) { 466448Sache if (n) 4729612Sjmg printf(", "); 486448Sache printf(names[i]); 496448Sache n = 1; 508857Srgrimes } 5129753Sache printf("\n rec devices: "); 5229612Sjmg for (i = 0, n = 0; i < SOUND_MIXER_NRDEVICES; i++) 5329612Sjmg if ((1 << i) & recmask) { 5429612Sjmg if (n) 5529612Sjmg printf(", "); 5629612Sjmg printf(names[i]); 5729612Sjmg n = 1; 5829612Sjmg } 5929612Sjmg printf("\n"); 606448Sache exit(1); 616448Sache} 626448Sache 6329612Sjmgint 6429612Sjmgres_name(const char *name, int mask) 656448Sache{ 6629612Sjmg int foo; 6729612Sjmg 6829612Sjmg for (foo = 0; foo < SOUND_MIXER_NRDEVICES; foo++) 6929612Sjmg if ((1 << foo) & mask && !strcmp(names[foo], name)) 7029612Sjmg break; 7129612Sjmg 7229612Sjmg return foo == SOUND_MIXER_NRDEVICES ? -1 : foo; 7329612Sjmg} 7429612Sjmg 7529612Sjmgvoid 7629612Sjmgprint_recsrc(int recsrc) 7729612Sjmg{ 786448Sache int i, n = 0; 796448Sache fprintf(stderr, "Recording source: "); 806448Sache 816448Sache for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) 826448Sache if ((1 << i) & recsrc) { 836448Sache if (n) 846448Sache fprintf(stderr, ", "); 856448Sache fprintf(stderr, names[i]); 866448Sache n = 1; 876448Sache } 886448Sache fprintf(stderr, "\n"); 896448Sache} 906448Sache 918857Srgrimesint 926448Sachemain(int argc, char *argv[]) 936448Sache{ 946448Sache int foo, bar, baz, dev; 9529612Sjmg int devmask = 0, recmask = 0, recsrc = 0, orecsrc; 9629612Sjmg int dusage = 0, drecsrc = 0; 9729612Sjmg int l, r; 986448Sache 9929612Sjmg char *name; 1006448Sache 10129612Sjmg name = strdup("/dev/mixer"); 10229612Sjmg 1036448Sache if (!strcmp(argv[0], "mixer2")) 10429612Sjmg name = strdup("/dev/mixer1"); 10529612Sjmg else if (!strcmp(argv[0], "mixer3")) 10629612Sjmg name = strdup("/dev/mixer2"); 1076448Sache 10829612Sjmg if (argc > 1 && !strcmp(argv[1], "-f")) { 10929612Sjmg name = strdup(argv[2]); 11029612Sjmg argc -= 2; argv += 2; 11129612Sjmg } 11229612Sjmg 11329963Scharnier if ((baz = open(name, O_RDWR)) < 0) 11429963Scharnier err(1, "%s", name); 11529612Sjmg free(name); 11629963Scharnier if (ioctl(baz, SOUND_MIXER_READ_DEVMASK, &devmask) == -1) 11729963Scharnier err(-1, "SOUND_MIXER_READ_DEVMASK"); 11829963Scharnier if (ioctl(baz, SOUND_MIXER_READ_RECMASK, &recmask) == -1) 11929963Scharnier err(-1, "SOUND_MIXER_READ_RECMASK"); 12029963Scharnier if (ioctl(baz, SOUND_MIXER_READ_RECSRC, &recsrc) == -1) 12129963Scharnier err(-1, "SOUND_MIXER_READ_RECSRC"); 12229612Sjmg orecsrc = recsrc; 1236448Sache 12429612Sjmg if (argc == 1) { 12513803Smpp for (foo = 0; foo < SOUND_MIXER_NRDEVICES; foo++) { 12613803Smpp if (!((1 << foo) & devmask)) 12713803Smpp continue; 12813803Smpp if (ioctl(baz, MIXER_READ(foo),&bar)== -1) { 12929963Scharnier warn("MIXER_READ"); 13013803Smpp continue; 13113803Smpp } 13213803Smpp printf("Mixer %-8s is currently set to %3d:%d\n", names[foo], bar & 0x7f, (bar >> 8) & 0x7f); 13313803Smpp } 13413803Smpp return(0); 13513803Smpp } 13613803Smpp 13729612Sjmg argc--; argv++; 1386448Sache 13929612Sjmg while (argc) { 14029612Sjmg if (!strcmp("recsrc", *argv)) { 14129612Sjmg drecsrc = 1; 14229612Sjmg argc--; argv++; 14329612Sjmg continue; 14429612Sjmg } else if (argc > 1 && !strcmp("rec", *argv + 1)) { 14529612Sjmg if (**argv != '+' && **argv != '-' && 14629612Sjmg **argv != '=' && **argv != '^') { 14729612Sjmg dusage = 1; 14829612Sjmg argc -= 1; argv += 1; 14929612Sjmg continue; 15013435Smpp } 15129612Sjmg if ((dev = res_name(argv[1], recmask)) == -1) { 15229612Sjmg dusage = 1; 15329612Sjmg argc -= 1; argv += 1; 15429612Sjmg continue; 1556448Sache } 15629612Sjmg switch(**argv) { 15729612Sjmg case '+': 1586448Sache recsrc |= (1 << dev); 15929612Sjmg break; 16029612Sjmg case '-': 1616448Sache recsrc &= ~(1 << dev); 16229612Sjmg break; 16329612Sjmg case '=': 16429612Sjmg recsrc = (1 << dev); 16529612Sjmg break; 16629612Sjmg case '^': 16729612Sjmg recsrc ^= (1 << dev); 16829612Sjmg break; 16929612Sjmg } 17029612Sjmg drecsrc = 1; 17129612Sjmg argc -= 2; argv += 2; 17229612Sjmg continue; 17329612Sjmg } 1746448Sache 17529612Sjmg if ((dev = res_name(*argv, devmask)) == -1) { 17629612Sjmg dusage = 1; 17729612Sjmg argc--; argv++; 17829612Sjmg continue; 17929612Sjmg } 18029612Sjmg 18129612Sjmg switch(argc > 1 ? sscanf(argv[1], "%d:%d", &l, &r) : 0) { 18229612Sjmg case 0: 18329612Sjmg if (ioctl(baz, MIXER_READ(dev),&bar)== -1) { 18429963Scharnier warn("MIXER_READ"); 18529612Sjmg argc--; argv++; 18629612Sjmg continue; 1876448Sache } 18829612Sjmg printf("Mixer %-8s is currently set to %3d:%d\n", 18929612Sjmg names[dev], bar & 0x7f, (bar >> 8) & 0x7f); 1906448Sache 19129612Sjmg argc--; argv++; 19229612Sjmg break; 19329612Sjmg case 1: 19429612Sjmg r = l; 19529612Sjmg case 2: 19629612Sjmg if (l < 0) 19729612Sjmg l = 0; 19829612Sjmg else if (l > 100) 19929612Sjmg l = 100; 20029612Sjmg if (r < 0) 20129612Sjmg r = 0; 20229612Sjmg else if (r > 100) 20329612Sjmg r = 100; 2048857Srgrimes 20529612Sjmg printf("Setting the mixer %s to %d:%d.\n", names[dev], 20629612Sjmg l, r); 2076448Sache 20829612Sjmg l |= r << 8; 20929612Sjmg if (ioctl(baz, MIXER_WRITE(dev), &l) == -1) 21029963Scharnier warn("WRITE_MIXER"); 2116448Sache 21229612Sjmg argc -= 2; argv += 2; 21329612Sjmg break; 2146448Sache } 2156448Sache } 2166448Sache 21729612Sjmg if (orecsrc != recsrc) 21829963Scharnier if (ioctl(baz, SOUND_MIXER_WRITE_RECSRC, &recsrc) == -1) 21929963Scharnier err(-1, "SOUND_MIXER_WRITE_RECSRC"); 22029612Sjmg 22129612Sjmg if (drecsrc) { 22229963Scharnier if (ioctl(baz, SOUND_MIXER_READ_RECSRC, &recsrc) == -1) 22329963Scharnier err(-1, "SOUND_MIXER_READ_RECSRC"); 22429612Sjmg print_recsrc(recsrc); 22529612Sjmg } 22629612Sjmg 2276448Sache close(baz); 22829612Sjmg 22929612Sjmg if (dusage) 23029612Sjmg usage(devmask, recmask); 23129612Sjmg 23229612Sjmg exit(0); 2336448Sache} 234