diff options
author | Andreas Schneider <asn@cryptomilk.org> | 2017-02-08 10:07:58 +0100 |
---|---|---|
committer | Andreas Schneider <asn@cryptomilk.org> | 2017-02-09 07:24:12 +0100 |
commit | 57fc1b8289fbb2359f45ce4d156a74a4dc531709 (patch) | |
tree | 632989d26f0621b0da80f76debf8dcc825362c59 | |
parent | c5b5812778e3596cf17ea1bee106b529880569d4 (diff) | |
download | android_system_media-cm-14.1_prerebase.tar.gz android_system_media-cm-14.1_prerebase.tar.bz2 android_system_media-cm-14.1_prerebase.zip |
audio_route: Add support to set complete byte arrayscm-14.1_prerebase
This adds a new directive <param> and allows us to set several values in
a byte array.
<param name="DSP4 XM f010:0" value="0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0" />
Change-Id: I9eda4cad414cd60e80b257c95858ff3e7fc2be07
-rw-r--r-- | audio_route/audio_route.c | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/audio_route/audio_route.c b/audio_route/audio_route.c index 74912cdd..58274dc3 100644 --- a/audio_route/audio_route.c +++ b/audio_route/audio_route.c @@ -17,6 +17,12 @@ #define LOG_TAG "audio_route" /*#define LOG_NDEBUG 0*/ +/*#define VERY_VERY_VERBOSE_LOGGING*/ +#ifdef VERY_VERY_VERBOSE_LOGGING +#define ALOGVV ALOGV +#else +#define ALOGVV(a...) do { } while(0) +#endif #include <errno.h> #include <expat.h> @@ -31,6 +37,7 @@ #define BUF_SIZE 1024 #define MIXER_XML_PATH "/system/etc/mixer_paths.xml" #define INITIAL_MIXER_PATH_SIZE 8 +#define BYTE_ARRAY_MAX_SIZE 512 union ctl_values { int *enumerated; @@ -39,6 +46,11 @@ union ctl_values { unsigned char *bytes; }; +struct param_values { + unsigned int num_bytes; + unsigned char *bytes; +}; + struct mixer_state { struct mixer_ctl *ctl; unsigned int num_values; @@ -555,6 +567,96 @@ static void start_tag(void *data, const XML_Char *tag_name, } } + else if (strcmp(tag_name, "param") == 0) { + unsigned int vnum; + int count; + char *str; + char *p; + + /* Obtain the mixer ctl and value */ + ctl = mixer_get_ctl_by_name(ar->mixer, attr_name); + if (ctl == NULL) { + ALOGE("Control '%s' doesn't exist - skipping", attr_name); + goto done; + } + + vnum = mixer_ctl_get_num_values(ctl); + if (vnum > BYTE_ARRAY_MAX_SIZE) { + ALOGE("Byte array control too big(%u)", vnum); + goto done; + } + + switch (mixer_ctl_get_type(ctl)) { + case MIXER_CTL_TYPE_BYTE: + str = strdup(attr_value); + if (str == NULL) { + goto done; + } + + p = strtok(str, " "); + for (count = 0; p != NULL; count++) { + p = strtok(NULL, " "); + } + free(str); + + ALOGVV("param: %d values in byte array %s to set", + count, + attr_name); + + if (count > BYTE_ARRAY_MAX_SIZE) { + count = BYTE_ARRAY_MAX_SIZE; + } + + break; + default: + 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; + } + } + + str = strdup(attr_value); + if (str == NULL) { + goto done; + } + + for (p = strtok(str, " "), count = 0; p != NULL; count++) { + value = strtol(p, NULL, 0); + if (value < 0) { + break; + } + ALOGE_IF(value > 0xFF, "Byte out of range"); + + if (state->level == 1) { + /* top level param */ + ALOGVV("param: Initialize %s byte[%d] with %ld", + attr_name, + count, + value); + ar->mixer_state[ctl_index].new_value.bytes[count] = value; + } else { + /* param in a ctl */ + mixer_value.ctl_index = ctl_index; + mixer_value.index = count; + mixer_value.value = value; + + ALOGVV("param: Add %s to path %s and set byte[%d] to %ld", + attr_name, + state->path->name, + count, + value); + path_add_value(ar, state->path, &mixer_value); + } + + p = strtok(NULL, " "); + } + free(str); + } + done: state->level++; } |