This commit is contained in:
Abramo Bagnara 2001-02-09 13:15:54 +00:00
parent fea0c73cdb
commit 7165608b17
3 changed files with 46 additions and 45 deletions

View file

@ -47,19 +47,20 @@ int snd_mixer_open(snd_mixer_t **mixerp, char *name)
return 0; return 0;
} }
snd_mixer_elem_t *snd_mixer_elem_add(snd_mixer_t *mixer) int snd_mixer_add_elem(snd_mixer_t *mixer, snd_mixer_elem_t *elem)
{ {
snd_mixer_elem_t *elem;
elem = calloc(1, sizeof(*elem));
if (!elem)
return NULL;
elem->mixer = mixer; elem->mixer = mixer;
list_add_tail(&elem->list, &mixer->elems); list_add_tail(&elem->list, &mixer->elems);
mixer->count++; mixer->count++;
return elem; if (mixer->callback) {
int err = mixer->callback(mixer, SND_CTL_EVENT_ADD, elem);
if (err < 0)
return err;
}
return 0;
} }
void snd_mixer_elem_remove(snd_mixer_elem_t *elem) void snd_mixer_remove_elem(snd_mixer_elem_t *elem)
{ {
snd_mixer_t *mixer = elem->mixer; snd_mixer_t *mixer = elem->mixer;
if (elem->private_free) if (elem->private_free)
@ -74,7 +75,7 @@ void snd_mixer_elem_remove(snd_mixer_elem_t *elem)
void snd_mixer_free(snd_mixer_t *mixer) void snd_mixer_free(snd_mixer_t *mixer)
{ {
while (!list_empty(&mixer->elems)) while (!list_empty(&mixer->elems))
snd_mixer_elem_remove(list_entry(mixer->elems.next, snd_mixer_elem_t, list)); snd_mixer_remove_elem(list_entry(mixer->elems.next, snd_mixer_elem_t, list));
} }
int snd_mixer_close(snd_mixer_t *mixer) int snd_mixer_close(snd_mixer_t *mixer)

View file

@ -77,5 +77,5 @@ struct _snd_mixer_selem {
long volume[32]; long volume[32];
}; };
snd_mixer_elem_t *snd_mixer_elem_add(snd_mixer_t *mixer); int snd_mixer_add_elem(snd_mixer_t *mixer, snd_mixer_elem_t *elem);
void snd_mixer_free(snd_mixer_t *mixer); void snd_mixer_free(snd_mixer_t *mixer);

View file

@ -70,7 +70,7 @@ typedef struct _selem {
/* -- */ /* -- */
mixer_simple_read_t *read; mixer_simple_read_t *read;
mixer_simple_write_t *write; mixer_simple_write_t *write;
snd_hctl_bag_t helems; /* bag of associated helems */ snd_hctl_bag_t elems; /* bag of associated elems */
unsigned long private_value; unsigned long private_value;
} selem_t; } selem_t;
@ -173,11 +173,13 @@ static int hctl_elem_event(snd_hctl_elem_t *helem,
return 0; return 0;
} }
static void hctl_elem_add(snd_hctl_bag_t *bag, snd_hctl_elem_t *helem) static void hctl_elem_add(selem_t *s, snd_hctl_elem_t *helem)
{ {
snd_hctl_bag_add(bag, helem); int err;
err = snd_hctl_bag_add(&s->elems, helem);
assert(err >= 0);
snd_hctl_elem_set_callback(helem, hctl_elem_event); snd_hctl_elem_set_callback(helem, hctl_elem_event);
snd_hctl_elem_set_callback_private(helem, bag); snd_hctl_elem_set_callback_private(helem, &s->elems);
} }
static const char *get_full_name(const char *sname) static const char *get_full_name(const char *sname)
@ -483,28 +485,27 @@ static void selem_free(snd_mixer_elem_t *elem)
selem_t *s; selem_t *s;
assert(elem->type == SND_MIXER_ELEM_SIMPLE); assert(elem->type == SND_MIXER_ELEM_SIMPLE);
s = elem->private; s = elem->private;
snd_hctl_bag_destroy(&s->helems); snd_hctl_bag_destroy(&s->elems);
free(s); free(s);
} }
static selem_t *build_elem_scontrol(snd_mixer_t *mixer, const char *sname, int index) static int build_elem_scontrol(snd_mixer_t *mixer, selem_t *s,
const char *sname, int index)
{ {
snd_mixer_elem_t *elem; snd_mixer_elem_t *elem;
selem_t *s;
s = calloc(1, sizeof(*s));
strcpy(s->id.name, sname); strcpy(s->id.name, sname);
s->id.index = index; s->id.index = index;
s->read = elem_read; s->read = elem_read;
s->write = elem_write; s->write = elem_write;
elem = snd_mixer_elem_add(mixer); elem = calloc(1, sizeof(*elem));
if (!elem) { if (!elem)
free(s); return -ENOMEM;
return NULL; s->elems.private = elem;
}
elem->type = SND_MIXER_ELEM_SIMPLE; elem->type = SND_MIXER_ELEM_SIMPLE;
elem->private = s; elem->private = s;
elem->private_free = selem_free; elem->private_free = selem_free;
return s; snd_mixer_add_elem(mixer, elem);
return 0;
} }
static int build_elem(snd_mixer_t *mixer, const char *sname) static int build_elem(snd_mixer_t *mixer, const char *sname)
@ -518,7 +519,6 @@ static int build_elem(snd_mixer_t *mixer, const char *sname)
snd_ctl_elem_info_t groute_info, proute_info, croute_info; snd_ctl_elem_info_t groute_info, proute_info, croute_info;
snd_ctl_elem_info_t csource_info; snd_ctl_elem_info_t csource_info;
long min, max; long min, max;
snd_hctl_bag_t bag;
selem_t *simple; selem_t *simple;
snd_hctl_elem_t *helem; snd_hctl_elem_t *helem;
const char *sname1; const char *sname1;
@ -533,11 +533,11 @@ static int build_elem(snd_mixer_t *mixer, const char *sname)
memset(&proute_info, 0, sizeof(proute_info)); memset(&proute_info, 0, sizeof(proute_info));
memset(&croute_info, 0, sizeof(croute_info)); memset(&croute_info, 0, sizeof(croute_info));
while (1) { while (1) {
simple = calloc(1, sizeof(*simple));
index++; index++;
voices = 0; voices = 0;
present = caps = capture_item = 0; present = caps = capture_item = 0;
min = max = 0; min = max = 0;
memset(&bag, 0, sizeof(bag));
if ((helem = test_mixer_id(mixer, sname, index)) != NULL) { if ((helem = test_mixer_id(mixer, sname, index)) != NULL) {
if ((err = get_mixer_info(mixer, sname, index, &global_info)) < 0) if ((err = get_mixer_info(mixer, sname, index, &global_info)) < 0)
return err; return err;
@ -553,7 +553,7 @@ static int build_elem(snd_mixer_t *mixer, const char *sname)
if (max < global_info.value.integer.max) if (max < global_info.value.integer.max)
max = global_info.value.integer.max; max = global_info.value.integer.max;
} }
hctl_elem_add(&bag, helem); hctl_elem_add(simple, helem);
} }
} }
sprintf(str, "%s Switch", sname); sprintf(str, "%s Switch", sname);
@ -565,7 +565,7 @@ static int build_elem(snd_mixer_t *mixer, const char *sname)
voices = gswitch_info.count; voices = gswitch_info.count;
caps |= SND_MIXER_SCTCAP_MUTE; caps |= SND_MIXER_SCTCAP_MUTE;
present |= MIXER_PRESENT_GLOBAL_SWITCH; present |= MIXER_PRESENT_GLOBAL_SWITCH;
hctl_elem_add(&bag, helem); hctl_elem_add(simple, helem);
} }
} }
sprintf(str, "%s Route", sname); sprintf(str, "%s Route", sname);
@ -577,7 +577,7 @@ static int build_elem(snd_mixer_t *mixer, const char *sname)
voices = 2; voices = 2;
caps |= SND_MIXER_SCTCAP_MUTE; caps |= SND_MIXER_SCTCAP_MUTE;
present |= MIXER_PRESENT_GLOBAL_ROUTE; present |= MIXER_PRESENT_GLOBAL_ROUTE;
hctl_elem_add(&bag, helem); hctl_elem_add(simple, helem);
} }
} }
sprintf(str, "%s Volume", sname); sprintf(str, "%s Volume", sname);
@ -593,7 +593,7 @@ static int build_elem(snd_mixer_t *mixer, const char *sname)
max = gvolume_info.value.integer.max; max = gvolume_info.value.integer.max;
caps |= SND_MIXER_SCTCAP_VOLUME; caps |= SND_MIXER_SCTCAP_VOLUME;
present |= MIXER_PRESENT_GLOBAL_VOLUME; present |= MIXER_PRESENT_GLOBAL_VOLUME;
hctl_elem_add(&bag, helem); hctl_elem_add(simple, helem);
} }
} }
sprintf(str, "%s Playback Switch", sname); sprintf(str, "%s Playback Switch", sname);
@ -605,7 +605,7 @@ static int build_elem(snd_mixer_t *mixer, const char *sname)
voices = pswitch_info.count; voices = pswitch_info.count;
caps |= SND_MIXER_SCTCAP_MUTE; caps |= SND_MIXER_SCTCAP_MUTE;
present |= MIXER_PRESENT_PLAYBACK_SWITCH; present |= MIXER_PRESENT_PLAYBACK_SWITCH;
hctl_elem_add(&bag, helem); hctl_elem_add(simple, helem);
} }
} }
sprintf(str, "%s Playback Route", sname); sprintf(str, "%s Playback Route", sname);
@ -617,7 +617,7 @@ static int build_elem(snd_mixer_t *mixer, const char *sname)
voices = 2; voices = 2;
caps |= SND_MIXER_SCTCAP_MUTE; caps |= SND_MIXER_SCTCAP_MUTE;
present |= MIXER_PRESENT_PLAYBACK_ROUTE; present |= MIXER_PRESENT_PLAYBACK_ROUTE;
hctl_elem_add(&bag, helem); hctl_elem_add(simple, helem);
} }
} }
sprintf(str, "%s Capture Switch", sname); sprintf(str, "%s Capture Switch", sname);
@ -629,7 +629,7 @@ static int build_elem(snd_mixer_t *mixer, const char *sname)
voices = cswitch_info.count; voices = cswitch_info.count;
caps |= SND_MIXER_SCTCAP_CAPTURE; caps |= SND_MIXER_SCTCAP_CAPTURE;
present |= MIXER_PRESENT_CAPTURE_SWITCH; present |= MIXER_PRESENT_CAPTURE_SWITCH;
hctl_elem_add(&bag, helem); hctl_elem_add(simple, helem);
} }
} }
sprintf(str, "%s Capture Route", sname); sprintf(str, "%s Capture Route", sname);
@ -641,7 +641,7 @@ static int build_elem(snd_mixer_t *mixer, const char *sname)
voices = 2; voices = 2;
caps |= SND_MIXER_SCTCAP_CAPTURE; caps |= SND_MIXER_SCTCAP_CAPTURE;
present |= MIXER_PRESENT_CAPTURE_ROUTE; present |= MIXER_PRESENT_CAPTURE_ROUTE;
hctl_elem_add(&bag, helem); hctl_elem_add(simple, helem);
} }
} }
sprintf(str, "%s Playback Volume", sname); sprintf(str, "%s Playback Volume", sname);
@ -657,7 +657,7 @@ static int build_elem(snd_mixer_t *mixer, const char *sname)
max = pvolume_info.value.integer.max; max = pvolume_info.value.integer.max;
caps |= SND_MIXER_SCTCAP_VOLUME; caps |= SND_MIXER_SCTCAP_VOLUME;
present |= MIXER_PRESENT_PLAYBACK_VOLUME; present |= MIXER_PRESENT_PLAYBACK_VOLUME;
hctl_elem_add(&bag, helem); hctl_elem_add(simple, helem);
} }
} }
sprintf(str, "%s Capture Volume", sname); sprintf(str, "%s Capture Volume", sname);
@ -673,7 +673,7 @@ static int build_elem(snd_mixer_t *mixer, const char *sname)
max = pvolume_info.value.integer.max; max = pvolume_info.value.integer.max;
caps |= SND_MIXER_SCTCAP_VOLUME; caps |= SND_MIXER_SCTCAP_VOLUME;
present |= MIXER_PRESENT_CAPTURE_VOLUME; present |= MIXER_PRESENT_CAPTURE_VOLUME;
hctl_elem_add(&bag, helem); hctl_elem_add(simple, helem);
} }
} }
if (index == 0 && (helem = test_mixer_id(mixer, "Capture Source", 0)) != NULL) { if (index == 0 && (helem = test_mixer_id(mixer, "Capture Source", 0)) != NULL) {
@ -691,7 +691,7 @@ static int build_elem(snd_mixer_t *mixer, const char *sname)
voices = csource_info.count; voices = csource_info.count;
caps |= SND_MIXER_SCTCAP_CAPTURE; caps |= SND_MIXER_SCTCAP_CAPTURE;
present |= MIXER_PRESENT_CAPTURE_SOURCE; present |= MIXER_PRESENT_CAPTURE_SOURCE;
hctl_elem_add(&bag, helem); hctl_elem_add(simple, helem);
} else for (capture_item = 1; capture_item < csource_info.value.enumerated.items; capture_item++) { } else for (capture_item = 1; capture_item < csource_info.value.enumerated.items; capture_item++) {
csource_info.value.enumerated.item = capture_item; csource_info.value.enumerated.item = capture_item;
if ((err = snd_ctl_elem_info(mixer->ctl, &csource_info)) < 0) if ((err = snd_ctl_elem_info(mixer->ctl, &csource_info)) < 0)
@ -701,7 +701,7 @@ static int build_elem(snd_mixer_t *mixer, const char *sname)
voices = csource_info.count; voices = csource_info.count;
caps |= SND_MIXER_SCTCAP_CAPTURE; caps |= SND_MIXER_SCTCAP_CAPTURE;
present |= MIXER_PRESENT_CAPTURE_SOURCE; present |= MIXER_PRESENT_CAPTURE_SOURCE;
hctl_elem_add(&bag, helem); hctl_elem_add(simple, helem);
break; break;
} }
} }
@ -751,14 +751,11 @@ static int build_elem(snd_mixer_t *mixer, const char *sname)
caps &= ~SND_MIXER_SCTCAP_JOIN_VOLUME; caps &= ~SND_MIXER_SCTCAP_JOIN_VOLUME;
} }
} }
if (present == 0) if (present == 0) {
free(simple);
break; break;
sname1 = get_short_name(sname);
simple = build_elem_scontrol(mixer, sname1, index);
if (simple == NULL) {
snd_hctl_bag_destroy(&bag);
return -ENOMEM;
} }
sname1 = get_short_name(sname);
simple->present = present; simple->present = present;
simple->global_values = global_info.count; simple->global_values = global_info.count;
simple->gswitch_values = gswitch_info.count; simple->gswitch_values = gswitch_info.count;
@ -776,8 +773,11 @@ static int build_elem(snd_mixer_t *mixer, const char *sname)
simple->voices = voices; simple->voices = voices;
simple->min = min; simple->min = min;
simple->max = max; simple->max = max;
bag.private = simple; if (build_elem_scontrol(mixer, simple, sname1, index) < 0) {
simple->helems = bag; snd_hctl_bag_destroy(&simple->elems);
free(simple);
return -ENOMEM;
}
// fprintf(stderr, "sname = '%s', index = %i, present = 0x%x, voices = %i\n", sname, index, present, voices); // fprintf(stderr, "sname = '%s', index = %i, present = 0x%x, voices = %i\n", sname, index, present, voices);
}; };
return 0; return 0;