diff options
author | Richard Fitzgerald <rf@opensource.wolfsonmicro.com> | 2014-09-09 17:03:21 +0100 |
---|---|---|
committer | Richard Fitzgerald <rf@opensource.wolfsonmicro.com> | 2015-10-20 14:23:28 +0100 |
commit | 899cecebd15a7d08781d5f9362ec4bd7cc8863da (patch) | |
tree | e58b995c36c9b8185a9e1f98d07e7df13db77d1a | |
parent | 33fe27c809e0fa67e14db9fec37c5f2ef849aecb (diff) |
mixer: remove separate info list
Each mixer_ctl has an associated snd_ctl_elem_info, which was
kept in a separate array with pointers from the mixer_ctl to
its corresponding snd_ctl_elem_info. This means double
pointer dereferences when looking up the info. It also means
extra work to add support for extending the arrays to include
dynamically added controls because the pointers from the ctl
array to the info array would have to be updated.
This patch removes the info list and gives each mixer_ctl struct
its own local snd_ctl_elem_info, removing the additional pointer
dereferencing.
Change-Id: I03f7d411afd9e37f58b984584712fee64d85ef4e
Signed-off-by: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
-rw-r--r-- | mixer.c | 89 |
1 files changed, 42 insertions, 47 deletions
@@ -47,14 +47,13 @@ struct mixer_ctl { struct mixer *mixer; - struct snd_ctl_elem_info *info; + struct snd_ctl_elem_info info; char **ename; }; struct mixer { int fd; struct snd_ctl_card_info card_info; - struct snd_ctl_elem_info *elem_info; struct mixer_ctl *ctl; unsigned int count; }; @@ -72,7 +71,7 @@ void mixer_close(struct mixer *mixer) if (mixer->ctl) { for (n = 0; n < mixer->count; n++) { if (mixer->ctl[n].ename) { - unsigned int max = mixer->ctl[n].info->value.enumerated.items; + unsigned int max = mixer->ctl[n].info.value.enumerated.items; for (m = 0; m < max; m++) free(mixer->ctl[n].ename[m]); free(mixer->ctl[n].ename); @@ -81,9 +80,6 @@ void mixer_close(struct mixer *mixer) free(mixer->ctl); } - if (mixer->elem_info) - free(mixer->elem_info); - free(mixer); /* TODO: verify frees */ @@ -113,8 +109,7 @@ struct mixer *mixer_open(unsigned int card) goto fail; mixer->ctl = calloc(elist.count, sizeof(struct mixer_ctl)); - mixer->elem_info = calloc(elist.count, sizeof(struct snd_ctl_elem_info)); - if (!mixer->ctl || !mixer->elem_info) + if (!mixer->ctl) goto fail; if (ioctl(fd, SNDRV_CTL_IOCTL_CARD_INFO, &mixer->card_info) < 0) @@ -132,11 +127,10 @@ struct mixer *mixer_open(unsigned int card) goto fail; for (n = 0; n < mixer->count; n++) { - struct snd_ctl_elem_info *ei = mixer->elem_info + n; + struct snd_ctl_elem_info *ei = &mixer->ctl[n].info; ei->id.numid = eid[n].numid; if (ioctl(fd, SNDRV_CTL_IOCTL_ELEM_INFO, ei) < 0) 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*)); @@ -194,13 +188,14 @@ struct mixer_ctl *mixer_get_ctl(struct mixer *mixer, unsigned int id) struct mixer_ctl *mixer_get_ctl_by_name(struct mixer *mixer, const char *name) { unsigned int n; + struct mixer_ctl *ctl = mixer->ctl; if (!mixer) return NULL; for (n = 0; n < mixer->count; n++) - if (!strcmp(name, (char*) mixer->elem_info[n].id.name)) - return mixer->ctl + n; + if (!strcmp(name, (char*) ctl[n].info.id.name)) + return &ctl[n]; return NULL; } @@ -218,7 +213,7 @@ unsigned int mixer_ctl_get_id(struct mixer_ctl *ctl) /* numid values start at 1, return a 0-base value that * can be passed to mixer_get_ctl() */ - return ctl->info->id.numid - 1; + return ctl->info.id.numid - 1; } const char *mixer_ctl_get_name(struct mixer_ctl *ctl) @@ -226,7 +221,7 @@ const char *mixer_ctl_get_name(struct mixer_ctl *ctl) if (!ctl) return NULL; - return (const char *)ctl->info->id.name; + return (const char *)ctl->info.id.name; } enum mixer_ctl_type mixer_ctl_get_type(struct mixer_ctl *ctl) @@ -234,7 +229,7 @@ enum mixer_ctl_type mixer_ctl_get_type(struct mixer_ctl *ctl) if (!ctl) return MIXER_CTL_TYPE_UNKNOWN; - switch (ctl->info->type) { + switch (ctl->info.type) { case SNDRV_CTL_ELEM_TYPE_BOOLEAN: return MIXER_CTL_TYPE_BOOL; case SNDRV_CTL_ELEM_TYPE_INTEGER: return MIXER_CTL_TYPE_INT; case SNDRV_CTL_ELEM_TYPE_ENUMERATED: return MIXER_CTL_TYPE_ENUM; @@ -250,7 +245,7 @@ const char *mixer_ctl_get_type_string(struct mixer_ctl *ctl) if (!ctl) return ""; - switch (ctl->info->type) { + switch (ctl->info.type) { case SNDRV_CTL_ELEM_TYPE_BOOLEAN: return "BOOL"; case SNDRV_CTL_ELEM_TYPE_INTEGER: return "INT"; case SNDRV_CTL_ELEM_TYPE_ENUMERATED: return "ENUM"; @@ -266,7 +261,7 @@ unsigned int mixer_ctl_get_num_values(struct mixer_ctl *ctl) if (!ctl) return 0; - return ctl->info->count; + return ctl->info.count; } static int percent_to_int(struct snd_ctl_elem_info *ei, int percent) @@ -292,18 +287,18 @@ static int int_to_percent(struct snd_ctl_elem_info *ei, int value) int mixer_ctl_get_percent(struct mixer_ctl *ctl, unsigned int id) { - if (!ctl || (ctl->info->type != SNDRV_CTL_ELEM_TYPE_INTEGER)) + if (!ctl || (ctl->info.type != SNDRV_CTL_ELEM_TYPE_INTEGER)) return -EINVAL; - return int_to_percent(ctl->info, mixer_ctl_get_value(ctl, id)); + return int_to_percent(&ctl->info, mixer_ctl_get_value(ctl, id)); } int mixer_ctl_set_percent(struct mixer_ctl *ctl, unsigned int id, int percent) { - if (!ctl || (ctl->info->type != SNDRV_CTL_ELEM_TYPE_INTEGER)) + if (!ctl || (ctl->info.type != SNDRV_CTL_ELEM_TYPE_INTEGER)) return -EINVAL; - return mixer_ctl_set_value(ctl, id, percent_to_int(ctl->info, percent)); + return mixer_ctl_set_value(ctl, id, percent_to_int(&ctl->info, percent)); } int mixer_ctl_get_value(struct mixer_ctl *ctl, unsigned int id) @@ -311,16 +306,16 @@ int mixer_ctl_get_value(struct mixer_ctl *ctl, unsigned int id) struct snd_ctl_elem_value ev; int ret; - if (!ctl || (id >= ctl->info->count)) + if (!ctl || (id >= ctl->info.count)) return -EINVAL; memset(&ev, 0, sizeof(ev)); - ev.id.numid = ctl->info->id.numid; + ev.id.numid = ctl->info.id.numid; ret = ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_READ, &ev); if (ret < 0) return ret; - switch (ctl->info->type) { + switch (ctl->info.type) { case SNDRV_CTL_ELEM_TYPE_BOOLEAN: return !!ev.value.integer.value[id]; @@ -347,13 +342,13 @@ int mixer_ctl_get_array(struct mixer_ctl *ctl, void *array, size_t count) size_t size; void *source; - if (!ctl || (count > ctl->info->count) || !count || !array) + if (!ctl || (count > ctl->info.count) || !count || !array) return -EINVAL; memset(&ev, 0, sizeof(ev)); - ev.id.numid = ctl->info->id.numid; + ev.id.numid = ctl->info.id.numid; - switch (ctl->info->type) { + switch (ctl->info.type) { case SNDRV_CTL_ELEM_TYPE_BOOLEAN: case SNDRV_CTL_ELEM_TYPE_INTEGER: ret = ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_READ, &ev); @@ -365,12 +360,12 @@ int mixer_ctl_get_array(struct mixer_ctl *ctl, void *array, size_t count) case SNDRV_CTL_ELEM_TYPE_BYTES: /* check if this is new bytes TLV */ - if (ctl->info->access & SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE) { + if (ctl->info.access & SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE) { struct snd_ctl_tlv *tlv; int ret; tlv = calloc(1, sizeof(*tlv) + count); - tlv->numid = ctl->info->id.numid; + tlv->numid = ctl->info.id.numid; tlv->length = count; ret = ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_TLV_READ, tlv); @@ -403,16 +398,16 @@ int mixer_ctl_set_value(struct mixer_ctl *ctl, unsigned int id, int value) struct snd_ctl_elem_value ev; int ret; - if (!ctl || (id >= ctl->info->count)) + if (!ctl || (id >= ctl->info.count)) return -EINVAL; memset(&ev, 0, sizeof(ev)); - ev.id.numid = ctl->info->id.numid; + ev.id.numid = ctl->info.id.numid; ret = ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_READ, &ev); if (ret < 0) return ret; - switch (ctl->info->type) { + switch (ctl->info.type) { case SNDRV_CTL_ELEM_TYPE_BOOLEAN: ev.value.integer.value[id] = !!value; break; @@ -447,13 +442,13 @@ int mixer_ctl_set_array(struct mixer_ctl *ctl, const void *array, size_t count) size_t size; void *dest; - if (!ctl || (count > ctl->info->count) || !count || !array) + if (!ctl || (count > ctl->info.count) || !count || !array) return -EINVAL; memset(&ev, 0, sizeof(ev)); - ev.id.numid = ctl->info->id.numid; + ev.id.numid = ctl->info.id.numid; - switch (ctl->info->type) { + switch (ctl->info.type) { case SNDRV_CTL_ELEM_TYPE_BOOLEAN: case SNDRV_CTL_ELEM_TYPE_INTEGER: size = sizeof(ev.value.integer.value[0]); @@ -462,11 +457,11 @@ int mixer_ctl_set_array(struct mixer_ctl *ctl, const void *array, size_t count) case SNDRV_CTL_ELEM_TYPE_BYTES: /* check if this is new bytes TLV */ - if (ctl->info->access & SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE) { + if (ctl->info.access & SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE) { struct snd_ctl_tlv *tlv; int ret = 0; tlv = calloc(1, sizeof(*tlv) + count); - tlv->numid = ctl->info->id.numid; + tlv->numid = ctl->info.id.numid; tlv->length = count; memcpy(tlv->tlv, array, count); @@ -491,18 +486,18 @@ int mixer_ctl_set_array(struct mixer_ctl *ctl, const void *array, size_t count) int mixer_ctl_get_range_min(struct mixer_ctl *ctl) { - if (!ctl || (ctl->info->type != SNDRV_CTL_ELEM_TYPE_INTEGER)) + if (!ctl || (ctl->info.type != SNDRV_CTL_ELEM_TYPE_INTEGER)) return -EINVAL; - return ctl->info->value.integer.min; + return ctl->info.value.integer.min; } int mixer_ctl_get_range_max(struct mixer_ctl *ctl) { - if (!ctl || (ctl->info->type != SNDRV_CTL_ELEM_TYPE_INTEGER)) + if (!ctl || (ctl->info.type != SNDRV_CTL_ELEM_TYPE_INTEGER)) return -EINVAL; - return ctl->info->value.integer.max; + return ctl->info.value.integer.max; } unsigned int mixer_ctl_get_num_enums(struct mixer_ctl *ctl) @@ -510,14 +505,14 @@ unsigned int mixer_ctl_get_num_enums(struct mixer_ctl *ctl) if (!ctl) return 0; - return ctl->info->value.enumerated.items; + return ctl->info.value.enumerated.items; } 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)) + if (!ctl || (ctl->info.type != SNDRV_CTL_ELEM_TYPE_ENUMERATED) || + (enum_id >= ctl->info.value.enumerated.items)) return NULL; return (const char *)ctl->ename[enum_id]; @@ -529,15 +524,15 @@ 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)) return -EINVAL; - num_enums = ctl->info->value.enumerated.items; + num_enums = ctl->info.value.enumerated.items; for (i = 0; i < num_enums; i++) { if (!strcmp(string, ctl->ename[i])) { memset(&ev, 0, sizeof(ev)); ev.value.enumerated.item[0] = i; - ev.id.numid = ctl->info->id.numid; + ev.id.numid = ctl->info.id.numid; ret = ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_WRITE, &ev); if (ret < 0) return ret; |