diff options
-rw-r--r-- | audio_route/audio_route.c | 71 | ||||
-rw-r--r-- | audio_route/include/audio_route/audio_route.h | 6 |
2 files changed, 77 insertions, 0 deletions
diff --git a/audio_route/audio_route.c b/audio_route/audio_route.c index d8e41511..15a28dd4 100644 --- a/audio_route/audio_route.c +++ b/audio_route/audio_route.c @@ -644,6 +644,77 @@ int audio_route_reset_path(struct audio_route *ar, const char *name) return 0; } +/* + * Operates on the specified path .. controls will be updated in the + * order listed in the XML file + */ +static int audio_route_update_path(struct audio_route *ar, const char *name, bool reverse) +{ + struct mixer_path *path; + int32_t i, end; + unsigned int j; + + if (!ar) { + ALOGE("invalid audio_route"); + return -1; + } + + path = path_get_by_name(ar, name); + if (!path) { + ALOGE("unable to find path '%s'", name); + return -1; + } + + i = reverse ? (path->length - 1) : 0; + end = reverse ? -1 : (int32_t)path->length; + + while (i != end) { + unsigned int ctl_index; + enum mixer_ctl_type type; + + ctl_index = path->setting[i].ctl_index; + + struct mixer_state * ms = &ar->mixer_state[ctl_index]; + + type = mixer_ctl_get_type(ms->ctl); + if ((type != MIXER_CTL_TYPE_BOOL) && (type != MIXER_CTL_TYPE_INT) && + (type != MIXER_CTL_TYPE_ENUM)) { + continue; + } + + /* if any value has changed, update the mixer */ + for (j = 0; j < ms->num_values; j++) { + if (ms->old_value[j] != ms->new_value[j]) { + if (type == MIXER_CTL_TYPE_ENUM) + mixer_ctl_set_value(ms->ctl, 0, ms->new_value[0]); + else + mixer_ctl_set_array(ms->ctl, ms->new_value, ms->num_values); + memcpy(ms->old_value, ms->new_value, ms->num_values * sizeof(int)); + break; + } + } + + i = reverse ? (i - 1) : (i + 1); + } + return 0; +} + +int audio_route_apply_and_update_path(struct audio_route *ar, const char *name) +{ + if (audio_route_apply_path(ar, name) < 0) { + return -1; + } + return audio_route_update_path(ar, name, false /*reverse*/); +} + +int audio_route_reset_and_update_path(struct audio_route *ar, const char *name) +{ + if (audio_route_reset_path(ar, name) < 0) { + return -1; + } + return audio_route_update_path(ar, name, true /*reverse*/); +} + struct audio_route *audio_route_init(unsigned int card, const char *xml_path) { struct config_parse_state state; diff --git a/audio_route/include/audio_route/audio_route.h b/audio_route/include/audio_route/audio_route.h index 452b6e27..9e46015c 100644 --- a/audio_route/include/audio_route/audio_route.h +++ b/audio_route/include/audio_route/audio_route.h @@ -28,9 +28,15 @@ void audio_route_free(struct audio_route *ar); /* Apply an audio route path by name */ int audio_route_apply_path(struct audio_route *ar, const char *name); +/* Apply and update mixer with audio route path by name */ +int audio_route_apply_and_update_path(struct audio_route *ar, const char *name); + /* Reset an audio route path by name */ int audio_route_reset_path(struct audio_route *ar, const char *name); +/* Reset and update mixer with audio route path by name */ +int audio_route_reset_and_update_path(struct audio_route *ar, const char *name); + /* Reset the audio routes back to the initial state */ void audio_route_reset(struct audio_route *ar); |