diff options
author | Zhang Chunfeng <zhangchunfeng@wingtech.com> | 2015-01-19 14:45:33 +0800 |
---|---|---|
committer | Scott Mertz <scott@cyngn.com> | 2015-02-02 14:16:32 -0800 |
commit | 8ac901f116f45d72f17dc955744262db22477969 (patch) | |
tree | fba0a4c3bee801e0eaea5eeca56170c0636d03d2 | |
parent | cd37382983781e1bdac7dff8b37e9dd2d4372d98 (diff) | |
download | android_system_media-8ac901f116f45d72f17dc955744262db22477969.tar.gz android_system_media-8ac901f116f45d72f17dc955744262db22477969.tar.bz2 android_system_media-8ac901f116f45d72f17dc955744262db22477969.zip |
audio_route: Support BYTE type controls
Change-Id: Ibe39c6d5cdd649b505da48f375010387ea94486c
-rw-r--r-- | audio_route/audio_route.c | 110 |
1 files changed, 87 insertions, 23 deletions
diff --git a/audio_route/audio_route.c b/audio_route/audio_route.c index c14cbf98..76d914fb 100644 --- a/audio_route/audio_route.c +++ b/audio_route/audio_route.c @@ -49,7 +49,7 @@ struct mixer_setting { struct mixer_value { unsigned int ctl_index; int index; - int value; + int *value; }; struct mixer_path { @@ -83,6 +83,7 @@ static bool is_supported_ctl_type(enum mixer_ctl_type type) case MIXER_CTL_TYPE_BOOL: case MIXER_CTL_TYPE_INT: case MIXER_CTL_TYPE_ENUM: + case MIXER_CTL_TYPE_BYTE: return true; default: return false; @@ -270,16 +271,22 @@ static int path_add_value(struct audio_route *ar, struct mixer_path *path, path->setting[path_index].ctl_index = mixer_value->ctl_index; path->setting[path_index].num_values = num_values; path->setting[path_index].value = malloc(num_values * sizeof(int)); - path->setting[path_index].value[0] = mixer_value->value; + path->setting[path_index].value[0] = mixer_value->value[0]; } if (mixer_value->index == -1) { - /* set all values the same */ - for (i = 0; i < num_values; i++) - path->setting[path_index].value[i] = mixer_value->value; + /* We have to fill the array of values now */ + if (mixer_ctl_get_type(ctl) == MIXER_CTL_TYPE_BYTE) { + memcpy(path->setting[path_index].value, mixer_value->value, + num_values * sizeof(int)); + } else { + /* set all values the same */ + for (i = 0; i < num_values; i++) + path->setting[path_index].value[i] = mixer_value->value[0]; + } } else { /* set only one value */ - path->setting[path_index].value[mixer_value->index] = mixer_value->value; + path->setting[path_index].value[mixer_value->index] = mixer_value->value[mixer_value->index]; } return 0; @@ -368,7 +375,8 @@ static void start_tag(void *data, const XML_Char *tag_name, unsigned int i; unsigned int ctl_index; struct mixer_ctl *ctl; - int value; + int num_values; + int *value; unsigned int id; struct mixer_value mixer_value; enum mixer_ctl_type type; @@ -407,24 +415,71 @@ static void start_tag(void *data, const XML_Char *tag_name, goto done; } + /* locate the mixer ctl in the list */ + for (ctl_index = 0; ctl_index < ar->num_mixer_ctls; ctl_index++) { + if (ar->mixer_state[ctl_index].ctl == ctl) + break; + } + + id = 0; + if (attr_id) { + id = atoi((char *)attr_id); + if (id < ar->mixer_state[ctl_index].num_values) { + ALOGE("value id out of range for mixer ctl '%s'", + mixer_ctl_get_name(ctl)); + goto done; + } + } + + value = malloc(ar->mixer_state[ctl_index].num_values * sizeof(int)); + switch (mixer_ctl_get_type(ctl)) { case MIXER_CTL_TYPE_BOOL: case MIXER_CTL_TYPE_INT: - value = (int) strtol((char *)attr_value, NULL, 0); + value[0] = (int) strtol((char *)attr_value, NULL, 0); break; case MIXER_CTL_TYPE_ENUM: - value = mixer_enum_string_to_value(ctl, (char *)attr_value); + value[0] = mixer_enum_string_to_value(ctl, (char *)attr_value); + break; + case MIXER_CTL_TYPE_BYTE: + if (attr_id) { + ar->mixer_state[ctl_index].new_value[id] = value[id]; + } else { + /* if we get here we have not got an ID but we do have a byte type */ + int byte_posn = 0; + int array_index = 0; + char *pch; + char *saveptr; + int read_val; + unsigned int write_val; + pch = strtok_r((char *)attr_value, " ", &saveptr); + while (pch != NULL) { + read_val = atoi((char *)pch); + if ((read_val > 255) || (read_val < 0)) { + ALOGE("Invalid value for byte mixer"); + goto done; + } + + if (byte_posn == 0) + value[array_index] = 0; + + write_val = value[array_index] + + (((unsigned int)read_val)<<(8*byte_posn)); + value[array_index] = write_val; + pch = strtok_r(NULL, " ", &saveptr); + byte_posn++; + if (byte_posn == 4) { + byte_posn = 0; + array_index++; + } + } + } break; default: value = 0; break; } - /* locate the mixer ctl in the list */ - for (ctl_index = 0; ctl_index < ar->num_mixer_ctls; ctl_index++) { - if (ar->mixer_state[ctl_index].ctl == ctl) - break; - } if (state->level == 1) { /* top level ctl (initial setting) */ @@ -434,28 +489,37 @@ static void start_tag(void *data, const XML_Char *tag_name, /* apply the new value */ if (attr_id) { /* set only one value */ - id = atoi((char *)attr_id); - if (id < ar->mixer_state[ctl_index].num_values) - ar->mixer_state[ctl_index].new_value[id] = value; - else - ALOGE("value id out of range for mixer ctl '%s'", - mixer_ctl_get_name(ctl)); + ar->mixer_state[ctl_index].new_value[id] = value[id]; } else { /* set all values the same */ - for (i = 0; i < ar->mixer_state[ctl_index].num_values; i++) - ar->mixer_state[ctl_index].new_value[i] = value; + if (mixer_ctl_get_type(ctl) == MIXER_CTL_TYPE_BYTE) { + memcpy(ar->mixer_state[ctl_index].new_value, value, + ar->mixer_state[ctl_index].num_values * sizeof(int)); + } else { + /* we can still be an array so set all values the same */ + for (i = 0; i < ar->mixer_state[ctl_index].num_values; i++) + ar->mixer_state[ctl_index].new_value[i] = value[0]; + } } } + + memcpy(ar->mixer_state[ctl_index].old_value, + ar->mixer_state[ctl_index].new_value, + ar->mixer_state[ctl_index].num_values * sizeof(int)); + } else { /* nested ctl (within a path) */ mixer_value.ctl_index = ctl_index; mixer_value.value = value; if (attr_id) - mixer_value.index = atoi((char *)attr_id); + mixer_value.index = id; else mixer_value.index = -1; path_add_value(ar, state->path, &mixer_value); } + + if (value) + free(value); } done: |