static struct mixer_path *path_create(struct audio_route *ar, const char *name)
{
    struct mixer_path *new_mixer_path = NULL;

    if (path_get_by_name(ar, name)) {
        ALOGE("Path name '%s' already exists", name);
        return NULL;
    }

    /* check if we need to allocate more space for mixer paths */
    if (ar->mixer_path_size <= ar->num_mixer_paths) {
        if (ar->mixer_path_size == 0)
            ar->mixer_path_size = INITIAL_MIXER_PATH_SIZE;
        else
            ar->mixer_path_size *= 2;

        new_mixer_path = realloc(ar->mixer_path, ar->mixer_path_size *
                                 sizeof(struct mixer_path));
        if (new_mixer_path == NULL) {
            ALOGE("Unable to allocate more paths");
            return NULL;
        } else {
            ar->mixer_path = new_mixer_path;
        }
    }

    /* initialise the new mixer path */
    ar->mixer_path[ar->num_mixer_paths].name = strdup(name);
    ar->mixer_path[ar->num_mixer_paths].size = 0;
    ar->mixer_path[ar->num_mixer_paths].length = 0;
    ar->mixer_path[ar->num_mixer_paths].setting = NULL;

    /* return the mixer path just added, then increment number of them */
    return &ar->mixer_path[ar->num_mixer_paths++];
}
Beispiel #2
0
void audio_route_apply_path(struct audio_route *ar, const char *name)
{
    struct mixer_path *path;

    if (!ar) {
		ALOGE("%s: invalid audio_route", __func__);
        return;
    }

    path = path_get_by_name(ar, name);
    if (!path) {
        ALOGE("unable to find path '%s'", name);
        return;
    }

    path_apply(ar, path);
}
Beispiel #3
0
static void start_tag(void *data, const XML_Char *tag_name,
                      const XML_Char **attr)
{
    const XML_Char *attr_name = NULL;
    const XML_Char *attr_id = NULL;
    const XML_Char *attr_value = NULL;
    struct config_parse_state *state = data;
    struct audio_route *ar = state->ar;
    unsigned int i;
    struct mixer_value mixer_value;

    /* Get name, id and value attributes (these may be empty) */
    for (i = 0; attr[i]; i += 2) {
        if (strcmp(attr[i], "name") == 0)
            attr_name = attr[i + 1];
        if (strcmp(attr[i], "id") == 0)
            attr_id = attr[i + 1];
        else if (strcmp(attr[i], "value") == 0)
            attr_value = attr[i + 1];
    }

    /* Look at tags */
    if (strcmp(tag_name, "path") == 0) {
        if (attr_name == NULL) {
            printf("Unnamed path!");
        } else {
            if (state->level == 1) {
                /* top level path: create and stash the path */
                state->path = path_create(ar, (char *)attr_name);
            } else {
                /* nested path */
                struct mixer_path *sub_path = path_get_by_name(ar, attr_name);
                path_add_path(ar, state->path, sub_path);
            }
        }
    }
    else if (strcmp(tag_name, "ctl") == 0) {
        mixer_value.name = (char *) attr_name;
        mixer_value.value = (char *) attr_value;
        mixer_value.id = (char *) attr_id;

        path_add_value(ar, state->path, &mixer_value);
    }

    state->level++;
}
/* Reset an audio route path by name */
int audio_route_reset_path(struct audio_route *ar, const char *name)
{
    struct mixer_path *path;

    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;
    }

    path_reset(ar, path);

    return 0;
}
Beispiel #5
0
static void start_tag(void *data, const XML_Char *tag_name,
                      const XML_Char **attr)
{
    const XML_Char *attr_name = NULL;
    const XML_Char *attr_value = NULL;
    const XML_Char *attr_ignore = NULL;
	char *sub_attr_value;
    struct config_parse_state *state = data;
    struct audio_route *ar = state->ar;
    unsigned int i;
    unsigned int j;
    unsigned int k;
    struct mixer_ctl *ctl;
    int values[MAX_CTL_VALS];
	unsigned int num_values;
	unsigned int num_ctl_vals;
    struct mixer_setting mixer_setting;
	unsigned ignored = 0;

    /* Get name, type and value attributes (these may be empty) */
    for (i = 0; attr[i]; i += 2) {
        if (strcmp(attr[i], "name") == 0)
            attr_name = attr[i + 1];
        else if (strcmp(attr[i], "value") == 0)
            attr_value = attr[i + 1];
        else if (strcmp(attr[i], "ignore") == 0)
            attr_ignore = attr[i + 1];
    }

	if (attr_ignore && strcmp(attr_ignore, "1") == 0) {
		ignored = 1;
	}

    /* Look at tags */
    if (strcmp(tag_name, "path") == 0) {
        if (attr_name == NULL) {
            ALOGE("Unnamed path!");
        } else {
            if (state->level == 1) {
                /* top level path: create and stash the path */
                state->path = path_create(ar, (char *)attr_name);
            } else {
                /* nested path */
                struct mixer_path *sub_path = path_get_by_name(ar, attr_name);
                path_add_path(state->path, sub_path);
            }
        }
    }

	else if (strcmp(tag_name, "ctl") == 0 && state->level == 1 && ignored) {
        /* Obtain the mixer ctl and value */
        ctl = mixer_get_ctl_by_name(ar->mixer, attr_name);

		/* locate the mixer ctl in the list */
		for (i = 0; i < ar->num_mixer_ctls; i++) {
			if (ar->mixer_state[i].ctl == ctl)
				break;
		}
        ar->mixer_state[i].ignored = 1;
	}

    else if (strcmp(tag_name, "ctl") == 0) {
        /* Obtain the mixer ctl and value */
        ctl = mixer_get_ctl_by_name(ar->mixer, attr_name);
        switch (mixer_ctl_get_type(ctl)) {
        case MIXER_CTL_TYPE_BOOL:
        case MIXER_CTL_TYPE_INT:
			/* TODO */
			num_values = 1;
			char *sub_attr_value;
			for (j = 0; j < strlen((char*)attr_value); j++) {
				if (attr_value[j] == ',') num_values++;
			}
			sub_attr_value = (char*)attr_value;
			k = strlen((char*)attr_value);
			for (j = 0; j < k; j++) {
				if (sub_attr_value[j] == ',') sub_attr_value[j] = '\0';
			}
			sub_attr_value = (char*)attr_value;
			for (j = 0; j < num_values; j++) {
            	values[j] = atoi(sub_attr_value);
#if 1
				ALOGV("attr='%s' idx=%u str='%s' val=%d", attr_name, j,
						sub_attr_value, values[j]);
#endif
				sub_attr_value += (strlen(sub_attr_value) + 1);
			}
            break;
        case MIXER_CTL_TYPE_ENUM:
			num_values = 1;
            values[0] = mixer_enum_string_to_value(ctl, (char *)attr_value);
			ALOGV("attr='%s' attr_val='%s' val=%d", attr_name, attr_value, values[0]);
            break;
        default:
			num_values = 1;
            values[0] = 0;
			ALOGV("attr='%s' UNKNOWN CTL TYPE", attr_name);
            break;
        }

        if (state->level == 1) {
            /* top level ctl (initial setting) */

            /* locate the mixer ctl in the list */
            for (i = 0; i < ar->num_mixer_ctls; i++) {
                if (ar->mixer_state[i].ctl == ctl)
                    break;
            }

            /* apply the new value */
            ar->mixer_state[i].ignored = 0;
            ar->mixer_state[i].ctl_vals = num_values;
			for (j = 0; j < num_values; j++) {
            	ar->mixer_state[i].new_value[j] = values[j];
			}
        } else {
            /* nested ctl (within a path) */
            mixer_setting.ctl = ctl;
            mixer_setting.ctl_vals = num_values;
			for (j = 0; j < num_values; j++) {
            	mixer_setting.value[j] = values[j];
			}
            path_add_setting(state->path, &mixer_setting);
        }
    }

    state->level++;
}
static void start_tag(void *data, const XML_Char *tag_name,
                      const XML_Char **attr)
{
    const XML_Char *attr_name = NULL;
    const XML_Char *attr_id = NULL;
    const XML_Char *attr_value = NULL;
    struct config_parse_state *state = data;
    struct audio_route *ar = state->ar;
    unsigned int i;
    unsigned int ctl_index;
    struct mixer_ctl *ctl;
    int value;
    unsigned int id;
    struct mixer_value mixer_value;

    /* Get name, id and value attributes (these may be empty) */
    for (i = 0; attr[i]; i += 2) {
        if (strcmp(attr[i], "name") == 0)
            attr_name = attr[i + 1];
        if (strcmp(attr[i], "id") == 0)
            attr_id = attr[i + 1];
        else if (strcmp(attr[i], "value") == 0)
            attr_value = attr[i + 1];
    }

    /* Look at tags */
    if (strcmp(tag_name, "path") == 0) {
        if (attr_name == NULL) {
            ALOGE("Unnamed path!");
        } else {
            if (state->level == 1) {
                /* top level path: create and stash the path */
                state->path = path_create(ar, (char *)attr_name);
            } else {
                /* nested path */
                struct mixer_path *sub_path = path_get_by_name(ar, attr_name);
                path_add_path(ar, state->path, sub_path);
            }
        }
    }

    else if (strcmp(tag_name, "ctl") == 0) {
        /* 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;
        }

        switch (mixer_ctl_get_type(ctl)) {
        case MIXER_CTL_TYPE_BOOL:
        case MIXER_CTL_TYPE_INT:
            value = atoi((char *)attr_value);
            break;
        case MIXER_CTL_TYPE_ENUM:
            value = mixer_enum_string_to_value(ctl, (char *)attr_value);
            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) */

            /* 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));
            } 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;
            }
        } 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);
            else
                mixer_value.index = -1;
            path_add_value(ar, state->path, &mixer_value);
        }
    }

done:
    state->level++;
}
static void start_tag(void *data, const XML_Char *tag_name,
                      const XML_Char **attr)
{
    const XML_Char *attr_name = NULL;
    const XML_Char *attr_value = NULL;
    struct config_parse_state *state = data;
    struct audio_route *ar = state->ar;
    unsigned int i;
    struct mixer_ctl *ctl;
    int value = 0;
    struct mixer_setting mixer_setting;
    struct mixer_path *new_mixer_path = NULL;

    /* Get name, type and value attributes (these may be empty) */
    for (i = 0; attr[i]; i += 2) {
        if (strcmp(attr[i], "name") == 0)
            attr_name = attr[i + 1];
        else if (strcmp(attr[i], "value") == 0)
            attr_value = attr[i + 1];
    }

    /* Look at tags */
    if (strcmp(tag_name, "path") == 0) {
        if (attr_name == NULL) {
            ALOGE("Unnamed path!");
        } else {
            if (state->level == 1) {
                /* top level path: create and stash the path */
                new_mixer_path = path_create(ar, (char *)attr_name);
                if (new_mixer_path != NULL)
                    state->path = new_mixer_path;
            } else {
                /* nested path */
                struct mixer_path *sub_path = path_get_by_name(ar, attr_name);
                if (sub_path != NULL)
                    path_add_path(state->path, sub_path);
            }
        }
    }

    else if (strcmp(tag_name, "ctl") == 0) {
        if (attr_name == NULL) {
            ALOGE("Unnamed ctl!");
        } else {
            /* Obtain the mixer ctl and value */
            ctl = mixer_get_ctl_by_name(ar->mixer, attr_name);
            switch (mixer_ctl_get_type(ctl)) {
            case MIXER_CTL_TYPE_BOOL:
            case MIXER_CTL_TYPE_INT:
                if (attr_value != NULL)
                    value = atoi((char *)attr_value);
                break;
            case MIXER_CTL_TYPE_ENUM:
                if (attr_value != NULL)
                    value = mixer_enum_string_to_value(ctl, (char *)attr_value);
                break;
            default:
                value = 0;
                break;
            }

            if (state->level == 1) {
                /* top level ctl (initial setting) */

                /* locate the mixer ctl in the list */
                for (i = 0; i < ar->num_mixer_ctls; i++) {
                    if (ar->mixer_state[i].ctl == ctl)
                        break;
                }

                if (i < ar->num_mixer_ctls) {
                    /* apply the new value */
                    ar->mixer_state[i].new_value = value;
                }
            } else {
                /* nested ctl (within a path) */
                mixer_setting.ctl = ctl;
                mixer_setting.value = value;
                path_add_setting(state->path, &mixer_setting);
            }
        }
    }

    state->level++;
}