summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Schneider <asn@cryptomilk.org>2017-02-08 10:07:58 +0100
committerZhao Wei Liew <zhaoweiliew@lineageos.org>2017-02-09 13:52:38 +0000
commit0211728b4eeec735f5229e75cd5e838e1dc0109b (patch)
tree8030f3dea36cea6b1c09ab641d2fc25e46f738f6
parent40a30034dcce4b1fedaa617d992580a024468acf (diff)
downloadandroid_system_media-staging/cm-14.1-cafrebase.tar.gz
android_system_media-staging/cm-14.1-cafrebase.tar.bz2
android_system_media-staging/cm-14.1-cafrebase.zip
audio_route: Add support to set complete byte arraysstaging/cm-14.1-cafrebasecm-14.1_old
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 (cherry picked from commit 57fc1b8289fbb2359f45ce4d156a74a4dc531709)
-rw-r--r--audio_route/audio_route.c102
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++;
}