mixer.c revision 108421
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[] = 1650479Speter "$FreeBSD: head/usr.sbin/mixer/mixer.c 108421 2002-12-30 04:23:08Z jmallett $"; 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#include <sys/soundcard.h> 266448Sache 2778778Sddconst char *names[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_NAMES; 286448Sache 2929612Sjmgvoid usage(int devmask, int recmask); 3029612Sjmgint res_name(const char *name, int mask); 3129612Sjmgvoid print_recsrc(int recsrc); 326448Sache 3329612Sjmgvoid 3429612Sjmgusage(int devmask, int recmask) 356448Sache{ 3629612Sjmg int i, n; 376448Sache 3864657Ssobomax printf("usage: mixer [-f device] [-s] [[dev [voll[:volr]] | recsrc | {^|+|-|=}rec recdev] ... ]\n"); 3929753Sache printf(" devices: "); 4029612Sjmg for (i = 0, n = 0; i < SOUND_MIXER_NRDEVICES; i++) 416448Sache if ((1 << i) & devmask) { 426448Sache if (n) 4329612Sjmg printf(", "); 4469258Skris printf("%s", names[i]); 456448Sache n = 1; 468857Srgrimes } 4729753Sache printf("\n rec devices: "); 4829612Sjmg for (i = 0, n = 0; i < SOUND_MIXER_NRDEVICES; i++) 4929612Sjmg if ((1 << i) & recmask) { 5029612Sjmg if (n) 5129612Sjmg printf(", "); 5269258Skris printf("%s", names[i]); 5329612Sjmg n = 1; 5429612Sjmg } 5529612Sjmg printf("\n"); 566448Sache exit(1); 576448Sache} 586448Sache 5929612Sjmgint 6029612Sjmgres_name(const char *name, int mask) 616448Sache{ 6229612Sjmg int foo; 6329612Sjmg 6429612Sjmg for (foo = 0; foo < SOUND_MIXER_NRDEVICES; foo++) 6529612Sjmg if ((1 << foo) & mask && !strcmp(names[foo], name)) 6629612Sjmg break; 6729612Sjmg 6829612Sjmg return foo == SOUND_MIXER_NRDEVICES ? -1 : foo; 6929612Sjmg} 7029612Sjmg 7129612Sjmgvoid 7229612Sjmgprint_recsrc(int recsrc) 7329612Sjmg{ 746448Sache int i, n = 0; 756448Sache fprintf(stderr, "Recording source: "); 766448Sache 776448Sache for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) 786448Sache if ((1 << i) & recsrc) { 796448Sache if (n) 806448Sache fprintf(stderr, ", "); 8169258Skris fprintf(stderr, "%s", names[i]); 826448Sache n = 1; 836448Sache } 846448Sache fprintf(stderr, "\n"); 856448Sache} 866448Sache 878857Srgrimesint 886448Sachemain(int argc, char *argv[]) 896448Sache{ 906448Sache int foo, bar, baz, dev; 9129612Sjmg int devmask = 0, recmask = 0, recsrc = 0, orecsrc; 9260741Sjkh int dusage = 0, drecsrc = 0, shortflag = 0; 9375334Sgreid int l = 0, r = 0, t = 0; 9464657Ssobomax char ch; 956448Sache 9629612Sjmg char *name; 976448Sache 9829612Sjmg name = strdup("/dev/mixer"); 9929612Sjmg 1006448Sache if (!strcmp(argv[0], "mixer2")) 10129612Sjmg name = strdup("/dev/mixer1"); 10229612Sjmg else if (!strcmp(argv[0], "mixer3")) 10329612Sjmg name = strdup("/dev/mixer2"); 1046448Sache 10564657Ssobomax while ((ch = getopt(argc, argv, "f:s")) != -1) 10664657Ssobomax switch (ch) { 10764657Ssobomax case 'f': 10864657Ssobomax name = strdup(optarg); 10964657Ssobomax break; 11064657Ssobomax case 's': 11164657Ssobomax shortflag = 1; 11264657Ssobomax break; 11364657Ssobomax default: 11464657Ssobomax dusage = 1; 11564657Ssobomax } 11664657Ssobomax argc -= (optind - 1); 11764657Ssobomax argv += (optind - 1); 11829612Sjmg 11929963Scharnier if ((baz = open(name, O_RDWR)) < 0) 12029963Scharnier err(1, "%s", name); 12129612Sjmg free(name); 12229963Scharnier if (ioctl(baz, SOUND_MIXER_READ_DEVMASK, &devmask) == -1) 12330028Scharnier err(1, "SOUND_MIXER_READ_DEVMASK"); 12429963Scharnier if (ioctl(baz, SOUND_MIXER_READ_RECMASK, &recmask) == -1) 12530028Scharnier err(1, "SOUND_MIXER_READ_RECMASK"); 12629963Scharnier if (ioctl(baz, SOUND_MIXER_READ_RECSRC, &recsrc) == -1) 12730028Scharnier err(1, "SOUND_MIXER_READ_RECSRC"); 12829612Sjmg orecsrc = recsrc; 1296448Sache 13064657Ssobomax if ((argc == 1) && (dusage == 0)) { 13113803Smpp for (foo = 0; foo < SOUND_MIXER_NRDEVICES; foo++) { 13213803Smpp if (!((1 << foo) & devmask)) 13313803Smpp continue; 13413803Smpp if (ioctl(baz, MIXER_READ(foo),&bar)== -1) { 13529963Scharnier warn("MIXER_READ"); 13613803Smpp continue; 13713803Smpp } 13860741Sjkh if (shortflag) 13960741Sjkh printf("%s %d:%d ", names[foo], bar & 0x7f, (bar >> 8) & 0x7f); 14060741Sjkh else 14160741Sjkh printf("Mixer %-8s is currently set to %3d:%d\n", names[foo], bar & 0x7f, (bar >> 8) & 0x7f); 14213803Smpp } 14313803Smpp return(0); 14413803Smpp } 14513803Smpp 14629612Sjmg argc--; argv++; 1476448Sache 14875334Sgreid while ((argc > 0) && (dusage == 0)) { 14929612Sjmg if (!strcmp("recsrc", *argv)) { 15029612Sjmg drecsrc = 1; 15129612Sjmg argc--; argv++; 15229612Sjmg continue; 15329612Sjmg } else if (argc > 1 && !strcmp("rec", *argv + 1)) { 15429612Sjmg if (**argv != '+' && **argv != '-' && 15529612Sjmg **argv != '=' && **argv != '^') { 15664657Ssobomax warnx("unknown modifier: %c", **argv); 15729612Sjmg dusage = 1; 15864657Ssobomax break; 15913435Smpp } 16029612Sjmg if ((dev = res_name(argv[1], recmask)) == -1) { 16164657Ssobomax warnx("unknown recording device: %s", argv[1]); 16229612Sjmg dusage = 1; 16364657Ssobomax break; 1646448Sache } 16529612Sjmg switch(**argv) { 16629612Sjmg case '+': 1676448Sache recsrc |= (1 << dev); 16829612Sjmg break; 16929612Sjmg case '-': 1706448Sache recsrc &= ~(1 << dev); 17129612Sjmg break; 17229612Sjmg case '=': 17329612Sjmg recsrc = (1 << dev); 17429612Sjmg break; 17529612Sjmg case '^': 17629612Sjmg recsrc ^= (1 << dev); 17729612Sjmg break; 17829612Sjmg } 17929612Sjmg drecsrc = 1; 18029612Sjmg argc -= 2; argv += 2; 18129612Sjmg continue; 18229612Sjmg } 1836448Sache 18475334Sgreid if ((t = sscanf(*argv, "%d:%d", &l, &r)) > 0) { 18575334Sgreid dev = 0; 18675334Sgreid } 18775334Sgreid else if((dev = res_name(*argv, devmask)) == -1) { 18864657Ssobomax warnx("unknown device: %s", *argv); 18929612Sjmg dusage = 1; 19064657Ssobomax break; 19129612Sjmg } 19229612Sjmg 19375334Sgreid switch(argc > 1 ? sscanf(argv[1], "%d:%d", &l, &r) : t) { 19429612Sjmg case 0: 19529612Sjmg if (ioctl(baz, MIXER_READ(dev),&bar)== -1) { 19629963Scharnier warn("MIXER_READ"); 19729612Sjmg argc--; argv++; 19829612Sjmg continue; 1996448Sache } 20060741Sjkh if (shortflag) 20160741Sjkh printf("%s %d:%d ", names[dev], bar & 0x7f, (bar >> 8) & 0x7f); 20260741Sjkh else 20360741Sjkh printf("Mixer %-8s is currently set to %3d:%d\n", 20460741Sjkh names[dev], bar & 0x7f, (bar >> 8) & 0x7f); 2056448Sache 20629612Sjmg argc--; argv++; 20729612Sjmg break; 20829612Sjmg case 1: 20929612Sjmg r = l; 21029612Sjmg case 2: 21129612Sjmg if (l < 0) 21229612Sjmg l = 0; 21329612Sjmg else if (l > 100) 21429612Sjmg l = 100; 21529612Sjmg if (r < 0) 21629612Sjmg r = 0; 21729612Sjmg else if (r > 100) 21829612Sjmg r = 100; 2198857Srgrimes 220108421Sjmallett if (ioctl(baz, MIXER_READ(dev),&bar)== -1) { 221108421Sjmallett warn("MIXER_READ"); 222108421Sjmallett argc--; argv++; 223108421Sjmallett continue; 224108421Sjmallett } 2256448Sache 226108421Sjmallett printf("Setting the mixer %s from %d:%d to %d:%d.\n", 227108421Sjmallett names[dev], bar & 0x7f, (bar >> 8) & 0x7f, l, r); 228108421Sjmallett 22929612Sjmg l |= r << 8; 23029612Sjmg if (ioctl(baz, MIXER_WRITE(dev), &l) == -1) 23129963Scharnier warn("WRITE_MIXER"); 2326448Sache 23329612Sjmg argc -= 2; argv += 2; 23429612Sjmg break; 2356448Sache } 2366448Sache } 2376448Sache 23864657Ssobomax if (dusage) { 23964657Ssobomax close(baz); 24064657Ssobomax usage(devmask, recmask); 24164657Ssobomax /* Not reached */ 24264657Ssobomax } 24364657Ssobomax 24429612Sjmg if (orecsrc != recsrc) 24529963Scharnier if (ioctl(baz, SOUND_MIXER_WRITE_RECSRC, &recsrc) == -1) 24630028Scharnier err(1, "SOUND_MIXER_WRITE_RECSRC"); 24729612Sjmg 24829612Sjmg if (drecsrc) { 24929963Scharnier if (ioctl(baz, SOUND_MIXER_READ_RECSRC, &recsrc) == -1) 25030028Scharnier err(1, "SOUND_MIXER_READ_RECSRC"); 25129612Sjmg print_recsrc(recsrc); 25229612Sjmg } 25329612Sjmg 2546448Sache close(baz); 25529612Sjmg 25629612Sjmg exit(0); 2576448Sache} 258