mixer.c revision 29612
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 146448Sache#include <stdio.h> 156448Sache#include <fcntl.h> 166448Sache#include <string.h> 1729612Sjmg#include <stdlib.h> 1829612Sjmg#include <unistd.h> 196448Sache#ifdef __FreeBSD__ 206448Sache#include <machine/soundcard.h> 216448Sache#else 226448Sache#include <sys/soundcard.h> 236448Sache#endif 246448Sache 256448Sachechar *names[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_NAMES; 266448Sache 2729612Sjmgvoid usage(int devmask, int recmask); 2829612Sjmgint res_name(const char *name, int mask); 2929612Sjmgvoid print_recsrc(int recsrc); 306448Sache 3129612Sjmgvoid 3229612Sjmgusage(int devmask, int recmask) 336448Sache{ 3429612Sjmg int i, n; 356448Sache 3629612Sjmg printf("usage:\tmixer [[dev [voll[:volr]] | recsrc | {^|+|-|=}rec recdev] ... ]\n"); 3729612Sjmg printf(" devices:\t"); 3829612Sjmg for (i = 0, n = 0; i < SOUND_MIXER_NRDEVICES; i++) 396448Sache if ((1 << i) & devmask) { 406448Sache if (n) 4129612Sjmg printf(", "); 426448Sache printf(names[i]); 436448Sache n = 1; 448857Srgrimes } 4529612Sjmg printf("\n rec devices:\t"); 4629612Sjmg for (i = 0, n = 0; i < SOUND_MIXER_NRDEVICES; i++) 4729612Sjmg if ((1 << i) & recmask) { 4829612Sjmg if (n) 4929612Sjmg printf(", "); 5029612Sjmg printf(names[i]); 5129612Sjmg n = 1; 5229612Sjmg } 5329612Sjmg printf("\n"); 546448Sache exit(1); 556448Sache} 566448Sache 5729612Sjmgint 5829612Sjmgres_name(const char *name, int mask) 596448Sache{ 6029612Sjmg int foo; 6129612Sjmg 6229612Sjmg for (foo = 0; foo < SOUND_MIXER_NRDEVICES; foo++) 6329612Sjmg if ((1 << foo) & mask && !strcmp(names[foo], name)) 6429612Sjmg break; 6529612Sjmg 6629612Sjmg return foo == SOUND_MIXER_NRDEVICES ? -1 : foo; 6729612Sjmg} 6829612Sjmg 6929612Sjmgvoid 7029612Sjmgprint_recsrc(int recsrc) 7129612Sjmg{ 726448Sache int i, n = 0; 736448Sache fprintf(stderr, "Recording source: "); 746448Sache 756448Sache for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) 766448Sache if ((1 << i) & recsrc) { 776448Sache if (n) 786448Sache fprintf(stderr, ", "); 796448Sache fprintf(stderr, names[i]); 806448Sache n = 1; 816448Sache } 826448Sache fprintf(stderr, "\n"); 836448Sache} 846448Sache 858857Srgrimesint 866448Sachemain(int argc, char *argv[]) 876448Sache{ 886448Sache int foo, bar, baz, dev; 8929612Sjmg int devmask = 0, recmask = 0, recsrc = 0, orecsrc; 9029612Sjmg int dusage = 0, drecsrc = 0; 9129612Sjmg int l, r; 926448Sache 9329612Sjmg char *name; 946448Sache 9529612Sjmg name = strdup("/dev/mixer"); 9629612Sjmg 976448Sache if (!strcmp(argv[0], "mixer2")) 9829612Sjmg name = strdup("/dev/mixer1"); 9929612Sjmg else if (!strcmp(argv[0], "mixer3")) 10029612Sjmg name = strdup("/dev/mixer2"); 1016448Sache 10229612Sjmg if (argc > 1 && !strcmp(argv[1], "-f")) { 10329612Sjmg name = strdup(argv[2]); 10429612Sjmg argc -= 2; argv += 2; 10529612Sjmg } 10629612Sjmg 1076448Sache if ((baz = open(name, O_RDWR)) < 0) { 1086448Sache perror(name); 1096448Sache exit(1); 1106448Sache } 11129612Sjmg free(name); 1126448Sache if (ioctl(baz, SOUND_MIXER_READ_DEVMASK, &devmask) == -1) { 1136448Sache perror("SOUND_MIXER_READ_DEVMASK"); 1146448Sache exit(-1); 1156448Sache } 1166448Sache if (ioctl(baz, SOUND_MIXER_READ_RECMASK, &recmask) == -1) { 1176448Sache perror("SOUND_MIXER_READ_RECMASK"); 1186448Sache exit(-1); 1196448Sache } 1206448Sache if (ioctl(baz, SOUND_MIXER_READ_RECSRC, &recsrc) == -1) { 1216448Sache perror("SOUND_MIXER_READ_RECSRC"); 1226448Sache exit(-1); 1236448Sache } 12429612Sjmg orecsrc = recsrc; 1256448Sache 12629612Sjmg if (argc == 1) { 12713803Smpp for (foo = 0; foo < SOUND_MIXER_NRDEVICES; foo++) { 12813803Smpp if (!((1 << foo) & devmask)) 12913803Smpp continue; 13013803Smpp if (ioctl(baz, MIXER_READ(foo),&bar)== -1) { 13113803Smpp perror("MIXER_READ"); 13213803Smpp continue; 13313803Smpp } 13413803Smpp printf("Mixer %-8s is currently set to %3d:%d\n", names[foo], bar & 0x7f, (bar >> 8) & 0x7f); 13513803Smpp } 13613803Smpp return(0); 13713803Smpp } 13813803Smpp 13929612Sjmg argc--; argv++; 1406448Sache 14129612Sjmg while (argc) { 14229612Sjmg if (!strcmp("recsrc", *argv)) { 14329612Sjmg drecsrc = 1; 14429612Sjmg argc--; argv++; 14529612Sjmg continue; 14629612Sjmg } else if (argc > 1 && !strcmp("rec", *argv + 1)) { 14729612Sjmg if (**argv != '+' && **argv != '-' && 14829612Sjmg **argv != '=' && **argv != '^') { 14929612Sjmg dusage = 1; 15029612Sjmg argc -= 1; argv += 1; 15129612Sjmg continue; 15213435Smpp } 15329612Sjmg if ((dev = res_name(argv[1], recmask)) == -1) { 15429612Sjmg dusage = 1; 15529612Sjmg argc -= 1; argv += 1; 15629612Sjmg continue; 1576448Sache } 15829612Sjmg switch(**argv) { 15929612Sjmg case '+': 1606448Sache recsrc |= (1 << dev); 16129612Sjmg break; 16229612Sjmg case '-': 1636448Sache recsrc &= ~(1 << dev); 16429612Sjmg break; 16529612Sjmg case '=': 16629612Sjmg recsrc = (1 << dev); 16729612Sjmg break; 16829612Sjmg case '^': 16929612Sjmg recsrc ^= (1 << dev); 17029612Sjmg break; 17129612Sjmg } 17229612Sjmg drecsrc = 1; 17329612Sjmg argc -= 2; argv += 2; 17429612Sjmg continue; 17529612Sjmg } 1766448Sache 17729612Sjmg if ((dev = res_name(*argv, devmask)) == -1) { 17829612Sjmg dusage = 1; 17929612Sjmg argc--; argv++; 18029612Sjmg continue; 18129612Sjmg } 18229612Sjmg 18329612Sjmg switch(argc > 1 ? sscanf(argv[1], "%d:%d", &l, &r) : 0) { 18429612Sjmg case 0: 18529612Sjmg if (ioctl(baz, MIXER_READ(dev),&bar)== -1) { 18629612Sjmg perror("MIXER_READ"); 18729612Sjmg argc--; argv++; 18829612Sjmg continue; 1896448Sache } 19029612Sjmg printf("Mixer %-8s is currently set to %3d:%d\n", 19129612Sjmg names[dev], bar & 0x7f, (bar >> 8) & 0x7f); 1926448Sache 19329612Sjmg argc--; argv++; 19429612Sjmg break; 19529612Sjmg case 1: 19629612Sjmg r = l; 19729612Sjmg case 2: 19829612Sjmg if (l < 0) 19929612Sjmg l = 0; 20029612Sjmg else if (l > 100) 20129612Sjmg l = 100; 20229612Sjmg if (r < 0) 20329612Sjmg r = 0; 20429612Sjmg else if (r > 100) 20529612Sjmg r = 100; 2068857Srgrimes 20729612Sjmg printf("Setting the mixer %s to %d:%d.\n", names[dev], 20829612Sjmg l, r); 2096448Sache 21029612Sjmg l |= r << 8; 21129612Sjmg if (ioctl(baz, MIXER_WRITE(dev), &l) == -1) 21229612Sjmg perror("WRITE_MIXER"); 2136448Sache 21429612Sjmg argc -= 2; argv += 2; 21529612Sjmg break; 2166448Sache } 2176448Sache } 2186448Sache 21929612Sjmg if (orecsrc != recsrc) 22029612Sjmg if (ioctl(baz, SOUND_MIXER_WRITE_RECSRC, &recsrc) == -1) { 22129612Sjmg perror("SOUND_MIXER_WRITE_RECSRC"); 22229612Sjmg exit(-1); 22329612Sjmg } 22429612Sjmg 22529612Sjmg if (drecsrc) { 22629612Sjmg if (ioctl(baz, SOUND_MIXER_READ_RECSRC, &recsrc) == -1) { 22729612Sjmg perror("SOUND_MIXER_READ_RECSRC"); 22829612Sjmg exit(-1); 22929612Sjmg } 23029612Sjmg print_recsrc(recsrc); 23129612Sjmg } 23229612Sjmg 2336448Sache close(baz); 23429612Sjmg 23529612Sjmg if (dusage) 23629612Sjmg usage(devmask, recmask); 23729612Sjmg 23829612Sjmg exit(0); 2396448Sache} 240