diff options
author | David.Coutherut <davidx.coutherut@intel.com> | 2013-06-03 13:45:51 +0200 |
---|---|---|
committer | David Wagner <david.wagner@intel.com> | 2014-09-24 13:54:42 +0200 |
commit | 9b42396aa0713be3435e30362bcb6ca52e544bf0 (patch) | |
tree | 4f487ce16c511d06ebe3d2e396372f45348f29f5 | |
parent | 867920ca46cc8ddc726bc0d406c454c17b7b9262 (diff) |
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
-rw-r--r-- | mixer.c | 61 |
1 files changed, 42 insertions, 19 deletions
@@ -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; |