mirror of
https://github.com/alsa-project/alsa-utils
synced 2024-11-10 00:15:43 +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
|
Package should be compiled only with installed ALSA driver and
|
||||||
ALSA C library.
|
ALSA C library.
|
||||||
|
|
||||||
|
alsactl - utility for store / restore of soundcard settings
|
||||||
aplay/arecord - utility for playback / record of .wav,.voc,.au files
|
aplay/arecord - utility for playback / record of .wav,.voc,.au files
|
||||||
amixer - a command line mixer
|
amixer - a command line mixer
|
||||||
alsamixer - ncurses 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 ALSACTL_FILE "/etc/asound.conf"
|
||||||
|
|
||||||
|
#define LEFT 1
|
||||||
|
#define RIGHT 2
|
||||||
|
|
||||||
|
#define OUTPUT 0
|
||||||
|
#define INPUT 1
|
||||||
|
|
||||||
extern int debugflag;
|
extern int debugflag;
|
||||||
|
|
||||||
extern void error(const char *fmt,...);
|
extern void error(const char *fmt,...);
|
||||||
|
@ -44,10 +50,12 @@ struct ctl {
|
||||||
|
|
||||||
struct mixer_channel {
|
struct mixer_channel {
|
||||||
int no;
|
int no;
|
||||||
int change;
|
int direction;
|
||||||
snd_mixer_channel_info_t i;
|
int voice;
|
||||||
snd_mixer_channel_t c;
|
snd_mixer_channel_info_t info;
|
||||||
snd_mixer_channel_t cr;
|
snd_mixer_channel_t data;
|
||||||
|
snd_mixer_channel_direction_info_t dinfo[2];
|
||||||
|
snd_mixer_channel_direction_t ddata[2];
|
||||||
struct mixer_channel *next;
|
struct mixer_channel *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -72,8 +72,7 @@ gstatus return L_GSTATUS;
|
||||||
enable return L_ENABLE;
|
enable return L_ENABLE;
|
||||||
disable return L_DISABLE;
|
disable return L_DISABLE;
|
||||||
mute return L_MUTE;
|
mute return L_MUTE;
|
||||||
swout return L_SWOUT;
|
swap return L_SWAP;
|
||||||
swin return L_SWIN;
|
|
||||||
|
|
||||||
/* boolean */
|
/* boolean */
|
||||||
|
|
||||||
|
|
|
@ -42,10 +42,12 @@ static void select_pcm(char *name);
|
||||||
static void select_rawmidi(char *name);
|
static void select_rawmidi(char *name);
|
||||||
|
|
||||||
static void select_mixer_channel(char *name);
|
static void select_mixer_channel(char *name);
|
||||||
static void set_mixer_channel(int left, int right);
|
static void select_mixer_direction(int direction);
|
||||||
static void set_mixer_channel_record(int left, int right);
|
static void select_mixer_voice(int voice);
|
||||||
static void set_mixer_channel_flags(unsigned int mask, unsigned int flags);
|
static void set_mixer_volume(int volume);
|
||||||
static void set_mixer_channel_end(void);
|
static void set_mixer_flags(int flags);
|
||||||
|
static void select_mixer_channel_end(void);
|
||||||
|
|
||||||
|
|
||||||
#define SWITCH_CONTROL 0
|
#define SWITCH_CONTROL 0
|
||||||
#define SWITCH_MIXER 1
|
#define SWITCH_MIXER 1
|
||||||
|
@ -70,8 +72,7 @@ static struct soundcard *Xsoundcard = NULL;
|
||||||
static struct mixer *Xmixer = NULL;
|
static struct mixer *Xmixer = NULL;
|
||||||
static struct pcm *Xpcm = NULL;
|
static struct pcm *Xpcm = NULL;
|
||||||
static struct rawmidi *Xrawmidi = NULL;
|
static struct rawmidi *Xrawmidi = NULL;
|
||||||
static struct mixer_channel *Xmixerchannel = NULL;
|
static struct mixer_channel *Xchannel = NULL;
|
||||||
static unsigned int Xmixerchannelflags = 0;
|
|
||||||
static int Xswitchtype = SWITCH_CONTROL;
|
static int Xswitchtype = SWITCH_CONTROL;
|
||||||
static int *Xswitchchange = NULL;
|
static int *Xswitchchange = NULL;
|
||||||
static void *Xswitch = 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_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_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_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 <b_value> boolean
|
||||||
%type <i_value> integer
|
%type <i_value> integer
|
||||||
|
@ -144,55 +145,42 @@ mixers : mixer
|
||||||
| mixers mixer
|
| mixers mixer
|
||||||
;
|
;
|
||||||
|
|
||||||
mixer : L_CHANNEL '(' string { select_mixer_channel( $3 ); } ',' mvalues ')' { set_mixer_channel_end(); select_mixer_channel( NULL ); }
|
mixer : L_CHANNEL '(' string { select_mixer_channel( $3 ); }
|
||||||
| L_SWITCH '(' string { select_mixer_switch( $3 ); } ',' switches ')' { select_mixer_switch( NULL ); }
|
',' settings ')' { select_mixer_channel_end();
|
||||||
| error { yyerror( "unknown keyword in mixer{} level" ); }
|
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 ')'
|
setting : L_OUTPUT { select_mixer_direction(OUTPUT); }
|
||||||
| L_MONO '(' xmchs ')'
|
dsetting
|
||||||
| error { yyerror( "unknown keyword in mixer channel{} level" ); }
|
| L_INPUT { select_mixer_direction(INPUT); }
|
||||||
|
dsetting
|
||||||
|
| error { yyerror( "unknown keyword in mixer channel level" ); }
|
||||||
;
|
;
|
||||||
|
|
||||||
xmchls : xmchl
|
dsetting: L_STEREO '(' { select_mixer_voice(LEFT); }
|
||||||
| xmchls xmchl
|
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 ); }
|
vsettings: vsetting
|
||||||
| '[' L_INTEGER ']' { set_mixer_channel_record( $2, -1 ); }
|
| vsettings vsetting
|
||||||
| 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..." ); }
|
|
||||||
;
|
;
|
||||||
|
|
||||||
xmchrs : xmchr
|
vsetting: L_INTEGER { set_mixer_volume($1); }
|
||||||
| xmchrs xmchr
|
| 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" ); }
|
||||||
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..." ); }
|
|
||||||
;
|
;
|
||||||
|
|
||||||
pcms : pcm
|
pcms : pcm
|
||||||
|
@ -383,19 +371,14 @@ static void select_mixer_channel(char *name)
|
||||||
struct mixer_channel *channel;
|
struct mixer_channel *channel;
|
||||||
|
|
||||||
if (!name) {
|
if (!name) {
|
||||||
Xmixerchannel = NULL;
|
Xchannel = NULL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (channel = Xmixer->channels; channel; channel = channel->next)
|
for (channel = Xmixer->channels; channel; channel = channel->next)
|
||||||
if (!strcmp(channel->i.name, name)) {
|
if (!strcmp(channel->info.name, name)) {
|
||||||
Xmixerchannel = channel;
|
Xchannel = channel;
|
||||||
Xmixerchannelflags = Xmixerchannel->c.flags &
|
Xchannel->ddata[OUTPUT].flags = 0;
|
||||||
~(SND_MIXER_FLG_RECORD |
|
Xchannel->ddata[INPUT].flags = 0;
|
||||||
SND_MIXER_FLG_MUTE |
|
|
||||||
SND_MIXER_FLG_SWITCH_OUT |
|
|
||||||
SND_MIXER_FLG_SWITCH_IN |
|
|
||||||
SND_MIXER_FLG_DECIBEL |
|
|
||||||
SND_MIXER_FLG_FORCE);
|
|
||||||
free(name);
|
free(name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -403,54 +386,51 @@ static void select_mixer_channel(char *name)
|
||||||
free(name);
|
free(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_mixer_channel(int left, int right)
|
static void select_mixer_direction(int direction)
|
||||||
{
|
{
|
||||||
if (left >= 0) {
|
Xchannel->direction = direction;
|
||||||
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)
|
static void select_mixer_voice(int voice)
|
||||||
Xmixerchannel->change = 1;
|
{
|
||||||
Xmixerchannel->c.left = left;
|
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 (right >= 0) {
|
if (Xchannel->voice & RIGHT) {
|
||||||
if (Xmixerchannel->i.min > right || Xmixerchannel->i.max < right)
|
if (i->min > volume || i->max < volume)
|
||||||
yyerror("Value out of range (%i-%i)...", Xmixerchannel->i.min, Xmixerchannel->i.max);
|
yyerror("Value out of range (%i-%i)...", i->min, i->max);
|
||||||
if (Xmixerchannel->c.right != right)
|
d->right = volume;
|
||||||
Xmixerchannel->change = 1;
|
|
||||||
Xmixerchannel->c.right = right;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_mixer_channel_record(int left, int right)
|
static void set_mixer_flags(int flags)
|
||||||
{
|
{
|
||||||
if (left >= 0) {
|
snd_mixer_channel_direction_t *d = &Xchannel->ddata[Xchannel->direction];
|
||||||
if (Xmixerchannel->i.min > left || Xmixerchannel->i.max < left)
|
if (Xchannel->voice & LEFT) {
|
||||||
yyerror("Value out of range (%i-%i)...", Xmixerchannel->i.min, Xmixerchannel->i.max);
|
if (flags & SND_MIXER_DFLG_MUTE)
|
||||||
if (Xmixerchannel->cr.left != left)
|
d->flags |= SND_MIXER_DFLG_MUTE_LEFT;
|
||||||
Xmixerchannel->change = 1;
|
if (flags & SND_MIXER_DFLG_SWAP)
|
||||||
Xmixerchannel->cr.left = left;
|
d->flags |= SND_MIXER_DFLG_LTOR;
|
||||||
}
|
}
|
||||||
if (right >= 0) {
|
if (Xchannel->voice & RIGHT) {
|
||||||
if (Xmixerchannel->i.min > right || Xmixerchannel->i.max < right)
|
if (flags & SND_MIXER_DFLG_MUTE)
|
||||||
yyerror("Value out of range (%i-%i)...", Xmixerchannel->i.min, Xmixerchannel->i.max);
|
d->flags |= SND_MIXER_DFLG_MUTE_RIGHT;
|
||||||
if (Xmixerchannel->cr.right != right)
|
if (flags & SND_MIXER_DFLG_SWAP)
|
||||||
Xmixerchannel->change = 1;
|
d->flags |= SND_MIXER_DFLG_RTOL;
|
||||||
Xmixerchannel->cr.right = right;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 ) \
|
#define FIND_SWITCH( xtype, first, name, err ) \
|
||||||
|
|
178
alsactl/setup.c
178
alsactl/setup.c
|
@ -350,20 +350,38 @@ int soundcard_setup_collect(int cardno)
|
||||||
}
|
}
|
||||||
bzero(mixerchannel, sizeof(struct mixer_channel));
|
bzero(mixerchannel, sizeof(struct mixer_channel));
|
||||||
mixerchannel->no = idx;
|
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);
|
free(mixerchannel);
|
||||||
error("MIXER channel info error (%s) - skipping", snd_strerror(err));
|
error("MIXER channel info error (%s) - skipping", snd_strerror(err));
|
||||||
break;
|
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);
|
free(mixerchannel);
|
||||||
error("MIXER channel read error (%s) - skipping", snd_strerror(err));
|
error("MIXER channel read error (%s) - skipping", snd_strerror(err));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ((mixerchannel->i.caps & SND_MIXER_CINFO_CAP_RECORDVOLUME) &&
|
if ((mixerchannel->info.caps & SND_MIXER_CINFO_CAP_OUTPUT) &&
|
||||||
(err = snd_mixer_channel_record_read(mhandle, idx, &mixerchannel->cr)) < 0) {
|
(err = snd_mixer_channel_output_read(mhandle, idx, &mixerchannel->ddata[OUTPUT])) < 0) {
|
||||||
free(mixerchannel);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
if (!mixerchannelprev) {
|
if (!mixerchannelprev) {
|
||||||
|
@ -651,55 +669,91 @@ 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",
|
int k, d;
|
||||||
info->caps & SND_MIXER_CINFO_CAP_RECORD ? " record" : "",
|
struct capdes {
|
||||||
info->caps & SND_MIXER_CINFO_CAP_JOINRECORD ? " join-record" : "",
|
unsigned int flag;
|
||||||
info->caps & SND_MIXER_CINFO_CAP_STEREO ? " stereo" : "",
|
char* description;
|
||||||
info->caps & SND_MIXER_CINFO_CAP_HWMUTE ? " hardware-mute" : "",
|
};
|
||||||
info->caps & SND_MIXER_CINFO_CAP_JOINMUTE ? " join-mute" : "",
|
static struct capdes caps[] = {
|
||||||
info->caps & SND_MIXER_CINFO_CAP_DIGITAL ? " digital" : "",
|
{ SND_MIXER_CINFO_CAP_OUTPUT, "output" },
|
||||||
info->caps & SND_MIXER_CINFO_CAP_INPUT ? " external-input" : "",
|
{ SND_MIXER_CINFO_CAP_INPUT, "input" },
|
||||||
info->caps & SND_MIXER_CINFO_CAP_LTOR_OUT ? " ltor-out" : "",
|
{ SND_MIXER_CINFO_CAP_EXTINPUT, "external-input" },
|
||||||
info->caps & SND_MIXER_CINFO_CAP_RTOL_OUT ? " rtol-out" : "",
|
{ SND_MIXER_CINFO_CAP_EFFECT, "effect" }
|
||||||
info->caps & SND_MIXER_CINFO_CAP_SWITCH_OUT ? " switch-out" : "",
|
};
|
||||||
info->caps & SND_MIXER_CINFO_CAP_LTOR_IN ? " ltor-in" : "",
|
static struct capdes dcaps[] = {
|
||||||
info->caps & SND_MIXER_CINFO_CAP_RTOL_IN ? " rtol-in" : "",
|
{ SND_MIXER_CINFO_DCAP_STEREO, "stereo" },
|
||||||
info->caps & SND_MIXER_CINFO_CAP_RECORDVOLUME ? " record-volume" : "");
|
{ SND_MIXER_CINFO_DCAP_HWMUTE, "hardware-mute" },
|
||||||
fprintf(out, " ; Accepted channel range is from %i to %i.\n", info->min, info->max);
|
{ SND_MIXER_CINFO_DCAP_JOINMUTE, "join-mute" },
|
||||||
fprintf(out, " channel( \"%s\", ", info->name);
|
{ SND_MIXER_CINFO_DCAP_ROUTE, "route" },
|
||||||
if (info->caps & SND_MIXER_CINFO_CAP_STEREO) {
|
{ SND_MIXER_CINFO_DCAP_SWAPROUTE, "swap-route" },
|
||||||
char bufl[16] = "";
|
{ SND_MIXER_CINFO_DCAP_DIGITAL, "digital" },
|
||||||
char bufr[16] = "";
|
{ SND_MIXER_CINFO_DCAP_RECORDBYMUTE, "recordbymute" },
|
||||||
if (info->caps & SND_MIXER_CINFO_CAP_RECORDVOLUME) {
|
};
|
||||||
sprintf(bufl, " [%i]", record_channel->left);
|
|
||||||
sprintf(bufr, " [%i]", record_channel->right);
|
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, "\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" : ""
|
||||||
|
);
|
||||||
|
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, "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" : ""
|
|
||||||
);
|
|
||||||
} 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
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
fprintf(out, " )\n");
|
fprintf(out, " )\n");
|
||||||
}
|
}
|
||||||
|
@ -735,7 +789,7 @@ int soundcard_setup_write(const char *cfgfile)
|
||||||
for (mixer = first->mixers; mixer; mixer = mixer->next) {
|
for (mixer = first->mixers; mixer; mixer = mixer->next) {
|
||||||
fprintf(out, " mixer( \"%s\" ) {\n", mixer->info.name);
|
fprintf(out, " mixer( \"%s\" ) {\n", mixer->info.name);
|
||||||
for (mixerchannel = mixer->channels; mixerchannel; mixerchannel = mixerchannel->next)
|
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)
|
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));
|
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");
|
fprintf(out, " }\n");
|
||||||
|
@ -839,14 +893,14 @@ int soundcard_setup_process(int cardno)
|
||||||
}
|
}
|
||||||
for (mixer = soundcard->mixers; mixer; mixer = mixer->next) {
|
for (mixer = soundcard->mixers; mixer; mixer = mixer->next) {
|
||||||
for (channel = mixer->channels; channel; channel = channel->next)
|
for (channel = mixer->channels; channel; channel = channel->next)
|
||||||
if (channel->change)
|
if (!soundcard_open_mix(&mixhandle, soundcard, mixer)) {
|
||||||
if (!soundcard_open_mix(&mixhandle, soundcard, mixer)) {
|
if ((channel->info.caps & SND_MIXER_CINFO_CAP_OUTPUT) &&
|
||||||
if ((err = snd_mixer_channel_write(mixhandle, channel->no, &channel->c)) < 0)
|
(err = snd_mixer_channel_output_write(mixhandle, channel->no, &channel->ddata[OUTPUT])) < 0)
|
||||||
error("Mixer channel '%s' write error: %s", channel->i.name, snd_strerror(err));
|
error("Mixer channel '%s' write error: %s", channel->info.name, snd_strerror(err));
|
||||||
if ((channel->i.caps & SND_MIXER_CINFO_CAP_RECORDVOLUME) &&
|
if ((channel->info.caps & SND_MIXER_CINFO_CAP_INPUT) &&
|
||||||
(err = snd_mixer_channel_record_write(mixhandle, channel->no, &channel->cr)) < 0)
|
(err = snd_mixer_channel_input_write(mixhandle, channel->no, &channel->ddata[INPUT])) < 0)
|
||||||
error("Mixer channel '%s' record write error: %s", channel->i.name, snd_strerror(err));
|
error("Mixer channel '%s' record write error: %s", channel->info.name, snd_strerror(err));
|
||||||
}
|
}
|
||||||
if (mixhandle) {
|
if (mixhandle) {
|
||||||
snd_mixer_close(mixhandle);
|
snd_mixer_close(mixhandle);
|
||||||
mixhandle = NULL;
|
mixhandle = NULL;
|
||||||
|
@ -869,7 +923,7 @@ int soundcard_setup_process(int cardno)
|
||||||
for (pcmsw = pcm->rswitches; pcmsw; pcmsw = pcmsw->next) {
|
for (pcmsw = pcm->rswitches; pcmsw; pcmsw = pcmsw->next) {
|
||||||
if (pcmsw->change)
|
if (pcmsw->change)
|
||||||
if (!soundcard_open_ctl(&ctlhandle, soundcard)) {
|
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));
|
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()
|
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);
|
fprintf(stderr, "Can't read data from channel %i\n", current_device);
|
||||||
return; /* No fail code? */
|
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.left = left;
|
||||||
ch_data.right = right;
|
ch_data.right = right;
|
||||||
ch_data.flags = flags;
|
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);
|
fprintf(stderr, "Can't write data to channel %i\n", device);
|
||||||
return; /* No fail code? */
|
return; /* No fail code? */
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,10 +21,12 @@
|
||||||
#define E_MIXER_SUCCESS 1
|
#define E_MIXER_SUCCESS 1
|
||||||
#define E_MIXER_NEED_CLOSE 2
|
#define E_MIXER_NEED_CLOSE 2
|
||||||
|
|
||||||
#define E_MIXER_RECORD SND_MIXER_FLG_RECORD
|
/* FIXME */
|
||||||
#define E_MIXER_MUTE_LEFT SND_MIXER_FLG_MUTE_LEFT
|
#define E_MIXER_RECORD 0
|
||||||
#define E_MIXER_MUTE_RIGHT SND_MIXER_FLG_MUTE_RIGHT
|
|
||||||
#define E_MIXER_MUTE SND_MIXER_FLG_MUTE
|
#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
|
class Mixer
|
||||||
|
@ -63,7 +65,7 @@ public:
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
snd_mixer_info_t info;
|
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;
|
snd_mixer_channel_info_t ch_info;
|
||||||
|
|
||||||
void * mixer_handle;
|
void * mixer_handle;
|
||||||
|
|
|
@ -31,7 +31,7 @@ List all available soundcards and devices.
|
||||||
.TP
|
.TP
|
||||||
\fI-c\fP <card number>
|
\fI-c\fP <card number>
|
||||||
Select the soundcard to use, if you have more than one. Cards are
|
Select the soundcard to use, if you have more than one. Cards are
|
||||||
numbered from 1 (the default).
|
numbered from 0 (the default).
|
||||||
.TP
|
.TP
|
||||||
\fI-d\fP <device number>
|
\fI-d\fP <device number>
|
||||||
Select the soundcard device to use, if your card has more than
|
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"
|
" -h,--help help\n"
|
||||||
" -V,--version print current version\n"
|
" -V,--version print current version\n"
|
||||||
" -l list all soundcards and digital audio devices\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"
|
" -d <device> select device #, defaults to 0\n"
|
||||||
" -q quiet mode\n"
|
" -q quiet mode\n"
|
||||||
" -v file format Voc\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 CD-ROM quality (44100Hz,stereo,16-bit linear)\n"
|
||||||
" -M set DAT quality (48000Hz,stereo,16-bit linear)\n"
|
" -M set DAT quality (48000Hz,stereo,16-bit linear)\n"
|
||||||
" -p <type> compression type (alaw, ulaw, adpcm)\n"
|
" -p <type> compression type (alaw, ulaw, adpcm)\n"
|
||||||
,command, snd_cards());
|
,command, snd_cards()-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void device_list(void)
|
static void device_list(void)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
dnl Process this file with autoconf to produce a configure script.
|
dnl Process this file with autoconf to produce a configure script.
|
||||||
AC_INIT(alsamixer/alsamixer.c)
|
AC_INIT(alsamixer/alsamixer.c)
|
||||||
AC_PREFIX_DEFAULT(/usr)
|
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.
|
dnl Checks for programs.
|
||||||
AC_PROG_CC
|
AC_PROG_CC
|
||||||
|
@ -33,5 +33,7 @@ AC_HEADER_TIME
|
||||||
dnl Checks for library functions.
|
dnl Checks for library functions.
|
||||||
AC_PROG_GCC_TRADITIONAL
|
AC_PROG_GCC_TRADITIONAL
|
||||||
|
|
||||||
|
SAVE_UTIL_VERSION
|
||||||
|
|
||||||
AC_OUTPUT(Makefile alsactl/Makefile alsamixer/Makefile amixer/Makefile aplay/Makefile \
|
AC_OUTPUT(Makefile alsactl/Makefile alsamixer/Makefile amixer/Makefile aplay/Makefile \
|
||||||
include/Makefile utils/Makefile utils/alsa-utils.spec)
|
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