/* * Copyright 1998, Andy Lo A Foe * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include "amixer.h" #define MIXER_RC ".amixerrc" char *rc_file(void) { static char rc_path[1024]; char *p; p = getenv("HOME"); if (p) { sprintf(rc_path, "%s/%s", p, MIXER_RC); } else { printf("Error reading HOME env. variable\n"); return NULL; } return rc_path; } void copyright() { printf("CLI ALSA Mixer v0.11 (c) 1998 Adnans\n\n"); } void usage() { printf("\n" "Usage: amixer [-c card] [-d dev] device [vol|L:R] [mute|unmute] [rec|norec]\n\n" " amixer [-p path] -r\tRead %s or settings\n" " amixer -w\t\tWrite %s settings\n" " amixer -q ...\t\tQuiet mode\n" " amixer -h\t\tHelp\n\n" "Example: amixer line-out 80:50 unmute rec\n\n", rc_file(), rc_file()); } void read_config(Mixer * mix, const char *path) { FILE *rc; char buf[1024]; int opt1; int opt2; int left, right; int dev; int count = 0; int flags; if ((rc = fopen(path ? path : rc_file(), "r")) == NULL) { printf("Mixer values not read\n"); return; } while (!feof(rc) && fgets(buf, 1024, rc)) { count++; if (buf[0] == '\n') continue; if (buf[0] == '#' || strlen(buf) == 0) continue; if (sscanf(buf, "%d %d:%d %d %d\n", &dev, &left, &right, &opt1, &opt2) != 5) { printf("WARNING: unable to make out line %d of .rc file -> \"%s\"\n", count, buf); continue; } flags = 0; if (opt1) flags |= E_MIXER_MUTE; if (opt2) flags |= E_MIXER_RECORD; // Set mixer settings mix->DeviceSet(dev); mix->Write(left, right, flags); } fclose(rc); return; } void write_config(Mixer * mix) { FILE *rc; int32 left, right, flags; if ((rc = fopen(rc_file(), "w+")) == NULL) { printf("Mixer values not written\n"); return; } fprintf(rc, "# CLI ALSA mixer settings file. Autogenerated\n" "# Modify at your own risk :)\n\n"); for (int i = 0; i < mix->NumDevices(); i++) { mix->DeviceSet(i); mix->Read(&left, &right, &flags); fprintf(rc, "%d %d:%d %d %d\n", i, mix->Left(), mix->Right(), flags & E_MIXER_MUTE ? 1 : 0, flags & E_MIXER_RECORD ? 1 : 0); } fclose(rc); return; } int main(int argc, char **argv) { int card = 0, device = 0; char device_name[64] = ""; int32 exact, mute, unmute, norec, rec, left, right, flags, device_index; int32 left_dB, right_dB; int32 cur_left, cur_right, cur_flags; int count, quiet = 0; int i, add; int pathind = 0; Mixer *the_mixer; exact = mute = rec = norec = unmute = device_index = left = right = -1; left_dB = right_dB = -1; for (add = 0; add + 1 < argc; i++) { if (!strcmp(argv[add + 1], "--help")) { usage(); return 0; } if (argv[add + 1][0] == '-') { add++; if (argv[add][1] == 'c') { card = snd_card_name(argv[++add]); if (card < 0) { fprintf(stderr, "Invalid card: %s\n", argv[2]); exit(1); } } else if (argv[add][1] == 'd') { device = atoi(argv[++add]); if (device < 0 || device > 128) { fprintf(stderr, "Invalid device: %s\n", argv[2]); exit(1); } } else if (argv[add][1] == 'h') { usage(); return 0; } else if (argv[add][1] == 'p') { pathind = ++add; } else if (argv[add][1] == 'r') { the_mixer = new Mixer(card, device); if (the_mixer && the_mixer->Init()) read_config(the_mixer, pathind ? argv[pathind] : (const char *) NULL); delete the_mixer; return 0; } else if (argv[add][1] == 'w') { the_mixer = new Mixer(card, device); if (the_mixer && the_mixer->Init()) write_config(the_mixer); delete the_mixer; return 0; } else if (argv[add][1] == 'q') { quiet = 1; } else { fprintf(stderr, "Invalid option: %s\n", argv[add] + 1); return 1; } } else { break; } } for (i = 1 + add; i < argc; i++) { if (strcmp(argv[i], "exact") == 0) { exact = 1; } else if (strcmp(argv[i], "mute") == 0) { mute = 1; } else if (strcmp(argv[i], "unmute") == 0) { unmute = 1; } else if (strcmp(argv[i], "rec") == 0) { rec = 1; } else if (strcmp(argv[i], "norec") == 0) { norec = 1; } else if (sscanf(argv[i], "%d:%d", &left, &right) == 2) { } else if (sscanf(argv[i], "%d", &left) == 1) { right = left; } else { strncpy(device_name, argv[i], sizeof(device_name)); device_name[sizeof(device_name) - 1] = 0; } } Mixer mixer(card, device); if (mixer.Init() == false) { fprintf(stderr, "Failed to open mixer device\n"); return 1; } count = mixer.NumDevices(); for (i = 0; i < count; i++) { mixer.DeviceSet(i); if (strcasecmp(device_name, mixer.Name()) == 0) device_index = i; } if (!quiet) copyright(); if (device_index >= 0) { mixer.DeviceSet(device_index); mixer.Read(&cur_left, &cur_right, &cur_flags); if (left >= 0) cur_left = left; if (right >= 0) cur_right = right; if (rec == 1) cur_flags |= E_MIXER_RECORD; else if (norec == 1) cur_flags &= ~E_MIXER_RECORD; if (mute == 1) cur_flags |= E_MIXER_MUTE; else if (unmute == 1) cur_flags &= ~E_MIXER_MUTE; if (left != -1 || rec != -1 || norec != -1 || mute != -1 || unmute != -1) { mixer.Write(cur_left, cur_right, cur_flags); } if (!quiet) { printf("%-16s", mixer.Name()); mixer.Read(&left, &right, &flags); mixer.Read_dB(&left_dB, &right_dB); printf("%-3d%% (%6.2fdB) : %-3d%% (%6.2fdB) %s %s\n\n", left, ((float) left_dB) / 100.0, right, ((float) right_dB) / 100.0, (flags & E_MIXER_MUTE) ? "Mute" : " ", (flags & E_MIXER_RECORD) ? "Rec" : " "); } } else { if (quiet) { usage(); return 1; } if (strlen(device_name)) printf("Device not found: %s\n\n", device_name); for (i = 0; i < count; i++) { mixer.DeviceSet(i); printf("%-16s", mixer.Name()); mixer.Read(&left, &right, &flags); mixer.Read_dB(&left_dB, &right_dB); printf("%-3d%% (%6.2fdB) : %-3d%% (%6.2fdB) %s %s\n", left, ((float) left_dB) / 100.0, right, ((float) right_dB) / 100.0, (flags & E_MIXER_MUTE) ? "Mute" : " ", (flags & E_MIXER_RECORD) ? "Rec" : " "); } return 0; } return 0; }