mirror of
https://github.com/alsa-project/alsa-utils
synced 2024-11-14 04:55:41 +01:00
New universal switch v2.0 interface.
This commit is contained in:
parent
9b9ccc77e2
commit
daab0cd6d0
3 changed files with 270 additions and 327 deletions
|
@ -22,6 +22,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <sys/asoundlib.h>
|
#include <sys/asoundlib.h>
|
||||||
|
|
||||||
#define ALSACTL_FILE "/etc/asound.conf"
|
#define ALSACTL_FILE "/etc/asound.conf"
|
||||||
|
@ -37,9 +38,8 @@ extern int debugflag;
|
||||||
extern void error(const char *fmt,...);
|
extern void error(const char *fmt,...);
|
||||||
|
|
||||||
struct ctl_switch {
|
struct ctl_switch {
|
||||||
int no;
|
|
||||||
int change;
|
int change;
|
||||||
snd_ctl_switch_t s;
|
snd_switch_t s;
|
||||||
struct ctl_switch *next;
|
struct ctl_switch *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -59,48 +59,27 @@ struct mixer_channel {
|
||||||
struct mixer_channel *next;
|
struct mixer_channel *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mixer_switch {
|
|
||||||
int no;
|
|
||||||
int change;
|
|
||||||
snd_mixer_switch_t s;
|
|
||||||
struct mixer_switch *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct mixer {
|
struct mixer {
|
||||||
int no;
|
int no;
|
||||||
snd_mixer_info_t info;
|
snd_mixer_info_t info;
|
||||||
struct mixer_channel *channels;
|
struct mixer_channel *channels;
|
||||||
struct mixer_switch *switches;
|
struct ctl_switch *switches;
|
||||||
struct mixer *next;
|
struct mixer *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pcm_switch {
|
|
||||||
int no;
|
|
||||||
int change;
|
|
||||||
snd_pcm_switch_t s;
|
|
||||||
struct pcm_switch *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct pcm {
|
struct pcm {
|
||||||
int no;
|
int no;
|
||||||
snd_pcm_info_t info;
|
snd_pcm_info_t info;
|
||||||
struct pcm_switch *pswitches;
|
struct ctl_switch *pswitches;
|
||||||
struct pcm_switch *rswitches;
|
struct ctl_switch *rswitches;
|
||||||
struct pcm *next;
|
struct pcm *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rawmidi_switch {
|
|
||||||
int no;
|
|
||||||
int change;
|
|
||||||
snd_rawmidi_switch_t s;
|
|
||||||
struct rawmidi_switch *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct rawmidi {
|
struct rawmidi {
|
||||||
int no;
|
int no;
|
||||||
snd_rawmidi_info_t info;
|
snd_rawmidi_info_t info;
|
||||||
struct rawmidi_switch *iswitches;
|
struct ctl_switch *iswitches;
|
||||||
struct rawmidi_switch *oswitches;
|
struct ctl_switch *oswitches;
|
||||||
struct rawmidi *next;
|
struct rawmidi *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,6 @@ static void set_mixer_volume(int volume);
|
||||||
static void set_mixer_flags(int flags);
|
static void set_mixer_flags(int flags);
|
||||||
static void select_mixer_channel_end(void);
|
static void select_mixer_channel_end(void);
|
||||||
|
|
||||||
|
|
||||||
#define SWITCH_CONTROL 0
|
#define SWITCH_CONTROL 0
|
||||||
#define SWITCH_MIXER 1
|
#define SWITCH_MIXER 1
|
||||||
#define SWITCH_PCM 2
|
#define SWITCH_PCM 2
|
||||||
|
@ -75,7 +74,7 @@ static struct rawmidi *Xrawmidi = NULL;
|
||||||
static struct mixer_channel *Xchannel = NULL;
|
static struct mixer_channel *Xchannel = NULL;
|
||||||
static int Xswitchtype = SWITCH_CONTROL;
|
static int Xswitchtype = SWITCH_CONTROL;
|
||||||
static int *Xswitchchange = NULL;
|
static int *Xswitchchange = NULL;
|
||||||
static void *Xswitch = NULL;
|
static snd_switch_t *Xswitch = NULL;
|
||||||
static unsigned int Xswitchiec958ocs = 0;
|
static unsigned int Xswitchiec958ocs = 0;
|
||||||
static unsigned short Xswitchiec958ocs1[16];
|
static unsigned short Xswitchiec958ocs1[16];
|
||||||
|
|
||||||
|
@ -433,63 +432,64 @@ static void select_mixer_channel_end(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FIND_SWITCH( xtype, first, name, err ) \
|
static void find_switch(int xtype, struct ctl_switch *first, char *name, char *err)
|
||||||
if ( !name ) { Xswitch = Xswitchchange = NULL; return; } \
|
{
|
||||||
for ( sw = first; sw; sw = sw -> next ) { \
|
struct ctl_switch *sw;
|
||||||
if ( !strcmp( sw -> s.name, name ) ) { \
|
|
||||||
Xswitchtype = xtype; \
|
if (!name) {
|
||||||
Xswitchchange = &sw -> change; \
|
Xswitch = NULL;
|
||||||
Xswitch = (void *)&sw -> s; \
|
Xswitchchange = NULL;
|
||||||
free( name ); \
|
return;
|
||||||
return; \
|
}
|
||||||
} \
|
for (sw = first; sw; sw = sw->next) {
|
||||||
} \
|
if (!strcmp(sw -> s.name, name)) {
|
||||||
yyerror( "Cannot find " err " switch '%s'...", name ); \
|
Xswitchtype = xtype;
|
||||||
free( name );
|
Xswitchchange = &sw->change;
|
||||||
|
Xswitch = &sw->s;
|
||||||
|
free(name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
yyerror("Cannot find %s switch '%s'...", err, name);
|
||||||
|
free(name);
|
||||||
|
}
|
||||||
|
|
||||||
static void select_control_switch(char *name)
|
static void select_control_switch(char *name)
|
||||||
{
|
{
|
||||||
struct ctl_switch *sw;
|
find_switch(SWITCH_CONTROL, Xsoundcard->control.switches, name, "control");
|
||||||
FIND_SWITCH(SWITCH_CONTROL, Xsoundcard->control.switches, name, "control");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void select_mixer_switch(char *name)
|
static void select_mixer_switch(char *name)
|
||||||
{
|
{
|
||||||
struct mixer_switch *sw;
|
find_switch(SWITCH_MIXER, Xmixer->switches, name, "mixer");
|
||||||
FIND_SWITCH(SWITCH_MIXER, Xmixer->switches, name, "mixer");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void select_pcm_playback_switch(char *name)
|
static void select_pcm_playback_switch(char *name)
|
||||||
{
|
{
|
||||||
struct pcm_switch *sw;
|
find_switch(SWITCH_PCM, Xpcm->pswitches, name, "pcm playback");
|
||||||
FIND_SWITCH(SWITCH_PCM, Xpcm->pswitches, name, "pcm playback");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void select_pcm_record_switch(char *name)
|
static void select_pcm_record_switch(char *name)
|
||||||
{
|
{
|
||||||
struct pcm_switch *sw;
|
find_switch(SWITCH_PCM, Xpcm->rswitches, name, "pcm record");
|
||||||
FIND_SWITCH(SWITCH_PCM, Xpcm->rswitches, name, "pcm record");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void select_rawmidi_output_switch(char *name)
|
static void select_rawmidi_output_switch(char *name)
|
||||||
{
|
{
|
||||||
struct rawmidi_switch *sw;
|
find_switch(SWITCH_RAWMIDI, Xrawmidi->oswitches, name, "rawmidi output");
|
||||||
FIND_SWITCH(SWITCH_RAWMIDI, Xrawmidi->oswitches, name, "rawmidi output");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void select_rawmidi_input_switch(char *name)
|
static void select_rawmidi_input_switch(char *name)
|
||||||
{
|
{
|
||||||
struct rawmidi_switch *sw;
|
find_switch(SWITCH_RAWMIDI, Xrawmidi->iswitches, name, "rawmidi input");
|
||||||
FIND_SWITCH(SWITCH_RAWMIDI, Xrawmidi->iswitches, name, "rawmidi input");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_switch_boolean(int val)
|
static void set_switch_boolean(int val)
|
||||||
{
|
{
|
||||||
/* ok.. this is a little bit wrong, but at these times are all switches same */
|
snd_switch_t *sw = Xswitch;
|
||||||
snd_ctl_switch_t *sw = (snd_ctl_switch_t *) Xswitch;
|
|
||||||
unsigned int xx;
|
unsigned int xx;
|
||||||
|
|
||||||
if (sw->type != SND_CTL_SW_TYPE_BOOLEAN)
|
if (sw->type != SND_SW_TYPE_BOOLEAN)
|
||||||
yyerror("Switch '%s' isn't boolean type...", sw->name);
|
yyerror("Switch '%s' isn't boolean type...", sw->name);
|
||||||
xx = val ? 1 : 0;
|
xx = val ? 1 : 0;
|
||||||
if (sw->value.enable != xx)
|
if (sw->value.enable != xx)
|
||||||
|
@ -502,13 +502,12 @@ static void set_switch_boolean(int val)
|
||||||
|
|
||||||
static void set_switch_integer(int val)
|
static void set_switch_integer(int val)
|
||||||
{
|
{
|
||||||
/* ok.. this is a little bit wrong, but at these times are all switches same */
|
snd_switch_t *sw = Xswitch;
|
||||||
snd_ctl_switch_t *sw = (snd_ctl_switch_t *) Xswitch;
|
|
||||||
unsigned int xx;
|
unsigned int xx;
|
||||||
|
|
||||||
if (sw->type != SND_CTL_SW_TYPE_BYTE &&
|
if (sw->type != SND_SW_TYPE_BYTE &&
|
||||||
sw->type != SND_CTL_SW_TYPE_WORD &&
|
sw->type != SND_SW_TYPE_WORD &&
|
||||||
sw->type != SND_CTL_SW_TYPE_DWORD)
|
sw->type != SND_SW_TYPE_DWORD)
|
||||||
yyerror("Switch '%s' isn't integer type...", sw->name);
|
yyerror("Switch '%s' isn't integer type...", sw->name);
|
||||||
if (val < sw->low || val > sw->high)
|
if (val < sw->low || val > sw->high)
|
||||||
yyerror("Value for switch '%s' out of range (%i-%i)...\n", sw->name, sw->low, sw->high);
|
yyerror("Value for switch '%s' out of range (%i-%i)...\n", sw->name, sw->low, sw->high);
|
||||||
|
@ -520,8 +519,7 @@ static void set_switch_integer(int val)
|
||||||
|
|
||||||
static void set_switch_iec958ocs_begin(int end)
|
static void set_switch_iec958ocs_begin(int end)
|
||||||
{
|
{
|
||||||
/* ok.. this is a little bit wrong, but at these times are all switches same */
|
snd_switch_t *sw = Xswitch;
|
||||||
snd_ctl_switch_t *sw = (snd_ctl_switch_t *) Xswitch;
|
|
||||||
|
|
||||||
if (end) {
|
if (end) {
|
||||||
if (Xswitchiec958ocs != sw->value.enable) {
|
if (Xswitchiec958ocs != sw->value.enable) {
|
||||||
|
@ -544,7 +542,7 @@ static void set_switch_iec958ocs_begin(int end)
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Xswitchtype != SWITCH_MIXER || sw->type != SND_MIXER_SW_TYPE_BOOLEAN ||
|
if (Xswitchtype != SWITCH_MIXER || sw->type != SND_SW_TYPE_BOOLEAN ||
|
||||||
strcmp(sw->name, SND_MIXER_SW_IEC958OUT))
|
strcmp(sw->name, SND_MIXER_SW_IEC958OUT))
|
||||||
yyerror("Switch '%s' cannot store IEC958 information for Cirrus Logic chips...", sw->name);
|
yyerror("Switch '%s' cannot store IEC958 information for Cirrus Logic chips...", sw->name);
|
||||||
if (sw->value.data32[1] != (('C' << 8) | 'S'))
|
if (sw->value.data32[1] != (('C' << 8) | 'S'))
|
||||||
|
|
488
alsactl/setup.c
488
alsactl/setup.c
|
@ -58,23 +58,12 @@ static void soundcard_mixer_channel_free(struct mixer_channel *first)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void soundcard_mixer_switch_free(struct mixer_switch *first)
|
|
||||||
{
|
|
||||||
struct mixer_switch *next;
|
|
||||||
|
|
||||||
while (first) {
|
|
||||||
next = first->next;
|
|
||||||
free(first);
|
|
||||||
first = next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void soundcard_mixer_free1(struct mixer *mixer)
|
static void soundcard_mixer_free1(struct mixer *mixer)
|
||||||
{
|
{
|
||||||
if (!mixer)
|
if (!mixer)
|
||||||
return;
|
return;
|
||||||
soundcard_mixer_channel_free(mixer->channels);
|
soundcard_mixer_channel_free(mixer->channels);
|
||||||
soundcard_mixer_switch_free(mixer->switches);
|
soundcard_ctl_switch_free(mixer->switches);
|
||||||
free(mixer);
|
free(mixer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,23 +78,12 @@ static void soundcard_mixer_free(struct mixer *first)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void soundcard_pcm_switch_free(struct pcm_switch *first)
|
|
||||||
{
|
|
||||||
struct pcm_switch *next;
|
|
||||||
|
|
||||||
while (first) {
|
|
||||||
next = first->next;
|
|
||||||
free(first);
|
|
||||||
first = next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void soundcard_pcm_free1(struct pcm *pcm)
|
static void soundcard_pcm_free1(struct pcm *pcm)
|
||||||
{
|
{
|
||||||
if (!pcm)
|
if (!pcm)
|
||||||
return;
|
return;
|
||||||
soundcard_pcm_switch_free(pcm->pswitches);
|
soundcard_ctl_switch_free(pcm->pswitches);
|
||||||
soundcard_pcm_switch_free(pcm->rswitches);
|
soundcard_ctl_switch_free(pcm->rswitches);
|
||||||
free(pcm);
|
free(pcm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,23 +98,12 @@ static void soundcard_pcm_free(struct pcm *first)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void soundcard_rawmidi_switch_free(struct rawmidi_switch *first)
|
|
||||||
{
|
|
||||||
struct rawmidi_switch *next;
|
|
||||||
|
|
||||||
while (first) {
|
|
||||||
next = first->next;
|
|
||||||
free(first);
|
|
||||||
first = next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void soundcard_rawmidi_free1(struct rawmidi *rawmidi)
|
static void soundcard_rawmidi_free1(struct rawmidi *rawmidi)
|
||||||
{
|
{
|
||||||
if (!rawmidi)
|
if (!rawmidi)
|
||||||
return;
|
return;
|
||||||
soundcard_rawmidi_switch_free(rawmidi->iswitches);
|
soundcard_ctl_switch_free(rawmidi->iswitches);
|
||||||
soundcard_rawmidi_switch_free(rawmidi->oswitches);
|
soundcard_ctl_switch_free(rawmidi->oswitches);
|
||||||
free(rawmidi);
|
free(rawmidi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,19 +176,133 @@ void soundcard_setup_done(void)
|
||||||
soundcards = NULL;
|
soundcards = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int switch_list(void *handle, snd_switch_list_t *list, int interface, int device)
|
||||||
|
{
|
||||||
|
switch (interface) {
|
||||||
|
case 0:
|
||||||
|
return snd_ctl_switch_list(handle, list);
|
||||||
|
case 1:
|
||||||
|
return snd_ctl_mixer_switch_list(handle, device, list);
|
||||||
|
case 2:
|
||||||
|
return snd_ctl_pcm_playback_switch_list(handle, device, list);
|
||||||
|
case 3:
|
||||||
|
return snd_ctl_pcm_record_switch_list(handle, device, list);
|
||||||
|
case 4:
|
||||||
|
return snd_ctl_rawmidi_output_switch_list(handle, device, list);
|
||||||
|
case 5:
|
||||||
|
return snd_ctl_rawmidi_input_switch_list(handle, device, list);
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int switch_read(void *handle, snd_switch_t *sw, int interface, int device)
|
||||||
|
{
|
||||||
|
switch (interface) {
|
||||||
|
case 0:
|
||||||
|
return snd_ctl_switch_read(handle, sw);
|
||||||
|
case 1:
|
||||||
|
return snd_ctl_mixer_switch_read(handle, device, sw);
|
||||||
|
case 2:
|
||||||
|
return snd_ctl_pcm_playback_switch_read(handle, device, sw);
|
||||||
|
case 3:
|
||||||
|
return snd_ctl_pcm_record_switch_read(handle, device, sw);
|
||||||
|
case 4:
|
||||||
|
return snd_ctl_rawmidi_output_switch_read(handle, device, sw);
|
||||||
|
case 5:
|
||||||
|
return snd_ctl_rawmidi_input_switch_read(handle, device, sw);
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
static int switch_write(void *handle, snd_switch_t *sw, int interface, int device)
|
||||||
|
{
|
||||||
|
switch (interface) {
|
||||||
|
case 0:
|
||||||
|
return snd_ctl_switch_write(handle, sw);
|
||||||
|
case 1:
|
||||||
|
return snd_ctl_mixer_switch_write(handle, device, sw);
|
||||||
|
case 2:
|
||||||
|
return snd_ctl_pcm_playback_switch_write(handle, device, sw);
|
||||||
|
case 3:
|
||||||
|
return snd_ctl_pcm_record_switch_write(handle, device, sw);
|
||||||
|
case 4:
|
||||||
|
return snd_ctl_rawmidi_output_switch_write(handle, device, sw);
|
||||||
|
case 5:
|
||||||
|
return snd_ctl_rawmidi_input_switch_write(handle, device, sw);
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int determine_switches(void *handle, struct ctl_switch **csw, int interface, int device)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
*csw = NULL;
|
||||||
|
bzero(&list, sizeof(list));
|
||||||
|
if ((err = switch_list(handle, &list, interface, device)) < 0) {
|
||||||
|
error("Cannot determine switches for interface %i and device %i: %s", interface, device, snd_strerror(err));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (list.switches_over <= 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) {
|
||||||
|
error("No enough memory...");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if ((err = switch_list(handle, &list, interface, device)) < 0) {
|
||||||
|
error("Cannot determine switches (2) for interface %i and device %i: %s", interface, device, snd_strerror(err));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
for (idx = 0, prev_csw = NULL; idx < list.switches; idx++) {
|
||||||
|
item = &list.pswitches[idx];
|
||||||
|
bzero(&sw, sizeof(sw));
|
||||||
|
strncpy(sw.name, item->name, sizeof(sw.name));
|
||||||
|
if ((err = switch_read(handle, &sw, interface, device)) < 0) {
|
||||||
|
error("Cannot read switch for interface %i and device %i: %s", interface, device, snd_strerror(err));
|
||||||
|
free(list.pswitches);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
new_csw = malloc(sizeof(*new_csw));
|
||||||
|
if (!new_csw) {
|
||||||
|
error("No enough memory...");
|
||||||
|
free(list.pswitches);
|
||||||
|
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;
|
||||||
|
} else {
|
||||||
|
*csw = prev_csw = new_csw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(list.pswitches);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int soundcard_setup_collect(int cardno)
|
int soundcard_setup_collect(int cardno)
|
||||||
{
|
{
|
||||||
void *handle, *mhandle;
|
void *handle, *mhandle;
|
||||||
struct soundcard *card, *first, *prev;
|
struct soundcard *card, *first, *prev;
|
||||||
int err, idx, count, device;
|
int err, idx, count, device;
|
||||||
struct ctl_switch *ctl, *ctlprev;
|
|
||||||
struct mixer *mixer, *mixerprev;
|
struct mixer *mixer, *mixerprev;
|
||||||
struct mixer_switch *mixsw, *mixswprev;
|
|
||||||
struct mixer_channel *mixerchannel, *mixerchannelprev;
|
struct mixer_channel *mixerchannel, *mixerchannelprev;
|
||||||
struct pcm *pcm, *pcmprev;
|
struct pcm *pcm, *pcmprev;
|
||||||
struct pcm_switch *pcmsw, *pcmswprev;
|
|
||||||
struct rawmidi *rawmidi, *rawmidiprev;
|
struct rawmidi *rawmidi, *rawmidiprev;
|
||||||
struct rawmidi_switch *rawmidisw, *rawmidiswprev;
|
|
||||||
|
|
||||||
soundcard_remove(cardno);
|
soundcard_remove(cardno);
|
||||||
if ((err = snd_ctl_open(&handle, cardno)) < 0) {
|
if ((err = snd_ctl_open(&handle, cardno)) < 0) {
|
||||||
|
@ -262,27 +343,9 @@ int soundcard_setup_collect(int cardno)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/* --- */
|
/* --- */
|
||||||
count = snd_ctl_switches(handle);
|
if (determine_switches(handle, &card->control.switches, 0, 0)) {
|
||||||
for (idx = 0, ctlprev = NULL; idx < count; idx++) {
|
snd_ctl_close(handle);
|
||||||
ctl = (struct ctl_switch *) malloc(sizeof(struct ctl_switch));
|
return 1;
|
||||||
if (!ctl) {
|
|
||||||
snd_ctl_close(handle);
|
|
||||||
error("malloc error");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
bzero(ctl, sizeof(struct ctl_switch));
|
|
||||||
ctl->no = idx;
|
|
||||||
if ((err = snd_ctl_switch_read(handle, idx, &ctl->s)) < 0) {
|
|
||||||
free(ctl);
|
|
||||||
error("CTL switch read error (%s) - skipping", snd_strerror(err));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!ctlprev) {
|
|
||||||
card->control.switches = ctl;
|
|
||||||
} else {
|
|
||||||
ctlprev->next = ctl;
|
|
||||||
}
|
|
||||||
ctlprev = ctl;
|
|
||||||
}
|
}
|
||||||
/* --- */
|
/* --- */
|
||||||
for (device = 0, mixerprev = NULL; device < card->control.hwinfo.mixerdevs; device++) {
|
for (device = 0, mixerprev = NULL; device < card->control.hwinfo.mixerdevs; device++) {
|
||||||
|
@ -294,27 +357,9 @@ int soundcard_setup_collect(int cardno)
|
||||||
}
|
}
|
||||||
bzero(mixer, sizeof(struct mixer));
|
bzero(mixer, sizeof(struct mixer));
|
||||||
mixer->no = device;
|
mixer->no = device;
|
||||||
count = snd_ctl_mixer_switches(handle, device);
|
if (determine_switches(handle, &mixer->switches, 1, device)) {
|
||||||
for (idx = 0, mixswprev = NULL; idx < count; idx++) {
|
snd_ctl_close(handle);
|
||||||
mixsw = (struct mixer_switch *) malloc(sizeof(struct mixer_switch));
|
return 1;
|
||||||
if (!mixsw) {
|
|
||||||
snd_ctl_close(handle);
|
|
||||||
error("malloc error");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
bzero(mixsw, sizeof(struct mixer_switch));
|
|
||||||
mixsw->no = idx;
|
|
||||||
if ((err = snd_ctl_mixer_switch_read(handle, device, idx, &mixsw->s)) < 0) {
|
|
||||||
free(mixsw);
|
|
||||||
error("MIXER switch read error (%s) - skipping", snd_strerror(err));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!mixswprev) {
|
|
||||||
mixer->switches = mixsw;
|
|
||||||
} else {
|
|
||||||
mixswprev->next = mixsw;
|
|
||||||
}
|
|
||||||
mixswprev = mixsw;
|
|
||||||
}
|
}
|
||||||
if (!mixerprev) {
|
if (!mixerprev) {
|
||||||
card->mixers = mixer;
|
card->mixers = mixer;
|
||||||
|
@ -408,49 +453,13 @@ int soundcard_setup_collect(int cardno)
|
||||||
error("PCM info error: %s\n", snd_strerror(err));
|
error("PCM info error: %s\n", snd_strerror(err));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
count = snd_ctl_pcm_playback_switches(handle, device);
|
if (determine_switches(handle, &pcm->pswitches, 2, device)) {
|
||||||
for (idx = 0, pcmswprev = NULL; idx < count; idx++) {
|
snd_ctl_close(handle);
|
||||||
pcmsw = (struct pcm_switch *) malloc(sizeof(struct pcm_switch));
|
return 1;
|
||||||
if (!pcmsw) {
|
|
||||||
snd_ctl_close(handle);
|
|
||||||
error("malloc error");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
bzero(pcmsw, sizeof(struct mixer_switch));
|
|
||||||
pcmsw->no = idx;
|
|
||||||
if ((err = snd_ctl_pcm_playback_switch_read(handle, device, idx, &pcmsw->s)) < 0) {
|
|
||||||
free(pcmsw);
|
|
||||||
error("PCM playback switch read error (%s) - skipping", snd_strerror(err));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!pcmswprev) {
|
|
||||||
pcm->pswitches = pcmsw;
|
|
||||||
} else {
|
|
||||||
pcmswprev->next = pcmsw;
|
|
||||||
}
|
|
||||||
pcmswprev = pcmsw;
|
|
||||||
}
|
}
|
||||||
count = snd_ctl_pcm_record_switches(handle, device);
|
if (determine_switches(handle, &pcm->rswitches, 3, device)) {
|
||||||
for (idx = 0, pcmswprev = NULL; idx < count; idx++) {
|
snd_ctl_close(handle);
|
||||||
pcmsw = (struct pcm_switch *) malloc(sizeof(struct pcm_switch));
|
return 1;
|
||||||
if (!pcmsw) {
|
|
||||||
snd_ctl_close(handle);
|
|
||||||
error("malloc error");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
bzero(pcmsw, sizeof(struct mixer_switch));
|
|
||||||
pcmsw->no = idx;
|
|
||||||
if ((err = snd_ctl_pcm_record_switch_read(handle, device, idx, &pcmsw->s)) < 0) {
|
|
||||||
free(pcmsw);
|
|
||||||
error("PCM record switch read error (%s) - skipping", snd_strerror(err));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!pcmswprev) {
|
|
||||||
pcm->rswitches = pcmsw;
|
|
||||||
} else {
|
|
||||||
pcmswprev->next = pcmsw;
|
|
||||||
}
|
|
||||||
pcmswprev = pcmsw;
|
|
||||||
}
|
}
|
||||||
if (!pcmprev) {
|
if (!pcmprev) {
|
||||||
card->pcms = pcm;
|
card->pcms = pcm;
|
||||||
|
@ -474,49 +483,13 @@ int soundcard_setup_collect(int cardno)
|
||||||
error("RAWMIDI info error: %s\n", snd_strerror(err));
|
error("RAWMIDI info error: %s\n", snd_strerror(err));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
count = snd_ctl_rawmidi_input_switches(handle, device);
|
if (determine_switches(handle, &rawmidi->oswitches, 4, device)) {
|
||||||
for (idx = 0, rawmidiswprev = NULL; idx < count; idx++) {
|
snd_ctl_close(handle);
|
||||||
rawmidisw = (struct rawmidi_switch *) malloc(sizeof(struct rawmidi_switch));
|
return 1;
|
||||||
if (!rawmidisw) {
|
|
||||||
snd_ctl_close(handle);
|
|
||||||
error("malloc error");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
bzero(rawmidisw, sizeof(struct rawmidi_switch));
|
|
||||||
rawmidisw->no = idx;
|
|
||||||
if ((err = snd_ctl_rawmidi_input_switch_read(handle, device, idx, &rawmidisw->s)) < 0) {
|
|
||||||
free(rawmidisw);
|
|
||||||
error("RAWMIDI input switch read error (%s) - skipping", snd_strerror(err));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!rawmidiswprev) {
|
|
||||||
rawmidi->iswitches = rawmidisw;
|
|
||||||
} else {
|
|
||||||
rawmidiswprev->next = rawmidisw;
|
|
||||||
}
|
|
||||||
rawmidiswprev = rawmidisw;
|
|
||||||
}
|
}
|
||||||
count = snd_ctl_rawmidi_output_switches(handle, device);
|
if (determine_switches(handle, &rawmidi->iswitches, 5, device)) {
|
||||||
for (idx = 0, rawmidiswprev = NULL; idx < count; idx++) {
|
snd_ctl_close(handle);
|
||||||
rawmidisw = (struct rawmidi_switch *) malloc(sizeof(struct rawmidi_switch));
|
return 1;
|
||||||
if (!rawmidisw) {
|
|
||||||
snd_ctl_close(handle);
|
|
||||||
error("malloc error");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
bzero(rawmidisw, sizeof(struct rawmidi_switch));
|
|
||||||
rawmidisw->no = idx;
|
|
||||||
if ((err = snd_ctl_rawmidi_output_switch_read(handle, device, idx, &rawmidisw->s)) < 0) {
|
|
||||||
free(rawmidisw);
|
|
||||||
error("RAWMIDI output switch read error (%s) - skipping", snd_strerror(err));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!rawmidiswprev) {
|
|
||||||
rawmidi->oswitches = rawmidisw;
|
|
||||||
} else {
|
|
||||||
rawmidiswprev->next = rawmidisw;
|
|
||||||
}
|
|
||||||
rawmidiswprev = rawmidisw;
|
|
||||||
}
|
}
|
||||||
if (!rawmidiprev) {
|
if (!rawmidiprev) {
|
||||||
card->rawmidis = rawmidi;
|
card->rawmidis = rawmidi;
|
||||||
|
@ -559,115 +532,121 @@ int soundcard_setup_load(const char *cfgfile, int skip)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void soundcard_setup_write_switch(FILE * out, int interface, const unsigned char *name, unsigned int type, unsigned int low, unsigned int high, void *data)
|
static void soundcard_setup_write_switch(FILE * out, const char *space, int interface, snd_switch_t *sw)
|
||||||
{
|
{
|
||||||
union {
|
|
||||||
unsigned int enable;
|
|
||||||
unsigned char data8[32];
|
|
||||||
unsigned short data16[16];
|
|
||||||
unsigned int data32[8];
|
|
||||||
} *pdata = data;
|
|
||||||
char *s, v[16];
|
char *s, v[16];
|
||||||
int idx, first, switchok = 0;
|
int idx, first, switchok = 0;
|
||||||
const char *space = " ";
|
|
||||||
|
|
||||||
v[0] = '\0';
|
v[0] = '\0';
|
||||||
switch (type) {
|
switch (sw->type) {
|
||||||
case SND_CTL_SW_TYPE_BOOLEAN:
|
case SND_SW_TYPE_BOOLEAN:
|
||||||
s = "bool";
|
s = "bool";
|
||||||
strcpy(v, pdata->enable ? "true" : "false");
|
strcpy(v, sw->value.enable ? "true" : "false");
|
||||||
break;
|
break;
|
||||||
case SND_CTL_SW_TYPE_BYTE:
|
case SND_SW_TYPE_BYTE:
|
||||||
s = "byte";
|
s = "byte";
|
||||||
sprintf(v, "%u", (unsigned int) pdata->data8[0]);
|
sprintf(v, "%u", (unsigned int) sw->value.data8[0]);
|
||||||
break;
|
break;
|
||||||
case SND_CTL_SW_TYPE_WORD:
|
case SND_SW_TYPE_WORD:
|
||||||
s = "word";
|
s = "word";
|
||||||
if (interface == SND_INTERFACE_CONTROL &&
|
if (interface == SND_INTERFACE_CONTROL &&
|
||||||
!strcmp(name, SND_CTL_SW_JOYSTICK_ADDRESS)) {
|
!strcmp(sw->name, SND_CTL_SW_JOYSTICK_ADDRESS)) {
|
||||||
sprintf(v, "0x%x", (unsigned int) pdata->data16[0]);
|
sprintf(v, "0x%x", (unsigned int) sw->value.data16[0]);
|
||||||
} else {
|
} else {
|
||||||
sprintf(v, "%u", (unsigned int) pdata->data16[0]);
|
sprintf(v, "%u", (unsigned int) sw->value.data16[0]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SND_CTL_SW_TYPE_DWORD:
|
case SND_SW_TYPE_DWORD:
|
||||||
s = "dword";
|
s = "dword";
|
||||||
sprintf(v, "%u", pdata->data32[0]);
|
sprintf(v, "%u", sw->value.data32[0]);
|
||||||
break;
|
break;
|
||||||
case SND_CTL_SW_TYPE_USER:
|
case SND_SW_TYPE_USER:
|
||||||
s = "user";
|
s = "user";
|
||||||
break;
|
break;
|
||||||
|
case SND_SW_TYPE_LIST:
|
||||||
|
s = "list";
|
||||||
|
sprintf(v, "%u", sw->value.item_number);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
s = "unknown";
|
s = "unknown";
|
||||||
}
|
}
|
||||||
fprintf(out, "%s; Type is '%s'.\n", space, s);
|
fprintf(out, "%s; Type is '%s'.\n", space, s);
|
||||||
if (low != 0 || high != 0)
|
if (sw->low != 0 || sw->high != 0)
|
||||||
fprintf(out, "%s; Accepted switch range is from %u to %u.\n", space, low, high);
|
fprintf(out, "%s; Accepted switch range is from %u to %u.\n", space, sw->low, sw->high);
|
||||||
if (interface == SND_INTERFACE_CONTROL && type == SND_CTL_SW_TYPE_WORD &&
|
if (interface == SND_INTERFACE_CONTROL && sw->type == SND_SW_TYPE_WORD &&
|
||||||
!strcmp(name, SND_CTL_SW_JOYSTICK_ADDRESS)) {
|
!strcmp(sw->name, SND_CTL_SW_JOYSTICK_ADDRESS)) {
|
||||||
for (idx = 1, first = 1; idx < 16; idx++) {
|
for (idx = 1, first = 1; idx < 16; idx++) {
|
||||||
if (pdata->data16[idx]) {
|
if (sw->value.data16[idx]) {
|
||||||
if (first) {
|
if (first) {
|
||||||
fprintf(out, "%s; Available addresses - 0x%x", space, pdata->data16[idx]);
|
fprintf(out, "%s; Available addresses - 0x%x", space, sw->value.data16[idx]);
|
||||||
first = 0;
|
first = 0;
|
||||||
} else {
|
} else {
|
||||||
fprintf(out, ", 0x%x", pdata->data16[idx]);
|
fprintf(out, ", 0x%x", sw->value.data16[idx]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!first)
|
if (!first)
|
||||||
fprintf(out, "\n");
|
fprintf(out, "\n");
|
||||||
}
|
}
|
||||||
if (interface == SND_INTERFACE_MIXER && type == SND_MIXER_SW_TYPE_BOOLEAN &&
|
if (interface == SND_INTERFACE_MIXER && sw->type == SND_SW_TYPE_BOOLEAN &&
|
||||||
!strcmp(name, SND_MIXER_SW_IEC958OUT)) {
|
!strcmp(sw->name, SND_MIXER_SW_IEC958OUT)) {
|
||||||
fprintf(out, "%sswitch( \"%s\", ", space, name);
|
fprintf(out, "%sswitch( \"%s\", ", space, sw->name);
|
||||||
if (pdata->data32[1] == (('C' << 8) | 'S')) { /* Cirrus Crystal */
|
if (sw->value.data32[1] == (('C' << 8) | 'S')) { /* Cirrus Crystal */
|
||||||
switchok = 0;
|
switchok = 0;
|
||||||
fprintf(out, "iec958ocs( %s", pdata->enable ? "enable" : "disable");
|
fprintf(out, "iec958ocs( %s", sw->value.enable ? "enable" : "disable");
|
||||||
if (pdata->data16[4] & 0x2000)
|
if (sw->value.data16[4] & 0x2000)
|
||||||
fprintf(out, " 3d");
|
fprintf(out, " 3d");
|
||||||
if (pdata->data16[4] & 0x0040)
|
if (sw->value.data16[4] & 0x0040)
|
||||||
fprintf(out, " reset");
|
fprintf(out, " reset");
|
||||||
if (pdata->data16[4] & 0x0020)
|
if (sw->value.data16[4] & 0x0020)
|
||||||
fprintf(out, " user");
|
fprintf(out, " user");
|
||||||
if (pdata->data16[4] & 0x0010)
|
if (sw->value.data16[4] & 0x0010)
|
||||||
fprintf(out, " valid");
|
fprintf(out, " valid");
|
||||||
if (pdata->data16[5] & 0x0002)
|
if (sw->value.data16[5] & 0x0002)
|
||||||
fprintf(out, " data");
|
fprintf(out, " data");
|
||||||
if (!(pdata->data16[5] & 0x0004))
|
if (!(sw->value.data16[5] & 0x0004))
|
||||||
fprintf(out, " protect");
|
fprintf(out, " protect");
|
||||||
switch (pdata->data16[5] & 0x0018) {
|
switch (sw->value.data16[5] & 0x0018) {
|
||||||
case 0x0008:
|
case 0x0008:
|
||||||
fprintf(out, " pre2");
|
fprintf(out, " pre2");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (pdata->data16[5] & 0x0020)
|
if (sw->value.data16[5] & 0x0020)
|
||||||
fprintf(out, " fsunlock");
|
fprintf(out, " fsunlock");
|
||||||
fprintf(out, " type( 0x%x )", (pdata->data16[5] >> 6) & 0x7f);
|
fprintf(out, " type( 0x%x )", (sw->value.data16[5] >> 6) & 0x7f);
|
||||||
if (pdata->data16[5] & 0x2000)
|
if (sw->value.data16[5] & 0x2000)
|
||||||
fprintf(out, " gstatus");
|
fprintf(out, " gstatus");
|
||||||
fprintf(out, " )");
|
fprintf(out, " )");
|
||||||
goto __end;
|
goto __end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fprintf(out, "%sswitch( \"%s\", ", space, name);
|
fprintf(out, "%sswitch(\"%s\", ", space, sw->name);
|
||||||
if (!switchok) {
|
if (!switchok) {
|
||||||
fprintf(out, v);
|
fprintf(out, v);
|
||||||
if (type < 0 || type > SND_CTL_SW_TYPE_DWORD) {
|
if (sw->type < 0 || sw->type > SND_SW_TYPE_LIST_ITEM) {
|
||||||
/* TODO: some well known types should be verbose */
|
/* TODO: some well known types should be verbose */
|
||||||
fprintf(out, " rawdata( ");
|
fprintf(out, " rawdata( ");
|
||||||
for (idx = 0; idx < 31; idx++) {
|
for (idx = 0; idx < 31; idx++) {
|
||||||
fprintf(out, "@%02x:", pdata->data8[idx]);
|
fprintf(out, "@%02x:", sw->value.data8[idx]);
|
||||||
}
|
}
|
||||||
fprintf(out, "%02x@ )\n", pdata->data8[31]);
|
fprintf(out, "%02x@ )\n", sw->value.data8[31]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
__end:
|
__end:
|
||||||
fprintf(out, " )\n");
|
fprintf(out, " )\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void soundcard_setup_write_switches(FILE *out, const char *space, int interface, struct ctl_switch **switches)
|
||||||
|
{
|
||||||
|
struct ctl_switch *sw;
|
||||||
|
|
||||||
|
if (!(*switches))
|
||||||
|
return;
|
||||||
|
for (sw = *switches; sw; sw = sw->next)
|
||||||
|
soundcard_setup_write_switch(out, space, interface, &sw->s);
|
||||||
|
}
|
||||||
|
|
||||||
static void soundcard_setup_write_mixer_channel(FILE * out, struct mixer_channel * channel)
|
static void soundcard_setup_write_mixer_channel(FILE * out, struct mixer_channel * channel)
|
||||||
{
|
{
|
||||||
|
@ -717,7 +696,7 @@ static void soundcard_setup_write_mixer_channel(FILE * out, struct mixer_channel
|
||||||
}
|
}
|
||||||
fprintf(out, "\n");
|
fprintf(out, "\n");
|
||||||
}
|
}
|
||||||
fprintf(out, " channel( \"%s\"", channel->info.name);
|
fprintf(out, " channel(\"%s\"", channel->info.name);
|
||||||
for (d = OUTPUT; d <= INPUT; ++d) {
|
for (d = OUTPUT; d <= INPUT; ++d) {
|
||||||
snd_mixer_channel_direction_info_t *di;
|
snd_mixer_channel_direction_info_t *di;
|
||||||
snd_mixer_channel_direction_t *dd;
|
snd_mixer_channel_direction_t *dd;
|
||||||
|
@ -741,7 +720,7 @@ static void soundcard_setup_write_mixer_channel(FILE * out, struct mixer_channel
|
||||||
if (di->caps & SND_MIXER_CINFO_DCAP_VOLUME)
|
if (di->caps & SND_MIXER_CINFO_DCAP_VOLUME)
|
||||||
fprintf(out, " %i", dd->right);
|
fprintf(out, " %i", dd->right);
|
||||||
|
|
||||||
fprintf(out, "%s%s )",
|
fprintf(out, "%s%s)",
|
||||||
dd->flags & SND_MIXER_DFLG_MUTE_RIGHT ? " mute" : "",
|
dd->flags & SND_MIXER_DFLG_MUTE_RIGHT ? " mute" : "",
|
||||||
dd->flags & SND_MIXER_DFLG_RTOL ? " swap" : ""
|
dd->flags & SND_MIXER_DFLG_RTOL ? " swap" : ""
|
||||||
);
|
);
|
||||||
|
@ -750,7 +729,7 @@ static void soundcard_setup_write_mixer_channel(FILE * out, struct mixer_channel
|
||||||
fprintf(out, "mono(");
|
fprintf(out, "mono(");
|
||||||
if (di->caps & SND_MIXER_CINFO_DCAP_VOLUME)
|
if (di->caps & SND_MIXER_CINFO_DCAP_VOLUME)
|
||||||
fprintf(out, " %i", (dd->left + dd->right)/2);
|
fprintf(out, " %i", (dd->left + dd->right)/2);
|
||||||
fprintf(out, "%s )",
|
fprintf(out, "%s)",
|
||||||
dd->flags & SND_MIXER_DFLG_MUTE ? " mute" : ""
|
dd->flags & SND_MIXER_DFLG_MUTE ? " mute" : ""
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -762,14 +741,10 @@ int soundcard_setup_write(const char *cfgfile)
|
||||||
{
|
{
|
||||||
FILE *out;
|
FILE *out;
|
||||||
struct soundcard *first;
|
struct soundcard *first;
|
||||||
struct ctl_switch *ctlsw;
|
|
||||||
struct mixer *mixer;
|
struct mixer *mixer;
|
||||||
struct mixer_switch *mixersw;
|
|
||||||
struct mixer_channel *mixerchannel;
|
struct mixer_channel *mixerchannel;
|
||||||
struct pcm *pcm;
|
struct pcm *pcm;
|
||||||
struct pcm_switch *pcmsw;
|
|
||||||
struct rawmidi *rawmidi;
|
struct rawmidi *rawmidi;
|
||||||
struct rawmidi_switch *rawmidisw;
|
|
||||||
|
|
||||||
if ((out = fopen(cfgfile, "w+")) == NULL) {
|
if ((out = fopen(cfgfile, "w+")) == NULL) {
|
||||||
error("Cannot open file '%s' for writing...\n", cfgfile);
|
error("Cannot open file '%s' for writing...\n", cfgfile);
|
||||||
|
@ -779,35 +754,31 @@ int soundcard_setup_write(const char *cfgfile)
|
||||||
fprintf(out, "# Generated by alsactl\n");
|
fprintf(out, "# Generated by alsactl\n");
|
||||||
fprintf(out, "\n");
|
fprintf(out, "\n");
|
||||||
for (first = soundcards; first; first = first->next) {
|
for (first = soundcards; first; first = first->next) {
|
||||||
fprintf(out, "soundcard( \"%s\" ) {\n", first->control.hwinfo.id);
|
fprintf(out, "soundcard(\"%s\") {\n", first->control.hwinfo.id);
|
||||||
if (first->control.switches) {
|
if (first->control.switches) {
|
||||||
fprintf(out, " control {\n");
|
fprintf(out, " control {\n");
|
||||||
for (ctlsw = first->control.switches; ctlsw; ctlsw = ctlsw->next)
|
soundcard_setup_write_switches(out, " ", SND_INTERFACE_CONTROL, &first->control.switches);
|
||||||
soundcard_setup_write_switch(out, SND_INTERFACE_CONTROL, ctlsw->s.name, ctlsw->s.type, ctlsw->s.low, ctlsw->s.high, (void *) &ctlsw->s.value);
|
|
||||||
fprintf(out, " }\n");
|
fprintf(out, " }\n");
|
||||||
}
|
}
|
||||||
for (mixer = first->mixers; mixer; mixer = mixer->next) {
|
for (mixer = first->mixers; mixer; mixer = mixer->next) {
|
||||||
fprintf(out, " mixer( \"%s\" ) {\n", mixer->info.name);
|
fprintf(out, " mixer(\"%s\") {\n", mixer->info.name);
|
||||||
|
soundcard_setup_write_switches(out, " ", SND_INTERFACE_MIXER, &mixer->switches);
|
||||||
for (mixerchannel = mixer->channels; mixerchannel; mixerchannel = mixerchannel->next)
|
for (mixerchannel = mixer->channels; mixerchannel; mixerchannel = mixerchannel->next)
|
||||||
soundcard_setup_write_mixer_channel(out, mixerchannel);
|
soundcard_setup_write_mixer_channel(out, mixerchannel);
|
||||||
for (mixersw = mixer->switches; mixersw; mixersw = mixersw->next)
|
|
||||||
soundcard_setup_write_switch(out, SND_INTERFACE_MIXER, mixersw->s.name, mixersw->s.type, mixersw->s.low, mixersw->s.high, (void *) (&mixersw->s.value));
|
|
||||||
fprintf(out, " }\n");
|
fprintf(out, " }\n");
|
||||||
}
|
}
|
||||||
for (pcm = first->pcms; pcm; pcm = pcm->next) {
|
for (pcm = first->pcms; pcm; pcm = pcm->next) {
|
||||||
if (!pcm->pswitches && !pcm->rswitches)
|
if (!pcm->pswitches && !pcm->rswitches)
|
||||||
continue;
|
continue;
|
||||||
fprintf(out, " pcm( \"%s\" ) {\n", pcm->info.name);
|
fprintf(out, " pcm(\"%s\") {\n", pcm->info.name);
|
||||||
if (pcm->pswitches) {
|
if (pcm->pswitches) {
|
||||||
fprintf(out, " playback {");
|
fprintf(out, " playback {");
|
||||||
for (pcmsw = pcm->pswitches; pcmsw; pcmsw = pcmsw->next)
|
soundcard_setup_write_switches(out, " ", SND_INTERFACE_PCM, &pcm->pswitches);
|
||||||
soundcard_setup_write_switch(out, SND_INTERFACE_PCM, pcmsw->s.name, pcmsw->s.type, pcmsw->s.low, pcmsw->s.high, (void *) &pcmsw->s.value);
|
|
||||||
fprintf(out, " }\n");
|
fprintf(out, " }\n");
|
||||||
}
|
}
|
||||||
if (pcm->rswitches) {
|
if (pcm->rswitches) {
|
||||||
fprintf(out, " record {");
|
fprintf(out, " record {");
|
||||||
for (pcmsw = pcm->pswitches; pcmsw; pcmsw = pcmsw->next)
|
soundcard_setup_write_switches(out, " ", SND_INTERFACE_PCM, &pcm->rswitches);
|
||||||
soundcard_setup_write_switch(out, SND_INTERFACE_PCM, pcmsw->s.name, pcmsw->s.type, pcmsw->s.low, pcmsw->s.high, (void *) &pcmsw->s.value);
|
|
||||||
fprintf(out, " }\n");
|
fprintf(out, " }\n");
|
||||||
}
|
}
|
||||||
fprintf(out, " }\n");
|
fprintf(out, " }\n");
|
||||||
|
@ -815,17 +786,15 @@ int soundcard_setup_write(const char *cfgfile)
|
||||||
for (rawmidi = first->rawmidis; rawmidi; rawmidi = rawmidi->next) {
|
for (rawmidi = first->rawmidis; rawmidi; rawmidi = rawmidi->next) {
|
||||||
if (!rawmidi->oswitches && !rawmidi->iswitches)
|
if (!rawmidi->oswitches && !rawmidi->iswitches)
|
||||||
continue;
|
continue;
|
||||||
fprintf(out, " rawmidi( \"%s\" ) {\n", rawmidi->info.name);
|
fprintf(out, " rawmidi(\"%s\") {\n", rawmidi->info.name);
|
||||||
if (rawmidi->oswitches) {
|
if (rawmidi->oswitches) {
|
||||||
fprintf(out, " output {");
|
fprintf(out, " output {");
|
||||||
for (rawmidisw = rawmidi->oswitches; rawmidisw; rawmidisw = rawmidisw->next)
|
soundcard_setup_write_switches(out, " ", SND_INTERFACE_RAWMIDI, &rawmidi->oswitches);
|
||||||
soundcard_setup_write_switch(out, SND_INTERFACE_RAWMIDI, rawmidisw->s.name, rawmidisw->s.type, rawmidisw->s.low, rawmidisw->s.high, (void *) &rawmidisw->s.value);
|
|
||||||
fprintf(out, " }\n");
|
fprintf(out, " }\n");
|
||||||
}
|
}
|
||||||
if (rawmidi->iswitches) {
|
if (rawmidi->iswitches) {
|
||||||
fprintf(out, " input {");
|
fprintf(out, " input {");
|
||||||
for (rawmidisw = rawmidi->iswitches; rawmidisw; rawmidisw = rawmidisw->next)
|
soundcard_setup_write_switches(out, " ", SND_INTERFACE_RAWMIDI, &rawmidi->iswitches);
|
||||||
soundcard_setup_write_switch(out, SND_INTERFACE_RAWMIDI, rawmidisw->s.name, rawmidisw->s.type, rawmidisw->s.low, rawmidisw->s.high, (void *) &rawmidisw->s.value);
|
|
||||||
fprintf(out, " }\n");
|
fprintf(out, " }\n");
|
||||||
}
|
}
|
||||||
fprintf(out, " }\n");
|
fprintf(out, " }\n");
|
||||||
|
@ -875,11 +844,8 @@ int soundcard_setup_process(int cardno)
|
||||||
struct ctl_switch *ctlsw;
|
struct ctl_switch *ctlsw;
|
||||||
struct mixer *mixer;
|
struct mixer *mixer;
|
||||||
struct mixer_channel *channel;
|
struct mixer_channel *channel;
|
||||||
struct mixer_switch *mixersw;
|
|
||||||
struct pcm *pcm;
|
struct pcm *pcm;
|
||||||
struct pcm_switch *pcmsw;
|
|
||||||
struct rawmidi *rawmidi;
|
struct rawmidi *rawmidi;
|
||||||
struct rawmidi_switch *rawmidisw;
|
|
||||||
|
|
||||||
for (soundcard = soundcards; soundcard; soundcard = soundcard->next) {
|
for (soundcard = soundcards; soundcard; soundcard = soundcard->next) {
|
||||||
if (cardno >= 0 && soundcard->no != cardno)
|
if (cardno >= 0 && soundcard->no != cardno)
|
||||||
|
@ -887,7 +853,7 @@ int soundcard_setup_process(int cardno)
|
||||||
for (ctlsw = soundcard->control.switches; ctlsw; ctlsw = ctlsw->next) {
|
for (ctlsw = soundcard->control.switches; ctlsw; ctlsw = ctlsw->next) {
|
||||||
if (ctlsw->change)
|
if (ctlsw->change)
|
||||||
if (!soundcard_open_ctl(&ctlhandle, soundcard)) {
|
if (!soundcard_open_ctl(&ctlhandle, soundcard)) {
|
||||||
if ((err = snd_ctl_switch_write(ctlhandle, ctlsw->no, &ctlsw->s)) < 0)
|
if ((err = snd_ctl_switch_write(ctlhandle, &ctlsw->s)) < 0)
|
||||||
error("Control switch '%s' write error: %s", ctlsw->s.name, snd_strerror(err));
|
error("Control switch '%s' write error: %s", ctlsw->s.name, snd_strerror(err));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -905,42 +871,42 @@ int soundcard_setup_process(int cardno)
|
||||||
snd_mixer_close(mixhandle);
|
snd_mixer_close(mixhandle);
|
||||||
mixhandle = NULL;
|
mixhandle = NULL;
|
||||||
}
|
}
|
||||||
for (mixersw = mixer->switches; mixersw; mixersw = mixersw->next)
|
for (ctlsw = mixer->switches; ctlsw; ctlsw = ctlsw->next)
|
||||||
if (mixersw->change)
|
if (ctlsw->change)
|
||||||
if (!soundcard_open_ctl(&ctlhandle, soundcard)) {
|
if (!soundcard_open_ctl(&ctlhandle, soundcard)) {
|
||||||
if ((err = snd_ctl_mixer_switch_write(ctlhandle, mixer->no, mixersw->no, &mixersw->s)) < 0)
|
if ((err = snd_ctl_mixer_switch_write(ctlhandle, mixer->no, &ctlsw->s)) < 0)
|
||||||
error("Mixer switch '%s' write error: %s", mixersw->s.name, snd_strerror(err));
|
error("Mixer switch '%s' write error: %s", ctlsw->s.name, snd_strerror(err));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (pcm = soundcard->pcms; pcm; pcm = pcm->next) {
|
for (pcm = soundcard->pcms; pcm; pcm = pcm->next) {
|
||||||
for (pcmsw = pcm->pswitches; pcmsw; pcmsw = pcmsw->next) {
|
for (ctlsw = pcm->pswitches; ctlsw; ctlsw = ctlsw->next) {
|
||||||
if (pcmsw->change)
|
if (ctlsw->change)
|
||||||
if (!soundcard_open_ctl(&ctlhandle, soundcard)) {
|
if (!soundcard_open_ctl(&ctlhandle, soundcard)) {
|
||||||
if ((err = snd_ctl_pcm_playback_switch_write(ctlhandle, pcm->no, pcmsw->no, &pcmsw->s)) < 0)
|
if ((err = snd_ctl_pcm_playback_switch_write(ctlhandle, pcm->no, &ctlsw->s)) < 0)
|
||||||
error("PCM playback switch '%s' write error: %s", pcmsw->s.name, snd_strerror(err));
|
error("PCM playback switch '%s' write error: %s", ctlsw->s.name, snd_strerror(err));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (pcmsw = pcm->rswitches; pcmsw; pcmsw = pcmsw->next) {
|
for (ctlsw = pcm->rswitches; ctlsw; ctlsw = ctlsw->next) {
|
||||||
if (pcmsw->change)
|
if (ctlsw->change)
|
||||||
if (!soundcard_open_ctl(&ctlhandle, soundcard)) {
|
if (!soundcard_open_ctl(&ctlhandle, soundcard)) {
|
||||||
if ((err = snd_ctl_pcm_record_switch_write(ctlhandle, pcm->no, pcmsw->no, &pcmsw->s)) < 0)
|
if ((err = snd_ctl_pcm_record_switch_write(ctlhandle, pcm->no, &ctlsw->s)) < 0)
|
||||||
error("PCM record switch '%s' write error: %s", pcmsw->s.name, snd_strerror(err));
|
error("PCM record switch '%s' write error: %s", ctlsw->s.name, snd_strerror(err));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (rawmidi = soundcard->rawmidis; rawmidi; rawmidi = rawmidi->next) {
|
for (rawmidi = soundcard->rawmidis; rawmidi; rawmidi = rawmidi->next) {
|
||||||
for (rawmidisw = rawmidi->oswitches; rawmidisw; rawmidisw = rawmidisw->next) {
|
for (ctlsw = rawmidi->oswitches; ctlsw; ctlsw = ctlsw->next) {
|
||||||
if (rawmidisw->change)
|
if (ctlsw->change)
|
||||||
if (!soundcard_open_ctl(&ctlhandle, soundcard)) {
|
if (!soundcard_open_ctl(&ctlhandle, soundcard)) {
|
||||||
if ((err = snd_ctl_rawmidi_output_switch_write(ctlhandle, rawmidi->no, rawmidisw->no, &rawmidisw->s)) < 0)
|
if ((err = snd_ctl_rawmidi_output_switch_write(ctlhandle, rawmidi->no, &ctlsw->s)) < 0)
|
||||||
error("RAWMIDI output switch '%s' write error: %s", rawmidisw->s.name, snd_strerror(err));
|
error("RAWMIDI output switch '%s' write error: %s", ctlsw->s.name, snd_strerror(err));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (rawmidisw = rawmidi->iswitches; rawmidisw; rawmidisw = rawmidisw->next) {
|
for (ctlsw = rawmidi->iswitches; ctlsw; ctlsw = ctlsw->next) {
|
||||||
if (rawmidisw->change)
|
if (ctlsw->change)
|
||||||
if (!soundcard_open_ctl(&ctlhandle, soundcard)) {
|
if (!soundcard_open_ctl(&ctlhandle, soundcard)) {
|
||||||
if ((err = snd_ctl_rawmidi_output_switch_write(ctlhandle, rawmidi->no, rawmidisw->no, &rawmidisw->s)) < 0)
|
if ((err = snd_ctl_rawmidi_output_switch_write(ctlhandle, rawmidi->no, &ctlsw->s)) < 0)
|
||||||
error("RAWMIDI input switch '%s' write error: %s", rawmidisw->s.name, snd_strerror(err));
|
error("RAWMIDI input switch '%s' write error: %s", ctlsw->s.name, snd_strerror(err));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue