alsa-utils/amixer/amain.cpp
1998-08-30 21:10:35 +00:00

254 lines
6.7 KiB
C++

/*
* Copyright 1998, Andy Lo A Foe <arloafoe@cs.vu.nl>
*
* 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/asoundlib.h>
#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 <path> 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;
}