mirror of
https://github.com/alsa-project/alsa-utils
synced 2024-11-09 17:45:41 +01:00
Merged new-mixer branch...
This commit is contained in:
parent
1bf9bb468b
commit
4db1fd02ce
14 changed files with 2701 additions and 1680 deletions
1
README
1
README
|
@ -6,6 +6,7 @@ This packages contains command line utilities for the ALSA project.
|
|||
Package should be compiled only with installed ALSA driver and
|
||||
ALSA C library.
|
||||
|
||||
alsactl - utility for store / restore of soundcard settings
|
||||
aplay/arecord - utility for playback / record of .wav,.voc,.au files
|
||||
amixer - a command line mixer
|
||||
alsamixer - ncurses mixer
|
||||
|
|
12
acinclude.m4
Normal file
12
acinclude.m4
Normal file
|
@ -0,0 +1,12 @@
|
|||
AC_DEFUN(SAVE_UTIL_VERSION, [
|
||||
SND_UTIL_VERSION=$VERSION
|
||||
echo $VERSION > $srcdir/version
|
||||
AC_DEFINE_UNQUOTED(VERSION, "$SND_UTIL_VERSION")
|
||||
AC_SUBST(SND_UTIL_VERSION)
|
||||
SND_UTIL_MAJOR=`echo $VERSION | cut -d . -f 1`
|
||||
AC_SUBST(SND_UTIL_MAJOR)
|
||||
SND_UTIL_MINOR=`echo $VERSION | cut -d . -f 2`
|
||||
AC_SUBST(SND_UTIL_MINOR)
|
||||
SND_UTIL_SUBMINOR=`echo $VERSION | cut -d . -f 3 | sed -e 's/pre[[0-9]]*//g'`
|
||||
AC_SUBST(SND_UTIL_SUBMINOR)
|
||||
])
|
|
@ -26,6 +26,12 @@
|
|||
|
||||
#define ALSACTL_FILE "/etc/asound.conf"
|
||||
|
||||
#define LEFT 1
|
||||
#define RIGHT 2
|
||||
|
||||
#define OUTPUT 0
|
||||
#define INPUT 1
|
||||
|
||||
extern int debugflag;
|
||||
|
||||
extern void error(const char *fmt,...);
|
||||
|
@ -44,10 +50,12 @@ struct ctl {
|
|||
|
||||
struct mixer_channel {
|
||||
int no;
|
||||
int change;
|
||||
snd_mixer_channel_info_t i;
|
||||
snd_mixer_channel_t c;
|
||||
snd_mixer_channel_t cr;
|
||||
int direction;
|
||||
int voice;
|
||||
snd_mixer_channel_info_t info;
|
||||
snd_mixer_channel_t data;
|
||||
snd_mixer_channel_direction_info_t dinfo[2];
|
||||
snd_mixer_channel_direction_t ddata[2];
|
||||
struct mixer_channel *next;
|
||||
};
|
||||
|
||||
|
|
|
@ -72,8 +72,7 @@ gstatus return L_GSTATUS;
|
|||
enable return L_ENABLE;
|
||||
disable return L_DISABLE;
|
||||
mute return L_MUTE;
|
||||
swout return L_SWOUT;
|
||||
swin return L_SWIN;
|
||||
swap return L_SWAP;
|
||||
|
||||
/* boolean */
|
||||
|
||||
|
|
|
@ -42,10 +42,12 @@ static void select_pcm(char *name);
|
|||
static void select_rawmidi(char *name);
|
||||
|
||||
static void select_mixer_channel(char *name);
|
||||
static void set_mixer_channel(int left, int right);
|
||||
static void set_mixer_channel_record(int left, int right);
|
||||
static void set_mixer_channel_flags(unsigned int mask, unsigned int flags);
|
||||
static void set_mixer_channel_end(void);
|
||||
static void select_mixer_direction(int direction);
|
||||
static void select_mixer_voice(int voice);
|
||||
static void set_mixer_volume(int volume);
|
||||
static void set_mixer_flags(int flags);
|
||||
static void select_mixer_channel_end(void);
|
||||
|
||||
|
||||
#define SWITCH_CONTROL 0
|
||||
#define SWITCH_MIXER 1
|
||||
|
@ -70,8 +72,7 @@ static struct soundcard *Xsoundcard = NULL;
|
|||
static struct mixer *Xmixer = NULL;
|
||||
static struct pcm *Xpcm = NULL;
|
||||
static struct rawmidi *Xrawmidi = NULL;
|
||||
static struct mixer_channel *Xmixerchannel = NULL;
|
||||
static unsigned int Xmixerchannelflags = 0;
|
||||
static struct mixer_channel *Xchannel = NULL;
|
||||
static int Xswitchtype = SWITCH_CONTROL;
|
||||
static int *Xswitchchange = NULL;
|
||||
static void *Xswitch = NULL;
|
||||
|
@ -104,7 +105,7 @@ static unsigned short Xswitchiec958ocs1[16];
|
|||
%token L_SOUNDCARD L_MIXER L_CHANNEL L_STEREO L_MONO L_SWITCH L_RAWDATA
|
||||
%token L_CONTROL L_PCM L_RAWMIDI L_PLAYBACK L_RECORD L_OUTPUT L_INPUT
|
||||
%token L_IEC958OCS L_3D L_RESET L_USER L_VALID L_DATA L_PROTECT L_PRE2
|
||||
%token L_FSUNLOCK L_TYPE L_GSTATUS L_ENABLE L_DISABLE L_MUTE L_SWOUT L_SWIN
|
||||
%token L_FSUNLOCK L_TYPE L_GSTATUS L_ENABLE L_DISABLE L_MUTE L_SWAP
|
||||
|
||||
%type <b_value> boolean
|
||||
%type <i_value> integer
|
||||
|
@ -144,55 +145,42 @@ mixers : mixer
|
|||
| mixers mixer
|
||||
;
|
||||
|
||||
mixer : L_CHANNEL '(' string { select_mixer_channel( $3 ); } ',' mvalues ')' { set_mixer_channel_end(); select_mixer_channel( NULL ); }
|
||||
| L_SWITCH '(' string { select_mixer_switch( $3 ); } ',' switches ')' { select_mixer_switch( NULL ); }
|
||||
| error { yyerror( "unknown keyword in mixer{} level" ); }
|
||||
mixer : L_CHANNEL '(' string { select_mixer_channel( $3 ); }
|
||||
',' settings ')' { select_mixer_channel_end();
|
||||
select_mixer_channel( NULL ); }
|
||||
| L_SWITCH '(' string { select_mixer_switch( $3 ); }
|
||||
',' switches ')' { select_mixer_switch( NULL ); }
|
||||
| error { yyerror( "unknown keyword in mixer level" ); }
|
||||
;
|
||||
|
||||
mvalues : mvalue
|
||||
| mvalues mvalue
|
||||
|
||||
settings: setting
|
||||
| settings ',' setting
|
||||
;
|
||||
|
||||
mvalue : L_STEREO '(' xmchls ',' xmchrs ')'
|
||||
| L_MONO '(' xmchs ')'
|
||||
| error { yyerror( "unknown keyword in mixer channel{} level" ); }
|
||||
setting : L_OUTPUT { select_mixer_direction(OUTPUT); }
|
||||
dsetting
|
||||
| L_INPUT { select_mixer_direction(INPUT); }
|
||||
dsetting
|
||||
| error { yyerror( "unknown keyword in mixer channel level" ); }
|
||||
;
|
||||
|
||||
xmchls : xmchl
|
||||
| xmchls xmchl
|
||||
dsetting: L_STEREO '(' { select_mixer_voice(LEFT); }
|
||||
vsettings ',' { select_mixer_voice(RIGHT); }
|
||||
vsettings ')'
|
||||
| L_MONO '(' { select_mixer_voice(LEFT|RIGHT); }
|
||||
vsettings ')'
|
||||
| error { yyerror( "unknown keyword in mixer direction level" ); }
|
||||
;
|
||||
|
||||
xmchl : L_INTEGER { set_mixer_channel( $1, -1 ); }
|
||||
| '[' L_INTEGER ']' { set_mixer_channel_record( $2, -1 ); }
|
||||
| L_MUTE { set_mixer_channel_flags( SND_MIXER_FLG_MUTE_LEFT, SND_MIXER_FLG_MUTE_LEFT ); }
|
||||
| L_RECORD { set_mixer_channel_flags( SND_MIXER_FLG_RECORD_LEFT, SND_MIXER_FLG_RECORD_LEFT ); }
|
||||
| L_SWOUT { set_mixer_channel_flags( SND_MIXER_FLG_LTOR_OUT, SND_MIXER_FLG_LTOR_OUT ); }
|
||||
| L_SWIN { set_mixer_channel_flags( SND_MIXER_FLG_LTOR_IN, SND_MIXER_FLG_LTOR_IN ); }
|
||||
| error { yyerror( "unknown keyword in left channel section..." ); }
|
||||
vsettings: vsetting
|
||||
| vsettings vsetting
|
||||
;
|
||||
|
||||
xmchrs : xmchr
|
||||
| xmchrs xmchr
|
||||
;
|
||||
|
||||
xmchr : L_INTEGER { set_mixer_channel( -1, $1 ); }
|
||||
| '[' L_INTEGER ']' { set_mixer_channel_record( -1, $2 ); }
|
||||
| L_MUTE { set_mixer_channel_flags( SND_MIXER_FLG_MUTE_RIGHT, SND_MIXER_FLG_MUTE_RIGHT ); }
|
||||
| L_RECORD { set_mixer_channel_flags( SND_MIXER_FLG_RECORD_RIGHT, SND_MIXER_FLG_RECORD_RIGHT ); }
|
||||
| L_SWOUT { set_mixer_channel_flags( SND_MIXER_FLG_RTOL_OUT, SND_MIXER_FLG_RTOL_OUT ); }
|
||||
| L_SWIN { set_mixer_channel_flags( SND_MIXER_FLG_RTOL_IN, SND_MIXER_FLG_RTOL_IN ); }
|
||||
| error { yyerror( "unknown keyword in right channel section..." ); }
|
||||
;
|
||||
|
||||
xmchs : xmch
|
||||
| xmchs xmch
|
||||
;
|
||||
|
||||
xmch : L_INTEGER { set_mixer_channel( $1, $1 ); }
|
||||
| '[' L_INTEGER ']' { set_mixer_channel_record( $2, $2 ); }
|
||||
| L_MUTE { set_mixer_channel_flags( SND_MIXER_FLG_MUTE, SND_MIXER_FLG_MUTE ); }
|
||||
| L_RECORD { set_mixer_channel_flags( SND_MIXER_FLG_RECORD, SND_MIXER_FLG_RECORD ); }
|
||||
| error { yyerror( "unknown keyword in mono channel section..." ); }
|
||||
vsetting: L_INTEGER { set_mixer_volume($1); }
|
||||
| L_MUTE { set_mixer_flags(SND_MIXER_DFLG_MUTE); }
|
||||
| L_SWAP { set_mixer_flags(SND_MIXER_DFLG_SWAP); }
|
||||
| error { yyerror( "unknown keyword in mixer voice level" ); }
|
||||
;
|
||||
|
||||
pcms : pcm
|
||||
|
@ -383,19 +371,14 @@ static void select_mixer_channel(char *name)
|
|||
struct mixer_channel *channel;
|
||||
|
||||
if (!name) {
|
||||
Xmixerchannel = NULL;
|
||||
Xchannel = NULL;
|
||||
return;
|
||||
}
|
||||
for (channel = Xmixer->channels; channel; channel = channel->next)
|
||||
if (!strcmp(channel->i.name, name)) {
|
||||
Xmixerchannel = channel;
|
||||
Xmixerchannelflags = Xmixerchannel->c.flags &
|
||||
~(SND_MIXER_FLG_RECORD |
|
||||
SND_MIXER_FLG_MUTE |
|
||||
SND_MIXER_FLG_SWITCH_OUT |
|
||||
SND_MIXER_FLG_SWITCH_IN |
|
||||
SND_MIXER_FLG_DECIBEL |
|
||||
SND_MIXER_FLG_FORCE);
|
||||
if (!strcmp(channel->info.name, name)) {
|
||||
Xchannel = channel;
|
||||
Xchannel->ddata[OUTPUT].flags = 0;
|
||||
Xchannel->ddata[INPUT].flags = 0;
|
||||
free(name);
|
||||
return;
|
||||
}
|
||||
|
@ -403,54 +386,51 @@ static void select_mixer_channel(char *name)
|
|||
free(name);
|
||||
}
|
||||
|
||||
static void set_mixer_channel(int left, int right)
|
||||
static void select_mixer_direction(int direction)
|
||||
{
|
||||
if (left >= 0) {
|
||||
if (Xmixerchannel->i.min > left || Xmixerchannel->i.max < left)
|
||||
yyerror("Value out of range (%i-%i)...", Xmixerchannel->i.min, Xmixerchannel->i.max);
|
||||
if (Xmixerchannel->c.left != left)
|
||||
Xmixerchannel->change = 1;
|
||||
Xmixerchannel->c.left = left;
|
||||
Xchannel->direction = direction;
|
||||
}
|
||||
if (right >= 0) {
|
||||
if (Xmixerchannel->i.min > right || Xmixerchannel->i.max < right)
|
||||
yyerror("Value out of range (%i-%i)...", Xmixerchannel->i.min, Xmixerchannel->i.max);
|
||||
if (Xmixerchannel->c.right != right)
|
||||
Xmixerchannel->change = 1;
|
||||
Xmixerchannel->c.right = right;
|
||||
|
||||
static void select_mixer_voice(int voice)
|
||||
{
|
||||
Xchannel->voice = voice;
|
||||
}
|
||||
|
||||
static void set_mixer_volume(int volume)
|
||||
{
|
||||
snd_mixer_channel_direction_info_t *i = &Xchannel->dinfo[Xchannel->direction];
|
||||
snd_mixer_channel_direction_t *d = &Xchannel->ddata[Xchannel->direction];
|
||||
if (Xchannel->voice & LEFT) {
|
||||
if (i->min > volume || i->max < volume)
|
||||
yyerror("Value out of range (%i-%i)...", i->min, i->max);
|
||||
d->left = volume;
|
||||
}
|
||||
if (Xchannel->voice & RIGHT) {
|
||||
if (i->min > volume || i->max < volume)
|
||||
yyerror("Value out of range (%i-%i)...", i->min, i->max);
|
||||
d->right = volume;
|
||||
}
|
||||
}
|
||||
|
||||
static void set_mixer_channel_record(int left, int right)
|
||||
static void set_mixer_flags(int flags)
|
||||
{
|
||||
if (left >= 0) {
|
||||
if (Xmixerchannel->i.min > left || Xmixerchannel->i.max < left)
|
||||
yyerror("Value out of range (%i-%i)...", Xmixerchannel->i.min, Xmixerchannel->i.max);
|
||||
if (Xmixerchannel->cr.left != left)
|
||||
Xmixerchannel->change = 1;
|
||||
Xmixerchannel->cr.left = left;
|
||||
snd_mixer_channel_direction_t *d = &Xchannel->ddata[Xchannel->direction];
|
||||
if (Xchannel->voice & LEFT) {
|
||||
if (flags & SND_MIXER_DFLG_MUTE)
|
||||
d->flags |= SND_MIXER_DFLG_MUTE_LEFT;
|
||||
if (flags & SND_MIXER_DFLG_SWAP)
|
||||
d->flags |= SND_MIXER_DFLG_LTOR;
|
||||
}
|
||||
if (right >= 0) {
|
||||
if (Xmixerchannel->i.min > right || Xmixerchannel->i.max < right)
|
||||
yyerror("Value out of range (%i-%i)...", Xmixerchannel->i.min, Xmixerchannel->i.max);
|
||||
if (Xmixerchannel->cr.right != right)
|
||||
Xmixerchannel->change = 1;
|
||||
Xmixerchannel->cr.right = right;
|
||||
if (Xchannel->voice & RIGHT) {
|
||||
if (flags & SND_MIXER_DFLG_MUTE)
|
||||
d->flags |= SND_MIXER_DFLG_MUTE_RIGHT;
|
||||
if (flags & SND_MIXER_DFLG_SWAP)
|
||||
d->flags |= SND_MIXER_DFLG_RTOL;
|
||||
}
|
||||
}
|
||||
|
||||
static void set_mixer_channel_flags(unsigned int mask, unsigned int flags)
|
||||
static void select_mixer_channel_end(void)
|
||||
{
|
||||
Xmixerchannelflags &= ~mask;
|
||||
Xmixerchannelflags |= flags;
|
||||
}
|
||||
|
||||
static void set_mixer_channel_end(void)
|
||||
{
|
||||
if (Xmixerchannel->c.flags != Xmixerchannelflags) {
|
||||
Xmixerchannel->change = 1;
|
||||
}
|
||||
Xmixerchannel->c.flags = Xmixerchannelflags;
|
||||
}
|
||||
|
||||
#define FIND_SWITCH( xtype, first, name, err ) \
|
||||
|
|
170
alsactl/setup.c
170
alsactl/setup.c
|
@ -350,20 +350,38 @@ int soundcard_setup_collect(int cardno)
|
|||
}
|
||||
bzero(mixerchannel, sizeof(struct mixer_channel));
|
||||
mixerchannel->no = idx;
|
||||
if ((err = snd_mixer_channel_info(mhandle, idx, &mixerchannel->i)) < 0) {
|
||||
if ((err = snd_mixer_channel_info(mhandle, idx, &mixerchannel->info)) < 0) {
|
||||
free(mixerchannel);
|
||||
error("MIXER channel info error (%s) - skipping", snd_strerror(err));
|
||||
break;
|
||||
}
|
||||
if ((err = snd_mixer_channel_read(mhandle, idx, &mixerchannel->c)) < 0) {
|
||||
if ((mixerchannel->info.caps & SND_MIXER_CINFO_CAP_OUTPUT) &&
|
||||
(err = snd_mixer_channel_output_info(mhandle, idx, &mixerchannel->dinfo[OUTPUT])) < 0) {
|
||||
free(mixerchannel);
|
||||
error("MIXER channel output info error (%s) - skipping", snd_strerror(err));
|
||||
break;
|
||||
}
|
||||
if ((mixerchannel->info.caps & SND_MIXER_CINFO_CAP_INPUT) &&
|
||||
(err = snd_mixer_channel_input_info(mhandle, idx, &mixerchannel->dinfo[INPUT])) < 0) {
|
||||
free(mixerchannel);
|
||||
error("MIXER channel input info error (%s) - skipping", snd_strerror(err));
|
||||
break;
|
||||
}
|
||||
if ((err = snd_mixer_channel_read(mhandle, idx, &mixerchannel->data)) < 0) {
|
||||
free(mixerchannel);
|
||||
error("MIXER channel read error (%s) - skipping", snd_strerror(err));
|
||||
break;
|
||||
}
|
||||
if ((mixerchannel->i.caps & SND_MIXER_CINFO_CAP_RECORDVOLUME) &&
|
||||
(err = snd_mixer_channel_record_read(mhandle, idx, &mixerchannel->cr)) < 0) {
|
||||
if ((mixerchannel->info.caps & SND_MIXER_CINFO_CAP_OUTPUT) &&
|
||||
(err = snd_mixer_channel_output_read(mhandle, idx, &mixerchannel->ddata[OUTPUT])) < 0) {
|
||||
free(mixerchannel);
|
||||
error("MIXER channel record read error (%s) - skipping", snd_strerror(err));
|
||||
error("MIXER channel output read error (%s) - skipping", snd_strerror(err));
|
||||
break;
|
||||
}
|
||||
if ((mixerchannel->info.caps & SND_MIXER_CINFO_CAP_INPUT) &&
|
||||
(err = snd_mixer_channel_input_read(mhandle, idx, &mixerchannel->ddata[INPUT])) < 0) {
|
||||
free(mixerchannel);
|
||||
error("MIXER channel input read error (%s) - skipping", snd_strerror(err));
|
||||
break;
|
||||
}
|
||||
if (!mixerchannelprev) {
|
||||
|
@ -651,56 +669,92 @@ static void soundcard_setup_write_switch(FILE * out, int interface, const unsign
|
|||
}
|
||||
|
||||
|
||||
static void soundcard_setup_write_mixer_channel(FILE * out, snd_mixer_channel_info_t * info, snd_mixer_channel_t * channel, snd_mixer_channel_t * record_channel)
|
||||
static void soundcard_setup_write_mixer_channel(FILE * out, struct mixer_channel * channel)
|
||||
{
|
||||
fprintf(out, " ; Capabilities:%s%s%s%s%s%s%s%s%s%s%s%s%s.\n",
|
||||
info->caps & SND_MIXER_CINFO_CAP_RECORD ? " record" : "",
|
||||
info->caps & SND_MIXER_CINFO_CAP_JOINRECORD ? " join-record" : "",
|
||||
info->caps & SND_MIXER_CINFO_CAP_STEREO ? " stereo" : "",
|
||||
info->caps & SND_MIXER_CINFO_CAP_HWMUTE ? " hardware-mute" : "",
|
||||
info->caps & SND_MIXER_CINFO_CAP_JOINMUTE ? " join-mute" : "",
|
||||
info->caps & SND_MIXER_CINFO_CAP_DIGITAL ? " digital" : "",
|
||||
info->caps & SND_MIXER_CINFO_CAP_INPUT ? " external-input" : "",
|
||||
info->caps & SND_MIXER_CINFO_CAP_LTOR_OUT ? " ltor-out" : "",
|
||||
info->caps & SND_MIXER_CINFO_CAP_RTOL_OUT ? " rtol-out" : "",
|
||||
info->caps & SND_MIXER_CINFO_CAP_SWITCH_OUT ? " switch-out" : "",
|
||||
info->caps & SND_MIXER_CINFO_CAP_LTOR_IN ? " ltor-in" : "",
|
||||
info->caps & SND_MIXER_CINFO_CAP_RTOL_IN ? " rtol-in" : "",
|
||||
info->caps & SND_MIXER_CINFO_CAP_RECORDVOLUME ? " record-volume" : "");
|
||||
fprintf(out, " ; Accepted channel range is from %i to %i.\n", info->min, info->max);
|
||||
fprintf(out, " channel( \"%s\", ", info->name);
|
||||
if (info->caps & SND_MIXER_CINFO_CAP_STEREO) {
|
||||
char bufl[16] = "";
|
||||
char bufr[16] = "";
|
||||
if (info->caps & SND_MIXER_CINFO_CAP_RECORDVOLUME) {
|
||||
sprintf(bufl, " [%i]", record_channel->left);
|
||||
sprintf(bufr, " [%i]", record_channel->right);
|
||||
int k, d;
|
||||
struct capdes {
|
||||
unsigned int flag;
|
||||
char* description;
|
||||
};
|
||||
static struct capdes caps[] = {
|
||||
{ SND_MIXER_CINFO_CAP_OUTPUT, "output" },
|
||||
{ SND_MIXER_CINFO_CAP_INPUT, "input" },
|
||||
{ SND_MIXER_CINFO_CAP_EXTINPUT, "external-input" },
|
||||
{ SND_MIXER_CINFO_CAP_EFFECT, "effect" }
|
||||
};
|
||||
static struct capdes dcaps[] = {
|
||||
{ SND_MIXER_CINFO_DCAP_STEREO, "stereo" },
|
||||
{ SND_MIXER_CINFO_DCAP_HWMUTE, "hardware-mute" },
|
||||
{ SND_MIXER_CINFO_DCAP_JOINMUTE, "join-mute" },
|
||||
{ SND_MIXER_CINFO_DCAP_ROUTE, "route" },
|
||||
{ SND_MIXER_CINFO_DCAP_SWAPROUTE, "swap-route" },
|
||||
{ SND_MIXER_CINFO_DCAP_DIGITAL, "digital" },
|
||||
{ SND_MIXER_CINFO_DCAP_RECORDBYMUTE, "recordbymute" },
|
||||
};
|
||||
|
||||
fprintf(out, " ; Capabilities:");
|
||||
for (k = 0; k < sizeof(caps)/sizeof(*caps); ++k) {
|
||||
if (channel->info.caps & caps[k].flag)
|
||||
fprintf(out, " %s", caps[k].description);
|
||||
}
|
||||
fprintf(out, "stereo( %i%s%s%s%s%s, %i%s%s%s%s%s )",
|
||||
channel->left,
|
||||
channel->flags & SND_MIXER_FLG_MUTE_LEFT ? " mute" : "",
|
||||
channel->flags & SND_MIXER_FLG_RECORD_LEFT ? " record" : "",
|
||||
bufl,
|
||||
channel->flags & SND_MIXER_FLG_LTOR_OUT ? " swout" : "",
|
||||
channel->flags & SND_MIXER_FLG_LTOR_IN ? " swin" : "",
|
||||
channel->right,
|
||||
channel->flags & SND_MIXER_FLG_MUTE_RIGHT ? " mute" : "",
|
||||
channel->flags & SND_MIXER_FLG_RECORD_RIGHT ? " record" : "",
|
||||
bufr,
|
||||
channel->flags & SND_MIXER_FLG_RTOL_OUT ? " swout" : "",
|
||||
channel->flags & SND_MIXER_FLG_RTOL_IN ? " swin" : ""
|
||||
fprintf(out, "\n");
|
||||
for (d = OUTPUT; d <= INPUT; ++d) {
|
||||
snd_mixer_channel_direction_info_t *di;
|
||||
if (d == OUTPUT &&
|
||||
!(channel->info.caps & SND_MIXER_CINFO_CAP_OUTPUT))
|
||||
continue;
|
||||
if (d == INPUT &&
|
||||
!(channel->info.caps & SND_MIXER_CINFO_CAP_INPUT))
|
||||
continue;
|
||||
di = &channel->dinfo[d];
|
||||
fprintf(out, " ; %s capabilities:",
|
||||
d == OUTPUT ? "Output" : "Input" );
|
||||
if (di->caps & SND_MIXER_CINFO_DCAP_VOLUME)
|
||||
fprintf(out, " volume(%i, %i)", di->min, di->max);
|
||||
for (k = 0; k < sizeof(caps)/sizeof(*caps); ++k) {
|
||||
if (di->caps & dcaps[k].flag)
|
||||
fprintf(out, " %s", dcaps[k].description);
|
||||
}
|
||||
fprintf(out, "\n");
|
||||
}
|
||||
fprintf(out, " channel( \"%s\"", channel->info.name);
|
||||
for (d = OUTPUT; d <= INPUT; ++d) {
|
||||
snd_mixer_channel_direction_info_t *di;
|
||||
snd_mixer_channel_direction_t *dd;
|
||||
if (d == OUTPUT &&
|
||||
!(channel->info.caps & SND_MIXER_CINFO_CAP_OUTPUT))
|
||||
continue;
|
||||
if (d == INPUT &&
|
||||
!(channel->info.caps & SND_MIXER_CINFO_CAP_INPUT))
|
||||
continue;
|
||||
dd = &channel->ddata[d];
|
||||
di = &channel->dinfo[d];
|
||||
fprintf(out, ", %s ", d == OUTPUT ? "output" : "input" );
|
||||
if (di->caps & SND_MIXER_CINFO_DCAP_STEREO) {
|
||||
fprintf(out, "stereo(");
|
||||
if (di->caps & SND_MIXER_CINFO_DCAP_VOLUME)
|
||||
fprintf(out, " %i", dd->left);
|
||||
fprintf(out, "%s%s,",
|
||||
dd->flags & SND_MIXER_DFLG_MUTE_LEFT ? " mute" : "",
|
||||
dd->flags & SND_MIXER_DFLG_LTOR ? " swap" : ""
|
||||
);
|
||||
} else {
|
||||
char buf[16] = "";
|
||||
if (info->caps & SND_MIXER_CINFO_CAP_RECORDVOLUME)
|
||||
sprintf(buf, " [%i]", (record_channel->left+record_channel->right) /2);
|
||||
fprintf(out, "mono( %i%s%s%s )",
|
||||
(channel->left + channel->right) / 2,
|
||||
channel->flags & SND_MIXER_FLG_MUTE ? " mute" : "",
|
||||
channel->flags & SND_MIXER_FLG_RECORD ? " record" : "",
|
||||
buf
|
||||
if (di->caps & SND_MIXER_CINFO_DCAP_VOLUME)
|
||||
fprintf(out, " %i", dd->right);
|
||||
|
||||
fprintf(out, "%s%s )",
|
||||
dd->flags & SND_MIXER_DFLG_MUTE_RIGHT ? " mute" : "",
|
||||
dd->flags & SND_MIXER_DFLG_RTOL ? " swap" : ""
|
||||
);
|
||||
}
|
||||
else {
|
||||
fprintf(out, "mono(");
|
||||
if (di->caps & SND_MIXER_CINFO_DCAP_VOLUME)
|
||||
fprintf(out, " %i", (dd->left + dd->right)/2);
|
||||
fprintf(out, "%s )",
|
||||
dd->flags & SND_MIXER_DFLG_MUTE ? " mute" : ""
|
||||
);
|
||||
}
|
||||
}
|
||||
fprintf(out, " )\n");
|
||||
}
|
||||
|
||||
|
@ -735,7 +789,7 @@ int soundcard_setup_write(const char *cfgfile)
|
|||
for (mixer = first->mixers; mixer; mixer = mixer->next) {
|
||||
fprintf(out, " mixer( \"%s\" ) {\n", mixer->info.name);
|
||||
for (mixerchannel = mixer->channels; mixerchannel; mixerchannel = mixerchannel->next)
|
||||
soundcard_setup_write_mixer_channel(out, &mixerchannel->i, &mixerchannel->c, &mixerchannel->cr);
|
||||
soundcard_setup_write_mixer_channel(out, mixerchannel);
|
||||
for (mixersw = mixer->switches; mixersw; mixersw = mixersw->next)
|
||||
soundcard_setup_write_switch(out, SND_INTERFACE_MIXER, mixersw->s.name, mixersw->s.type, mixersw->s.low, mixersw->s.high, (void *) (&mixersw->s.value));
|
||||
fprintf(out, " }\n");
|
||||
|
@ -839,13 +893,13 @@ int soundcard_setup_process(int cardno)
|
|||
}
|
||||
for (mixer = soundcard->mixers; mixer; mixer = mixer->next) {
|
||||
for (channel = mixer->channels; channel; channel = channel->next)
|
||||
if (channel->change)
|
||||
if (!soundcard_open_mix(&mixhandle, soundcard, mixer)) {
|
||||
if ((err = snd_mixer_channel_write(mixhandle, channel->no, &channel->c)) < 0)
|
||||
error("Mixer channel '%s' write error: %s", channel->i.name, snd_strerror(err));
|
||||
if ((channel->i.caps & SND_MIXER_CINFO_CAP_RECORDVOLUME) &&
|
||||
(err = snd_mixer_channel_record_write(mixhandle, channel->no, &channel->cr)) < 0)
|
||||
error("Mixer channel '%s' record write error: %s", channel->i.name, snd_strerror(err));
|
||||
if ((channel->info.caps & SND_MIXER_CINFO_CAP_OUTPUT) &&
|
||||
(err = snd_mixer_channel_output_write(mixhandle, channel->no, &channel->ddata[OUTPUT])) < 0)
|
||||
error("Mixer channel '%s' write error: %s", channel->info.name, snd_strerror(err));
|
||||
if ((channel->info.caps & SND_MIXER_CINFO_CAP_INPUT) &&
|
||||
(err = snd_mixer_channel_input_write(mixhandle, channel->no, &channel->ddata[INPUT])) < 0)
|
||||
error("Mixer channel '%s' record write error: %s", channel->info.name, snd_strerror(err));
|
||||
}
|
||||
if (mixhandle) {
|
||||
snd_mixer_close(mixhandle);
|
||||
|
@ -869,7 +923,7 @@ int soundcard_setup_process(int cardno)
|
|||
for (pcmsw = pcm->rswitches; pcmsw; pcmsw = pcmsw->next) {
|
||||
if (pcmsw->change)
|
||||
if (!soundcard_open_ctl(&ctlhandle, soundcard)) {
|
||||
if ((err = snd_ctl_pcm_playback_switch_write(ctlhandle, pcm->no, pcmsw->no, &pcmsw->s)) < 0)
|
||||
if ((err = snd_ctl_pcm_record_switch_write(ctlhandle, pcm->no, pcmsw->no, &pcmsw->s)) < 0)
|
||||
error("PCM record switch '%s' write error: %s", pcmsw->s.name, snd_strerror(err));
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
1640
alsamixer/alsamixer_tim.c
Normal file
1640
alsamixer/alsamixer_tim.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -97,7 +97,7 @@ char* Mixer::Name(int32 device)
|
|||
|
||||
void Mixer::Update()
|
||||
{
|
||||
if(snd_mixer_channel_read(mixer_handle, current_device, &ch_data) < 0) {
|
||||
if(snd_mixer_channel_output_read(mixer_handle, current_device, &ch_data) < 0) {
|
||||
fprintf(stderr, "Can't read data from channel %i\n", current_device);
|
||||
return; /* No fail code? */
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ void Mixer::DeviceWrite(int32 device, int32 left, int32 right, int32 flags)
|
|||
ch_data.left = left;
|
||||
ch_data.right = right;
|
||||
ch_data.flags = flags;
|
||||
if(snd_mixer_channel_write(mixer_handle, device, &ch_data) < 0) {
|
||||
if(snd_mixer_channel_output_write(mixer_handle, device, &ch_data) < 0) {
|
||||
fprintf(stderr, "Can't write data to channel %i\n", device);
|
||||
return; /* No fail code? */
|
||||
}
|
||||
|
|
|
@ -21,10 +21,12 @@
|
|||
#define E_MIXER_SUCCESS 1
|
||||
#define E_MIXER_NEED_CLOSE 2
|
||||
|
||||
#define E_MIXER_RECORD SND_MIXER_FLG_RECORD
|
||||
#define E_MIXER_MUTE_LEFT SND_MIXER_FLG_MUTE_LEFT
|
||||
#define E_MIXER_MUTE_RIGHT SND_MIXER_FLG_MUTE_RIGHT
|
||||
#define E_MIXER_MUTE SND_MIXER_FLG_MUTE
|
||||
/* FIXME */
|
||||
#define E_MIXER_RECORD 0
|
||||
|
||||
#define E_MIXER_MUTE_LEFT SND_MIXER_DFLG_MUTE_LEFT
|
||||
#define E_MIXER_MUTE_RIGHT SND_MIXER_DFLG_MUTE_RIGHT
|
||||
#define E_MIXER_MUTE SND_MIXER_DFLG_MUTE
|
||||
|
||||
|
||||
class Mixer
|
||||
|
@ -63,7 +65,7 @@ public:
|
|||
}
|
||||
private:
|
||||
snd_mixer_info_t info;
|
||||
snd_mixer_channel_t ch_data;
|
||||
snd_mixer_channel_direction_t ch_data;
|
||||
snd_mixer_channel_info_t ch_info;
|
||||
|
||||
void * mixer_handle;
|
||||
|
|
|
@ -31,7 +31,7 @@ List all available soundcards and devices.
|
|||
.TP
|
||||
\fI-c\fP <card number>
|
||||
Select the soundcard to use, if you have more than one. Cards are
|
||||
numbered from 1 (the default).
|
||||
numbered from 0 (the default).
|
||||
.TP
|
||||
\fI-d\fP <device number>
|
||||
Select the soundcard device to use, if your card has more than
|
||||
|
|
|
@ -141,7 +141,7 @@ static void usage(char *command)
|
|||
" -h,--help help\n"
|
||||
" -V,--version print current version\n"
|
||||
" -l list all soundcards and digital audio devices\n"
|
||||
" -c <card> select card # or card id (1-%i), defaults to 1\n"
|
||||
" -c <card> select card # or card id (0-%i), defaults to 0\n"
|
||||
" -d <device> select device #, defaults to 0\n"
|
||||
" -q quiet mode\n"
|
||||
" -v file format Voc\n"
|
||||
|
@ -155,7 +155,7 @@ static void usage(char *command)
|
|||
" -m set CD-ROM quality (44100Hz,stereo,16-bit linear)\n"
|
||||
" -M set DAT quality (48000Hz,stereo,16-bit linear)\n"
|
||||
" -p <type> compression type (alaw, ulaw, adpcm)\n"
|
||||
,command, snd_cards());
|
||||
,command, snd_cards()-1);
|
||||
}
|
||||
|
||||
static void device_list(void)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
dnl Process this file with autoconf to produce a configure script.
|
||||
AC_INIT(alsamixer/alsamixer.c)
|
||||
AC_PREFIX_DEFAULT(/usr)
|
||||
AM_INIT_AUTOMAKE(alsa-utils, 0.3.0-pre3)
|
||||
AM_INIT_AUTOMAKE(alsa-utils, 0.3.0pre5)
|
||||
|
||||
dnl Checks for programs.
|
||||
AC_PROG_CC
|
||||
|
@ -33,5 +33,7 @@ AC_HEADER_TIME
|
|||
dnl Checks for library functions.
|
||||
AC_PROG_GCC_TRADITIONAL
|
||||
|
||||
SAVE_UTIL_VERSION
|
||||
|
||||
AC_OUTPUT(Makefile alsactl/Makefile alsamixer/Makefile amixer/Makefile aplay/Makefile \
|
||||
include/Makefile utils/Makefile utils/alsa-utils.spec)
|
||||
|
|
1
version
1
version
|
@ -1 +0,0 @@
|
|||
0.3.0-pre3
|
Loading…
Reference in a new issue