mirror of
https://github.com/alsa-project/alsa-utils
synced 2024-12-22 19:46:31 +01:00
254 lines
6.7 KiB
C++
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;
|
|
}
|