mirror of
https://github.com/openharmony/third_party_tinyalsa.git
synced 2026-07-19 15:24:22 -04:00
Defer filling enum-type mixers information
Currently, all information about all mixers are fetched during mixer_open(). For enum mixers, an additional step gets the string for each enumerated value - this can lead to a lot of ioctls and take time even when these mixers aren't used afterward. Defer fetching integer/string mapping values when needed (when getting/setting a enum mixer). Change-Id: I3681699eb55631a2bc7a1e66bf08aff3a845534f Signed-off-by: David Coutherut <davidx.coutherut@intel.com> Signed-off-by: David Wagner <david.wagner@intel.com> Author-Tracking-BZ: 113043
This commit is contained in:
committed by
David Wagner
parent
867920ca46
commit
9b42396aa0
@@ -91,7 +91,6 @@ void mixer_close(struct mixer *mixer)
|
||||
struct mixer *mixer_open(unsigned int card)
|
||||
{
|
||||
struct snd_ctl_elem_list elist;
|
||||
struct snd_ctl_elem_info tmp;
|
||||
struct snd_ctl_elem_id *eid = NULL;
|
||||
struct mixer *mixer = NULL;
|
||||
unsigned int n, m;
|
||||
@@ -137,22 +136,6 @@ struct mixer *mixer_open(unsigned int card)
|
||||
goto fail;
|
||||
mixer->ctl[n].info = ei;
|
||||
mixer->ctl[n].mixer = mixer;
|
||||
if (ei->type == SNDRV_CTL_ELEM_TYPE_ENUMERATED) {
|
||||
char **enames = calloc(ei->value.enumerated.items, sizeof(char*));
|
||||
if (!enames)
|
||||
goto fail;
|
||||
mixer->ctl[n].ename = enames;
|
||||
for (m = 0; m < ei->value.enumerated.items; m++) {
|
||||
memset(&tmp, 0, sizeof(tmp));
|
||||
tmp.id.numid = ei->id.numid;
|
||||
tmp.value.enumerated.item = m;
|
||||
if (ioctl(fd, SNDRV_CTL_IOCTL_ELEM_INFO, &tmp) < 0)
|
||||
goto fail;
|
||||
enames[m] = strdup(tmp.value.enumerated.name);
|
||||
if (!enames[m])
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(eid);
|
||||
@@ -463,11 +446,50 @@ unsigned int mixer_ctl_get_num_enums(struct mixer_ctl *ctl)
|
||||
return ctl->info->value.enumerated.items;
|
||||
}
|
||||
|
||||
int mixer_ctl_fill_enum_string(struct mixer_ctl *ctl)
|
||||
{
|
||||
struct snd_ctl_elem_info tmp;
|
||||
unsigned int m;
|
||||
char **enames;
|
||||
|
||||
if (ctl->ename) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
enames = calloc(ctl->info->value.enumerated.items, sizeof(char*));
|
||||
if (!enames)
|
||||
goto fail;
|
||||
for (m = 0; m < ctl->info->value.enumerated.items; m++) {
|
||||
memset(&tmp, 0, sizeof(tmp));
|
||||
tmp.id.numid = ctl->info->id.numid;
|
||||
tmp.value.enumerated.item = m;
|
||||
if (ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_INFO, &tmp) < 0)
|
||||
goto fail;
|
||||
enames[m] = strdup(tmp.value.enumerated.name);
|
||||
if (!enames[m])
|
||||
goto fail;
|
||||
}
|
||||
ctl->ename = enames;
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
if (enames) {
|
||||
for (m = 0; m < ctl->info->value.enumerated.items; m++) {
|
||||
if (enames[m]) {
|
||||
free(enames[m]);
|
||||
}
|
||||
}
|
||||
free(enames);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char *mixer_ctl_get_enum_string(struct mixer_ctl *ctl,
|
||||
unsigned int enum_id)
|
||||
{
|
||||
if (!ctl || (ctl->info->type != SNDRV_CTL_ELEM_TYPE_ENUMERATED) ||
|
||||
(enum_id >= ctl->info->value.enumerated.items))
|
||||
(enum_id >= ctl->info->value.enumerated.items) ||
|
||||
mixer_ctl_fill_enum_string(ctl) != 0)
|
||||
return NULL;
|
||||
|
||||
return (const char *)ctl->ename[enum_id];
|
||||
@@ -479,7 +501,8 @@ int mixer_ctl_set_enum_by_string(struct mixer_ctl *ctl, const char *string)
|
||||
struct snd_ctl_elem_value ev;
|
||||
int ret;
|
||||
|
||||
if (!ctl || (ctl->info->type != SNDRV_CTL_ELEM_TYPE_ENUMERATED))
|
||||
if (!ctl || (ctl->info->type != SNDRV_CTL_ELEM_TYPE_ENUMERATED) ||
|
||||
mixer_ctl_fill_enum_string(ctl) != 0)
|
||||
return -EINVAL;
|
||||
|
||||
num_enums = ctl->info->value.enumerated.items;
|
||||
|
||||
Reference in New Issue
Block a user