soundcard_setup_init();
for (idx = 0; idx < 32; idx++) {
if (card_mask & (1 << idx)) { /* find each installed soundcards */
- if ((err = soundcard_setup_collect_switches(idx))) {
- soundcard_setup_done();
- return err;
- }
- if ((err = soundcard_setup_collect_data(idx))) {
+ if ((err = soundcard_setup_collect_controls(idx))) {
soundcard_setup_done();
return err;
}
error("Cannot find soundcard '%s'...", cardname);
return 1;
}
- if ((err = soundcard_setup_collect_switches(cardno))) {
- soundcard_setup_done();
- return err;
- }
- if ((err = soundcard_setup_collect_data(cardno))) {
+ if ((err = soundcard_setup_collect_controls(cardno))) {
soundcard_setup_done();
return err;
}
}
if ((err = soundcard_setup_load(cfgfile, 0)))
return err;
- if ((err = soundcard_setup_collect_switches(cardno))) {
- soundcard_setup_done();
- return err;
- }
- if ((err = soundcard_setup_merge_switches(cardno))) {
- soundcard_setup_done();
- return err;
- }
- if ((err = soundcard_setup_process_switches(cardno))) {
- soundcard_setup_done();
- return err;
- }
- if ((err = soundcard_setup_collect_data(cardno))) {
+ if ((err = soundcard_setup_collect_controls(cardno))) {
soundcard_setup_done();
return err;
}
- if ((err = soundcard_setup_merge_data(cardno))) {
+ if ((err = soundcard_setup_merge_controls(cardno))) {
soundcard_setup_done();
return err;
}
- if ((err = soundcard_setup_process_data(cardno))) {
+ if ((err = soundcard_setup_process_controls(cardno))) {
soundcard_setup_done();
return err;
}
extern void error(const char *fmt,...);
-struct ctl_switch {
+struct ctl_control {
int change;
- snd_switch_t s;
- struct ctl_switch *next;
+ snd_control_type_t type;
+ snd_control_info_t info;
+ snd_control_t c;
+ struct ctl_control *next;
};
struct ctl {
snd_ctl_hw_info_t hwinfo;
- struct ctl_switch *switches;
-};
-
-struct mixer_element {
- snd_mixer_element_info_t info;
- snd_mixer_element_t element;
- struct mixer_element *next;
-};
-
-struct mixer {
- int no;
- snd_mixer_info_t info;
- struct mixer_element *elements;
- struct ctl_switch *switches;
- struct mixer *next;
-};
-
-struct pcm {
- int no;
- snd_pcm_info_t info;
- struct ctl_switch *pswitches;
- struct ctl_switch *rswitches;
- struct pcm *next;
-};
-
-struct rawmidi {
- int no;
- snd_rawmidi_info_t info;
- struct ctl_switch *iswitches;
- struct ctl_switch *oswitches;
- struct rawmidi *next;
+ struct ctl_control *controls;
};
struct soundcard {
int no; /* card number */
struct ctl control;
- struct mixer *mixers;
- struct pcm *pcms;
- struct rawmidi *rawmidis;
struct soundcard *next;
};
void soundcard_setup_done(void);
int soundcard_setup_load(const char *filename, int skip);
int soundcard_setup_write(const char *filename, int cardno);
-int soundcard_setup_collect_switches(int cardno);
-int soundcard_setup_collect_data(int cardno);
-int soundcard_setup_merge_switches(int cardno);
-int soundcard_setup_merge_data(int cardno);
-int soundcard_setup_process_switches(int cardno);
-int soundcard_setup_process_data(int cardno);
+int soundcard_setup_collect_controls(int cardno);
+int soundcard_setup_merge_controls(int cardno);
+int soundcard_setup_process_controls(int cardno);
-char *mixer_element_id(snd_mixer_eid_t *eid);
+char *control_id(snd_control_id_t *id);
soundcard return L_SOUNDCARD;
control return L_CONTROL;
+
+global return L_GLOBAL;
+hwdep return L_HWDEP;
mixer return L_MIXER;
-element return L_ELEMENT;
-switch return L_SWITCH;
-rawdata return L_RAWDATA;
pcm return L_PCM;
rawmidi return L_RAWMIDI;
-playback return L_PLAYBACK;
-capture return L_CAPTURE;
-output return L_OUTPUT;
-input return L_INPUT;
-iec958ocs return L_IEC958OCS;
-3d return L_3D;
-reset return L_RESET;
-user return L_USER;
-valid return L_VALID;
-data return L_DATA;
-protect return L_PROTECT;
-pre2 return L_PRE2;
-fsunlock return L_FSUNLOCK;
-type return L_TYPE;
-gstatus return L_GSTATUS;
-enable return L_ENABLE;
-disable return L_DISABLE;
-sw return L_SW;
-mono_sw return L_MONO_SW;
-wide return L_WIDE;
-volume return L_VOLUME;
-center return L_CENTER;
-space return L_SPACE;
-depth return L_DEPTH;
-delay return L_DELAY;
-feedback return L_FEEDBACK;
-depth_rear return L_DEPTH_REAR;
-bass return L_BASS;
-treble return L_TREBLE;
-
- /* element types */
-
-Switch1 return L_SWITCH1;
-Switch2 return L_SWITCH2;
-Switch3 return L_SWITCH3;
-Volume1 return L_VOLUME1;
-Accu3 return L_ACCU3;
-Mux1 return L_MUX1;
-Mux2 return L_MUX2;
-ToneControl1 return L_TONE_CONTROL1;
-_3D_Effect1 return L_3D_EFFECT1;
+timer return L_TIMER;
+sequencer return L_SEQUENCER;
/* boolean */
/* integers */
-[0-9]+ { yylval.i_value = atoi(yytext); return L_INTEGER; }
-0x[0-9a-f]+ { char *end;
- yylval.i_value = strtol(yytext, &end, 0);
- return L_INTEGER; }
+[0-9]+ { yylval.i_value = strtol(yytext, (char **)NULL, 10); return L_INTEGER; }
+0x[0-9a-f]+ { yylval.i_value = strtol(yytext, (char **)NULL, 0); return L_INTEGER; }
/* byte array */
static void yyerror(char *, ...);
static void build_soundcard(char *name);
-static void build_mixer(char *name);
-static void build_pcm(char *name);
-static void build_rawmidi(char *name);
-
-static void build_mixer_element(char *name, int index, int etype);
-
-static void build_control_switch(char *name);
-static void build_mixer_switch(char *name);
-static void build_pcm_playback_switch(char *name);
-static void build_pcm_capture_switch(char *name);
-static void build_rawmidi_output_switch(char *name);
-static void build_rawmidi_input_switch(char *name);
-
-static void mixer_switch1(int end);
-static void mixer_switch1_value(int val);
-static void mixer_switch2(int end);
-static void mixer_switch2_value(int val);
-static void mixer_switch3(int end);
-static void mixer_switch3_value(int val);
-static void mixer_volume1(int end);
-static void mixer_volume1_value(int val);
-static void mixer_3d_effect1(int end);
-static void mixer_3d_effect1_value(unsigned int effect, int val);
-static void mixer_accu3(int end);
-static void mixer_accu3_value(int val);
-static void mixer_mux1(int end);
-static void mixer_mux1_value(char *str, int index, int type);
-static void mixer_mux2(int end);
-static void mixer_mux2_value(char *str, int index, int type);
-static void mixer_tone_control1(int end);
-static void mixer_tone_control1_value(unsigned int effect, int val);
-
-static void set_switch_boolean(int val);
-static void set_switch_integer(int val);
-static void set_switch_bytearray(struct bytearray val);
-static void set_switch_iec958ocs_begin(int end);
-static void set_switch_iec958ocs(int idx, unsigned short val, unsigned short mask);
+static void build_control_begin(int iface, unsigned int device, unsigned int subdevice, char *name, unsigned int index);
+static void build_control_end(void);
+static void set_control_boolean(int val);
+static void set_control_integer(long val);
+static void set_control_bytearray(struct bytearray val);
/* local variables */
static struct soundcard *Xsoundcard = NULL;
-static struct mixer *Xmixer = NULL;
-static struct pcm *Xpcm = NULL;
-static struct rawmidi *Xrawmidi = NULL;
-static struct mixer_element *Xelement = NULL;
-static struct ctl_switch *Xswitch = NULL;
-static unsigned int Xswitchiec958ocs = 0;
-static unsigned short Xswitchiec958ocs1[16];
+static struct ctl_control *Xcontrol = NULL;
+static int Xposition = 0;
+static snd_control_type_t Xtype = SND_CONTROL_TYPE_NONE;
%}
%union {
int b_value;
- int i_value;
+ long i_value;
char *s_value;
struct bytearray a_value;
};
/* misc */
%token L_DOUBLE1
/* other keywords */
-%token L_SOUNDCARD L_MIXER L_ELEMENT L_SWITCH L_RAWDATA
-%token L_CONTROL L_PCM L_RAWMIDI L_PLAYBACK L_CAPTURE L_INPUT L_OUTPUT
-%token L_SWITCH1 L_SWITCH2 L_SWITCH3 L_VOLUME1 L_3D_EFFECT1 L_ACCU3
-%token L_MUX1 L_MUX2 L_TONE_CONTROL1
-%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
-%token L_SW L_MONO_SW L_WIDE L_VOLUME L_CENTER L_SPACE L_DEPTH L_DELAY
-%token L_DEPTH_REAR
-%token L_FEEDBACK L_BASS L_TREBLE
+%token L_SOUNDCARD L_CONTROL L_RAWDATA
+%token L_GLOBAL L_HWDEP L_MIXER L_PCM L_RAWMIDI L_TIMER L_SEQUENCER
%type <b_value> boolean
-%type <i_value> integer
+%type <i_value> integer iface
%type <s_value> string
%type <a_value> rawdata
| soundcards soundcard
;
-soundcard : L_CONTROL '{' controls '}'
- | L_MIXER '(' string { build_mixer($3); }
- L_DOUBLE1 mixers '}' { build_mixer(NULL); }
- | L_PCM '(' string { build_pcm($3); }
- L_DOUBLE1 pcms '}' { build_pcm(NULL); }
- | L_RAWMIDI '(' string { build_rawmidi($3); }
- L_DOUBLE1 rawmidis '}' { build_rawmidi(NULL); }
+soundcard : L_CONTROL '(' iface ',' integer ',' integer ',' string ',' integer
+ { build_control_begin($3, $5, $7, $9, $11); }
+ ',' controls ')' { build_control_end(); }
| error { yyerror( "an unknown keyword in the soundcard{} level"); }
;
controls : control
- | controls control
+ | controls ',' control
;
-control : L_SWITCH '(' string { build_control_switch($3); }
- ',' switches ')' { build_control_switch(NULL); }
- | error { yyerror("an unknown keyword in the control{} level"); }
+control : boolean { set_control_boolean($1); }
+ | integer { set_control_integer($1); }
+ | rawdata { set_control_bytearray($1); }
+ | error { yyerror( "an unknown keyword in the control() data parameter" ); }
;
-
-mixers : /* empty */
- | mixers mixer
- ;
-
-mixer : L_ELEMENT '(' string
- ',' integer ',' integer { build_mixer_element($3, $5, $7); }
- ',' etype ')' { build_mixer_element(NULL, -1, -1); }
- | L_SWITCH '(' string { build_mixer_switch($3); }
- ',' switches ')' { build_mixer_switch(NULL); }
- | error { yyerror("an unknown keyword in the mixer level"); }
- ;
-
-
-etype : L_SWITCH1 '(' { mixer_switch1(0); }
- m_switch1 ')' { mixer_switch1(1); }
- | L_SWITCH2 '(' { mixer_switch2(0); }
- m_switch2 ')' { mixer_switch2(1); }
- | L_SWITCH3 '(' { mixer_switch3(0); }
- m_switch3 ')' { mixer_switch3(1); }
- | L_VOLUME1 '(' { mixer_volume1(0); }
- m_volume1 ')' { mixer_volume1(1); }
- | L_3D_EFFECT1 '(' { mixer_3d_effect1(0); }
- m_3d_effect1 ')' { mixer_3d_effect1(1); }
- | L_ACCU3 '(' { mixer_accu3(0); }
- m_accu3 ')' { mixer_accu3(1); }
- | L_MUX1 '(' { mixer_mux1(0); }
- m_mux1 ')' { mixer_mux1(1); }
- | L_MUX2 '(' { mixer_mux2(0); }
- L_ELEMENT '('
- string ','
- integer ','
- integer ')' { mixer_mux2_value($6, $8, $10); }
- ')' { mixer_mux2(1); }
- | L_TONE_CONTROL1 '(' { mixer_tone_control1(0); }
- m_tone_control1 ')' { mixer_tone_control1(1); }
- | error { yyerror("an unknown keyword in the mixer element level"); }
- ;
-
-m_switch1 : m_switch1_0
- | m_switch1 ',' m_switch1_0
- ;
-
-m_switch1_0 : boolean { mixer_switch1_value($1); }
- | error { yyerror("an unknown keyword in the Switch1 element level"); }
- ;
-
-m_switch2 : m_switch2_0
- | m_switch2 ',' m_switch2_0
- ;
-
-m_switch2_0 : boolean { mixer_switch2_value($1); }
- | error { yyerror("an unknown keyword in the Switch2 element level"); }
- ;
-
-m_switch3 : m_switch3_0
- | m_switch3 ',' m_switch3_0
- ;
-
-m_switch3_0 : boolean { mixer_switch3_value($1); }
- | error { yyerror("an unknown keyword in the Switch3 element level"); }
- ;
-
-m_volume1 : m_volume1_0
- | m_volume1 ',' m_volume1_0
- ;
-
-m_volume1_0 : integer { mixer_volume1_value($1); }
- | error { yyerror("an unknown keyword in the Volume1 element level"); }
- ;
-
-m_3d_effect1 : m_3d_effect1_0
- | m_3d_effect1 ',' m_3d_effect1_0
- ;
-
-m_3d_effect1_0 : L_SW '=' boolean { mixer_3d_effect1_value(SND_MIXER_EFF1_SW, $3); }
- | L_MONO_SW '=' boolean { mixer_3d_effect1_value(SND_MIXER_EFF1_MONO_SW, $3); }
- | L_WIDE '=' integer { mixer_3d_effect1_value(SND_MIXER_EFF1_WIDE, $3); }
- | L_VOLUME '=' integer { mixer_3d_effect1_value(SND_MIXER_EFF1_VOLUME, $3); }
- | L_CENTER '=' integer { mixer_3d_effect1_value(SND_MIXER_EFF1_CENTER, $3); }
- | L_SPACE '=' integer { mixer_3d_effect1_value(SND_MIXER_EFF1_SPACE, $3); }
- | L_DEPTH '=' integer { mixer_3d_effect1_value(SND_MIXER_EFF1_DEPTH, $3); }
- | L_DELAY '=' integer { mixer_3d_effect1_value(SND_MIXER_EFF1_DELAY, $3); }
- | L_FEEDBACK '=' integer { mixer_3d_effect1_value(SND_MIXER_EFF1_FEEDBACK, $3); }
- | L_DEPTH_REAR '=' integer { mixer_3d_effect1_value(SND_MIXER_EFF1_DEPTH_REAR, $3); }
- | error { yyerror("an unknown keyword in the 3D Effect1 element level"); }
- ;
-
-m_accu3 : m_accu3_0
- | m_accu3 ',' m_accu3_0
- ;
-
-m_accu3_0 : integer { mixer_accu3_value($1); }
- | error { yyerror("an unknown keyword in the Accu3 element level"); }
- ;
-
-m_mux1 : m_mux1_0
- | m_mux1 ',' m_mux1_0
- ;
-
-m_mux1_0 : L_ELEMENT '(' string
- ',' integer ','
- integer ')' { mixer_mux1_value($3, $5, $7); }
- | error { yyerror("an unknown keyword in the Mux1 element level"); }
- ;
-
-m_tone_control1 : m_tone_control1_0
- | m_tone_control1 ',' m_tone_control1_0
- ;
-
-m_tone_control1_0 : L_SW '=' boolean { mixer_tone_control1_value(SND_MIXER_TC1_SW, $3); }
- | L_BASS '=' integer { mixer_tone_control1_value(SND_MIXER_TC1_BASS, $3); }
- | L_TREBLE '=' integer { mixer_tone_control1_value(SND_MIXER_TC1_TREBLE, $3); }
- | error { yyerror("an unknown keyword in the ToneControl1 element level"); }
- ;
-
-
-pcms : pcm
- | pcms pcm
- ;
-
-pcm : L_PLAYBACK '{' playbacks '}'
- | L_CAPTURE '{' captures '}'
- | error { yyerror("an unknown keyword in the pcm{} section"); }
- ;
-
-playbacks : playback
- | playbacks playback
- ;
-
-playback : L_SWITCH '(' string { build_pcm_playback_switch($3); }
- ',' switches ')' { build_pcm_playback_switch(NULL); }
- | error { yyerror("an unknown keyword in the playback{} section"); }
- ;
-
-captures : capture
- | captures capture
- ;
-
-capture : L_SWITCH '(' string { build_pcm_capture_switch($3); }
- ',' switches ')' { build_pcm_capture_switch(NULL); }
- | error { yyerror("an unknown keyword in the capture{} section"); }
- ;
-
-rawmidis : rawmidi
- | rawmidis rawmidi
- ;
-
-rawmidi : L_INPUT '{' inputs '}'
- | L_OUTPUT '{' outputs '}'
- ;
-
-inputs : input
- | inputs input
- ;
-
-input : L_SWITCH '(' string { build_rawmidi_input_switch($3); }
- ',' switches ')' { build_rawmidi_input_switch(NULL); }
- | error { yyerror( "an unknown keyword in the input{} section" ); }
- ;
-
-outputs : output
- | outputs output
- ;
-
-output : L_SWITCH '(' string { build_rawmidi_output_switch($3); }
- ',' switches ')' { build_rawmidi_output_switch(NULL); }
- | error { yyerror( "an unknown keyword in the output{} section" ); }
- ;
-
-switches : switch
- | switches switch
- ;
-
-switch : boolean { set_switch_boolean($1); }
- | integer { set_switch_integer($1); }
- | L_IEC958OCS '(' { set_switch_iec958ocs_begin(0); }
- iec958ocs ')' { set_switch_iec958ocs_begin(1); }
- | rawdata { set_switch_bytearray($1); }
- | error { yyerror( "an unknown keyword in the switch() data parameter" ); }
- ;
-
-iec958ocs : iec958ocs1
- | iec958ocs ',' iec958ocs1
- ;
-
-iec958ocs1 : L_ENABLE { set_switch_iec958ocs( 0, 1, 0 ); }
- | L_DISABLE { set_switch_iec958ocs( 0, 0, 0 ); }
- | L_3D { set_switch_iec958ocs( 4, 0x2000, ~0x2000 ); }
- | L_RESET { set_switch_iec958ocs( 4, 0x0040, ~0x0040 ); }
- | L_USER { set_switch_iec958ocs( 4, 0x0020, ~0x0020 ); }
- | L_VALID { set_switch_iec958ocs( 4, 0x0010, ~0x0010 ); }
- | L_DATA { set_switch_iec958ocs( 5, 0x0002, ~0x0002 ); }
- | L_PROTECT { set_switch_iec958ocs( 5, 0, ~0x0004 ); }
- | L_PRE2 { set_switch_iec958ocs( 5, 0x0008, ~0x0018 ); }
- | L_FSUNLOCK { set_switch_iec958ocs( 5, 0x0020, ~0x0020 ); }
- | L_TYPE '(' integer ')' { set_switch_iec958ocs( 5, ($3 & 0x7f) << 6, ~(0x7f<<6) ); }
- | L_GSTATUS { set_switch_iec958ocs( 5, 0x2000, ~0x2000 ); }
- | error { yyerror( "an unknown keyword in the iec958ocs1() arguments" ); }
+iface : L_INTEGER { $$ = $1; }
+ | L_GLOBAL { $$ = SND_CONTROL_IFACE_CARD; }
+ | L_HWDEP { $$ = SND_CONTROL_IFACE_HWDEP; }
+ | L_MIXER { $$ = SND_CONTROL_IFACE_MIXER; }
+ | L_PCM { $$ = SND_CONTROL_IFACE_PCM; }
+ | L_RAWMIDI { $$ = SND_CONTROL_IFACE_RAWMIDI; }
+ | L_TIMER { $$ = SND_CONTROL_IFACE_TIMER; }
+ | L_SEQUENCER { $$ = SND_CONTROL_IFACE_SEQUENCER; }
+ | error { yyerror( "an unknown keyword in the interface field"); }
;
boolean : L_TRUE { $$ = 1; }
free(name);
}
-static void build_mixer(char *name)
-{
- struct mixer *mixer;
-
- if (!name) {
- Xmixer = NULL;
- return;
- }
- Xmixer = (struct mixer *)malloc(sizeof(struct pcm));
- if (!Xmixer) {
- free(name);
- error_nomem();
- return;
- }
- bzero(Xmixer, sizeof(*Xmixer));
- for (mixer = Xsoundcard->mixers; mixer && mixer->next; mixer = mixer->next);
- if (mixer) {
- mixer->next = Xmixer;
- } else {
- Xsoundcard->mixers = Xmixer;
- }
- strncpy(Xmixer->info.name, name, sizeof(Xmixer->info.name));
- free(name);
-}
-
-static void build_pcm(char *name)
-{
- struct pcm *pcm;
-
- if (!name) {
- Xpcm = NULL;
- return;
- }
- Xpcm = (struct pcm *)malloc(sizeof(struct pcm));
- if (!Xpcm) {
- free(name);
- error_nomem();
- return;
- }
- bzero(Xpcm, sizeof(*Xpcm));
- for (pcm = Xsoundcard->pcms; pcm && pcm->next; pcm = pcm->next);
- if (pcm) {
- pcm->next = Xpcm;
- } else {
- Xsoundcard->pcms = Xpcm;
- }
- strncpy(Xpcm->info.name, name, sizeof(Xpcm->info.name));
- free(name);
-}
-
-static void build_rawmidi(char *name)
-{
- struct rawmidi *rawmidi;
-
- if (!name) {
- Xrawmidi = NULL;
- return;
- }
- Xrawmidi = (struct rawmidi *)malloc(sizeof(struct rawmidi));
- if (!Xrawmidi) {
- free(name);
- error_nomem();
- return;
- }
- bzero(Xrawmidi, sizeof(*Xrawmidi));
- for (rawmidi = Xsoundcard->rawmidis; rawmidi && rawmidi->next; rawmidi = rawmidi->next);
- if (rawmidi) {
- rawmidi->next = Xrawmidi;
- } else {
- Xsoundcard->rawmidis = Xrawmidi;
- }
- strncpy(Xrawmidi->info.name, name, sizeof(Xrawmidi->info.name));
- free(name);
-}
-
-static void build_mixer_element(char *name, int index, int etype)
+static void build_control_begin(int iface, unsigned int device, unsigned int subdevice, char *name, unsigned int index)
{
- struct mixer_element *element;
+ struct ctl_control **first;
+ struct ctl_control *ctl;
- if (!name) {
- Xelement = NULL;
- return;
- }
- Xelement = (struct mixer_element *)malloc(sizeof(struct mixer_element));
- if (!Xelement) {
+ first = &Xsoundcard->control.controls;
+ Xcontrol = (struct ctl_control *)malloc(sizeof(struct ctl_control));
+ if (!Xcontrol) {
free(name);
error_nomem();
return;
}
- bzero(Xelement, sizeof(*Xelement));
- for (element = Xmixer->elements; element && element->next; element = element->next);
- if (element) {
- element->next = Xelement;
+ Xposition = 0;
+ Xtype = SND_CONTROL_TYPE_NONE;
+ bzero(Xcontrol, sizeof(*Xcontrol));
+ for (ctl = *first; ctl && ctl->next; ctl = ctl->next);
+ if (ctl) {
+ ctl->next = Xcontrol;
} else {
- Xmixer->elements = Xelement;
+ *first = Xcontrol;
}
- strncpy(Xelement->element.eid.name, name, sizeof(Xelement->element.eid.name));
- Xelement->element.eid.index = index;
- Xelement->element.eid.type = etype;
- Xelement->info.eid = Xelement->element.eid;
+ Xcontrol->c.id.iface = iface;
+ Xcontrol->c.id.device = device;
+ Xcontrol->c.id.subdevice = subdevice;
+ strncpy(Xcontrol->c.id.name, name, sizeof(Xcontrol->c.id.name));
+ Xcontrol->c.id.index = index;
free(name);
}
-static void mixer_type_check(int type)
-{
- if (Xelement->element.eid.type != type)
- yyerror("The element has got the unexpected data type.");
-}
-
-static void mixer_switch1(int end)
-{
- mixer_type_check(SND_MIXER_ETYPE_SWITCH1);
-}
-
-static void mixer_switch1_value(int val)
-{
- unsigned int *ptr;
-
- if (Xelement->element.data.switch1.sw_size <= Xelement->element.data.switch1.sw) {
- Xelement->element.data.switch1.sw_size += 32;
- ptr = (unsigned int *)realloc(Xelement->element.data.switch1.psw, ((Xelement->element.data.switch1.sw_size + 31) / 32) * sizeof(unsigned int));
- if (ptr == NULL) {
- error_nomem();
- return;
- }
- Xelement->element.data.switch1.psw = ptr;
- }
- snd_mixer_set_bit(Xelement->element.data.switch1.psw, Xelement->element.data.switch1.sw++, val ? 1 : 0);
-}
-
-static void mixer_switch2(int end)
-{
- mixer_type_check(SND_MIXER_ETYPE_SWITCH2);
-}
-
-static void mixer_switch2_value(int val)
-{
- Xelement->element.data.switch2.sw = val ? 1 : 0;
-}
-
-static void mixer_switch3(int end)
-{
- mixer_type_check(SND_MIXER_ETYPE_SWITCH3);
-}
-
-static void mixer_switch3_value(int val)
-{
- unsigned int *ptr;
-
- if (Xelement->element.data.switch3.rsw_size <= Xelement->element.data.switch3.rsw) {
- Xelement->element.data.switch3.rsw_size += 32;
- ptr = (unsigned int *)realloc(Xelement->element.data.switch1.psw, ((Xelement->element.data.switch3.rsw_size + 31) / 32) * sizeof(unsigned int));
- if (ptr == NULL) {
- error_nomem();
- return;
- }
- Xelement->element.data.switch3.prsw = ptr;
- }
- snd_mixer_set_bit(Xelement->element.data.switch3.prsw, Xelement->element.data.switch3.rsw++, val ? 1 : 0);
-}
-
-static void mixer_volume1(int end)
-{
- mixer_type_check(SND_MIXER_ETYPE_VOLUME1);
-}
-
-static void mixer_volume1_value(int val)
+static void build_control_end(void)
{
- int *ptr;
-
- if (Xelement->element.data.volume1.channels_size <= Xelement->element.data.volume1.channels) {
- Xelement->element.data.volume1.channels_size += 4;
- ptr = (int *)realloc(Xelement->element.data.volume1.pchannels, Xelement->element.data.volume1.channels_size * sizeof(int));
- if (ptr == NULL) {
- error_nomem();
- return;
- }
- Xelement->element.data.volume1.pchannels = ptr;
- }
- Xelement->element.data.volume1.pchannels[Xelement->element.data.volume1.channels++] = val;
-}
-
-static void mixer_3d_effect1(int end)
-{
- mixer_type_check(SND_MIXER_ETYPE_3D_EFFECT1);
+ Xcontrol = NULL;
}
-static void mixer_3d_effect1_value(unsigned int effect, int val)
+static void set_control_boolean(int val)
{
- switch (effect) {
- case SND_MIXER_EFF1_SW:
- Xelement->element.data.teffect1.sw = val ? 1 : 0;
- break;
- case SND_MIXER_EFF1_MONO_SW:
- Xelement->element.data.teffect1.mono_sw = val ? 1 : 0;
- break;
- case SND_MIXER_EFF1_WIDE:
- Xelement->element.data.teffect1.wide = val;
+ switch (Xtype) {
+ case SND_CONTROL_TYPE_NONE:
+ case SND_CONTROL_TYPE_BOOLEAN:
+ Xtype = Xcontrol->type = SND_CONTROL_TYPE_BOOLEAN;
break;
- case SND_MIXER_EFF1_VOLUME:
- Xelement->element.data.teffect1.volume = val;
- break;
- case SND_MIXER_EFF1_CENTER:
- Xelement->element.data.teffect1.center = val;
- break;
- case SND_MIXER_EFF1_SPACE:
- Xelement->element.data.teffect1.space = val;
- break;
- case SND_MIXER_EFF1_DEPTH:
- Xelement->element.data.teffect1.depth = val;
- break;
- case SND_MIXER_EFF1_DELAY:
- Xelement->element.data.teffect1.delay = val;
- break;
- case SND_MIXER_EFF1_FEEDBACK:
- Xelement->element.data.teffect1.feedback = val;
- break;
- case SND_MIXER_EFF1_DEPTH_REAR:
- Xelement->element.data.teffect1.depth_rear = val;
+ case SND_CONTROL_TYPE_INTEGER:
break;
default:
- yyerror("Unknown effect 0x%x\n", effect);
- }
-}
-
-static void mixer_accu3(int end)
-{
- mixer_type_check(SND_MIXER_ETYPE_ACCU3);
-}
-
-static void mixer_accu3_value(int val)
-{
- int *ptr;
-
- if (Xelement->element.data.accu3.channels_size <= Xelement->element.data.accu3.channels) {
- Xelement->element.data.accu3.channels_size += 4;
- ptr = (int *)realloc(Xelement->element.data.accu3.pchannels, Xelement->element.data.accu3.channels_size * sizeof(int));
- if (ptr == NULL) {
- error_nomem();
- return;
- }
- Xelement->element.data.accu3.pchannels = ptr;
- }
- Xelement->element.data.accu3.pchannels[Xelement->element.data.accu3.channels++] = val;
-}
-
-static void mixer_mux1(int end)
-{
- mixer_type_check(SND_MIXER_ETYPE_MUX1);
-}
-
-static void mixer_mux1_value(char *name, int index, int type)
-{
- snd_mixer_eid_t *ptr;
- snd_mixer_eid_t *eid;
-
- if (Xelement->element.data.mux1.sel_size <= Xelement->element.data.mux1.sel) {
- Xelement->element.data.mux1.sel_size += 4;
- ptr = (snd_mixer_eid_t *)realloc(Xelement->element.data.mux1.psel, Xelement->element.data.mux1.sel_size * sizeof(snd_mixer_eid_t));
- if (ptr == NULL) {
- error_nomem();
- free(name);
- return;
- }
- Xelement->element.data.mux1.psel = ptr;
+ yyerror("Unexpected previous type (%i).\n", Xtype);
}
- eid = &Xelement->element.data.mux1.psel[Xelement->element.data.mux1.sel++];
- strncpy(eid->name, name, sizeof(eid->name));
- eid->index = index;
- eid->type = type;
- free(name);
-}
-
-static void mixer_mux2(int end)
-{
- mixer_type_check(SND_MIXER_ETYPE_MUX2);
+ if (Xposition < 512)
+ Xcontrol->c.value.integer.value[Xposition++] = val ? 1 : 0;
+ else
+ yyerror("Array overflow.");
}
-static void mixer_mux2_value(char *name, int index, int type)
+static void set_control_integer(long val)
{
- snd_mixer_eid_t *eid;
-
- eid = &Xelement->element.data.mux2.sel;
- strncpy(eid->name, name, sizeof(eid->name));
- eid->index = index;
- eid->type = type;
- free(name);
-}
-
-static void mixer_tone_control1(int end)
-{
- mixer_type_check(SND_MIXER_ETYPE_TONE_CONTROL1);
-}
+ unsigned int xx;
-static void mixer_tone_control1_value(unsigned int effect, int val)
-{
- Xelement->element.data.tc1.tc |= effect;
- switch (effect) {
- case SND_MIXER_TC1_SW:
- Xelement->element.data.tc1.sw = val ? 1 : 0;
- break;
- case SND_MIXER_TC1_BASS:
- Xelement->element.data.tc1.bass = val;
- break;
- case SND_MIXER_TC1_TREBLE:
- Xelement->element.data.tc1.treble = val;
+ switch (Xtype) {
+ case SND_CONTROL_TYPE_NONE:
+ case SND_CONTROL_TYPE_BOOLEAN:
+ case SND_CONTROL_TYPE_INTEGER:
+ Xtype = Xcontrol->type = SND_CONTROL_TYPE_INTEGER;
break;
default:
- yyerror("Unknown effect 0x%x\n", effect);
- }
-}
-
-static void build_switch(struct ctl_switch **first, char *name)
-{
- struct ctl_switch *sw;
-
- if (!name) {
- Xswitch = NULL;
- return;
+ yyerror("Unexpected previous type (%i).\n", Xtype);
}
- Xswitch = (struct ctl_switch *)malloc(sizeof(struct ctl_switch));
- if (!Xswitch) {
- free(name);
- error_nomem();
- return;
+ if (Xposition < 512) {
+ xx = val;
+ Xcontrol->c.value.integer.value[Xposition++] = val;
}
- bzero(Xswitch, sizeof(*Xswitch));
- for (sw = *first; sw && sw->next; sw = sw->next);
- if (sw) {
- sw->next = Xswitch;
- } else {
- *first = Xswitch;
- }
- strncpy(Xswitch->s.name, name, sizeof(Xswitch->s.name));
- free(name);
-}
-
-static void build_control_switch(char *name)
-{
- build_switch(&Xsoundcard->control.switches, name);
-}
-
-static void build_mixer_switch(char *name)
-{
- build_switch(&Xmixer->switches, name);
-}
-
-static void build_pcm_playback_switch(char *name)
-{
- build_switch(&Xpcm->pswitches, name);
-}
-
-static void build_pcm_capture_switch(char *name)
-{
- build_switch(&Xpcm->rswitches, name);
-}
-
-static void build_rawmidi_output_switch(char *name)
-{
- build_switch(&Xrawmidi->oswitches, name);
-}
-
-static void build_rawmidi_input_switch(char *name)
-{
- build_switch(&Xrawmidi->iswitches, name);
-}
-
-static void set_switch_boolean(int val)
-{
- Xswitch->s.type = SND_SW_TYPE_BOOLEAN;
- Xswitch->s.value.enable = val ? 1 : 0;
-}
-
-static void set_switch_integer(int val)
-{
- unsigned int xx;
-
- Xswitch->s.type = SND_SW_TYPE_DWORD;
- xx = val;
- memcpy(&Xswitch->s.value, &xx, sizeof(xx));
}
-static void set_switch_bytearray(struct bytearray val)
+static void set_control_bytearray(struct bytearray val)
{
- Xswitch->s.type = SND_SW_TYPE_USER;
-
- if (val.datalen > 32)
- yyerror("Byte array too large for switch.");
-
- memcpy(Xswitch->s.value.data8, val.data, val.datalen);
-}
+ if (Xtype != SND_CONTROL_TYPE_NONE && Xtype != SND_CONTROL_TYPE_BYTES)
+ yyerror("Unexpected previous type (%i).\n", Xtype);
+ Xtype = Xcontrol->type = SND_CONTROL_TYPE_BYTES;
-static void set_switch_iec958ocs_begin(int end)
-{
- if (end) {
- Xswitch->s.value.enable = Xswitchiec958ocs;
- Xswitch->s.value.data16[4] = Xswitchiec958ocs1[4];
- Xswitch->s.value.data16[5] = Xswitchiec958ocs1[5];
-#if 0
- printf("IEC958: enable = %i, ocs1[4] = 0x%x, ocs1[5] = 0x%x\n",
- sw->value.enable,
- sw->value.data16[4],
- sw->value.data16[5]);
-#endif
- return;
- }
- Xswitch->s.type = SND_SW_TYPE_BOOLEAN;
- Xswitch->s.value.data32[1] = ('C' << 8) | 'S';
- Xswitchiec958ocs = 0;
- Xswitchiec958ocs1[4] = 0x0000;
- Xswitchiec958ocs1[5] = 0x0004; /* copy permitted */
-}
+ if (val.datalen + Xposition > 512)
+ yyerror("Byte array too large for control.");
-static void set_switch_iec958ocs(int idx, unsigned short val, unsigned short mask)
-{
- if (idx == 0) {
- Xswitchiec958ocs = val ? 1 : 0;
- return;
- }
- Xswitchiec958ocs1[idx] &= mask;
- Xswitchiec958ocs1[idx] |= val;
+ memcpy(&Xcontrol->c.value.bytes.data[Xposition], val.data, val.datalen);
+ Xposition += val.datalen;
}
#include "alsactl.h"
-static char *sw_id(const char *name, int cardno, int devno, const char *id)
+static int merge_one_control(struct ctl_control *cctl, struct ctl_control *uctl, int cardno)
{
- static char str[256];
-
- sprintf(str, "%s %s card %i", name, id, cardno);
- if (devno >= 0)
- sprintf(str + strlen(str)," device %i", devno);
- return str;
-}
+ int idx;
-static int merge_one_sw(struct ctl_switch *csw, struct ctl_switch *usw, int cardno, int devno, const char *id)
-{
- switch (csw->s.type) {
- case SND_SW_TYPE_BOOLEAN:
- if (usw->s.type != SND_SW_TYPE_BOOLEAN) {
- error("A wrong type for the switch %s. The type boolean is expected. Skipping...", sw_id(usw->s.name, cardno, devno, id));
+ if (!(cctl->info.access & SND_CONTROL_ACCESS_WRITE))
+ return 0;
+ switch (cctl->info.type) {
+ case SND_CONTROL_TYPE_BOOLEAN:
+ if (uctl->type != SND_CONTROL_TYPE_BOOLEAN && uctl->type != SND_CONTROL_TYPE_INTEGER) {
+ error("A wrong type %i for the control '%s'. The type integer is expected. Skipping...", uctl->type, control_id(&uctl->c.id));
return 1;
}
- if (csw->s.value.enable != usw->s.value.enable) {
- csw->change = 1;
- csw->s.value.enable = usw->s.value.enable;
- }
- if (!strncmp(csw->s.name, SND_MIXER_SW_IEC958_OUTPUT, sizeof(csw->s.name))) {
- if (usw->s.value.data32[1] == (('C' << 8) | 'S')) {
- if (csw->s.value.data16[4] != usw->s.value.data16[4] ||
- csw->s.value.data16[5] != usw->s.value.data16[5]) {
- csw->change = 1;
- csw->s.value.data16[4] = usw->s.value.data16[4];
- csw->s.value.data16[5] = usw->s.value.data16[5];
- }
+ for (idx = 0; idx < cctl->info.values_count; idx++) {
+ if (cctl->c.value.integer.value[idx] != uctl->c.value.integer.value[idx]) {
+ cctl->change = 1;
+ cctl->c.value.integer.value[idx] = uctl->c.value.integer.value[idx];
}
}
break;
- case SND_SW_TYPE_BYTE:
- if (usw->s.type != SND_SW_TYPE_DWORD) {
- error("A wrong type for the switch %s. The type byte is expected. Skipping...", sw_id(usw->s.name, cardno, devno, id));
- return 1;
- }
- if (csw->s.low > usw->s.value.data32[0] ||
- csw->s.high < usw->s.value.data32[0]) {
- error("The value %u for the switch %s is out of range %i-%i.", usw->s.value.data32[0], sw_id(usw->s.name, cardno, devno, id), csw->s.low, csw->s.high);
- return 1;
- }
- if (csw->s.value.data8[0] != (unsigned char)usw->s.value.data32[0]) {
- csw->change = 1;
- csw->s.value.data8[0] = (unsigned char)usw->s.value.data32[0];
- }
- break;
- case SND_SW_TYPE_WORD:
- if (usw->s.type != SND_SW_TYPE_DWORD) {
- error("A wrong type for the switch %s. The type word is expected. Skipping...", sw_id(usw->s.name, cardno, devno, id));
- return 1;
- }
- if (csw->s.low > usw->s.value.data32[0] ||
- csw->s.high < usw->s.value.data32[0]) {
- error("The value %u for the switch %s is out of range %i-%i.", usw->s.value.data32[0], sw_id(usw->s.name, cardno, devno, id), csw->s.low, csw->s.high);
- return 1;
- }
- if (csw->s.value.data16[0] != (unsigned short)usw->s.value.data32[0]) {
- csw->change = 1;
- csw->s.value.data16[0] = (unsigned short)usw->s.value.data32[0];
- }
- break;
- case SND_SW_TYPE_DWORD:
- if (usw->s.type != SND_SW_TYPE_DWORD) {
- error("A wrong type for the switch %s. The type dword is expected. Skipping...", sw_id(usw->s.name, cardno, devno, id));
+ case SND_CONTROL_TYPE_INTEGER:
+ if (uctl->type != SND_CONTROL_TYPE_BOOLEAN && uctl->type != SND_CONTROL_TYPE_INTEGER) {
+ error("A wrong type %i for the control '%s'. The type integer is expected. Skipping...", uctl->type, control_id(&uctl->c.id));
return 1;
}
- if (csw->s.low > usw->s.value.data32[0] ||
- csw->s.high < usw->s.value.data32[0]) {
- error("The value %u for the switch %s is out of range %i-%i.", usw->s.value.data32[0], sw_id(usw->s.name, cardno, devno, id), csw->s.low, csw->s.high);
- return 1;
- }
- if (csw->s.value.data32[0] != usw->s.value.data32[0]) {
- csw->change = 1;
- csw->s.value.data32[0] = usw->s.value.data32[0];
- }
- break;
- case SND_SW_TYPE_LIST:
- if (usw->s.type != SND_SW_TYPE_DWORD) {
- error("A wrong type for the switch %s. The type list is expected. Skipping...", sw_id(usw->s.name, cardno, devno, id));
- return 1;
- }
- if (csw->s.low > usw->s.value.data32[0] ||
- csw->s.high < usw->s.value.data32[0]) {
- error("The value %i for the switch %s is out of range %i-%i.", usw->s.value.data32[0], sw_id(usw->s.name, cardno, devno, id), csw->s.low, csw->s.high);
- return 1;
- }
- if (csw->s.value.item_number != usw->s.value.data32[0]) {
- csw->change = 1;
- csw->s.value.item_number = usw->s.value.data32[0];
- }
- break;
- case SND_SW_TYPE_USER_READ_ONLY:
- break;
- case SND_SW_TYPE_USER:
- if (usw->s.type != SND_SW_TYPE_USER) {
- error("A wrong type %i for the switch %s. The type user is expected. Skipping...", usw->s.type, sw_id(usw->s.name, cardno, devno, id));
- return 1;
- }
- if (memcmp(csw->s.value.data8, usw->s.value.data8, 32)) {
- csw->change = 1;
- memcpy(csw->s.value.data8, usw->s.value.data8, 32);
- }
- break;
- default:
- error("The switch type %i is not known.", csw->s.type);
- }
- return 0;
-}
-
-static int soundcard_setup_merge_sw(struct ctl_switch *csw, struct ctl_switch *usw, int cardno, int devno, const char *id)
-{
- struct ctl_switch *csw1;
-
- for ( ; usw; usw = usw->next) {
- for (csw1 = csw; csw1; csw1 = csw1->next) {
- if (!strncmp(csw1->s.name, usw->s.name, sizeof(csw1->s.name))) {
- merge_one_sw(csw1, usw, cardno, devno, id);
- break;
- }
- }
- if (!csw1) {
- error("Cannot find the switch %s...", sw_id(usw->s.name, cardno, devno, id));
- }
- }
- return 0;
-}
-
-int soundcard_setup_merge_switches(int cardno)
-{
- struct soundcard *soundcard, *rsoundcard;
- struct mixer *mixer, *rmixer;
- struct pcm *pcm, *rpcm;
- struct rawmidi *rawmidi, *rrawmidi;
-
- for (rsoundcard = rsoundcards; rsoundcard; rsoundcard = rsoundcard->next) {
- for (soundcard = soundcards; soundcard; soundcard = soundcard->next) {
- if (!strncmp(soundcard->control.hwinfo.id, rsoundcard->control.hwinfo.id, sizeof(soundcard->control.hwinfo.id)))
- break;
- }
- if (!soundcard) {
- error("The soundcard '%s' was not found...\n", rsoundcard->control.hwinfo.id);
- continue;
- }
- if (cardno >= 0 && soundcard->no != cardno)
- continue;
- soundcard_setup_merge_sw(soundcard->control.switches, rsoundcard->control.switches, soundcard->no, -1, "control");
- for (rmixer = rsoundcard->mixers; rmixer; rmixer = rmixer->next) {
- for (mixer = soundcard->mixers; mixer; mixer = mixer->next) {
- if (!strncmp(mixer->info.name, rmixer->info.name, sizeof(mixer->info.name)))
- break;
- }
- if (!mixer) {
- error("The mixer device '%s' from the soundcard %i was not found...\n", rmixer->info.name, soundcard->no);
- continue;
- }
- soundcard_setup_merge_sw(mixer->switches, rmixer->switches, soundcard->no, mixer->no, "mixer");
- }
- for (rpcm = rsoundcard->pcms; rpcm; rpcm = rpcm->next) {
- for (pcm = soundcard->pcms; pcm; pcm = pcm->next) {
- if (!strncmp(pcm->info.name, rpcm->info.name, sizeof(pcm->info.name)))
- break;
- }
- if (!rpcm) {
- error("The PCM device '%s' from the soundcard %i was not found...\n", rpcm->info.name, soundcard->no);
- continue;
- }
- soundcard_setup_merge_sw(pcm->pswitches, rpcm->pswitches, soundcard->no, pcm->no, "PCM playback");
- soundcard_setup_merge_sw(pcm->rswitches, rpcm->rswitches, soundcard->no, pcm->no, "PCM capture");
- }
- for (rrawmidi = rsoundcard->rawmidis; rrawmidi; rrawmidi = rrawmidi->next) {
- for (rawmidi = soundcard->rawmidis; rawmidi; rawmidi = rawmidi->next) {
- if (!strncmp(rawmidi->info.name, rrawmidi->info.name, sizeof(rawmidi->info.name)))
- break;
+ for (idx = 0; idx < cctl->info.values_count; idx++) {
+ if (cctl->info.value.integer.min > uctl->c.value.integer.value[idx] ||
+ cctl->info.value.integer.max < uctl->c.value.integer.value[idx]) {
+ error("The value %li for the control '%s' is out of range %i-%i.", uctl->c.value.integer.value[idx], control_id(&uctl->c.id), cctl->info.value.integer.min, cctl->info.value.integer.max);
+ return 1;
}
- if (!rrawmidi) {
- error("The rawmidi device '%s' from the soundcard %i was not found...\n", rrawmidi->info.name, soundcard->no);
- continue;
+ if (cctl->c.value.integer.value[idx] != uctl->c.value.integer.value[idx]) {
+ cctl->change = 1;
+ cctl->c.value.integer.value[idx] = uctl->c.value.integer.value[idx];
}
- soundcard_setup_merge_sw(rawmidi->iswitches, rrawmidi->iswitches, soundcard->no, rawmidi->no, "rawmidi input");
- soundcard_setup_merge_sw(rawmidi->oswitches, rrawmidi->oswitches, soundcard->no, rawmidi->no, "rawmidi output");
}
- }
- return 0;
-}
-
-static char *element_id(snd_mixer_eid_t *eid, int cardno, int devno, const char *id)
-{
- static char str[256];
-
- sprintf(str, "%s %s card %i", mixer_element_id(eid), id, cardno);
- if (devno >= 0)
- sprintf(str + strlen(str)," device %i", devno);
- return str;
-}
-
-static int merge_one_element(struct mixer_element *celement, struct mixer_element *uelement, int cardno, int devno, const char *id)
-{
- int tmp;
-
- if (snd_mixer_element_has_control(&celement->element.eid) != 1)
- return 0;
- switch (celement->element.eid.type) {
- case SND_MIXER_ETYPE_SWITCH1:
- if (celement->element.data.switch1.sw != uelement->element.data.switch1.sw) {
- error("Element %s has got a wrong count of channels.", element_id(&celement->element.eid, cardno, devno, id));
- return 1;
- }
- tmp = ((celement->element.data.switch1.sw + 31) / 32) * sizeof(unsigned int);
- memcpy(celement->element.data.switch1.psw, uelement->element.data.switch1.psw, tmp);
break;
- case SND_MIXER_ETYPE_SWITCH2:
- celement->element.data.switch2.sw = uelement->element.data.switch2.sw;
- break;
- case SND_MIXER_ETYPE_SWITCH3:
- if (celement->element.data.switch3.rsw != uelement->element.data.switch3.rsw) {
- error("Element %s has got a wrong count of switches.", element_id(&celement->element.eid, cardno, devno, id));
+ case SND_CONTROL_TYPE_ENUMERATED:
+ if (uctl->type != SND_CONTROL_TYPE_BOOLEAN && uctl->type != SND_CONTROL_TYPE_INTEGER) {
+ error("A wrong type %i for the control '%s'. The type integer is expected. Skipping...", uctl->type, control_id(&uctl->c.id));
return 1;
}
- tmp = ((celement->element.data.switch3.rsw + 31) / 32) * sizeof(unsigned int);
- memcpy(celement->element.data.switch3.prsw, uelement->element.data.switch3.prsw, tmp);
- break;
- case SND_MIXER_ETYPE_VOLUME1:
- if (celement->element.data.volume1.channels != uelement->element.data.volume1.channels) {
- error("Element %s has got a wrong count of channels.", element_id(&celement->element.eid, cardno, devno, id));
- return 1;
- }
- tmp = celement->element.data.volume1.channels * sizeof(int);
- memcpy(celement->element.data.volume1.pchannels, uelement->element.data.volume1.pchannels, tmp);
- break;
- case SND_MIXER_ETYPE_VOLUME2:
- if (celement->element.data.volume2.achannels != uelement->element.data.volume2.achannels) {
- error("Element %s has got a wrong count of channels.", element_id(&celement->element.eid, cardno, devno, id));
- return 1;
- }
- tmp = celement->element.data.volume2.achannels * sizeof(int);
- memcpy(celement->element.data.volume2.pachannels, uelement->element.data.volume2.pachannels, tmp);
- break;
- case SND_MIXER_ETYPE_ACCU3:
- if (celement->element.data.accu3.channels != uelement->element.data.accu3.channels) {
- error("Element %s has got a wrong count of channels.", element_id(&celement->element.eid, cardno, devno, id));
- return 1;
- }
- tmp = celement->element.data.accu3.channels * sizeof(int);
- memcpy(celement->element.data.accu3.pchannels, uelement->element.data.accu3.pchannels, tmp);
- break;
- case SND_MIXER_ETYPE_MUX1:
- if (celement->element.data.mux1.psel)
- free(celement->element.data.mux1.psel);
- celement->element.data.mux1.sel_size = 0;
- celement->element.data.mux1.sel = 0;
- celement->element.data.mux1.sel_over = 0;
- tmp = uelement->element.data.mux1.sel * sizeof(snd_mixer_eid_t);
- if (tmp > 0) {
- celement->element.data.mux1.psel = (snd_mixer_eid_t *)malloc(uelement->element.data.mux1.sel_size * sizeof(snd_mixer_eid_t));
- if (!celement->element.data.mux1.psel) {
- error("No enough memory...");
+ for (idx = 0; idx < cctl->info.values_count; idx++) {
+ if (cctl->info.value.enumerated.items <= uctl->c.value.integer.value[idx]) {
+ error("The value %u for the control '%s' is out of range 0-%i.", uctl->c.value.integer.value[idx], control_id(&uctl->c.id), cctl->info.value.enumerated.items-1);
return 1;
}
- celement->element.data.mux1.sel_size = uelement->element.data.mux1.sel_size;
- celement->element.data.mux1.sel = uelement->element.data.mux1.sel;
- memcpy(celement->element.data.mux1.psel, uelement->element.data.mux1.psel, tmp);
- }
- break;
- case SND_MIXER_ETYPE_MUX2:
- celement->element.data.mux2.sel = uelement->element.data.mux2.sel;
- break;
- case SND_MIXER_ETYPE_TONE_CONTROL1:
- if ((uelement->element.data.tc1.tc & ~celement->info.data.tc1.tc) != 0) {
- error("Wrong (unsupported) input for the element %s.", element_id(&celement->element.eid, cardno, devno, id));
- return 1;
+ if (cctl->c.value.enumerated.item[idx] != uctl->c.value.integer.value[idx]) {
+ cctl->change = 1;
+ cctl->c.value.enumerated.item[idx] = uctl->c.value.integer.value[idx];
+ }
}
- celement->element.data.tc1.tc = uelement->element.data.tc1.tc;
- celement->element.data.tc1.sw = uelement->element.data.tc1.sw;
- celement->element.data.tc1.bass = uelement->element.data.tc1.bass;
- celement->element.data.tc1.treble = uelement->element.data.tc1.treble;
break;
- case SND_MIXER_ETYPE_3D_EFFECT1:
- if ((uelement->element.data.teffect1.effect & ~celement->info.data.teffect1.effect) != 0) {
- error("Wrong (unsupported) input for the element %s.", element_id(&celement->element.eid, cardno, devno, id));
+ case SND_CONTROL_TYPE_BYTES:
+ if (uctl->type != SND_CONTROL_TYPE_BYTES) {
+ error("A wrong type %i for the control %s. The type 'bytes' is expected. Skipping...", uctl->type, control_id(&uctl->c.id));
return 1;
}
- celement->element.data.teffect1.effect = uelement->element.data.teffect1.effect;
- celement->element.data.teffect1.sw = uelement->element.data.teffect1.sw;
- celement->element.data.teffect1.mono_sw = uelement->element.data.teffect1.mono_sw;
- celement->element.data.teffect1.wide = uelement->element.data.teffect1.wide;
- celement->element.data.teffect1.volume = uelement->element.data.teffect1.volume;
- celement->element.data.teffect1.center = uelement->element.data.teffect1.center;
- celement->element.data.teffect1.space = uelement->element.data.teffect1.space;
- celement->element.data.teffect1.depth = uelement->element.data.teffect1.depth;
- celement->element.data.teffect1.delay = uelement->element.data.teffect1.delay;
- celement->element.data.teffect1.feedback = uelement->element.data.teffect1.feedback;
- celement->element.data.teffect1.depth_rear = uelement->element.data.teffect1.depth_rear;
- break;
- case SND_MIXER_ETYPE_PRE_EFFECT1:
- if (celement->element.data.peffect1.pparameters)
- free(celement->element.data.peffect1.pparameters);
- celement->element.data.peffect1.parameters_size = 0;
- celement->element.data.peffect1.parameters = 0;
- celement->element.data.peffect1.parameters_over = 0;
- celement->element.data.peffect1.item = uelement->element.data.peffect1.item;
- if (celement->element.data.peffect1.item < 0) {
- celement->element.data.peffect1.pparameters = (int *)malloc(uelement->element.data.peffect1.parameters_size * sizeof(int));
- if (!celement->element.data.peffect1.pparameters) {
- error("No enough memory..");
- return 1;
- }
- celement->element.data.peffect1.parameters_size = uelement->element.data.peffect1.parameters_size;
- celement->element.data.peffect1.parameters = uelement->element.data.peffect1.parameters;
- tmp = celement->element.data.peffect1.parameters * sizeof(int);
- memcpy(celement->element.data.peffect1.pparameters, uelement->element.data.peffect1.pparameters, tmp);
+ if (memcmp(cctl->c.value.bytes.data, uctl->c.value.bytes.data, uctl->info.values_count)) {
+ cctl->change = 1;
+ memcpy(cctl->c.value.bytes.data, uctl->c.value.bytes.data, uctl->info.values_count);
}
break;
default:
- error("The element type %i for the element %s is not known.", celement->element.eid.type, mixer_element_id(&celement->element.eid));
+ error("The control type %i is not known.", cctl->type);
}
return 0;
}
-static int soundcard_setup_merge_element(struct mixer_element *celement, struct mixer_element *uelement, int cardno, int devno, const char *id)
+static int soundcard_setup_merge_control(struct ctl_control *cctl, struct ctl_control *uctl, int cardno)
{
- struct mixer_element *element;
+ struct ctl_control *cctl1;
- for ( ; uelement; uelement = uelement->next) {
- for (element = celement; element; element = element->next) {
- if (!strncmp(element->element.eid.name, uelement->element.eid.name, sizeof(element->element.eid.name)) &&
- element->element.eid.index == uelement->element.eid.index &&
- element->element.eid.type == uelement->element.eid.type) {
- merge_one_element(element, uelement, cardno, devno, id);
+ for ( ; uctl; uctl = uctl->next) {
+ for (cctl1 = cctl; cctl1; cctl1 = cctl1->next) {
+ if (cctl1->c.id.iface == uctl->c.id.iface &&
+ cctl1->c.id.device == uctl->c.id.device &&
+ cctl1->c.id.subdevice == uctl->c.id.subdevice &&
+ !strncmp(cctl1->c.id.name, uctl->c.id.name, sizeof(cctl1->c.id.name))) {
+ merge_one_control(cctl1, uctl, cardno);
break;
}
}
- if (!element) {
- error("Cannot find the element %s...", element_id(&uelement->element.eid, cardno, devno, id));
+ if (!cctl1) {
+ error("Cannot find the control %s...", control_id(&uctl->c.id));
}
}
return 0;
}
-int soundcard_setup_merge_data(int cardno)
+int soundcard_setup_merge_controls(int cardno)
{
struct soundcard *soundcard, *rsoundcard;
- struct mixer *mixer, *rmixer;
for (rsoundcard = rsoundcards; rsoundcard; rsoundcard = rsoundcard->next) {
for (soundcard = soundcards; soundcard; soundcard = soundcard->next) {
}
if (cardno >= 0 && soundcard->no != cardno)
continue;
- for (rmixer = rsoundcard->mixers; rmixer; rmixer = rmixer->next) {
- for (mixer = soundcard->mixers; mixer; mixer = mixer->next) {
- if (!strncmp(mixer->info.name, rmixer->info.name, sizeof(mixer->info.name)))
- break;
- }
- if (!mixer) {
- error("The mixer device '%s' from the soundcard %i was not found...\n", rmixer->info.name, soundcard->no);
- continue;
- }
- soundcard_setup_merge_element(mixer->elements, rmixer->elements, soundcard->no, mixer->no, "mixer");
- }
+ soundcard_setup_merge_control(soundcard->control.controls, rsoundcard->control.controls, soundcard->no);
}
return 0;
}
return 0;
}
-static int soundcard_open_mix(snd_mixer_t **mixhandle, struct soundcard *soundcard, struct mixer *mixer)
-{
- int err;
-
- if (*mixhandle)
- return 0;
- if ((err = snd_mixer_open(mixhandle, soundcard->no, mixer->no)) < 0) {
- error("Cannot open mixer interface for soundcard #%i.", soundcard->no + 1);
- return 1;
- }
- return 0;
-}
-
-int soundcard_setup_process_switches(int cardno)
+int soundcard_setup_process_controls(int cardno)
{
int err;
snd_ctl_t *ctlhandle = NULL;
struct soundcard *soundcard;
- struct ctl_switch *ctlsw;
- struct mixer *mixer;
- struct pcm *pcm;
- struct rawmidi *rawmidi;
+ struct ctl_control *ctl;
for (soundcard = soundcards; soundcard; soundcard = soundcard->next) {
if (cardno >= 0 && soundcard->no != cardno)
continue;
- for (ctlsw = soundcard->control.switches; ctlsw; ctlsw = ctlsw->next) {
- if (ctlsw->change)
+ for (ctl = soundcard->control.controls; ctl; ctl = ctl->next) {
+ if (ctl->change)
if (!soundcard_open_ctl(&ctlhandle, soundcard)) {
- if ((err = snd_ctl_switch_write(ctlhandle, &ctlsw->s)) < 0)
- error("Control switch '%s' write error: %s", ctlsw->s.name, snd_strerror(err));
- }
- }
- for (mixer = soundcard->mixers; mixer; mixer = mixer->next) {
- for (ctlsw = mixer->switches; ctlsw; ctlsw = ctlsw->next)
- if (ctlsw->change)
- if (!soundcard_open_ctl(&ctlhandle, soundcard)) {
- if ((err = snd_ctl_switch_write(ctlhandle, &ctlsw->s)) < 0)
- error("Mixer switch '%s' write error: %s", ctlsw->s.name, snd_strerror(err));
- }
- }
- for (pcm = soundcard->pcms; pcm; pcm = pcm->next) {
- for (ctlsw = pcm->pswitches; ctlsw; ctlsw = ctlsw->next) {
- if (ctlsw->change)
- if (!soundcard_open_ctl(&ctlhandle, soundcard)) {
- if ((err = snd_ctl_switch_write(ctlhandle, &ctlsw->s)) < 0)
- error("PCM playback switch '%s' write error: %s", ctlsw->s.name, snd_strerror(err));
- }
- }
- for (ctlsw = pcm->rswitches; ctlsw; ctlsw = ctlsw->next) {
- if (ctlsw->change)
- if (!soundcard_open_ctl(&ctlhandle, soundcard)) {
- if ((err = snd_ctl_switch_write(ctlhandle, &ctlsw->s)) < 0)
- error("PCM capture switch '%s' write error: %s", ctlsw->s.name, snd_strerror(err));
- }
- }
- }
- for (rawmidi = soundcard->rawmidis; rawmidi; rawmidi = rawmidi->next) {
- for (ctlsw = rawmidi->oswitches; ctlsw; ctlsw = ctlsw->next) {
- if (ctlsw->change)
- if (!soundcard_open_ctl(&ctlhandle, soundcard)) {
- if ((err = snd_ctl_switch_write(ctlhandle, &ctlsw->s)) < 0)
- error("RAWMIDI output switch '%s' write error: %s", ctlsw->s.name, snd_strerror(err));
- }
- }
- for (ctlsw = rawmidi->iswitches; ctlsw; ctlsw = ctlsw->next) {
- if (ctlsw->change)
- if (!soundcard_open_ctl(&ctlhandle, soundcard)) {
- if ((err = snd_ctl_switch_write(ctlhandle, &ctlsw->s)) < 0)
- error("RAWMIDI input switch '%s' write error: %s", ctlsw->s.name, snd_strerror(err));
- }
- }
- }
- if (ctlhandle) {
- snd_ctl_close(ctlhandle);
- ctlhandle = NULL;
- }
- }
- return 0;
-}
-
-int soundcard_setup_process_data(int cardno)
-{
- int err;
- snd_ctl_t *ctlhandle = NULL;
- snd_mixer_t *mixhandle = NULL;
- struct soundcard *soundcard;
- struct mixer *mixer;
- struct mixer_element *element;
-
- for (soundcard = soundcards; soundcard; soundcard = soundcard->next) {
- if (cardno >= 0 && soundcard->no != cardno)
- continue;
- for (mixer = soundcard->mixers; mixer; mixer = mixer->next) {
- for (element = mixer->elements; element; element = element->next)
- if (snd_mixer_element_has_control(&element->element.eid) == 1) {
- if (!soundcard_open_mix(&mixhandle, soundcard, mixer)) {
- if ((err = snd_mixer_element_write(mixhandle, &element->element)) < 0)
- error("Mixer element %s write error: %s", mixer_element_id(&element->element.eid), snd_strerror(err));
- }
+ if ((err = snd_ctl_cwrite(ctlhandle, &ctl->c)) < 0)
+ error("Control '%s' write error: %s", control_id(&ctl->c.id), snd_strerror(err));
}
- if (mixhandle) {
- snd_mixer_close(mixhandle);
- mixhandle = NULL;
- }
}
if (ctlhandle) {
snd_ctl_close(ctlhandle);
* misc functions
*/
-static char *mixer_element_name(snd_mixer_eid_t *eid)
+char *control_id(snd_control_id_t *id)
{
- static char str[32];
+ static char str[128];
- if (!eid)
+ if (!id)
return "???";
- strncpy(str, eid->name, sizeof(eid->name));
- str[sizeof(eid->name)] = '\0';
- return str;
-}
-
-char *mixer_element_id(snd_mixer_eid_t *eid)
-{
- static char str[64];
-
- if (!eid)
- return "???";
- sprintf(str, "%s:%i:%i", mixer_element_name(eid), eid->index, eid->type);
+ sprintf(str, "%i,%i,%i,%s,%i", id->iface, id->device, id->subdevice, id->name, id->index);
return str;
}
* free functions
*/
-static void soundcard_ctl_switch_free(struct ctl_switch *first)
-{
- struct ctl_switch *next;
-
- while (first) {
- next = first->next;
- free(first);
- first = next;
- }
-}
-
-static void soundcard_mixer_element_free(struct mixer_element *first)
+static void soundcard_ctl_control_free(struct ctl_control *first)
{
- struct mixer_element *next;
+ struct ctl_control *next;
while (first) {
next = first->next;
- snd_mixer_element_info_free(&first->info);
- snd_mixer_element_free(&first->element);
free(first);
first = next;
}
}
-static void soundcard_mixer_free1(struct mixer *mixer)
-{
- if (!mixer)
- return;
- soundcard_mixer_element_free(mixer->elements);
- soundcard_ctl_switch_free(mixer->switches);
- free(mixer);
-}
-
-static void soundcard_mixer_free(struct mixer *first)
-{
- struct mixer *next;
-
- while (first) {
- next = first->next;
- soundcard_mixer_free1(first);
- first = next;
- }
-}
-
-static void soundcard_pcm_free1(struct pcm *pcm)
-{
- if (!pcm)
- return;
- soundcard_ctl_switch_free(pcm->pswitches);
- soundcard_ctl_switch_free(pcm->rswitches);
- free(pcm);
-}
-
-static void soundcard_pcm_free(struct pcm *first)
-{
- struct pcm *next;
-
- while (first) {
- next = first->next;
- soundcard_pcm_free1(first);
- first = next;
- }
-}
-
-static void soundcard_rawmidi_free1(struct rawmidi *rawmidi)
-{
- if (!rawmidi)
- return;
- soundcard_ctl_switch_free(rawmidi->iswitches);
- soundcard_ctl_switch_free(rawmidi->oswitches);
- free(rawmidi);
-}
-
-static void soundcard_rawmidi_free(struct rawmidi *first)
-{
- struct rawmidi *next;
-
- while (first) {
- next = first->next;
- soundcard_rawmidi_free1(first);
- first = next;
- }
-}
-
static void soundcard_free1(struct soundcard *soundcard)
{
if (!soundcard)
return;
- soundcard_ctl_switch_free(soundcard->control.switches);
- soundcard_mixer_free(soundcard->mixers);
- soundcard_pcm_free(soundcard->pcms);
- soundcard_rawmidi_free(soundcard->rawmidis);
+ soundcard_ctl_control_free(soundcard->control.controls);
free(soundcard);
}
soundcards = NULL;
}
-static int determine_switches(void *handle, struct ctl_switch **csw, int iface, int device, int stream)
+static int determine_controls(void *handle, struct ctl_control **cctl)
{
int err, idx;
- snd_switch_list_t list;
- snd_switch_list_item_t *item;
- snd_switch_t sw;
- struct ctl_switch *prev_csw;
- struct ctl_switch *new_csw;
+ snd_control_list_t list;
+ snd_control_id_t *item;
+ snd_control_t ctl;
+ struct ctl_control *prev_control;
+ struct ctl_control *new_control;
- *csw = NULL;
+ *cctl = NULL;
bzero(&list, sizeof(list));
- list.iface = iface;
- list.device = device;
- list.stream = stream;
- if ((err = snd_ctl_switch_list(handle, &list)) < 0) {
- error("Cannot determine switches for interface %i and device %i and stream %i: %s", iface, device, stream, snd_strerror(err));
+ if ((err = snd_ctl_clist(handle, &list)) < 0) {
+ error("Cannot determine controls: %s", snd_strerror(err));
return 1;
}
- if (list.switches_over <= 0)
+ if (list.controls <= 0)
return 0;
- list.switches_size = list.switches_over + 16;
- list.switches = list.switches_over = 0;
- list.pswitches = malloc(sizeof(snd_switch_list_item_t) * list.switches_size);
- if (!list.pswitches) {
+ list.controls_request = list.controls + 16;
+ list.controls_offset = list.controls_count = 0;
+ list.pids = malloc(sizeof(snd_control_id_t) * list.controls_request);
+ if (!list.pids) {
error("No enough memory...");
return 1;
}
- if ((err = snd_ctl_switch_list(handle, &list)) < 0) {
- error("Cannot determine switches (2) for interface %i and device %i and stream %i: %s", iface, device, stream, snd_strerror(err));
+ if ((err = snd_ctl_clist(handle, &list)) < 0) {
+ error("Cannot determine controls (2): %s", snd_strerror(err));
return 1;
}
- for (idx = 0, prev_csw = NULL; idx < list.switches; idx++) {
- item = &list.pswitches[idx];
- bzero(&sw, sizeof(sw));
- sw.iface = iface;
- sw.device = device;
- sw.stream = stream;
- strncpy(sw.name, item->name, sizeof(sw.name));
- if ((err = snd_ctl_switch_read(handle, &sw)) < 0) {
- error("Cannot read switch '%s' for interface %i and device %i and stream %i: %s", sw.name, iface, device, stream, snd_strerror(err));
- free(list.pswitches);
+ for (idx = 0, prev_control = NULL; idx < list.controls_count; idx++) {
+ item = &list.pids[idx];
+ bzero(&ctl, sizeof(ctl));
+ ctl.id = *item;
+ if ((err = snd_ctl_cread(handle, &ctl)) < 0) {
+ error("Cannot read control '%s': %s", control_id(item), snd_strerror(err));
+ free(list.pids);
return 1;
}
- new_csw = malloc(sizeof(*new_csw));
- if (!new_csw) {
+ new_control = malloc(sizeof(*new_control));
+ if (!new_control) {
error("No enough memory...");
- free(list.pswitches);
+ free(list.pids);
+ return 1;
+ }
+ bzero(new_control, sizeof(*new_control));
+ memcpy(&new_control->c, &ctl, sizeof(new_control->c));
+ new_control->info.id = ctl.id;
+ if ((err = snd_ctl_cinfo(handle, &new_control->info)) < 0) {
+ error("Cannot read control info '%s': %s", control_id(item), snd_strerror(err));
+ free(new_control);
+ free(list.pids);
return 1;
}
- bzero(new_csw, sizeof(*new_csw));
- memcpy(&new_csw->s, &sw, sizeof(new_csw->s));
- if (*csw) {
- prev_csw->next = new_csw;
- prev_csw = new_csw;
+ if (*cctl) {
+ prev_control->next = new_control;
+ prev_control = new_control;
} else {
- *csw = prev_csw = new_csw;
+ *cctl = prev_control = new_control;
}
}
- free(list.pswitches);
+ free(list.pids);
return 0;
}
-static int soundcard_setup_collect_switches1(int cardno)
+static int soundcard_setup_collect_controls1(int cardno)
{
snd_ctl_t *handle;
- snd_mixer_t *mhandle;
struct soundcard *card, *first, *prev;
- int err, device;
- struct mixer *mixer, *mixerprev;
- struct pcm *pcm, *pcmprev;
- struct rawmidi *rawmidi, *rawmidiprev;
+ int err;
soundcard_remove(cardno);
if ((err = snd_ctl_open(&handle, cardno)) < 0) {
return 1;
}
/* --- */
- if (determine_switches(handle, &card->control.switches, SND_CTL_IFACE_CONTROL, 0, 0)) {
+ if (determine_controls(handle, &card->control.controls)) {
snd_ctl_close(handle);
return 1;
- }
- /* --- */
- for (device = 0, mixerprev = NULL; device < card->control.hwinfo.mixerdevs; device++) {
- mixer = (struct mixer *) malloc(sizeof(struct mixer));
- if (!mixer) {
- snd_ctl_close(handle);
- error("malloc problem");
- return 1;
- }
- bzero(mixer, sizeof(struct mixer));
- mixer->no = device;
- if (determine_switches(handle, &mixer->switches, SND_CTL_IFACE_MIXER, device, 0)) {
- snd_ctl_close(handle);
- return 1;
- }
- if (!mixerprev) {
- card->mixers = mixer;
- } else {
- mixerprev->next = mixer;
- }
- mixerprev = mixer;
- if ((err = snd_mixer_open(&mhandle, cardno, device)) < 0) {
- snd_ctl_close(handle);
- error("MIXER open error: %s", snd_strerror(err));
- return 1;
- }
- if ((err = snd_mixer_info(mhandle, &mixer->info)) < 0) {
- snd_mixer_close(mhandle);
- snd_ctl_close(handle);
- error("MIXER info error: %s", snd_strerror(err));
- return 1;
- }
- snd_mixer_close(mhandle);
- }
- /* --- */
- for (device = 0, pcmprev = NULL; device < card->control.hwinfo.pcmdevs; device++) {
- pcm = (struct pcm *) malloc(sizeof(struct pcm));
- if (!pcm) {
- snd_ctl_close(handle);
- error("malloc problem");
- return 1;
- }
- bzero(pcm, sizeof(struct pcm));
- pcm->no = device;
- pcm->info.device = device;
- pcm->info.stream = -1;
- pcm->info.subdevice = -1;
- if ((err = snd_ctl_pcm_info(handle, &pcm->info)) < 0) {
- snd_ctl_close(handle);
- error("PCM info error: %s", snd_strerror(err));
- return 1;
- }
- if (determine_switches(handle, &pcm->pswitches, SND_CTL_IFACE_PCM, device, SND_PCM_STREAM_PLAYBACK)) {
- snd_ctl_close(handle);
- return 1;
- }
- if (determine_switches(handle, &pcm->rswitches, SND_CTL_IFACE_PCM, device, SND_PCM_STREAM_CAPTURE)) {
- snd_ctl_close(handle);
- return 1;
- }
- if (!pcmprev) {
- card->pcms = pcm;
- } else {
- pcmprev->next = pcm;
- }
- pcmprev = pcm;
- }
- /* --- */
- for (device = 0, rawmidiprev = NULL; device < card->control.hwinfo.mididevs; device++) {
- rawmidi = (struct rawmidi *) malloc(sizeof(struct rawmidi));
- if (!rawmidi) {
- snd_ctl_close(handle);
- error("malloc problem");
- return 1;
- }
- bzero(rawmidi, sizeof(struct rawmidi));
- rawmidi->no = device;
- rawmidi->info.device = device;
- if ((err = snd_ctl_rawmidi_info(handle, &rawmidi->info)) < 0) {
- snd_ctl_close(handle);
- error("RAWMIDI info error: %s", snd_strerror(err));
- return 1;
- }
- if (determine_switches(handle, &rawmidi->oswitches, SND_CTL_IFACE_RAWMIDI, device, SND_RAWMIDI_STREAM_OUTPUT)) {
- snd_ctl_close(handle);
- return 1;
- }
- if (determine_switches(handle, &rawmidi->iswitches, SND_CTL_IFACE_RAWMIDI, device, SND_RAWMIDI_STREAM_INPUT)) {
- snd_ctl_close(handle);
- return 1;
- }
- if (!rawmidiprev) {
- card->rawmidis = rawmidi;
- } else {
- rawmidiprev->next = rawmidi;
- }
- rawmidiprev = rawmidi;
- }
+ }
/* --- */
snd_ctl_close(handle);
return 0;
}
-int soundcard_setup_collect_switches(int cardno)
+int soundcard_setup_collect_controls(int cardno)
{
int err;
unsigned int mask;
if (cardno >= 0) {
- return soundcard_setup_collect_switches1(cardno);
+ return soundcard_setup_collect_controls1(cardno);
} else {
mask = snd_cards_mask();
for (cardno = 0; cardno < SND_CARDS; cardno++) {
if (!(mask & (1 << cardno)))
continue;
- err = soundcard_setup_collect_switches1(cardno);
+ err = soundcard_setup_collect_controls1(cardno);
if (err)
return err;
}
}
}
-static int soundcard_setup_collect_data1(int cardno)
-{
- snd_ctl_t *handle;
- snd_mixer_t *mhandle;
- struct soundcard *card;
- int err, idx;
- struct mixer *mixer;
- snd_mixer_elements_t elements;
- struct mixer_element *mixerelement, *mixerelementprev;
-
- if ((err = snd_ctl_open(&handle, cardno)) < 0) {
- error("SND CTL open error: %s", snd_strerror(err));
- return 1;
- }
- /* --- */
- for (card = soundcards; card && card->no != cardno; card = card->next);
- if (!card) {
- snd_ctl_close(handle);
- error("The soundcard %i does not exist.", cardno);
- return 1;
- }
- for (mixer = card->mixers; mixer; mixer = mixer->next) {
- if ((err = snd_mixer_open(&mhandle, cardno, mixer->no)) < 0) {
- snd_ctl_close(handle);
- error("MIXER open error: %s", snd_strerror(err));
- return 1;
- }
- if (mixer->elements)
- soundcard_mixer_element_free(mixer->elements);
- mixer->elements = NULL;
- bzero(&elements, sizeof(elements));
- if ((err = snd_mixer_elements(mhandle, &elements)) < 0) {
- snd_mixer_close(mhandle);
- snd_ctl_close(handle);
- error("MIXER elements error: %s", snd_strerror(err));
- return 1;
- }
- elements.elements_size = elements.elements_over + 16;
- elements.elements = elements.elements_over = 0;
- elements.pelements = (snd_mixer_eid_t *)malloc(elements.elements_size * sizeof(snd_mixer_eid_t));
- if ((err = snd_mixer_elements(mhandle, &elements)) < 0) {
- snd_mixer_close(mhandle);
- snd_ctl_close(handle);
- error("MIXER elements (2) error: %s", snd_strerror(err));
- return 1;
- }
- for (idx = 0, mixerelementprev = NULL; idx < elements.elements; idx++) {
- mixerelement = (struct mixer_element *) malloc(sizeof(struct mixer_element));
- if (!mixerelement) {
- snd_mixer_close(mhandle);
- snd_ctl_close(handle);
- error("malloc problem");
- return 1;
- }
- bzero(mixerelement, sizeof(*mixerelement));
- mixerelement->info.eid = elements.pelements[idx];
- mixerelement->element.eid = elements.pelements[idx];
- if (snd_mixer_element_has_info(&elements.pelements[idx]) == 1) {
- if ((err = snd_mixer_element_info_build(mhandle, &mixerelement->info)) < 0) {
- free(mixerelement);
- error("MIXER element %s info error (%s) - skipping", mixer_element_id(&mixerelement->info.eid), snd_strerror(err));
- break;
- }
- }
- if (snd_mixer_element_has_control(&elements.pelements[idx]) == 1) {
- if ((err = snd_mixer_element_build(mhandle, &mixerelement->element)) < 0) {
- free(mixerelement);
- error("MIXER element %s build error (%s) - skipping", mixer_element_id(&mixerelement->element.eid), snd_strerror(err));
- break;
- }
- }
- if (!mixerelementprev) {
- mixer->elements = mixerelement;
- } else {
- mixerelementprev->next = mixerelement;
- }
- mixerelementprev = mixerelement;
- }
- free(elements.pelements);
- snd_mixer_close(mhandle);
- }
- /* --- */
- snd_ctl_close(handle);
- return 0;
-}
-
-int soundcard_setup_collect_data(int cardno)
-{
- int err;
- unsigned int mask;
-
- if (cardno >= 0) {
- return soundcard_setup_collect_data1(cardno);
- } else {
- mask = snd_cards_mask();
- for (cardno = 0; cardno < SND_CARDS; cardno++) {
- if (!(mask & (1 << cardno)))
- continue;
- err = soundcard_setup_collect_data1(cardno);
- if (err)
- return err;
- }
- return 0;
- }
-}
-
-
-
int soundcard_setup_load(const char *cfgfile, int skip)
{
extern int yyparse(void);
extern int linecount;
extern FILE *yyin;
+#ifdef YYDEBUG
extern int yydebug;
+#endif
int xtry;
#ifdef YYDEBUG
return 0;
}
-static void soundcard_setup_write_switch(FILE * out, const char *space, int card, int interface, snd_switch_t *sw)
+static void soundcard_setup_write_control(FILE * out, const char *space, int card, struct ctl_control *control)
{
char *s, v[16];
- int idx, first, switchok = 0;
+ int err, idx;
+ snd_ctl_t *handle;
+ snd_control_info_t info;
+ memcpy(&info, &control->info, sizeof(info));
v[0] = '\0';
- switch (sw->type) {
- case SND_SW_TYPE_BOOLEAN:
- s = "bool";
- strcpy(v, sw->value.enable ? "true" : "false");
- break;
- case SND_SW_TYPE_BYTE:
- s = "byte";
- if (sw->subtype == SND_SW_SUBTYPE_HEXA) {
- sprintf(v, "0x%x", (unsigned int) sw->value.data8[0]);
- } else {
- sprintf(v, "%u", (unsigned int) sw->value.data8[0]);
- }
- break;
- case SND_SW_TYPE_WORD:
- s = "word";
- if (sw->subtype == SND_SW_SUBTYPE_HEXA) {
- sprintf(v, "0x%x", (unsigned int) sw->value.data16[0]);
- } else {
- sprintf(v, "%u", (unsigned int) sw->value.data16[0]);
- }
- break;
- case SND_SW_TYPE_DWORD:
- s = "dword";
- if (sw->subtype == SND_SW_SUBTYPE_HEXA) {
- sprintf(v, "0x%x", sw->value.data32[0]);
- } else {
- sprintf(v, "%u", sw->value.data32[0]);
- }
+ switch (info.type) {
+ case SND_CONTROL_TYPE_BOOLEAN: s = "bool"; break;
+ case SND_CONTROL_TYPE_INTEGER: s = "integer"; break;
+ case SND_CONTROL_TYPE_ENUMERATED: s = "enumerated"; break;
+ case SND_CONTROL_TYPE_BYTES: s = "bytes"; break;
+ default: s = "unknown";
+ }
+ fprintf(out, "\n%s; The type is '%s'. Access:", space, s);
+ if (info.access & SND_CONTROL_ACCESS_READ)
+ fprintf(out, " read");
+ if (info.access & SND_CONTROL_ACCESS_WRITE)
+ fprintf(out, " write");
+ if (info.access & SND_CONTROL_ACCESS_INACTIVE)
+ fprintf(out, " inactive");
+ fprintf(out, ". Count is %i.\n", info.values_count);
+ switch (info.type) {
+ case SND_CONTROL_TYPE_BOOLEAN:
+ if (info.value.integer.min != 0 || info.value.integer.max != 1 ||
+ info.value.integer.step != 0)
+ error("Wrong control '%s' (boolean)\n", control_id(&info.id));
break;
- case SND_SW_TYPE_USER:
- s = "user";
+ case SND_CONTROL_TYPE_INTEGER:
+ fprintf(out, "%s; The range is %li-%li (step %li)\n", space, info.value.integer.min, info.value.integer.max, info.value.integer.step);
break;
- case SND_SW_TYPE_LIST:
- s = "list";
- sprintf(v, "%u", sw->value.item_number);
- break;
- case SND_SW_TYPE_USER_READ_ONLY:
- return;
- default:
- s = "unknown";
- }
- fprintf(out, "%s; The type is '%s'.\n", space, s);
- if (sw->low != 0 || sw->high != 0)
- fprintf(out, "%s; The accepted switch range is from %u to %u.\n", space, sw->low, sw->high);
- if (sw->type == SND_SW_TYPE_LIST) {
- snd_ctl_t *handle;
- snd_switch_t swi;
- memset(&swi, 0, sizeof(swi));
- swi.iface = sw->iface;
- swi.device = sw->device;
- swi.stream = sw->stream;
- strncpy(swi.name, sw->name, sizeof(swi.name));
- swi.type = SND_SW_TYPE_LIST_ITEM;
- if (snd_ctl_open(&handle, card) >= 0) {
- for (idx = sw->low; idx <= sw->high; idx++) {
- swi.low = swi.high = idx;
- if (snd_ctl_switch_read(handle, &swi) >= 0)
- fprintf(out, "%s; Item #%i - %s\n", space, swi.low, swi.value.item);
+ case SND_CONTROL_TYPE_ENUMERATED:
+ if ((err = snd_ctl_open(&handle, card)) >= 0) {
+ for (idx = 0; idx < info.value.enumerated.items; idx++) {
+ info.value.enumerated.item = idx;
+ if (snd_ctl_cinfo(handle, &info) >= 0)
+ fprintf(out, "%s; Item #%i - %s\n", space, idx, info.value.enumerated.name);
}
snd_ctl_close(handle);
}
+ break;
+ default:
+ break;
}
- if (interface == SND_INTERFACE_CONTROL && sw->type == SND_SW_TYPE_WORD &&
- !strcmp(sw->name, SND_CTL_SW_JOYSTICK_ADDRESS)) {
- for (idx = 1, first = 1; idx < 16; idx++) {
- if (sw->value.data16[idx]) {
- if (first) {
- fprintf(out, "%s; Available addresses - 0x%x", space, sw->value.data16[idx]);
- first = 0;
- } else {
- fprintf(out, ", 0x%x", sw->value.data16[idx]);
- }
- }
- }
- if (!first)
- fprintf(out, "\n");
- }
- if (interface == SND_INTERFACE_MIXER && sw->type == SND_SW_TYPE_BOOLEAN &&
- !strcmp(sw->name, SND_MIXER_SW_IEC958_OUTPUT)) {
- fprintf(out, "%sswitch(\"%s\",", space, sw->name);
- if (sw->value.data32[1] == (('C' << 8) | 'S')) { /* Cirrus Crystal */
- switchok = 0;
- fprintf(out, "iec958ocs(%s", sw->value.enable ? "enable" : "disable");
- if (sw->value.data16[4] & 0x2000)
- fprintf(out, ",3d");
- if (sw->value.data16[4] & 0x0040)
- fprintf(out, ",reset");
- if (sw->value.data16[4] & 0x0020)
- fprintf(out, ",user");
- if (sw->value.data16[4] & 0x0010)
- fprintf(out, ",valid");
- if (sw->value.data16[5] & 0x0002)
- fprintf(out, ",data");
- if (!(sw->value.data16[5] & 0x0004))
- fprintf(out, ",protect");
- switch (sw->value.data16[5] & 0x0018) {
- case 0x0008:
- fprintf(out, ",pre2");
- break;
- default:
- break;
- }
- if (sw->value.data16[5] & 0x0020)
- fprintf(out, ",fsunlock");
- fprintf(out, ",type(0x%x)", (sw->value.data16[5] >> 6) & 0x7f);
- if (sw->value.data16[5] & 0x2000)
- fprintf(out, ",gstatus");
- fprintf(out, ")");
- goto __end;
- }
- }
- fprintf(out, "%sswitch(\"%s\", ", space, sw->name);
- if (!switchok) {
- fprintf(out, v);
- if (sw->type < 0 || sw->type > SND_SW_TYPE_LAST) {
- /* TODO: some well known types should be verbose */
- fprintf(out, "rawdata(@");
- for (idx = 0; idx < 31; idx++) {
- fprintf(out, "%02x:", sw->value.data8[idx]);
- }
- fprintf(out, "%02x@)", sw->value.data8[31]);
+ switch (info.id.iface) {
+ case SND_CONTROL_IFACE_CARD: s = "global"; break;
+ case SND_CONTROL_IFACE_HWDEP: s = "hwdep"; break;
+ case SND_CONTROL_IFACE_MIXER: s = "mixer"; break;
+ case SND_CONTROL_IFACE_PCM: s = "pcm"; break;
+ case SND_CONTROL_IFACE_RAWMIDI: s = "rawmidi"; break;
+ case SND_CONTROL_IFACE_TIMER: s = "timer"; break;
+ case SND_CONTROL_IFACE_SEQUENCER: s = "sequencer"; break;
+ default: sprintf(v, "%i", info.id.iface); s = v; break;
+ }
+ fprintf(out, "%scontrol(%s, %i, %i, \"%s\", %i", space, s, info.id.device, info.id.subdevice, info.id.name, info.id.index);
+ if (info.type == SND_CONTROL_TYPE_BYTES)
+ fprintf(out, "rawdata(@");
+ for (idx = 0; idx < info.values_count; idx++) {
+ switch (info.type) {
+ case SND_CONTROL_TYPE_BOOLEAN:
+ fprintf(out, ", %s", control->c.value.integer.value[idx] ? "true" : "false");
+ break;
+ case SND_CONTROL_TYPE_INTEGER:
+ fprintf(out, ", %li", control->c.value.integer.value[idx]);
+ break;
+ case SND_CONTROL_TYPE_ENUMERATED:
+ fprintf(out, ", %u", control->c.value.enumerated.item[idx]);
+ break;
+ case SND_CONTROL_TYPE_BYTES:
+ if (idx > 0)
+ fprintf(out, ":");
+ fprintf(out, "%02x", control->c.value.bytes.data[idx]);
+ break;
+ default:
+ break;
}
- }
- __end:
+ }
+ if (info.type == SND_CONTROL_TYPE_BYTES)
+ fprintf(out, ")");
fprintf(out, ")\n");
}
-static void soundcard_setup_write_switches(FILE *out, const char *space, int card, int interface, struct ctl_switch **switches)
+static void soundcard_setup_write_controls(FILE *out, const char *space, int card, struct ctl_control **controls)
{
- struct ctl_switch *sw;
+ struct ctl_control *ctl;
- if (!(*switches))
+ if (!(*controls))
return;
- for (sw = *switches; sw; sw = sw->next)
- soundcard_setup_write_switch(out, space, card, interface, &sw->s);
-}
-
-static void soundcard_setup_write_mixer_element(FILE * out, struct mixer_element * xelement)
-{
- snd_mixer_element_info_t *info;
- snd_mixer_element_t *element;
- int idx;
-
- info = &xelement->info;
- element = &xelement->element;
- if (snd_mixer_element_has_control(&element->eid) != 1)
- return;
- switch (element->eid.type) {
- case SND_MIXER_ETYPE_SWITCH1:
- fprintf(out, " element(\"%s\",%i,%i,Switch1(", mixer_element_name(&element->eid), element->eid.index, element->eid.type);
- for (idx = 0; idx < element->data.switch1.sw; idx++)
- fprintf(out, "%s%s", idx > 0 ? "," : "", snd_mixer_get_bit(element->data.switch1.psw, idx) ? "on" : "off");
- fprintf(out, "))\n");
- break;
- case SND_MIXER_ETYPE_SWITCH2:
- fprintf(out, " element(\"%s\",%i,%i,Switch2(%s))\n", mixer_element_name(&element->eid), element->eid.index, element->eid.type, element->data.switch2.sw ? "on" : "off");
- break;
- case SND_MIXER_ETYPE_SWITCH3:
- fprintf(out, " element(\"%s\",%i,%i,Switch3(", mixer_element_name(&element->eid), element->eid.index, element->eid.type);
- for (idx = 0; idx < element->data.switch3.rsw; idx++)
- fprintf(out, "%s%s", idx > 0 ? "," : "", snd_mixer_get_bit(element->data.switch3.prsw, idx) ? "on" : "off");
- fprintf(out, "))\n");
- break;
- case SND_MIXER_ETYPE_VOLUME1:
- for (idx = 0; idx < info->data.volume1.range; idx++)
- fprintf(out, " ; Channel %i : Min %i Max %i\n", idx, info->data.volume1.prange[idx].min, info->data.volume1.prange[idx].max);
- fprintf(out, " element(\"%s\",%i,%i,Volume1(", mixer_element_name(&element->eid), element->eid.index, element->eid.type);
- for (idx = 0; idx < element->data.volume1.channels; idx++)
- fprintf(out, "%s%i", idx > 0 ? "," : "", element->data.volume1.pchannels[idx]);
- fprintf(out, "))\n");
- break;
- case SND_MIXER_ETYPE_ACCU3:
- for (idx = 0; idx < info->data.accu3.range; idx++)
- fprintf(out, " ; Channel %i : Min %i Max %i\n", idx, info->data.accu3.prange[idx].min, info->data.accu3.prange[idx].max);
- fprintf(out, " element(\"%s\",%i,%i,Accu3(", mixer_element_name(&element->eid), element->eid.index, element->eid.type);
- for (idx = 0; idx < element->data.accu3.channels; idx++)
- fprintf(out, "%s%i", idx > 0 ? "," : "", element->data.accu3.pchannels[idx]);
- fprintf(out, "))\n");
- break;
- case SND_MIXER_ETYPE_MUX1:
- fprintf(out, " element(\"%s\",%i,%i,Mux1(", mixer_element_name(&element->eid), element->eid.index, element->eid.type);
- for (idx = 0; idx < element->data.mux1.sel; idx++) {
- fprintf(out, "%selement(\"%s\",%i,%i)", idx > 0 ? "," : "", mixer_element_name(&element->data.mux1.psel[idx]), element->data.mux1.psel[idx].index, element->data.mux1.psel[idx].type);
- }
- fprintf(out, "))\n");
- break;
- case SND_MIXER_ETYPE_MUX2:
- fprintf(out, " element(\"%s\",%i,%i,Mux2(", mixer_element_name(&element->eid), element->eid.index, element->eid.type);
- fprintf(out, "element(\"%s\",%i,%i)", mixer_element_name(&element->data.mux2.sel), element->data.mux2.sel.index, element->data.mux2.sel.type);
- fprintf(out, "))\n");
- break;
- case SND_MIXER_ETYPE_TONE_CONTROL1:
- if (info->data.tc1.tc & SND_MIXER_TC1_SW)
- fprintf(out, " ; The tone control has an on/off switch.\n");
- if (info->data.tc1.tc & SND_MIXER_TC1_BASS)
- fprintf(out, " ; Bass : Min %i Max %i\n", info->data.tc1.min_bass, info->data.tc1.max_bass);
- if (info->data.tc1.tc & SND_MIXER_TC1_TREBLE)
- fprintf(out, " ; Treble : Min %i Max %i\n", info->data.tc1.min_treble, info->data.tc1.max_treble);
- fprintf(out, " element(\"%s\",%i,%i,ToneControl1(", mixer_element_name(&element->eid), element->eid.index, element->eid.type);
- idx = 0;
- if (element->data.tc1.tc & SND_MIXER_TC1_SW)
- fprintf(out, "%ssw=%s", idx++ > 0 ? "," : "", element->data.tc1.sw ? "on" : "off");
- if (element->data.tc1.tc & SND_MIXER_TC1_BASS)
- fprintf(out, "%sbass=%i", idx++ > 0 ? "," : "", element->data.tc1.bass);
- if (element->data.tc1.tc & SND_MIXER_TC1_TREBLE)
- fprintf(out, "%streble=%i", idx++ > 0 ? "," : "", element->data.tc1.treble);
- fprintf(out, "))\n");
- break;
- case SND_MIXER_ETYPE_3D_EFFECT1:
- if (info->data.teffect1.effect & SND_MIXER_EFF1_SW)
- fprintf(out, " ; The 3D effect has an on/off switch.\n");
- if (info->data.teffect1.effect & SND_MIXER_EFF1_MONO_SW)
- fprintf(out, " ; The 3D effect has an mono processing on/off switch.\n");
- if (info->data.teffect1.effect & SND_MIXER_EFF1_WIDE)
- fprintf(out, " ; Wide : Min %i Max %i\n", info->data.teffect1.min_wide, info->data.teffect1.max_wide);
- if (info->data.teffect1.effect & SND_MIXER_EFF1_VOLUME)
- fprintf(out, " ; Volume : Min %i Max %i\n", info->data.teffect1.min_volume, info->data.teffect1.max_volume);
- if (info->data.teffect1.effect & SND_MIXER_EFF1_CENTER)
- fprintf(out, " ; Center : Min %i Max %i\n", info->data.teffect1.min_center, info->data.teffect1.max_center);
- if (info->data.teffect1.effect & SND_MIXER_EFF1_SPACE)
- fprintf(out, " ; Space : Min %i Max %i\n", info->data.teffect1.min_space, info->data.teffect1.max_space);
- if (info->data.teffect1.effect & SND_MIXER_EFF1_DEPTH)
- fprintf(out, " ; Depth : Min %i Max %i\n", info->data.teffect1.min_depth, info->data.teffect1.max_depth);
- if (info->data.teffect1.effect & SND_MIXER_EFF1_DELAY)
- fprintf(out, " ; Delay : Min %i Max %i\n", info->data.teffect1.min_delay, info->data.teffect1.max_delay);
- if (info->data.teffect1.effect & SND_MIXER_EFF1_FEEDBACK)
- fprintf(out, " ; Feedback : Min %i Max %i\n", info->data.teffect1.min_feedback, info->data.teffect1.max_feedback);
- if (info->data.teffect1.effect & SND_MIXER_EFF1_DEPTH_REAR)
- fprintf(out, " ; Depth rear : Min %i Max %i\n", info->data.teffect1.min_depth_rear, info->data.teffect1.max_depth_rear);
- fprintf(out, " element(\"%s\",%i,%i,_3D_Effect1(", mixer_element_name(&element->eid), element->eid.index, element->eid.type);
- idx = 0;
- if (element->data.teffect1.effect & SND_MIXER_EFF1_SW)
- fprintf(out, "%ssw=%s", idx++ > 0 ? "," : "", element->data.teffect1.sw ? "on" : "off");
- if (element->data.teffect1.effect & SND_MIXER_EFF1_MONO_SW)
- fprintf(out, "%smono_sw=%s", idx++ > 0 ? "," : "", element->data.teffect1.mono_sw ? "on" : "off");
- if (element->data.teffect1.effect & SND_MIXER_EFF1_WIDE)
- fprintf(out, "%swide=%i", idx++ > 0 ? "," : "", element->data.teffect1.wide);
- if (element->data.teffect1.effect & SND_MIXER_EFF1_VOLUME)
- fprintf(out, "%svolume=%i", idx++ > 0 ? "," : "", element->data.teffect1.volume);
- if (element->data.teffect1.effect & SND_MIXER_EFF1_CENTER)
- fprintf(out, "%scenter=%i", idx++ > 0 ? "," : "", element->data.teffect1.center);
- if (element->data.teffect1.effect & SND_MIXER_EFF1_SPACE)
- fprintf(out, "%sspace=%i", idx++ > 0 ? "," : "", element->data.teffect1.space);
- if (element->data.teffect1.effect & SND_MIXER_EFF1_DEPTH)
- fprintf(out, "%sdepth=%i", idx++ > 0 ? "," : "", element->data.teffect1.depth);
- if (element->data.teffect1.effect & SND_MIXER_EFF1_DELAY)
- fprintf(out, "%sdelay=%i", idx++ > 0 ? "," : "", element->data.teffect1.delay);
- if (element->data.teffect1.effect & SND_MIXER_EFF1_FEEDBACK)
- fprintf(out, "%sfeedback=%i", idx++ > 0 ? "," : "", element->data.teffect1.feedback);
- if (element->data.teffect1.effect & SND_MIXER_EFF1_DEPTH_REAR)
- fprintf(out, "%sdepth_rear=%i", idx++ > 0 ? "," : "", element->data.teffect1.depth_rear);
- fprintf(out, "))\n");
- break;
- default:
- fprintf(out, " ; Unknown element %s\n", mixer_element_id(&element->eid));
- }
+ for (ctl = *controls; ctl; ctl = ctl->next)
+ soundcard_setup_write_control(out, space, card, ctl);
}
#define MAX_LINE (32 * 1024)
FILE *out, *out1, *out2, *in;
char *tmpfile1, *tmpfile2;
struct soundcard *first, *sel = NULL;
- struct mixer *mixer;
- struct mixer_element *mixerelement;
- struct pcm *pcm;
- struct rawmidi *rawmidi;
char *line, cardname[sizeof(first->control.hwinfo.name)+16], *ptr1;
int mark, size, ok;
continue;
sel = first;
fprintf(out, "soundcard(\"%s\") {\n", first->control.hwinfo.id);
- if (first->control.switches) {
- fprintf(out, " control {\n");
- soundcard_setup_write_switches(out, " ", first->no, SND_INTERFACE_CONTROL, &first->control.switches);
- fprintf(out, " }\n");
- }
- for (mixer = first->mixers; mixer; mixer = mixer->next) {
- fprintf(out, " mixer(\"%s\") {\n", mixer->info.name);
- soundcard_setup_write_switches(out, " ", first->no, SND_INTERFACE_MIXER, &mixer->switches);
- for (mixerelement = mixer->elements; mixerelement; mixerelement = mixerelement->next)
- soundcard_setup_write_mixer_element(out, mixerelement);
- fprintf(out, " }\n");
- }
- for (pcm = first->pcms; pcm; pcm = pcm->next) {
- if (!pcm->pswitches && !pcm->rswitches)
- continue;
- fprintf(out, " pcm(\"%s\") {\n", pcm->info.name);
- if (pcm->pswitches) {
- fprintf(out, " playback {\n");
- soundcard_setup_write_switches(out, " ", first->no, SND_INTERFACE_PCM, &pcm->pswitches);
- fprintf(out, " }\n");
- }
- if (pcm->rswitches) {
- fprintf(out, " capture {\n");
- soundcard_setup_write_switches(out, " ", first->no, SND_INTERFACE_PCM, &pcm->rswitches);
- fprintf(out, " }\n");
- }
- fprintf(out, " }\n");
- }
- for (rawmidi = first->rawmidis; rawmidi; rawmidi = rawmidi->next) {
- if (!rawmidi->oswitches && !rawmidi->iswitches)
- continue;
- fprintf(out, " rawmidi(\"%s\") {\n", rawmidi->info.name);
- if (rawmidi->oswitches) {
- fprintf(out, " output {\n");
- soundcard_setup_write_switches(out, " ", first->no, SND_INTERFACE_RAWMIDI, &rawmidi->oswitches);
- fprintf(out, " }\n");
- }
- if (rawmidi->iswitches) {
- fprintf(out, " input {\n");
- soundcard_setup_write_switches(out, " ", first->no, SND_INTERFACE_RAWMIDI, &rawmidi->iswitches);
- fprintf(out, " }\n");
- }
- fprintf(out, " }\n");
+ if (first->control.controls) {
+ soundcard_setup_write_controls(out, " ", first->no, &first->control.controls);
}
fprintf(out, "}\n%s", cardno < 0 && first->next ? "\n" : "");
}
*
* ChangeLog:
*
+ * Fri Jun 23 14:10:00 MEST 2000 Jaroslav Kysela <perex@suse.cz>
+ *
+ * * ported to new mixer 0.6.x API (simple control)
+ * * improved error handling (mixer_abort)
+ *
* Thu Mar 9 22:54:16 MET 2000 Takashi iwai <iwai@ww.uni-erlangen.de>
*
* * a group is split into front, rear, center and woofer elements.
*
* * version 1.00
*
- * * ported to new mixer API (group control)
+ * * ported to new mixer API (scontrol control)
*
* Sun Feb 21 19:55:01 1999 Tim Janik <timj@gtk.org>
*
#define PRGNAME "alsamixer"
#define PRGNAME_UPPER "AlsaMixer"
#define VERSION "v1.00"
-#define CHECK_ABORT(e,s) ({ if (errno != EINTR) mixer_abort ((e), (s)); })
+#define CHECK_ABORT(e,s,n) ({ if ((n) != -EINTR) mixer_abort ((e), (s), (n)); })
#define GETCH_BLOCK(w) ({ timeout ((w) ? -1 : 0); })
#undef MAX
static int mixer_cbar_height = 0;
static int card_id = 0;
-static int mixer_id = 0;
static snd_mixer_t *mixer_handle;
-static char *mixer_card_name = NULL;
-static char *mixer_device_name = NULL;
+static char mixer_card_name[128];
+static char mixer_device_name[128];
/* mixer bar channel : left or right */
#define MIXER_CHN_LEFT 0
{ SND_MIXER_CHN_WOOFER, -1 },
};
-static snd_mixer_gid_t *mixer_gid = NULL;
-static int mixer_n_groups = 0;
+static snd_mixer_sid_t *mixer_sid = NULL;
+static int mixer_n_scontrols = 0;
-/* split groups */
+/* split scontrols */
static int mixer_n_elems = 0;
static int mixer_n_vis_elems = 0;
static int mixer_first_vis_elem = 0;
/* --- prototypes --- */
static void
mixer_abort (ErrType error,
- const char *err_string)
+ const char *err_string,
+ int xerrno)
__attribute__
((noreturn));
static void
mixer_abort (ErrType error,
- const char *err_string)
+ const char *err_string,
+ int xerrno)
{
if (mixer_window)
{
{
case ERR_OPEN:
fprintf (stderr,
- PRGNAME ": failed to open mixer #%i/#%i: %s\n",
+ PRGNAME ": failed to open mixer #%i: %s\n",
card_id,
- mixer_id,
- snd_strerror (errno));
+ snd_strerror (xerrno));
break;
case ERR_FCN:
fprintf (stderr,
PRGNAME ": function %s failed: %s\n",
err_string,
- snd_strerror (errno));
+ snd_strerror (xerrno));
break;
case ERR_SIGNAL:
fprintf (stderr,
}
static int
-mixer_calc_volume(snd_mixer_group_t *group, int vol, int chn)
+mixer_calc_volume(snd_mixer_simple_control_t *scontrol, int vol, int chn)
{
int vol1;
vol1 = (vol < 0) ? -vol : vol;
if (vol1 > 0) {
if (vol1 > 100)
- vol1 = group->max;
+ vol1 = scontrol->max;
else
- vol1 = mixer_conv(vol1, 0, 100, group->min, group->max);
+ vol1 = mixer_conv(vol1, 0, 100, scontrol->min, scontrol->max);
if (vol1 <= 0)
vol1 = 1;
if (vol < 0)
vol1 = -vol1;
}
- vol1 += group->volume.values[chn];
- return CLAMP(vol1, group->min, group->max);
+ vol1 += scontrol->volume.values[chn];
+ return CLAMP(vol1, scontrol->min, scontrol->max);
}
/* set new channel values
static void
mixer_write_cbar (int elem_index)
{
- snd_mixer_group_t group;
+ snd_mixer_simple_control_t scontrol;
int vleft, vright, vbalance;
int type, chn_left, chn_right;
- int i, changed;
+ int i, err, changed;
- bzero(&group, sizeof(group));
- group.gid = mixer_gid[mixer_grpidx[elem_index]];
- if (snd_mixer_group_read (mixer_handle, &group) < 0)
- CHECK_ABORT (ERR_FCN, "snd_mixer_group_read()");
+ bzero(&scontrol, sizeof(scontrol));
+ if (mixer_sid == NULL)
+ return;
+ scontrol.sid = mixer_sid[mixer_grpidx[elem_index]];
+ if ((err = snd_mixer_simple_control_read (mixer_handle, &scontrol)) < 0)
+ CHECK_ABORT (ERR_FCN, "snd_mixer_simple_control_read()", err);
type = mixer_type[elem_index];
chn_left = mixer_elem_chn[type][MIXER_CHN_LEFT];
- if (! (group.channels & (1 << chn_left)))
+ if (! (scontrol.channels & (1 << chn_left)))
return; /* ..??.. */
chn_right = mixer_elem_chn[type][MIXER_CHN_RIGHT];
- if (chn_right >= 0 && ! (group.channels & (1 << chn_right)))
+ if (chn_right >= 0 && ! (scontrol.channels & (1 << chn_right)))
chn_right = -1;
changed = 0;
if ((mixer_volume_delta[MIXER_CHN_LEFT] ||
mixer_volume_delta[MIXER_CHN_RIGHT] ||
mixer_balance_volumes) &&
- (group.caps & SND_MIXER_GRPCAP_VOLUME)) {
+ (scontrol.caps & SND_MIXER_SCTCAP_VOLUME)) {
int mono =
- (chn_right < 0 || (group.caps & SND_MIXER_GRPCAP_JOINTLY_VOLUME));
+ (chn_right < 0 || (scontrol.caps & SND_MIXER_SCTCAP_JOINTLY_VOLUME));
if (mono && !mixer_volume_delta[MIXER_CHN_LEFT])
mixer_volume_delta[MIXER_CHN_LEFT] = mixer_volume_delta[MIXER_CHN_RIGHT];
- vleft = mixer_calc_volume(&group, mixer_volume_delta[MIXER_CHN_LEFT], chn_left);
+ vleft = mixer_calc_volume(&scontrol, mixer_volume_delta[MIXER_CHN_LEFT], chn_left);
vbalance = vleft;
if (! mono) {
- vright = mixer_calc_volume(&group, mixer_volume_delta[MIXER_CHN_RIGHT], chn_right);
+ vright = mixer_calc_volume(&scontrol, mixer_volume_delta[MIXER_CHN_RIGHT], chn_right);
vbalance += vright;
vbalance /= 2;
} else
vright = vleft;
if (vleft >= 0 && vright >= 0) {
- if (group.caps & SND_MIXER_GRPCAP_JOINTLY_VOLUME) {
+ if (scontrol.caps & SND_MIXER_SCTCAP_JOINTLY_VOLUME) {
for (i = 0; i < SND_MIXER_CHN_LAST; i++) {
- if (group.channels & (1 << i))
- group.volume.values[i] = vleft;
+ if (scontrol.channels & (1 << i))
+ scontrol.volume.values[i] = vleft;
}
} else {
if (mixer_balance_volumes)
vleft = vright = vbalance;
- group.volume.values[chn_left] = vleft;
+ scontrol.volume.values[chn_left] = vleft;
if (! mono)
- group.volume.values[chn_right] = vright;
+ scontrol.volume.values[chn_right] = vright;
}
changed = 1;
}
/* mute
*/
- if (mixer_toggle_mute && (group.caps & SND_MIXER_GRPCAP_MUTE)) {
- group.mute &= group.channels;
- if (group.caps & SND_MIXER_GRPCAP_JOINTLY_MUTE)
- group.mute = group.mute ? 0 : group.channels;
+ if (mixer_toggle_mute && (scontrol.caps & SND_MIXER_SCTCAP_MUTE)) {
+ scontrol.mute &= scontrol.channels;
+ if (scontrol.caps & SND_MIXER_SCTCAP_JOINTLY_MUTE)
+ scontrol.mute = scontrol.mute ? 0 : scontrol.channels;
else {
if (mixer_toggle_mute & MIXER_MASK_LEFT)
- group.mute ^= (1 << chn_left);
+ scontrol.mute ^= (1 << chn_left);
if (chn_right >= 0 && (mixer_toggle_mute & MIXER_MASK_RIGHT))
- group.mute ^= (1 << chn_right);
+ scontrol.mute ^= (1 << chn_right);
}
changed = 1;
}
/* capture
*/
- if (mixer_toggle_capture && (group.caps & SND_MIXER_GRPCAP_CAPTURE)) {
- group.capture &= group.channels;
- if (group.caps & SND_MIXER_GRPCAP_JOINTLY_CAPTURE)
- group.capture = group.capture ? 0 : group.channels;
+ if (mixer_toggle_capture && (scontrol.caps & SND_MIXER_SCTCAP_CAPTURE)) {
+ scontrol.capture &= scontrol.channels;
+ if (scontrol.caps & SND_MIXER_SCTCAP_JOINTLY_CAPTURE)
+ scontrol.capture = scontrol.capture ? 0 : scontrol.channels;
else {
if (mixer_toggle_capture & MIXER_MASK_LEFT)
- group.capture ^= (1 << chn_left);
+ scontrol.capture ^= (1 << chn_left);
if (chn_right >= 0 && (mixer_toggle_capture & MIXER_MASK_RIGHT))
- group.capture ^= (1 << chn_right);
+ scontrol.capture ^= (1 << chn_right);
}
changed = 1;
}
mixer_toggle_capture = 0;
if (changed) {
- if (snd_mixer_group_write (mixer_handle, &group) < 0)
- CHECK_ABORT (ERR_FCN, "snd_mixer_group_write()");
+ if ((err = snd_mixer_simple_control_write (mixer_handle, &scontrol)) < 0)
+ CHECK_ABORT (ERR_FCN, "snd_mixer_simple_control_write()", err);
}
}
mixer_update_cbar (int elem_index)
{
char string[64], string1[64];
- int dc;
- snd_mixer_group_t group;
+ int err, dc;
+ snd_mixer_simple_control_t scontrol;
int vleft, vright;
int type, chn_left, chn_right;
int x, y, i;
- /* set new group indices and read info
+ fprintf(stderr, "update cbar\n");
+
+ /* set new scontrol indices and read info
*/
- bzero(&group, sizeof(group));
- group.gid = mixer_gid[mixer_grpidx[elem_index]];
- if (snd_mixer_group_read (mixer_handle, &group) < 0)
- CHECK_ABORT (ERR_FCN, "snd_mixer_group_read()");
+ bzero(&scontrol, sizeof(scontrol));
+ if (mixer_sid == NULL)
+ return;
+ scontrol.sid = mixer_sid[mixer_grpidx[elem_index]];
+ if ((err = snd_mixer_simple_control_read (mixer_handle, &scontrol)) < 0)
+ CHECK_ABORT (ERR_FCN, "snd_mixer_simple_control_read()", err);
+ fprintf(stderr, "scontrol.channels = 0x%x\n", scontrol.channels);
type = mixer_type[elem_index];
chn_left = mixer_elem_chn[type][MIXER_CHN_LEFT];
- if (! (group.channels & (1 << chn_left)))
+ if (! (scontrol.channels & (1 << chn_left)))
return; /* ..??.. */
chn_right = mixer_elem_chn[type][MIXER_CHN_RIGHT];
- if (chn_right >= 0 && ! (group.channels & (1 << chn_right)))
+ if (chn_right >= 0 && ! (scontrol.channels & (1 << chn_right)))
chn_right = -1;
/* first, read values for the numbers to be displayed
*/
- if (snd_mixer_group_read (mixer_handle, &group) < 0)
- CHECK_ABORT (ERR_FCN, "snd_mixer_group_read()");
+ if ((err = snd_mixer_simple_control_read (mixer_handle, &scontrol)) < 0)
+ CHECK_ABORT (ERR_FCN, "snd_mixer_simple_control_read()", err);
- vleft = group.volume.values[chn_left];
- vleft = mixer_conv(vleft, group.min, group.max, 0, 100);
+ vleft = scontrol.volume.values[chn_left];
+ vleft = mixer_conv(vleft, scontrol.min, scontrol.max, 0, 100);
if (chn_right >= 0) {
- vright = group.volume.values[chn_right];
- vright = mixer_conv(vright, group.min, group.max, 0, 100);
+ vright = scontrol.volume.values[chn_right];
+ vright = mixer_conv(vright, scontrol.min, scontrol.max, 0, 100);
} else {
vright = vleft;
}
/* channel bar name
*/
mixer_dc (elem_index == mixer_focus_elem ? DC_CBAR_FOCUS_LABEL : DC_CBAR_LABEL);
- if (group.gid.index > 0)
- sprintf(string1, "%s %d", group.gid.name, group.gid.index);
+ if (scontrol.sid.index > 0)
+ sprintf(string1, "%s %d", scontrol.sid.name, scontrol.sid.index);
else
- strcpy(string1, group.gid.name);
+ strcpy(string1, scontrol.sid.name);
string1[8] = 0;
for (i = 0; i < 8; i++)
{
mvaddstr (y, x, " ");
mixer_dc (DC_CBAR_FRAME);
mvaddch (y, x + 2, ACS_ULCORNER);
- dc = group.mute & (1 << chn_left) ? DC_CBAR_MUTE : DC_CBAR_NOMUTE;
+ dc = scontrol.mute & (1 << chn_left) ? DC_CBAR_MUTE : DC_CBAR_NOMUTE;
mvaddch (y, x + 3, mixer_dc (dc));
if (chn_right >= 0)
- dc = group.mute & (1 << chn_right) ? DC_CBAR_MUTE : DC_CBAR_NOMUTE;
+ dc = scontrol.mute & (1 << chn_right) ? DC_CBAR_MUTE : DC_CBAR_NOMUTE;
mvaddch (y, x + 4, mixer_dc (dc));
mixer_dc (DC_CBAR_FRAME);
mvaddch (y, x + 5, ACS_URCORNER);
/* capture input?
*/
- if ((group.capture & (1 << chn_left)) ||
- (chn_right >= 0 && (group.capture & (1 << chn_right))))
+ if ((scontrol.capture & (1 << chn_left)) ||
+ (chn_right >= 0 && (scontrol.capture & (1 << chn_right))))
{
mixer_dc (DC_CBAR_CAPTURE);
mvaddstr (y, x + 1, "CAPTUR");
- if (group.capture & (1 << chn_left)) {
+ if (scontrol.capture & (1 << chn_left)) {
mvaddstr (y + 1, x + 1, "L");
if (chn_right < 0)
mvaddstr (y + 1, x + 6, "R");
}
- if (chn_right >= 0 && (group.capture & (1 << chn_right)))
+ if (chn_right >= 0 && (scontrol.capture & (1 << chn_right)))
mvaddstr (y + 1, x + 6, "R");
}
- else if (group.caps & SND_MIXER_GRPCAP_CAPTURE)
+ else if (scontrol.caps & SND_MIXER_SCTCAP_CAPTURE)
for (i = 0; i < 6; i++)
mvaddch (y, x + 1 + i, mixer_dc (DC_CBAR_NOCAPTURE));
else
mixer_cbar_get_pos (mixer_focus_elem, &x, &y);
}
mixer_write_cbar(mixer_focus_elem);
+ fprintf(stderr, "mixer_n_vis_elems = %i\n", mixer_n_vis_elems);
for (i = 0; i < mixer_n_vis_elems; i++)
mixer_update_cbar (i + mixer_first_vis_elem);
static void
mixer_init (void)
{
- static snd_mixer_info_t mixer_info = { 0, };
- static struct snd_ctl_hw_info hw_info;
+ snd_ctl_hw_info_t hw_info;
snd_ctl_t *ctl_handle;
+ int err;
- if (snd_ctl_open (&ctl_handle, card_id) < 0)
- mixer_abort (ERR_OPEN, "snd_ctl_open");
- if (snd_ctl_hw_info (ctl_handle, &hw_info) < 0)
- mixer_abort (ERR_FCN, "snd_ctl_hw_info");
+ if ((err = snd_ctl_open (&ctl_handle, card_id)) < 0)
+ mixer_abort (ERR_OPEN, "snd_ctl_open", err);
+ if ((err = snd_ctl_hw_info (ctl_handle, &hw_info)) < 0)
+ mixer_abort (ERR_FCN, "snd_ctl_hw_info", err);
snd_ctl_close (ctl_handle);
/* open mixer device
*/
- if (snd_mixer_open (&mixer_handle, card_id, mixer_id) < 0)
- mixer_abort (ERR_OPEN, "snd_mixer_open");
+ if ((err = snd_mixer_open (&mixer_handle, card_id)) < 0)
+ mixer_abort (ERR_OPEN, "snd_mixer_open", err);
/* setup global variables
*/
- if (snd_mixer_info (mixer_handle, &mixer_info) < 0)
- mixer_abort (ERR_FCN, "snd_mixer_info");
- mixer_card_name = hw_info.name;
- mixer_device_name = mixer_info.name;
+ strcpy(mixer_card_name, hw_info.name);
+ strcpy(mixer_device_name, hw_info.mixername);
}
static void
mixer_reinit (void)
{
- snd_mixer_groups_t groups;
- int idx, elem_index, i;
- snd_mixer_gid_t focus_gid;
+ snd_mixer_simple_control_list_t scontrols;
+ int idx, err, elem_index, i;
+ snd_mixer_sid_t focus_gid;
int focus_type = -1;
- if (mixer_gid) {
- focus_gid = mixer_gid[mixer_grpidx[mixer_focus_elem]];
+ if (mixer_sid) {
+ focus_gid = mixer_sid[mixer_grpidx[mixer_focus_elem]];
focus_type = mixer_type[mixer_focus_elem];
}
while (1) {
- bzero(&groups, sizeof(groups));
- if (snd_mixer_groups(mixer_handle, &groups) < 0)
- mixer_abort (ERR_FCN, "snd_mixer_groups");
- mixer_n_groups = groups.groups_over;
- if (mixer_n_groups > 0) {
- groups.groups_size = mixer_n_groups;
- groups.pgroups = (snd_mixer_gid_t *)malloc(sizeof(snd_mixer_gid_t) * mixer_n_groups);
- if (groups.pgroups == NULL)
- mixer_abort (ERR_FCN, "malloc");
- groups.groups_over = 0;
- groups.groups = 0;
- if (snd_mixer_groups(mixer_handle, &groups) < 0)
- mixer_abort (ERR_FCN, "snd_mixer_groups");
- if (groups.groups_over > 0) {
- free(groups.pgroups);
+ bzero(&scontrols, sizeof(scontrols));
+ if ((err = snd_mixer_simple_control_list(mixer_handle, &scontrols)) < 0)
+ mixer_abort (ERR_FCN, "snd_mixer_simple_control_list", err);
+ mixer_n_scontrols = scontrols.controls;
+ fprintf(stderr, "controls = %i\n", scontrols.controls);
+ if (mixer_n_scontrols > 0) {
+ scontrols.controls_request = mixer_n_scontrols;
+ scontrols.pids = (snd_mixer_sid_t *)malloc(sizeof(snd_mixer_sid_t) * mixer_n_scontrols);
+ if (scontrols.pids == NULL)
+ mixer_abort (ERR_FCN, "malloc", 0);
+ scontrols.controls_offset = 0;
+ scontrols.controls_count = 0;
+ if ((err = snd_mixer_simple_control_list(mixer_handle, &scontrols)) < 0)
+ mixer_abort (ERR_FCN, "snd_mixer_simple_control_list", err);
+ if (scontrols.controls > scontrols.controls_count) {
+ free(scontrols.pids);
continue;
}
}
- if (mixer_gid)
- free(mixer_gid);
- mixer_gid = groups.pgroups;
+ if (mixer_sid)
+ free(mixer_sid);
+ mixer_sid = scontrols.pids;
+ fprintf(stderr, "mixer_sid = 0x%x\n", (int)mixer_sid);
break;
}
- snd_mixer_sort_gid_table(mixer_gid, mixer_n_groups, snd_mixer_default_weights);
+#if 0
+ snd_mixer_sort_gid_table(mixer_sid, mixer_n_scontrols, snd_mixer_default_weights);
+#endif
mixer_n_elems = 0;
- for (idx = 0; idx < mixer_n_groups; idx++) {
- snd_mixer_group_t group;
- bzero(&group, sizeof(group));
- group.gid = mixer_gid[idx];
- if (snd_mixer_group_read(mixer_handle, &group) < 0)
- CHECK_ABORT (ERR_FCN, "snd_mixer_group_read()");
+ for (idx = 0; idx < mixer_n_scontrols; idx++) {
+ snd_mixer_simple_control_t scontrol;
+ bzero(&scontrol, sizeof(scontrol));
+ scontrol.sid = mixer_sid[idx];
+ if ((err = snd_mixer_simple_control_read(mixer_handle, &scontrol)) < 0)
+ CHECK_ABORT (ERR_FCN, "snd_mixer_simple_control_read()", 0);
+ fprintf(stderr, "scontrol.channels = 0x%x\n", scontrol.channels);
for (i = 0; i < MIXER_ELEM_END; i++) {
- if (group.channels & mixer_elem_mask[i])
+ if (scontrol.channels & mixer_elem_mask[i])
mixer_n_elems++;
}
}
free(mixer_type);
mixer_type = (int *)malloc(sizeof(int) * mixer_n_elems);
if (mixer_type == NULL)
- mixer_abort(ERR_FCN, "malloc");
+ mixer_abort(ERR_FCN, "malloc", 0);
if (mixer_grpidx)
free(mixer_grpidx);
mixer_grpidx = (int *)malloc(sizeof(int) * mixer_n_elems);
if (mixer_grpidx == NULL)
- mixer_abort(ERR_FCN, "malloc");
+ mixer_abort(ERR_FCN, "malloc", 0);
elem_index = 0;
- for (idx = 0; idx < mixer_n_groups; idx++) {
- snd_mixer_group_t group;
- bzero(&group, sizeof(group));
- group.gid = mixer_gid[idx];
- if (snd_mixer_group_read(mixer_handle, &group) < 0)
- CHECK_ABORT (ERR_FCN, "snd_mixer_group_read()");
+ for (idx = 0; idx < mixer_n_scontrols; idx++) {
+ snd_mixer_simple_control_t scontrol;
+ bzero(&scontrol, sizeof(scontrol));
+ scontrol.sid = mixer_sid[idx];
+ if ((err = snd_mixer_simple_control_read(mixer_handle, &scontrol)) < 0)
+ CHECK_ABORT (ERR_FCN, "snd_mixer_simple_control_read()", err);
for (i = 0; i < MIXER_ELEM_END; i++) {
- if (group.channels & mixer_elem_mask[i]) {
+ if (scontrol.channels & mixer_elem_mask[i]) {
mixer_grpidx[elem_index] = idx;
mixer_type[elem_index] = i;
elem_index++;
mixer_focus_elem = 0;
if (focus_type >= 0) {
for (elem_index = 0; elem_index < mixer_n_elems; elem_index++) {
- if (!memcmp(&focus_gid, &mixer_gid[mixer_grpidx[elem_index]], sizeof(focus_gid)) &&
+ if (!memcmp(&focus_gid, &mixer_sid[mixer_grpidx[elem_index]], sizeof(focus_gid)) &&
mixer_type[elem_index] == focus_type) {
mixer_focus_elem = elem_index;
break;
}
static void
-mixer_callback_rebuild (void *private_data)
+mixer_callback_rebuild (snd_mixer_t *handle, void *private_data)
{
/* we don't actually need to update the individual channels because
* we redraw the whole screen upon every main iteration anyways.
}
static void
-mixer_callback_group (void *private_data, int cmd, snd_mixer_gid_t *gid)
+mixer_callback_scontrol (snd_mixer_t *handle, void *private_data, snd_mixer_sid_t *gid)
{
mixer_reinit ();
}
mixer_iteration (void)
{
struct timeval delay = { 0, };
- snd_mixer_callbacks_t callbacks = { 0, };
+ snd_mixer_simple_callbacks_t callbacks = { 0, };
int mixer_fd;
fd_set rfds;
int finished = 0;
int old_view;
callbacks.rebuild = mixer_callback_rebuild;
- callbacks.group = mixer_callback_group;
+ callbacks.value = mixer_callback_scontrol;
+ callbacks.change = mixer_callback_scontrol;
+ callbacks.add = mixer_callback_scontrol;
+ callbacks.remove = mixer_callback_scontrol;
/* setup for select on stdin and the mixer fd */
mixer_fd = snd_mixer_file_descriptor (mixer_handle);
mixer_resize ();
if (FD_ISSET (mixer_fd, &rfds))
- snd_mixer_read (mixer_handle, &callbacks);
+ snd_mixer_simple_read (mixer_handle, &callbacks);
if (FD_ISSET (fileno (stdin), &rfds))
key = getch ();
mixer_signal_handler (int signal)
{
if (signal != SIGSEGV)
- mixer_abort (ERR_SIGNAL, sys_siglist[signal]);
+ mixer_abort (ERR_SIGNAL, sys_siglist[signal], 0);
else
{
fprintf (stderr, "\nSegmentation fault.\n");
*/
do
{
- opt = getopt (argc, argv, "c:m:shg");
+ opt = getopt (argc, argv, "c:shg");
switch (opt)
{
case '?':
case 'h':
fprintf (stderr, "%s %s\n", PRGNAME_UPPER, VERSION);
- fprintf (stderr, "Usage: %s [-c <card: 1..%i>] [-m <mixer: 0..1>] [-z]\n", PRGNAME, snd_cards ());
- mixer_abort (ERR_NONE, "");
+ fprintf (stderr, "Usage: %s [-c <card: 0..%i>] [-z]\n", PRGNAME, snd_cards () - 1);
+ mixer_abort (ERR_NONE, "", 0);
case 'c':
card_id = snd_card_name (optarg);
break;
case 'g':
mixer_do_color = !mixer_do_color;
break;
- case 'm':
- mixer_id = CLAMP (optarg[0], '0', '1') - '0';
- break;
case 's':
mixer_minimize = 1;
break;
}
while (!mixer_iteration ());
- mixer_abort (ERR_NONE, "");
+ mixer_abort (ERR_NONE, "", 0);
};
/*
* ALSA command line mixer utility
- * Copyright (c) 1999 by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 1999-2000 by Jaroslav Kysela <perex@suse.cz>
*
* 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
#define HELPID_HELP 1000
#define HELPID_CARD 1001
-#define HELPID_DEVICE 1002
-#define HELPID_QUIET 1003
-#define HELPID_DEBUG 1004
-#define HELPID_VERSION 1005
+#define HELPID_QUIET 1002
+#define HELPID_DEBUG 1003
+#define HELPID_VERSION 1004
int quiet = 0;
int debugflag = 0;
int card;
-int device;
-int group_contents_is_on = 0;
-
-struct mixer_types {
- int type;
- char *name;
-};
-
-struct mixer_types mixer_types[] = {
- { SND_MIXER_ETYPE_INPUT, "Input" },
- { SND_MIXER_ETYPE_OUTPUT, "Output" },
- { SND_MIXER_ETYPE_CAPTURE1, "Capture Stream" },
- { SND_MIXER_ETYPE_CAPTURE2, "Capture Subchannel" },
- { SND_MIXER_ETYPE_PLAYBACK1, "Playback Stream" },
- { SND_MIXER_ETYPE_PLAYBACK2, "Playback Subchannel" },
- { SND_MIXER_ETYPE_ADC, "ADC" },
- { SND_MIXER_ETYPE_DAC, "DAC" },
- { SND_MIXER_ETYPE_SWITCH1, "Switch1" },
- { SND_MIXER_ETYPE_SWITCH2, "Switch2" },
- { SND_MIXER_ETYPE_SWITCH3, "Switch3" },
- { SND_MIXER_ETYPE_VOLUME1, "Volume1" },
- { SND_MIXER_ETYPE_VOLUME2, "Volume2" },
- { SND_MIXER_ETYPE_ACCU1, "Accumulator1" },
- { SND_MIXER_ETYPE_ACCU2, "Accumulator2" },
- { SND_MIXER_ETYPE_ACCU3, "Accumulator3" },
- { SND_MIXER_ETYPE_MUX1, "Mux1" },
- { SND_MIXER_ETYPE_MUX2, "Mux2" },
- { SND_MIXER_ETYPE_TONE_CONTROL1, "ToneControl1" },
- { SND_MIXER_ETYPE_EQUALIZER1, "Equalizer1" },
- { SND_MIXER_ETYPE_3D_EFFECT1, "3D-Effect1" },
- { SND_MIXER_ETYPE_PRE_EFFECT1, "PredefinedEffect1" },
- { -1, NULL }
-};
+int scontrol_contents_is_on = 0;
void error(const char *fmt,...)
{
printf("\nAvailable options:\n");
printf(" -h,--help this help\n");
printf(" -c,--card # use a card number (0-%i) or the card name, default %i\n", snd_cards() - 1, card);
- printf(" -d,--device # use a device number, default %i\n", device);
printf(" -D,--debug debug mode\n");
printf(" -v,--version print version of this program\n");
printf("\nAvailable commands:\n");
- printf(" info show useful information for the selected mixer\n");
printf(" groups show all mixer groups\n");
printf(" gcontents show contents of all mixer groups (default command)\n");
printf(" set G P set group contents for one mixer group\n");
int info(void)
{
int err;
- snd_mixer_t *handle;
- snd_mixer_info_t info;
+ snd_ctl_t *handle;
+ snd_mixer_t *mhandle;
+ snd_ctl_hw_info_t info;
+ snd_control_list_t clist;
+ snd_mixer_simple_control_list_t slist;
- if ((err = snd_mixer_open(&handle, card, device)) < 0) {
- error("Mixer %i/%i open error: %s", card, device, snd_strerror(err));
+ if ((err = snd_ctl_open(&handle, card)) < 0) {
+ error("Control device %i open error: %s", card, snd_strerror(err));
return -1;
}
- if ((err = snd_mixer_info(handle, &info)) < 0) {
- error("Mixer %i/%i info error: %s", card, device, snd_strerror(err));
+ if ((err = snd_ctl_hw_info(handle, &info)) < 0) {
+ error("Control device %i hw info error: %s", card, snd_strerror(err));
return -1;
}
- printf("Mixer '%s/%s':\n", info.id, info.name);
- printf(" Elements : %i\n", info.elements);
- printf(" Groups : %i\n", info.groups);
- printf(" Attribute : 0x%x\n", info.attrib);
- snd_mixer_close(handle);
+ printf("Card '%s/%s':\n", info.id, info.longname);
+ printf(" Mixer ID : '%s'\n", info.mixerid);
+ printf(" Mixer name : '%s'\n", info.mixername);
+ memset(&clist, 0, sizeof(clist));
+ if ((err = snd_ctl_clist(handle, &clist)) < 0) {
+ error("snd_ctl_clist failure: %s", snd_strerror(err));
+ } else {
+ printf(" Controls : %i\n", clist.controls);
+ }
+ snd_ctl_close(handle);
+ if ((err = snd_mixer_open(&mhandle, card)) < 0) {
+ error("Mixer device %i open error: %s", card, snd_strerror(err));
+ return -1;
+ }
+ if ((err = snd_mixer_simple_control_list(mhandle, &slist)) < 0) {
+ error("snd_mixer_simple_control_list failure: %s\n", snd_strerror(err));
+ } else {
+ printf(" Simple ctrls : %i\n", clist.controls);
+ }
+ snd_mixer_close(mhandle);
return 0;
}
return res;
}
-static const char *element_type(int type)
-{
- int idx;
- static char str[32];
-
- for (idx = 0; mixer_types[idx].type >= 0; idx++)
- if (type == mixer_types[idx].type)
- return mixer_types[idx].name;
- sprintf(str, "Type%i", type);
- return str;
-}
-
static int check_range(int val, int min, int max)
{
if (val < min)
return tmp1;
}
-int show_element(void *handle, snd_mixer_eid_t *eid, const char *space)
-{
- int err, idx;
- snd_mixer_routes_t routes;
- snd_mixer_eid_t *element;
-
- bzero(&routes, sizeof(routes));
- routes.eid = *eid;
- if ((err = snd_mixer_routes(handle, &routes)) < 0) {
- error("Mixer %i/%i route error: %s", card, device, snd_strerror(err));
- return -1;
- }
- if (!routes.routes_over)
- return 0;
- routes.proutes = (snd_mixer_eid_t *)malloc(routes.routes_over * sizeof(snd_mixer_eid_t));
- if (!routes.proutes) {
- error("Not enough memory...");
- return -1;
- }
- routes.routes_size = routes.routes_over;
- routes.routes = routes.routes_over = 0;
- if ((err = snd_mixer_routes(handle, &routes)) < 0) {
- error("Mixer %i/%i group (2) error: %s", card, device, snd_strerror(err));
- return -1;
- }
- for (idx = 0; idx < routes.routes; idx++) {
- element = &routes.proutes[idx];
- printf("%sRoute to element '%s',%i,%s\n", space, element_name(element->name), element->index, element_type(element->type));
- }
- free(routes.proutes);
- return 0;
-}
-
-static const char *speaker_position(int position)
-{
- static char str[32];
-
- switch (position) {
- case SND_MIXER_CHANNEL_UNKNOWN:
- return "Unknown";
- case SND_MIXER_CHANNEL_MONO:
- return "Mono";
- case SND_MIXER_CHANNEL_LEFT:
- return "Left";
- case SND_MIXER_CHANNEL_RIGHT:
- return "Right";
- case SND_MIXER_CHANNEL_CENTER:
- return "Center";
- case SND_MIXER_CHANNEL_REAR_LEFT:
- return "Rear-Left";
- case SND_MIXER_CHANNEL_REAR_RIGHT:
- return "Rear-Right";
- case SND_MIXER_CHANNEL_WOOFER:
- return "Woofer";
- default:
- sprintf(str, "Speaker%i", position);
- return str;
- }
-}
-
-int show_mux1_info(void *handle, snd_mixer_element_info_t *info, const char *space)
-{
- int idx, idx1, err;
- snd_mixer_elements_t elements;
- snd_mixer_routes_t routes;
- snd_mixer_eid_t *element;
-
- printf("%sMux supports none input: %s\n", space, (info->data.mux1.attrib & SND_MIXER_MUX1_NONE) ? "YES" : "NO");
- bzero(&elements, sizeof(elements));
- if ((err = snd_mixer_elements(handle, &elements)) < 0) {
- error("Mixer %i/%i elements error: %s", card, device, snd_strerror(err));
- return -1;
- }
- elements.pelements = (snd_mixer_eid_t *)malloc(elements.elements_over * sizeof(snd_mixer_eid_t));
- if (!elements.pelements) {
- error("Not enough memory");
- return -1;
- }
- elements.elements_size = elements.elements_over;
- elements.elements_over = elements.elements = 0;
- if ((err = snd_mixer_elements(handle, &elements)) < 0) {
- error("Mixer %i/%i elements (2) error: %s", card, device, snd_strerror(err));
- return -1;
- }
- for (idx = 0; idx < elements.elements; idx++) {
- bzero(&routes, sizeof(routes));
- routes.eid = elements.pelements[idx];
- if ((err = snd_mixer_routes(handle, &routes)) < 0) {
- error("Mixer %i/%i route error: %s", card, device, snd_strerror(err));
- free(elements.pelements);
- return -1;
- }
- if (!routes.routes_over)
- continue;
- routes.proutes = (snd_mixer_eid_t *)malloc(routes.routes_over * sizeof(snd_mixer_eid_t));
- if (!routes.proutes) {
- error("Not enough memory...");
- free(elements.pelements);
- return -1;
- }
- routes.routes_size = routes.routes_over;
- routes.routes = routes.routes_over = 0;
- if ((err = snd_mixer_routes(handle, &routes)) < 0) {
- error("Mixer %i/%i group (2) error: %s", card, device, snd_strerror(err));
- free(elements.pelements);
- return -1;
- }
- for (idx1 = 0; idx1 < routes.routes; idx1++) {
- element = &routes.proutes[idx1];
- if (!strncmp(element->name, info->eid.name, sizeof(element->name)) &&
- element->index == info->eid.index &&
- element->type == info->eid.type)
- printf("%sInput element '%s',%i,%s\n", space, element_name(routes.eid.name), routes.eid.index, element_type(routes.eid.type));
- }
- free(routes.proutes);
- }
- free(elements.pelements);
- return 0;
-}
-
-int show_mux2_info(void *handle, snd_mixer_element_info_t *info, const char *space)
-{
- int idx, idx1, err;
- snd_mixer_elements_t elements;
- snd_mixer_routes_t routes;
- snd_mixer_eid_t *element;
-
- printf("%sMux supports none input: %s\n", space, (info->data.mux2.attrib & SND_MIXER_MUX2_NONE) ? "YES" : "NO");
- bzero(&elements, sizeof(elements));
- if ((err = snd_mixer_elements(handle, &elements)) < 0) {
- error("Mixer %i/%i elements error: %s", card, device, snd_strerror(err));
- return -1;
- }
- elements.pelements = (snd_mixer_eid_t *)malloc(elements.elements_over * sizeof(snd_mixer_eid_t));
- if (!elements.pelements) {
- error("Not enough memory");
- return -1;
- }
- elements.elements_size = elements.elements_over;
- elements.elements_over = elements.elements = 0;
- if ((err = snd_mixer_elements(handle, &elements)) < 0) {
- error("Mixer %i/%i elements (2) error: %s", card, device, snd_strerror(err));
- return -1;
- }
- for (idx = 0; idx < elements.elements; idx++) {
- bzero(&routes, sizeof(routes));
- routes.eid = elements.pelements[idx];
- if ((err = snd_mixer_routes(handle, &routes)) < 0) {
- error("Mixer %i/%i route error: %s", card, device, snd_strerror(err));
- free(elements.pelements);
- return -1;
- }
- if (!routes.routes_over)
- continue;
- routes.proutes = (snd_mixer_eid_t *)malloc(routes.routes_over * sizeof(snd_mixer_eid_t));
- if (!routes.proutes) {
- error("Not enough memory...");
- free(elements.pelements);
- return -1;
- }
- routes.routes_size = routes.routes_over;
- routes.routes = routes.routes_over = 0;
- if ((err = snd_mixer_routes(handle, &routes)) < 0) {
- error("Mixer %i/%i group (2) error: %s", card, device, snd_strerror(err));
- free(elements.pelements);
- return -1;
- }
- for (idx1 = 0; idx1 < routes.routes; idx1++) {
- element = &routes.proutes[idx1];
- if (!strncmp(element->name, info->eid.name, sizeof(element->name)) &&
- element->index == info->eid.index &&
- element->type == info->eid.type)
- printf("%sInput element '%s',%i,%s\n", space, element_name(routes.eid.name), routes.eid.index, element_type(routes.eid.type));
- }
- free(routes.proutes);
- }
- free(elements.pelements);
- return 0;
-}
-
-int show_element_info(void *handle, snd_mixer_eid_t *eid, const char *space)
-{
- int err, idx;
- snd_mixer_element_info_t info;
-
- if (snd_mixer_element_has_info(eid) != 1)
- return 0;
- bzero(&info, sizeof(info));
- info.eid = *eid;
- if ((err = snd_mixer_element_info_build(handle, &info)) < 0) {
- error("Mixer %i/%i info error: %s", card, device, snd_strerror(err));
- return -1;
- }
- printf("%sInput/output channels: %i/%i\n", space, info.input_channels, info.output_channels);
- switch (info.eid.type) {
- case SND_MIXER_ETYPE_INPUT:
- case SND_MIXER_ETYPE_OUTPUT:
- if (info.data.io.attrib) {
- printf("%sAttributes%s\n", space,
- info.data.io.attrib & SND_MIXER_EIO_DIGITAL ? " digital" : "");
- }
- for (idx = 0; idx < info.data.io.channels; idx++) {
- printf("%sChannel %i: %s\n",
- space,
- idx,
- speaker_position(info.data.io.pchannels[idx].position));
- }
- break;
- case SND_MIXER_ETYPE_CAPTURE1:
- case SND_MIXER_ETYPE_PLAYBACK1:
- for (idx = 0; idx < info.data.pcm1.devices; idx++) {
- printf("%sPCM device %i: %i\n",
- space,
- idx,
- info.data.pcm1.pdevices[idx]);
- }
- break;
- case SND_MIXER_ETYPE_CAPTURE2:
- case SND_MIXER_ETYPE_PLAYBACK2:
- printf("%sPCM subdevice %i %i\n",
- space,
- info.data.pcm2.device,
- info.data.pcm2.subdevice);
- break;
- case SND_MIXER_ETYPE_ADC:
- case SND_MIXER_ETYPE_DAC:
- printf("%sResolution %i-bits\n", space, info.data.converter.resolution);
- break;
- case SND_MIXER_ETYPE_SWITCH3:
- printf("%sSwitch type is ", space);
- switch (info.data.switch3.type) {
- case SND_MIXER_SWITCH3_FULL_FEATURED:
- printf("full featured\n");
- break;
- case SND_MIXER_SWITCH3_ALWAYS_DESTINATION:
- printf("always destination\n");
- break;
- case SND_MIXER_SWITCH3_ONE_DESTINATION:
- printf("one destination\n");
- break;
- case SND_MIXER_SWITCH3_ALWAYS_ONE_DESTINATION:
- printf("always one destination\n");
- break;
- default:
- printf("unknown %i\n", info.data.switch3.type);
- }
- break;
- case SND_MIXER_ETYPE_VOLUME1:
- for (idx = 0; idx < info.data.volume1.range; idx++) {
- struct snd_mixer_element_volume1_range *range = &info.data.volume1.prange[idx];
- printf("%sChannel %i: Min %i (%i.%02idB), Max %i (%i.%02idB)\n",
- space,
- idx,
- range->min, range->min_dB / 100, abs(range->min_dB % 100),
- range->max, range->max_dB / 100, abs(range->max_dB % 100));
- }
- break;
- case SND_MIXER_ETYPE_ACCU1:
- printf("%sAttenuation %i.%02idB\n", space,
- info.data.accu1.attenuation / 100,
- abs(info.data.accu1.attenuation % 100));
- break;
- case SND_MIXER_ETYPE_ACCU2:
- printf("%sAttenuation %i.%02idB\n", space,
- info.data.accu2.attenuation / 100,
- abs(info.data.accu1.attenuation % 100));
- break;
- case SND_MIXER_ETYPE_ACCU3:
- for (idx = 0; idx < info.data.accu3.range; idx++) {
- struct snd_mixer_element_accu3_range *range = &info.data.accu3.prange[idx];
- printf("%sChannel %i: Min %i (%i.%02idB), Max %i (%i.%02idB)\n",
- space,
- idx,
- range->min, range->min_dB / 100, abs(range->min_dB % 100),
- range->max, range->max_dB / 100, abs(range->max_dB % 100));
- }
- break;
- case SND_MIXER_ETYPE_MUX1:
- show_mux1_info(handle, &info, space);
- break;
- case SND_MIXER_ETYPE_MUX2:
- show_mux2_info(handle, &info, space);
- break;
- case SND_MIXER_ETYPE_TONE_CONTROL1:
- if (info.data.tc1.tc & SND_MIXER_TC1_SW)
- printf("%sOn/Off switch\n", space);
- if (info.data.tc1.tc & SND_MIXER_TC1_BASS)
- printf("%sBass control: Min %i (%i.%02idB), Max %i (%i.%02idB)\n",
- space,
- info.data.tc1.min_bass,
- info.data.tc1.min_bass_dB / 100,
- abs(info.data.tc1.min_bass_dB % 100),
- info.data.tc1.max_bass,
- info.data.tc1.max_bass_dB / 100,
- abs(info.data.tc1.max_bass_dB % 100));
- if (info.data.tc1.tc & SND_MIXER_TC1_TREBLE)
- printf("%sTreble control: Min %i (%i.%02idB), Max %i (%i.%02idB)\n",
- space,
- info.data.tc1.min_treble,
- info.data.tc1.min_treble_dB / 100,
- abs(info.data.tc1.min_treble_dB % 100),
- info.data.tc1.max_treble,
- info.data.tc1.max_treble_dB / 100,
- abs(info.data.tc1.max_treble_dB % 100));
- break;
- case SND_MIXER_ETYPE_3D_EFFECT1:
- if (info.data.teffect1.effect & SND_MIXER_EFF1_SW)
- printf("%sOn/Off switch\n", space);
- if (info.data.teffect1.effect & SND_MIXER_EFF1_MONO_SW)
- printf("%sMono processing switch\n", space);
- if (info.data.teffect1.effect & SND_MIXER_EFF1_WIDE)
- printf("%sWide: Min %i, Max %i\n", space,
- info.data.teffect1.min_wide,
- info.data.teffect1.max_wide);
- if (info.data.teffect1.effect & SND_MIXER_EFF1_VOLUME)
- printf("%sVolume: Min %i, Max %i\n", space,
- info.data.teffect1.min_volume,
- info.data.teffect1.max_volume);
- if (info.data.teffect1.effect & SND_MIXER_EFF1_CENTER)
- printf("%sCenter: Min %i, Max %i\n", space,
- info.data.teffect1.min_center,
- info.data.teffect1.max_center);
- if (info.data.teffect1.effect & SND_MIXER_EFF1_SPACE)
- printf("%sSpace: Min %i, Max %i\n", space,
- info.data.teffect1.min_space,
- info.data.teffect1.max_space);
- if (info.data.teffect1.effect & SND_MIXER_EFF1_DEPTH)
- printf("%sDepth: Min %i, Max %i\n", space,
- info.data.teffect1.min_depth,
- info.data.teffect1.max_depth);
- if (info.data.teffect1.effect & SND_MIXER_EFF1_DELAY)
- printf("%sDelay: Min %i, Max %i\n", space,
- info.data.teffect1.min_delay,
- info.data.teffect1.max_delay);
- if (info.data.teffect1.effect & SND_MIXER_EFF1_FEEDBACK)
- printf("%sFeedback: Min %i, Max %i\n", space,
- info.data.teffect1.min_feedback,
- info.data.teffect1.max_feedback);
- if (info.data.teffect1.effect & SND_MIXER_EFF1_DEPTH_REAR)
- printf("%sDepth rear: Min %i, Max %i\n", space,
- info.data.teffect1.min_depth_rear,
- info.data.teffect1.max_depth_rear);
- break;
- default:
- printf("%sInfo handler for type %i is not available\n", space, info.eid.type);
- }
- snd_mixer_element_info_free(&info);
- return 0;
-}
-
-int show_element_contents(void *handle, snd_mixer_eid_t *eid, const char *space)
-{
- int err, idx;
- snd_mixer_element_t element;
- snd_mixer_element_info_t info;
-
- if (snd_mixer_element_has_control(eid) != 1)
- return 0;
- bzero(&element, sizeof(element));
- bzero(&info, sizeof(info));
- element.eid = info.eid = *eid;
- if ((err = snd_mixer_element_build(handle, &element)) < 0) {
- error("Mixer %i/%i element error: %s", card, device, snd_strerror(err));
- return -1;
- }
- if (snd_mixer_element_has_info(eid) == 1) {
- if ((err = snd_mixer_element_info_build(handle, &info)) < 0) {
- error("Mixer %i/%i element error: %s", card, device, snd_strerror(err));
- return -1;
- }
- }
- switch (element.eid.type) {
- case SND_MIXER_ETYPE_SWITCH1:
- for (idx = 0; idx < element.data.switch1.sw; idx++) {
- int val = snd_mixer_get_bit(element.data.switch1.psw, idx);
- printf("%sChannel %i: Switch is %s\n", space, idx, val ? "ON" : "OFF");
- }
- break;
- case SND_MIXER_ETYPE_SWITCH2:
- printf("%sSwitch is %s\n", space, element.data.switch2.sw ? "ON" : "OFF");
- break;
- case SND_MIXER_ETYPE_SWITCH3:
- if (element.data.switch3.rsw != info.input_channels * info.output_channels) {
- error("Switch3 !!!\n");
- goto __end;
- }
- for (idx = 0; idx < element.data.switch3.rsw; idx++) {
- int val = snd_mixer_get_bit(element.data.switch3.prsw, idx);
- printf("%sInput <%i> Output <%i>: Switch is %s\n",
- space,
- idx / info.input_channels,
- idx % info.output_channels,
- val ? "ON" : "OFF");
- }
- break;
- case SND_MIXER_ETYPE_VOLUME1:
- for (idx = 0; idx < element.data.volume1.channels; idx++) {
- int val = element.data.volume1.pchannels[idx];
- printf("%sChannel %i: Value %s\n", space, idx,
- get_percent1(val, info.data.volume1.prange[idx].min,
- info.data.volume1.prange[idx].max,
- info.data.volume1.prange[idx].min_dB,
- info.data.volume1.prange[idx].max_dB));
- }
- break;
- case SND_MIXER_ETYPE_ACCU3:
- for (idx = 0; idx < element.data.accu3.channels; idx++) {
- int val = element.data.accu3.pchannels[idx];
- printf("%sChannel %i: Value %s\n", space, idx,
- get_percent1(val, info.data.accu3.prange[idx].min,
- info.data.accu3.prange[idx].max,
- info.data.accu3.prange[idx].min_dB,
- info.data.accu3.prange[idx].max_dB));
- }
- break;
- case SND_MIXER_ETYPE_MUX1:
- for (idx = 0; idx < element.data.mux1.sel; idx++) {
- snd_mixer_eid_t *eid = &element.data.mux1.psel[idx];
- printf("%sChannel %i: Element ", space, idx);
- if (eid->name[0] == '\0') {
- printf("NONE\n");
- } else {
- printf("'%s',%i,%i\n",
- element_name(eid->name),
- eid->index, eid->type);
- }
- }
- break;
- case SND_MIXER_ETYPE_MUX2:
- {
- printf("%sAll channels: Element ", space);
- if (element.data.mux2.sel.name[0] == '\0') {
- printf("NONE\n");
- } else {
- printf("'%s',%i,%i\n",
- element_name(element.data.mux2.sel.name),
- element.data.mux2.sel.index,
- element.data.mux2.sel.type);
- }
- }
- break;
- case SND_MIXER_ETYPE_TONE_CONTROL1:
- if (element.data.tc1.tc & SND_MIXER_TC1_SW)
- printf("%sOn/Off switch is %s\n", space, element.data.tc1.sw ? "ON" : "OFF");
- if (element.data.tc1.tc & SND_MIXER_TC1_BASS)
- printf("%sBass: %s\n", space, get_percent1(element.data.tc1.bass, info.data.tc1.min_bass, info.data.tc1.max_bass, info.data.tc1.min_bass_dB, info.data.tc1.max_bass_dB));
- if (element.data.tc1.tc & SND_MIXER_TC1_TREBLE)
- printf("%sTreble: %s\n", space, get_percent1(element.data.tc1.treble, info.data.tc1.min_treble, info.data.tc1.max_treble, info.data.tc1.min_treble_dB, info.data.tc1.max_treble_dB));
- break;
- case SND_MIXER_ETYPE_3D_EFFECT1:
- if (element.data.teffect1.effect & SND_MIXER_EFF1_SW)
- printf("%sOn/Off switch is %s\n", space, element.data.teffect1.sw ? "ON" : "OFF");
- if (element.data.teffect1.effect & SND_MIXER_EFF1_MONO_SW)
- printf("%sMono processing switch is %s\n", space, element.data.teffect1.mono_sw ? "ON" : "OFF");
- if (element.data.teffect1.effect & SND_MIXER_EFF1_WIDE)
- printf("%sWide: %s\n", space, get_percent(element.data.teffect1.wide, info.data.teffect1.min_wide, info.data.teffect1.max_wide));
- if (element.data.teffect1.effect & SND_MIXER_EFF1_VOLUME)
- printf("%sVolume: %s\n", space, get_percent(element.data.teffect1.volume, info.data.teffect1.min_volume, info.data.teffect1.max_volume));
- if (element.data.teffect1.effect & SND_MIXER_EFF1_CENTER)
- printf("%sCenter: %s\n", space, get_percent(element.data.teffect1.center, info.data.teffect1.min_center, info.data.teffect1.max_center));
- if (element.data.teffect1.effect & SND_MIXER_EFF1_SPACE)
- printf("%sSpace: %s\n", space, get_percent(element.data.teffect1.space, info.data.teffect1.min_space, info.data.teffect1.max_space));
- if (element.data.teffect1.effect & SND_MIXER_EFF1_DEPTH)
- printf("%sDepth: %s\n", space, get_percent(element.data.teffect1.depth, info.data.teffect1.min_depth, info.data.teffect1.max_depth));
- if (element.data.teffect1.effect & SND_MIXER_EFF1_DELAY)
- printf("%sDelay: %s\n", space, get_percent(element.data.teffect1.delay, info.data.teffect1.min_delay, info.data.teffect1.max_delay));
- if (element.data.teffect1.effect & SND_MIXER_EFF1_FEEDBACK)
- printf("%sFeedback: %s\n", space, get_percent(element.data.teffect1.feedback, info.data.teffect1.min_feedback, info.data.teffect1.max_feedback));
- if (element.data.teffect1.effect & SND_MIXER_EFF1_DEPTH_REAR)
- printf("%sDepth rear: %s\n", space, get_percent(element.data.teffect1.depth_rear, info.data.teffect1.min_depth_rear, info.data.teffect1.max_depth_rear));
- break;
- default:
- printf("%sRead handler for type %i is not available\n", space, element.eid.type);
- }
- __end:
- snd_mixer_element_free(&element);
- if (snd_mixer_element_has_info(eid))
- snd_mixer_element_info_free(&info);
- return 0;
-}
-
-int elements(void)
+int controls(void)
{
+#if 0
int err, idx;
snd_mixer_t *handle;
snd_mixer_elements_t elements;
}
free(elements.pelements);
snd_mixer_close(handle);
+#endif
return 0;
}
-int elements_contents(void)
+int controls_contents(void)
{
+#if 0
int err, idx;
snd_mixer_t *handle;
snd_mixer_elements_t elements;
}
free(elements.pelements);
snd_mixer_close(handle);
+#endif
return 0;
}
return res;
}
-int show_group(void *handle, snd_mixer_gid_t *gid, const char *space)
+int show_group(void *handle, snd_mixer_sid_t *sid, const char *space)
{
- int err, idx, chn;
- snd_mixer_group_t group;
- snd_mixer_eid_t *element;
+ int err, chn;
+ snd_mixer_simple_control_t scontrol;
- bzero(&group, sizeof(group));
- group.gid = *gid;
- if ((err = snd_mixer_group_read(handle, &group)) < 0) {
- error("Mixer %i/%i group error: %s", card, device, snd_strerror(err));
+ bzero(&scontrol, sizeof(scontrol));
+ scontrol.sid = *sid;
+ if ((err = snd_mixer_simple_control_read(handle, &scontrol)) < 0) {
+ error("Mixer %i simple_control error: %s", card, snd_strerror(err));
return -1;
}
- if (group_contents_is_on && group.channels) {
+ if (scontrol_contents_is_on && scontrol.channels) {
printf("%sCapabilities:", space);
- if (group.caps & SND_MIXER_GRPCAP_VOLUME)
+ if (scontrol.caps & SND_MIXER_SCTCAP_VOLUME)
printf(" volume");
- if (group.caps & SND_MIXER_GRPCAP_MUTE)
+ if (scontrol.caps & SND_MIXER_SCTCAP_MUTE)
printf(" mute");
- if (group.caps & SND_MIXER_GRPCAP_JOINTLY_MUTE)
+ if (scontrol.caps & SND_MIXER_SCTCAP_JOINTLY_MUTE)
printf(" jointly-mute");
- if (group.caps & SND_MIXER_GRPCAP_CAPTURE) {
+ if (scontrol.caps & SND_MIXER_SCTCAP_CAPTURE) {
printf(" capture");
} else {
- group.capture = 0;
+ scontrol.capture = 0;
}
- if (group.caps & SND_MIXER_GRPCAP_JOINTLY_CAPTURE)
+ if (scontrol.caps & SND_MIXER_SCTCAP_JOINTLY_CAPTURE)
printf(" jointly-capture");
- if (group.caps & SND_MIXER_GRPCAP_EXCL_CAPTURE)
+ if (scontrol.caps & SND_MIXER_SCTCAP_EXCL_CAPTURE)
printf(" exclusive-capture");
printf("\n");
- if ((group.caps & SND_MIXER_GRPCAP_CAPTURE) &&
- (group.caps & SND_MIXER_GRPCAP_EXCL_CAPTURE))
- printf("%sCapture exclusive group: %i\n", space, group.capture_group);
+ if ((scontrol.caps & SND_MIXER_SCTCAP_CAPTURE) &&
+ (scontrol.caps & SND_MIXER_SCTCAP_EXCL_CAPTURE))
+ printf("%sCapture exclusive scontrol: %i\n", space, scontrol.capture_group);
printf("%sChannels: ", space);
- if (group.channels == SND_MIXER_CHN_MASK_MONO) {
+ if (scontrol.channels == SND_MIXER_CHN_MASK_MONO) {
printf("Mono");
} else {
for (chn = 0; chn <= SND_MIXER_CHN_LAST; chn++) {
- if (!(group.channels & (1<<chn)))
+ if (!(scontrol.channels & (1<<chn)))
continue;
- printf("%s ", snd_mixer_channel_name(chn));
+ printf("%s ", snd_mixer_simple_channel_name(chn));
}
}
printf("\n");
- printf("%sLimits: min = %i, max = %i\n", space, group.min, group.max);
- if (group.channels == SND_MIXER_CHN_MASK_MONO) {
- printf("%sMono: %s [%s]\n", space, get_percent(group.volume.names.front_left, group.min, group.max), group.mute & SND_MIXER_CHN_MASK_MONO ? "mute" : "on");
+ printf("%sLimits: min = %i, max = %i\n", space, scontrol.min, scontrol.max);
+ if (scontrol.channels == SND_MIXER_CHN_MASK_MONO) {
+ printf("%sMono: %s [%s]\n", space, get_percent(scontrol.volume.names.front_left, scontrol.min, scontrol.max), scontrol.mute & SND_MIXER_CHN_MASK_MONO ? "mute" : "on");
} else {
for (chn = 0; chn <= SND_MIXER_CHN_LAST; chn++) {
- if (!(group.channels & (1<<chn)))
+ if (!(scontrol.channels & (1<<chn)))
continue;
printf("%s%s: %s [%s] [%s]\n",
space,
- snd_mixer_channel_name(chn),
- get_percent(group.volume.values[chn], group.min, group.max),
- group.mute & (1<<chn) ? "mute" : "on",
- group.capture & (1<<chn) ? "capture" : "---");
+ snd_mixer_simple_channel_name(chn),
+ get_percent(scontrol.volume.values[chn], scontrol.min, scontrol.max),
+ scontrol.mute & (1<<chn) ? "mute" : "on",
+ scontrol.capture & (1<<chn) ? "capture" : "---");
}
}
}
- if (group_contents_is_on)
+ if (scontrol_contents_is_on)
return 0;
- group.pelements = (snd_mixer_eid_t *)malloc(group.elements_over * sizeof(snd_mixer_eid_t));
- if (!group.pelements) {
- error("Not enough memory...");
- return -1;
- }
- group.elements_size = group.elements_over;
- group.elements = group.elements_over = 0;
- if ((err = snd_mixer_group_read(handle, &group)) < 0) {
- error("Mixer %i/%i group (2) error: %s", card, device, snd_strerror(err));
- return -1;
- }
- for (idx = 0; idx < group.elements; idx++) {
- element = &group.pelements[idx];
- printf("%sElement '%s',%i,%s\n", space, element_name(element->name), element->index, element_type(element->type));
- }
- free(group.pelements);
return 0;
}
-int groups(void)
+int scontrols(void)
{
+#if 0
int err, idx;
snd_mixer_t *handle;
- snd_mixer_groups_t groups;
- snd_mixer_gid_t *group;
+ snd_mixer_scontrols_t scontrols;
+ snd_mixer_sid_t *scontrol;
if ((err = snd_mixer_open(&handle, card, device)) < 0) {
error("Mixer %i/%i open error: %s", card, device, snd_strerror(err));
return -1;
}
- bzero(&groups, sizeof(groups));
- if ((err = snd_mixer_groups(handle, &groups)) < 0) {
- error("Mixer %i/%i groups error: %s", card, device, snd_strerror(err));
+ bzero(&scontrols, sizeof(scontrols));
+ if ((err = snd_mixer_scontrols(handle, &scontrols)) < 0) {
+ error("Mixer %i/%i scontrols error: %s", card, device, snd_strerror(err));
return -1;
}
- groups.pgroups = (snd_mixer_gid_t *)malloc(groups.groups_over * sizeof(snd_mixer_eid_t));
- if (!groups.pgroups) {
+ scontrols.pscontrols = (snd_mixer_sid_t *)malloc(scontrols.scontrols_over * sizeof(snd_mixer_eid_t));
+ if (!scontrols.pscontrols) {
error("Not enough memory");
return -1;
}
- groups.groups_size = groups.groups_over;
- groups.groups_over = groups.groups = 0;
- if ((err = snd_mixer_groups(handle, &groups)) < 0) {
- error("Mixer %i/%i groups (2) error: %s", card, device, snd_strerror(err));
+ scontrols.scontrols_size = scontrols.scontrols_over;
+ scontrols.scontrols_over = scontrols.scontrols = 0;
+ if ((err = snd_mixer_scontrols(handle, &scontrols)) < 0) {
+ error("Mixer %i/%i scontrols (2) error: %s", card, device, snd_strerror(err));
return -1;
}
- for (idx = 0; idx < groups.groups; idx++) {
- group = &groups.pgroups[idx];
- printf("Group '%s',%i\n", group_name(group->name), group->index);
- show_group(handle, group, " ");
+ for (idx = 0; idx < scontrols.scontrols; idx++) {
+ scontrol = &scontrols.pscontrols[idx];
+ printf("Group '%s',%i\n", scontrol_name(scontrol->name), scontrol->index);
+ show_scontrol(handle, scontrol, " ");
}
- free(groups.pgroups);
+ free(scontrols.pscontrols);
snd_mixer_close(handle);
+#endif
return 0;
}
-int groups_contents(void)
+int scontrols_contents(void)
{
+#if 0
int err;
- group_contents_is_on = 1;
- err = groups();
- group_contents_is_on = 0;
+ scontrol_contents_is_on = 1;
+ err = scontrols();
+ scontrol_contents_is_on = 0;
return err;
+#else
+ return 0;
+#endif
}
-static int parse_eid(const char *str, snd_mixer_eid_t *eid)
-{
- int c, size, idx;
- char *ptr;
-
- while (*str == ' ' || *str == '\t')
- str++;
- if (!(*str))
- return 1;
- bzero(eid, sizeof(*eid));
- if (!strncmp(str, "none", 4) || !strncmp(str, "NONE", 4))
- return 0;
- ptr = eid->name;
- size = 0;
- if (*str != '"' && *str != '\'') {
- while (*str && *str != ',') {
- if (size < sizeof(eid->name)) {
- *ptr++ = *str;
- size++;
- }
- str++;
- }
- } else {
- c = *str++;
- while (*str && *str != c) {
- if (size < sizeof(eid->name)) {
- *ptr++ = *str;
- size++;
- }
- str++;
- }
- if (*str == c)
- str++;
- }
- if (*str != ',')
- return 1;
- str++;
- if (!isdigit(*str))
- return 1;
- eid->index = atoi(str);
- while (isdigit(*str))
- str++;
- if (*str != ',')
- return 1;
- str++;
- if (isdigit(*str)) {
- eid->type = atoi(str);
- return 0;
- } else {
- for (idx = 0; mixer_types[idx].type >= 0; idx++)
- if (!strncmp(mixer_types[idx].name, str, strlen(mixer_types[idx].name))) {
- eid->type = mixer_types[idx].type;
- return 0;
- }
- }
- return 1;
-}
-
-static int parse_gid(const char *str, snd_mixer_gid_t *gid)
+static int parse_sid(const char *str, snd_mixer_sid_t *sid)
{
int c, size;
char *ptr;
str++;
if (!(*str))
return 1;
- bzero(gid, sizeof(*gid));
- ptr = gid->name;
+ bzero(sid, sizeof(*sid));
+ ptr = sid->name;
size = 0;
if (*str != '"' && *str != '\'') {
while (*str && *str != ',') {
- if (size < sizeof(gid->name)) {
+ if (size < sizeof(sid->name)) {
*ptr++ = *str;
size++;
}
} else {
c = *str++;
while (*str && *str != c) {
- if (size < sizeof(gid->name)) {
+ if (size < sizeof(sid->name)) {
*ptr++ = *str;
size++;
}
str++;
if (!isdigit(*str))
return 1;
- gid->index = atoi(str);
- return 0;
-}
-
-int eset_switch1(int argc, char *argv[], void *handle, snd_mixer_eid_t *eid)
-{
- int err, tmp, idx = 0;
- snd_mixer_element_t element;
- char *ptr;
-
- if (argc != 1) {
- fprintf(stderr, "The set Switch1 command requires an argument:\n");
- fprintf(stderr, " on/off[,on/off] ...\n");
- return 1;
- }
- bzero(&element, sizeof(element));
- element.eid = *eid;
- if ((err = snd_mixer_element_build(handle, &element)) < 0) {
- error("Mixer element build error: %s", snd_strerror(err));
- return 1;
- }
- if (!strcmp(argv[0], "on") || !strcmp(argv[0], "off")) {
- tmp = !strcmp(argv[0], "on");
- for (idx = 0; idx < element.data.switch1.sw; idx++)
- snd_mixer_set_bit(element.data.switch1.psw, idx, tmp);
- } else {
- ptr = argv[idx];
- for (idx = 0; idx < element.data.switch1.sw; idx++) {
- tmp = !strncmp(ptr, "on", 2);
- snd_mixer_set_bit(element.data.switch1.psw, idx, tmp);
- while (*ptr && *ptr != ',')
- ptr++;
- if (*ptr == ',')
- ptr++;
- }
- }
- if ((err = snd_mixer_element_write(handle, &element)) < 0) {
- error("Mixer element write error: %s\n", snd_strerror(err));
- snd_mixer_element_free(&element);
- return 1;
- }
- snd_mixer_element_free(&element);
- return 0;
-}
-
-int eset_switch2(int argc, char *argv[], void *handle, snd_mixer_eid_t *eid)
-{
- int err;
- snd_mixer_element_t element;
-
- if (argc != 1) {
- fprintf(stderr, "The set Switch2 command requires an argument:\n");
- fprintf(stderr, " on/off\n");
- return 1;
- }
- bzero(&element, sizeof(element));
- element.eid = *eid;
- if ((err = snd_mixer_element_build(handle, &element)) < 0) {
- error("Mixer element build error: %s", snd_strerror(err));
- return 1;
- }
- element.data.switch2.sw = !strcmp(argv[0], "on") ? 1 : 0;
- if ((err = snd_mixer_element_write(handle, &element)) < 0) {
- error("Mixer element write error: %s\n", snd_strerror(err));
- snd_mixer_element_free(&element);
- return 1;
- }
- snd_mixer_element_free(&element);
+ sid->index = atoi(str);
return 0;
}
-int eset_volume1(int argc, char *argv[], void *handle, snd_mixer_eid_t *eid)
-{
- int err, tmp, idx = 0;
- snd_mixer_element_t element;
- snd_mixer_element_info_t info;
- char *ptr;
-
- if (argc != 1 || (!isdigit(*argv[0]) && *argv[0] != ':')) {
- fprintf(stderr, "The set Volume1 command requires an argument:\n");
- fprintf(stderr, " vol[,vol] ...\n");
- return 1;
- }
- bzero(&info, sizeof(info));
- info.eid = *eid;
- if ((err = snd_mixer_element_info_build(handle, &info)) < 0) {
- error("Mixer element read error: %s", snd_strerror(err));
- return 1;
- }
- bzero(&element, sizeof(element));
- element.eid = *eid;
- if ((err = snd_mixer_element_build(handle, &element)) < 0) {
- error("Mixer element read error: %s", snd_strerror(err));
- snd_mixer_element_info_free(&info);
- return 1;
- }
- if (!strchr(argv[0], ',')) {
- for (idx = 0; idx < element.data.volume1.channels; idx++) {
- ptr = argv[0];
- tmp = get_volume(&ptr,
- info.data.volume1.prange[idx].min,
- info.data.volume1.prange[idx].max,
- info.data.volume1.prange[idx].min_dB,
- info.data.volume1.prange[idx].max_dB);
- element.data.volume1.pchannels[idx] = tmp;
- }
- } else {
- ptr = argv[idx];
- for (idx = 0; idx < element.data.volume1.channels; idx++) {
- tmp = get_volume(&ptr,
- info.data.volume1.prange[idx].min,
- info.data.volume1.prange[idx].max,
- info.data.volume1.prange[idx].min_dB,
- info.data.volume1.prange[idx].max_dB);
- element.data.volume1.pchannels[idx] = tmp;
- }
- }
- if ((err = snd_mixer_element_write(handle, &element)) < 0) {
- error("Mixer element write error: %s\n", snd_strerror(err));
- snd_mixer_element_free(&element);
- snd_mixer_element_info_free(&info);
- return 1;
- }
- snd_mixer_element_free(&element);
- snd_mixer_element_info_free(&info);
- return 0;
-}
-
-int eset_accu3(int argc, char *argv[], void *handle, snd_mixer_eid_t *eid)
-{
- int err, tmp, idx = 0;
- snd_mixer_element_t element;
- snd_mixer_element_info_t info;
- char *ptr;
-
- if (argc != 1 || (!isdigit(*argv[0]) && *argv[0] != ':')) {
- fprintf(stderr, "The set Accu3 command requires an argument:\n");
- fprintf(stderr, " vol[,vol] ...\n");
- return 1;
- }
- bzero(&info, sizeof(info));
- info.eid = *eid;
- if ((err = snd_mixer_element_info_build(handle, &info)) < 0) {
- error("Mixer element read error: %s", snd_strerror(err));
- return 1;
- }
- bzero(&element, sizeof(element));
- element.eid = *eid;
- if ((err = snd_mixer_element_build(handle, &element)) < 0) {
- error("Mixer element read error: %s", snd_strerror(err));
- snd_mixer_element_info_free(&info);
- return 1;
- }
- if (!strchr(argv[0], ',')) {
- for (idx = 0; idx < element.data.accu3.channels; idx++) {
- ptr = argv[0];
- tmp = get_volume(&ptr,
- info.data.accu3.prange[idx].min,
- info.data.accu3.prange[idx].max,
- info.data.accu3.prange[idx].min_dB,
- info.data.accu3.prange[idx].max_dB);
- element.data.accu3.pchannels[idx] = tmp;
- }
- } else {
- ptr = argv[idx];
- for (idx = 0; idx < element.data.volume1.channels; idx++) {
- tmp = get_volume(&ptr,
- info.data.accu3.prange[idx].min,
- info.data.accu3.prange[idx].max,
- info.data.accu3.prange[idx].min_dB,
- info.data.accu3.prange[idx].max_dB);
- element.data.accu3.pchannels[idx] = tmp;
- }
- }
- if ((err = snd_mixer_element_write(handle, &element)) < 0) {
- error("Mixer element write error: %s\n", snd_strerror(err));
- snd_mixer_element_free(&element);
- snd_mixer_element_info_free(&info);
- return 1;
- }
- snd_mixer_element_free(&element);
- snd_mixer_element_info_free(&info);
- return 0;
-}
-
-int eset_mux1(int argc, char *argv[], void *handle, snd_mixer_eid_t *eid)
-{
- int err, idx = 0;
- snd_mixer_element_t element;
- snd_mixer_element_info_t info;
- snd_mixer_eid_t xeid;
-
- if (argc < 1) {
- fprintf(stderr, "The set Mux1 command requires an argument:\n");
- fprintf(stderr, " element[ element] ...\n");
- return 1;
- }
- bzero(&info, sizeof(info));
- info.eid = *eid;
- if ((err = snd_mixer_element_info_build(handle, &info)) < 0) {
- error("Mixer element read error: %s", snd_strerror(err));
- return 1;
- }
- bzero(&element, sizeof(element));
- element.eid = *eid;
- if ((err = snd_mixer_element_build(handle, &element)) < 0) {
- error("Mixer element read error: %s", snd_strerror(err));
- snd_mixer_element_info_free(&info);
- return 1;
- }
- if (argc == 1) {
- if (parse_eid(argv[0], &xeid)) {
- fprintf(stderr, "Wrong element identifier: %s\n", argv[0]);
- snd_mixer_element_free(&element);
- snd_mixer_element_info_free(&info);
- return 1;
- }
- for (idx = 0; idx < element.data.mux1.sel; idx++)
- element.data.mux1.psel[idx] = xeid;
- } else {
- for (idx = 0; idx < element.data.volume1.channels; idx++) {
- if (parse_eid(argv[idx >= argc ? argc - 1 : idx], &xeid)) {
- fprintf(stderr, "Wrong element identifier: %s\n", argv[0]);
- snd_mixer_element_free(&element);
- snd_mixer_element_info_free(&info);
- return 1;
- }
- element.data.mux1.psel[idx] = xeid;
- }
- }
- if ((err = snd_mixer_element_write(handle, &element)) < 0) {
- error("Mixer element write error: %s\n", snd_strerror(err));
- snd_mixer_element_free(&element);
- snd_mixer_element_info_free(&info);
- return 1;
- }
- snd_mixer_element_free(&element);
- snd_mixer_element_info_free(&info);
- return 0;
-}
-
-int eset_mux2(int argc, char *argv[], void *handle, snd_mixer_eid_t *eid)
-{
- int err;
- snd_mixer_element_t element;
- snd_mixer_element_info_t info;
- snd_mixer_eid_t xeid;
-
- if (argc != 1) {
- fprintf(stderr, "The set Mux2 command requires an argument:\n");
- fprintf(stderr, " element\n");
- return 1;
- }
- bzero(&info, sizeof(info));
- info.eid = *eid;
- if ((err = snd_mixer_element_info_build(handle, &info)) < 0) {
- error("Mixer element read error: %s", snd_strerror(err));
- return 1;
- }
- bzero(&element, sizeof(element));
- element.eid = *eid;
- if ((err = snd_mixer_element_build(handle, &element)) < 0) {
- error("Mixer element read error: %s", snd_strerror(err));
- snd_mixer_element_info_free(&info);
- return 1;
- }
- if (parse_eid(argv[0], &xeid)) {
- fprintf(stderr, "Wrong element identifier: %s\n", argv[0]);
- snd_mixer_element_free(&element);
- snd_mixer_element_info_free(&info);
- return 1;
- }
- element.data.mux2.sel = xeid;
- if ((err = snd_mixer_element_write(handle, &element)) < 0) {
- error("Mixer element write error: %s\n", snd_strerror(err));
- snd_mixer_element_free(&element);
- snd_mixer_element_info_free(&info);
- return 1;
- }
- snd_mixer_element_free(&element);
- snd_mixer_element_info_free(&info);
- return 0;
-}
-
-int eset(int argc, char *argv[])
+int cset(int argc, char *argv[])
{
+#if 0
int err;
snd_mixer_t *handle;
snd_mixer_eid_t eid;
}
__end:
snd_mixer_close(handle);
+#endif
return 0;
}
-int eget(int argc, char *argv[])
+int cget(int argc, char *argv[])
{
+#if 0
int err;
snd_mixer_t *handle;
snd_mixer_eid_t eid;
}
}
snd_mixer_close(handle);
+#endif
return 0;
}
+#if 0
+
typedef struct channel_mask {
char *name;
unsigned int mask;
return 0;
}
-int gset(int argc, char *argv[])
+#endif
+
+int sset(int argc, char *argv[])
{
+#if 0
int err, idx, chn;
unsigned int channels;
snd_mixer_t *handle;
- snd_mixer_gid_t gid;
- snd_mixer_group_t group;
+ snd_mixer_sid_t sid;
+ snd_mixer_scontrol_t scontrol;
if (argc < 1) {
- fprintf(stderr, "Specify a group identifier: 'name',index\n");
+ fprintf(stderr, "Specify a scontrol identifier: 'name',index\n");
return 1;
}
- if (parse_gid(argv[0], &gid)) {
- fprintf(stderr, "Wrong group identifier: %s\n", argv[0]);
+ if (parse_sid(argv[0], &sid)) {
+ fprintf(stderr, "Wrong scontrol identifier: %s\n", argv[0]);
return 1;
}
if (argc < 2) {
error("Mixer %i/%i open error: %s\n", card, device, snd_strerror(err));
return -1;
}
- bzero(&group, sizeof(group));
- group.gid = gid;
- if (snd_mixer_group_read(handle, &group)<0) {
- error("Unable to read group '%s',%i: %s\n", group_name(gid.name), gid.index, snd_strerror(err));
+ bzero(&scontrol, sizeof(scontrol));
+ scontrol.sid = sid;
+ if (snd_mixer_scontrol_read(handle, &scontrol)<0) {
+ error("Unable to read scontrol '%s',%i: %s\n", scontrol_name(sid.name), sid.index, snd_strerror(err));
snd_mixer_close(handle);
return -1;
}
- channels = group.channels; /* all channels */
+ channels = scontrol.channels; /* all channels */
for (idx = 1; idx < argc; idx++) {
if (!strncmp(argv[idx], "mute", 4) ||
!strncmp(argv[idx], "off", 3)) {
- group.mute = group.channels;
+ scontrol.mute = scontrol.channels;
continue;
} else if (!strncmp(argv[idx], "unmute", 6) ||
!strncmp(argv[idx], "on", 2)) {
- group.mute = 0;
+ scontrol.mute = 0;
continue;
} else if (!strncmp(argv[idx], "cap", 3) ||
!strncmp(argv[idx], "rec", 3)) {
- group.capture = group.channels;
+ scontrol.capture = scontrol.channels;
continue;
} else if (!strncmp(argv[idx], "nocap", 5) ||
!strncmp(argv[idx], "norec", 5)) {
- group.capture = 0;
+ scontrol.capture = 0;
continue;
}
- if (check_channels(argv[idx], group.channels, &channels))
+ if (check_channels(argv[idx], scontrol.channels, &channels))
continue;
if (isdigit(argv[idx][0]) ||
argv[idx][0] == '+' ||
multi = (strchr(argv[idx], ',') != NULL);
ptr = argv[idx];
for (chn = 0; chn <= SND_MIXER_CHN_LAST; chn++) {
- if (!(group.channels & (1<<chn)) ||
+ if (!(scontrol.channels & (1<<chn)) ||
!(channels & (1<<chn)))
continue;
if (! multi)
ptr = argv[idx];
- group.volume.values[chn] = get_volume_simple(&ptr, group.min, group.max, group.volume.values[chn]);
+ scontrol.volume.values[chn] = get_volume_simple(&ptr, scontrol.min, scontrol.max, scontrol.volume.values[chn]);
}
} else {
error("Unknown setup '%s'..\n", argv[idx]);
return -1;
}
}
- if (snd_mixer_group_write(handle, &group)<0) {
- error("Unable to write group '%s',%i: %s\n", group_name(gid.name), gid.index, snd_strerror(err));
+ if (snd_mixer_scontrol_write(handle, &scontrol)<0) {
+ error("Unable to write scontrol '%s',%i: %s\n", scontrol_name(sid.name), sid.index, snd_strerror(err));
snd_mixer_close(handle);
return -1;
}
if (!quiet) {
- printf("Group '%s',%i\n", group_name(gid.name), gid.index);
- group_contents_is_on = 1;
- show_group(handle, &gid, " ");
- group_contents_is_on = 0;
+ printf("Group '%s',%i\n", scontrol_name(sid.name), sid.index);
+ scontrol_contents_is_on = 1;
+ show_scontrol(handle, &sid, " ");
+ scontrol_contents_is_on = 0;
}
snd_mixer_close(handle);
+#endif
return 0;
}
-int gget(int argc, char *argv[])
+int sget(int argc, char *argv[])
{
+#if 0
int err;
snd_mixer_t *handle;
- snd_mixer_gid_t gid;
+ snd_mixer_sid_t sid;
if (argc < 1) {
- fprintf(stderr, "Specify a group identifier: 'name',index\n");
+ fprintf(stderr, "Specify a scontrol identifier: 'name',index\n");
return 1;
}
- if (parse_gid(argv[0], &gid)) {
- fprintf(stderr, "Wrong group identifier: %s\n", argv[0]);
+ if (parse_sid(argv[0], &sid)) {
+ fprintf(stderr, "Wrong scontrol identifier: %s\n", argv[0]);
return 1;
}
if ((err = snd_mixer_open(&handle, card, device)) < 0) {
return -1;
}
if (!quiet) {
- printf("Group '%s',%i\n", group_name(gid.name), gid.index);
- group_contents_is_on = 1;
- show_group(handle, &gid, " ");
- group_contents_is_on = 0;
+ printf("Group '%s',%i\n", scontrol_name(sid.name), sid.index);
+ scontrol_contents_is_on = 1;
+ show_scontrol(handle, &sid, " ");
+ scontrol_contents_is_on = 0;
}
snd_mixer_close(handle);
+#endif
return 0;
}
{
{"help", 0, NULL, HELPID_HELP},
{"card", 1, NULL, HELPID_CARD},
- {"device", 1, NULL, HELPID_DEVICE},
{"quiet", 0, NULL, HELPID_QUIET},
{"debug", 0, NULL, HELPID_DEBUG},
{"version", 0, NULL, HELPID_VERSION},
morehelp = 0;
card = snd_defaults_mixer_card();
- device = snd_defaults_mixer_device();
- if (card < 0 || device < 0) {
+ if (card < 0) {
fprintf(stderr, "The ALSA sound driver was not detected in this system.\n");
return 1;
}
while (1) {
int c;
- if ((c = getopt_long(argc, argv, "hc:d:qDv", long_option, NULL)) < 0)
+ if ((c = getopt_long(argc, argv, "hc:qDv", long_option, NULL)) < 0)
break;
switch (c) {
case 'h':
case HELPID_CARD:
card = snd_card_name(optarg);
break;
- case 'd':
- case HELPID_DEVICE:
- device = atoi(optarg);
- if (device < 0 || device > 32) {
- fprintf(stderr, "Error: device %i is invalid\n", device);
- return 1;
- }
- break;
case 'q':
case HELPID_QUIET:
quiet = 1;
return 1;
}
if (argc - optind <= 0) {
- return groups_contents() ? 1 : 0;
+ return scontrols_contents() ? 1 : 0;
}
if (!strcmp(argv[optind], "info")) {
return info() ? 1 : 0;
- } else if (!strcmp(argv[optind], "elements")) {
- return elements() ? 1 : 0;
+ } else if (!strcmp(argv[optind], "controls")) {
+ return controls() ? 1 : 0;
} else if (!strcmp(argv[optind], "contents")) {
- return elements_contents() ? 1 : 0;
- } else if (!strcmp(argv[optind], "groups")) {
- return groups() ? 1 : 0;
- } else if (!strcmp(argv[optind], "gcontents")) {
- return groups_contents() ? 1 : 0;
- } else if (!strcmp(argv[optind], "set")) {
- return gset(argc - optind - 1, argc - optind > 1 ? argv + optind + 1 : NULL) ? 1 : 0;
- } else if (!strcmp(argv[optind], "get")) {
- return gget(argc - optind - 1, argc - optind > 1 ? argv + optind + 1 : NULL) ? 1 : 0;
- } else if (!strcmp(argv[optind], "eset")) {
- return eset(argc - optind - 1, argc - optind > 1 ? argv + optind + 1 : NULL) ? 1 : 0;
- } else if (!strcmp(argv[optind], "eget")) {
- return eget(argc - optind - 1, argc - optind > 1 ? argv + optind + 1 : NULL) ? 1 : 0;
+ return controls_contents() ? 1 : 0;
+ } else if (!strcmp(argv[optind], "simple")) {
+ return scontrols() ? 1 : 0;
+ } else if (!strcmp(argv[optind], "scontents")) {
+ return scontrols_contents() ? 1 : 0;
+ } else if (!strcmp(argv[optind], "sset")) {
+ return sset(argc - optind - 1, argc - optind > 1 ? argv + optind + 1 : NULL) ? 1 : 0;
+ } else if (!strcmp(argv[optind], "sget")) {
+ return sget(argc - optind - 1, argc - optind > 1 ? argv + optind + 1 : NULL) ? 1 : 0;
+ } else if (!strcmp(argv[optind], "cset")) {
+ return cset(argc - optind - 1, argc - optind > 1 ? argv + optind + 1 : NULL) ? 1 : 0;
+ } else if (!strcmp(argv[optind], "cget")) {
+ return cget(argc - optind - 1, argc - optind > 1 ? argv + optind + 1 : NULL) ? 1 : 0;
} else {
fprintf(stderr, "amixer: Unknown command '%s'...\n", argv[optind]);
}