int list(int argc, char **argv) {
    int nMixer = -1;

    if (argc == 3)
        nMixer = atoi(argv[2]);

    if (argc != 3 || nMixer < 0 || nMixer > 7) {
        printf("Usage: ainfo list <card number>\n"
               "where <card number> is between 0 and 7\n");
        return 0;
    }

    mixer *m = mixer_open(nMixer);

    if (m == NULL) {
        printf("Unable to open card #%d\n", nMixer);
        return 0;
    }

    int count = mixer_get_num_ctls(m);
    printf("Found %d controls:\n", count);

    for (int i = 0; i < count; i++) {
        char name[64], type[64];
        mixer_ctl *ctl = mixer_get_ctl(m, i);
        mixer_ctl_get_name(ctl, name, sizeof(name));
        printf("%d: %s (0x%x)\n", i, name, mixer_ctl_get_type(ctl));
    }

    return 0;
}
Пример #2
0
size_t
actlstr(char *buf, size_t n, char *ch, struct mixer *mx) {
	size_t ret;
	char *status;
	struct mixer_ctl *ctl;

	if (!(ctl = mixer_get_ctl_by_name(mx, ch))) {
		mixer_close(mx);
		die("couldn't find mixer ctl '%s'\n", ch);
	}

	switch (mixer_ctl_get_type(ctl)) {
	case MIXER_CTL_TYPE_INT:
		if ((ret = snprintf(buf, n, "%d%%",
				mixer_ctl_get_percent(ctl, 0))) > n)
			ret = n;
		break;
	case MIXER_CTL_TYPE_BOOL:
		status = mixer_ctl_get_value(ctl, 0) ? "On" : "Off";
		ret = stpncpy(buf, status, n) - buf;
		break;
	default:
		mixer_close(mx);
		die("unsupported ctl type '%s'\n",
			mixer_ctl_get_type_string(ctl));
	};

	return ret;
}
Пример #3
0
static void tinymix_set_value(struct mixer *mixer, char *name, char *value)
{
    struct mixer_ctl *ctl;
    enum mixer_ctl_type type;
    unsigned int i, num_values;

    ctl = mixer_get_ctl_by_name(mixer, name);
    if(!ctl) {
        log_err("cannot find control \'%s\'", name);
        return;
    }
    type = mixer_ctl_get_type(ctl);
    num_values = mixer_ctl_get_num_values(ctl);

    if(isdigit(value[0])) {
        int val = atoi(value);
        for(i = 0; i < num_values; i++) {
            if(mixer_ctl_set_value(ctl, i, val)) {
		log_err("value %d not accepted for %s", val, name);
		return;
            }
        }
    } else if(type == MIXER_CTL_TYPE_ENUM) {
        if(mixer_ctl_set_enum_by_string(ctl, value))
            log_err("value %s not accepted for %s", value, name);
    } else if(type == MIXER_CTL_TYPE_BOOL) {
        if(strcasecmp(value,"on") == 0) i = 1;
        else if(strcasecmp(value, "off") == 0) i = 0;
        else {
            log_err("cannot set %s to \'%s\', on/off or 1/0 expected", name, value);
            return;
        }
        if(mixer_ctl_set_value(ctl, 0, i)) log_err("value %d not accepted for %s", i, name);
    } else log_err("type mismatch for %s, ignored", name);
}
static int set_clocks_enabled(bool enable)
{
    enum mixer_ctl_type type;
    struct mixer_ctl *ctl;
    struct mixer *mixer = mixer_open(0);

    if (mixer == NULL) {
        ALOGE("Error opening mixer 0");
        return -1;
    }

    ctl = mixer_get_ctl_by_name(mixer, AMP_MIXER_CTL);
    if (ctl == NULL) {
        mixer_close(mixer);
        ALOGE("%s: Could not find %s\n", __func__, AMP_MIXER_CTL);
        return -ENODEV;
    }

    type = mixer_ctl_get_type(ctl);
    if (type != MIXER_CTL_TYPE_ENUM) {
        ALOGE("%s: %s is not supported\n", __func__, AMP_MIXER_CTL);
        mixer_close(mixer);
        return -ENOTTY;
    }

    mixer_ctl_set_value(ctl, 0, enable);
    mixer_close(mixer);
    return 0;
}
Пример #5
0
static void tinymix_set_value(struct mixer *mixer, unsigned int id,
                              char *string)
{
    struct mixer_ctl *ctl;
    enum mixer_ctl_type type;
    unsigned int num_values;
    unsigned int i;

    ctl = mixer_get_ctl(mixer, id);
    type = mixer_ctl_get_type(ctl);
    num_values = mixer_ctl_get_num_values(ctl);

    if (isdigit(string[0])) {
        int value = atoi(string);

        for (i = 0; i < num_values; i++) {
            if (mixer_ctl_set_value(ctl, i, value)) {
                fprintf(stderr, "Error: invalid value\n");
                return;
            }
        }
    } else {
        if (type == MIXER_CTL_TYPE_ENUM) {
            if (mixer_ctl_set_enum_by_string(ctl, string))
                fprintf(stderr, "Error: invalid enum value\n");
        } else {
            fprintf(stderr, "Error: only enum types can be set with strings\n");
        }
    }
}
static void tinymix_set_value(struct mixer *mixer, const char *control,
                              char **values, unsigned int num_values)
{
    struct mixer_ctl *ctl;
    enum mixer_ctl_type type;
    unsigned int num_ctl_values;
    unsigned int i;

    if (isdigit(control[0]))
        ctl = mixer_get_ctl(mixer, atoi(control));
    else
        ctl = mixer_get_ctl_by_name(mixer, control);

    if (!ctl) {
        fprintf(stderr, "Invalid mixer control\n");
        return;
    }

    type = mixer_ctl_get_type(ctl);
    num_ctl_values = mixer_ctl_get_num_values(ctl);

    if (isdigit(values[0][0])) {
        if (num_values == 1) {
            /* Set all values the same */
            int value = atoi(values[0]);

            for (i = 0; i < num_ctl_values; i++) {
                if (mixer_ctl_set_value(ctl, i, value)) {
                    fprintf(stderr, "Error: invalid value\n");
                    return;
                }
            }
        } else {
            /* Set multiple values */
            if (num_values > num_ctl_values) {
                fprintf(stderr,
                        "Error: %d values given, but control only takes %d\n",
                        num_values, num_ctl_values);
                return;
            }
            for (i = 0; i < num_values; i++) {
                if (mixer_ctl_set_value(ctl, i, atoi(values[i]))) {
                    fprintf(stderr, "Error: invalid value for index %d\n", i);
                    return;
                }
            }
        }
    } else {
        if (type == MIXER_CTL_TYPE_ENUM) {
            if (num_values != 1) {
                fprintf(stderr, "Enclose strings in quotes and try again\n");
                return;
            }
            if (mixer_ctl_set_enum_by_string(ctl, values[0]))
                fprintf(stderr, "Error: invalid enum value\n");
        } else {
            fprintf(stderr, "Error: only enum types can be set with strings\n");
        }
    }
}
static void tinymix_detail_control(struct mixer *mixer, const char *control,
                                   int print_all)
{
    struct mixer_ctl *ctl;
    enum mixer_ctl_type type;
    unsigned int num_values;
    unsigned int i;
    int min, max;

    if (isdigit(control[0]))
        ctl = mixer_get_ctl(mixer, atoi(control));
    else
        ctl = mixer_get_ctl_by_name(mixer, control);

    if (!ctl) {
        fprintf(stderr, "Invalid mixer control\n");
        return;
    }

    type = mixer_ctl_get_type(ctl);
    num_values = mixer_ctl_get_num_values(ctl);

    if (print_all)
        printf("%s:", mixer_ctl_get_name(ctl));

    for (i = 0; i < num_values; i++) {
        switch (type)
        {
        case MIXER_CTL_TYPE_INT:
            printf(" %d", mixer_ctl_get_value(ctl, i));
            break;
        case MIXER_CTL_TYPE_BOOL:
            printf(" %s", mixer_ctl_get_value(ctl, i) ? "On" : "Off");
            break;
        case MIXER_CTL_TYPE_ENUM:
            tinymix_print_enum(ctl, print_all);
            break;
         case MIXER_CTL_TYPE_BYTE:
            printf(" 0x%02x", mixer_ctl_get_value(ctl, i));
            break;
        default:
            printf(" unknown");
            break;
        };
    }

    if (print_all) {
        if (type == MIXER_CTL_TYPE_INT) {
            min = mixer_ctl_get_range_min(ctl);
            max = mixer_ctl_get_range_max(ctl);
            printf(" (range %d->%d)", min, max);
        }
    }
    printf("\n");
}
Пример #8
0
static void tinymix_detail_control(struct mixer *mixer, unsigned int id,
                                   int print_all)
{
    struct mixer_ctl *ctl;
    enum mixer_ctl_type type;
    unsigned int num_values;
    char buffer[256];
    unsigned int i;
    int min, max;

    if (id >= mixer_get_num_ctls(mixer)) {
        fprintf(stderr, "Invalid mixer control\n");
        return;
    }

    ctl = mixer_get_ctl(mixer, id);

    mixer_ctl_get_name(ctl, buffer, sizeof(buffer));
    type = mixer_ctl_get_type(ctl);
    num_values = mixer_ctl_get_num_values(ctl);

    if (print_all)
        printf("%s:", buffer);

    for (i = 0; i < num_values; i++) {
        switch (type)
        {
        case MIXER_CTL_TYPE_INT:
            printf(" %d", mixer_ctl_get_value(ctl, i));
            break;
        case MIXER_CTL_TYPE_BOOL:
            printf(" %s", mixer_ctl_get_value(ctl, i) ? "On" : "Off");
            break;
        case MIXER_CTL_TYPE_ENUM:
            tinymix_print_enum(ctl, print_all);
            break;
         case MIXER_CTL_TYPE_BYTE:
            printf(" 0x%02x", mixer_ctl_get_value(ctl, i));
            break;
        default:
            printf(" unknown");
            break;
        };
    }

    if (print_all) {
        if (type == MIXER_CTL_TYPE_INT) {
            min = mixer_ctl_get_range_min(ctl);
            max = mixer_ctl_get_range_max(ctl);
            printf(" (range %d->%d)", min, max);
        }
    }
    printf("\n");
}
static bool setMixerValue(struct mixer* mixer, const char* name, const char* values)
{
    if (!mixer) {
        ALOGE("no mixer in setMixerValue");
        return false;
    }
    struct mixer_ctl *ctl = mixer_get_ctl_by_name(mixer, name);
    if (!ctl) {
        ALOGE("mixer_get_ctl_by_name failed for %s", name);
        return false;
    }

    enum mixer_ctl_type type = mixer_ctl_get_type(ctl);
    int numValues = mixer_ctl_get_num_values(ctl);
    int intValue;
    char stringValue[MAX_LINE_LENGTH];

    for (int i = 0; i < numValues && values; i++) {
        // strip leading space
        while (*values == ' ') values++;
        if (*values == 0) break;

        switch (type) {
            case MIXER_CTL_TYPE_BOOL:
            case MIXER_CTL_TYPE_INT:
                if (sscanf(values, "%d", &intValue) == 1) {
                    if (mixer_ctl_set_value(ctl, i, intValue) != 0) {
                        ALOGE("mixer_ctl_set_value failed for %s %d", name, intValue);
                    }
                } else {
                    ALOGE("Could not parse %s as int for %s", values, name);
                }
                break;
            case MIXER_CTL_TYPE_ENUM:
                if (sscanf(values, "%s", stringValue) == 1) {
                    if (mixer_ctl_set_enum_by_string(ctl, stringValue) != 0) {
                        ALOGE("mixer_ctl_set_enum_by_string failed for %s %s", name, stringValue);
                    }
                } else {
                    ALOGE("Could not parse %s as enum for %s", values, name);
                }
                break;
            default:
                ALOGE("unsupported mixer type %d for %s", type, name);
                break;
        }

        values = strchr(values, ' ');
    }

    return true;
}
Пример #10
0
/* saves the current state of the mixer, for resetting all controls */
static void save_mixer_state(struct audio_route *ar)
{
    unsigned int i;
    enum mixer_ctl_type type;

    for (i = 0; i < ar->num_mixer_ctls; i++) {
        type = mixer_ctl_get_type(ar->mixer_state[i].ctl);
        if (!is_supported_ctl_type(type))
            continue;

        memcpy(ar->mixer_state[i].reset_value, ar->mixer_state[i].new_value,
               ar->mixer_state[i].num_values * sizeof(int));
    }
}
Пример #11
0
int audio_route_control_set_enum(unsigned int card_slot, char *control_name,
                                 char *string)
{
    struct mixer *control_mixer;
    struct mixer_ctl *ctl;
    const char *name;
    unsigned int num_ctls, num_values;
    unsigned int i, j;
    enum mixer_ctl_type type;
    int value;
    int ret, mixer_ret;

    control_mixer = mixer_open(card_slot);
    if (!control_mixer) {
        ALOGE("Unable to open the control mixer, aborting.");
        return -1;
    }
    ALOGV("Control mixer open successful.");

    num_ctls = mixer_get_num_ctls(control_mixer);

    ret = 0;
    for (i = 0; i < num_ctls; i++) {
        ctl = mixer_get_ctl(control_mixer, i);
        name = mixer_ctl_get_name(ctl);
        if (name && strcmp(name, control_name) == 0) {
            /* Found the control, update and exit */
            type = mixer_ctl_get_type(ctl);
            if (type == MIXER_CTL_TYPE_ENUM) {
                if (mixer_ctl_set_enum_by_string(ctl, string)) {
                    ALOGE("Error: invalid enum value");
                    ret = -1;
                } else {
                    ALOGV("Setting %s to string %s", name, string);
                }
            } else {
                ALOGV("Error: only enum types can be set with strings");
                ret = -1;
            }
            break;
        }
    }

    mixer_close(control_mixer);
    return ret;
}
Пример #12
0
static void free_mixer_state(struct audio_route *ar)
{
    unsigned int i;
    enum mixer_ctl_type type;

    for (i = 0; i < ar->num_mixer_ctls; i++) {
        type = mixer_ctl_get_type(ar->mixer_state[i].ctl);
        if (!is_supported_ctl_type(type))
            continue;

        free(ar->mixer_state[i].old_value);
        free(ar->mixer_state[i].new_value);
        free(ar->mixer_state[i].reset_value);
    }

    free(ar->mixer_state);
    ar->mixer_state = NULL;
}
Пример #13
0
static void tinymix_set_value(struct mixer *mixer, unsigned int id,
                              unsigned int value)
{
	struct mixer_ctl *ctl;
	enum mixer_ctl_type type;
	unsigned int num_values;
	unsigned int i;

	ctl = mixer_get_ctl(mixer, id);
	type = mixer_ctl_get_type(ctl);
	num_values = mixer_ctl_get_num_values(ctl);

	for (i = 0; i < num_values; i++) {
		if (mixer_ctl_set_value(ctl, i, value)) {
			fprintf(stderr, "Error: invalid value\n");
			return;
		}
	}
}
Пример #14
0
static int path_apply(struct audio_route *ar, struct mixer_path *path)
{
    unsigned int i;
    unsigned int ctl_index;
    struct mixer_ctl *ctl;
    enum mixer_ctl_type type;

    for (i = 0; i < path->length; i++) {
        ctl_index = path->setting[i].ctl_index;
        ctl = index_to_ctl(ar, ctl_index);
        type = mixer_ctl_get_type(ctl);
        if (!is_supported_ctl_type(type))
            continue;

        /* apply the new value(s) */
        memcpy(ar->mixer_state[ctl_index].new_value, path->setting[i].value,
               path->setting[i].num_values * sizeof(int));
    }

    return 0;
}
static int alloc_mixer_state(struct audio_route *ar)
{
    unsigned int i;
    unsigned int j;
    unsigned int num_values;
    struct mixer_ctl *ctl;
    enum mixer_ctl_type type;

    ar->num_mixer_ctls = mixer_get_num_ctls(ar->mixer);
    ar->mixer_state = malloc(ar->num_mixer_ctls * sizeof(struct mixer_state));
    if (!ar->mixer_state)
        return -1;

    for (i = 0; i < ar->num_mixer_ctls; i++) {
        ctl = mixer_get_ctl(ar->mixer, i);
        num_values = mixer_ctl_get_num_values(ctl);

        ar->mixer_state[i].ctl = ctl;
        ar->mixer_state[i].num_values = num_values;

        /* Skip unsupported types that are not supported yet in XML */
        type = mixer_ctl_get_type(ctl);
        if ((type != MIXER_CTL_TYPE_BOOL) && (type != MIXER_CTL_TYPE_INT) &&
            (type != MIXER_CTL_TYPE_ENUM))
            continue;

        ar->mixer_state[i].old_value = malloc(num_values * sizeof(int));
        ar->mixer_state[i].new_value = malloc(num_values * sizeof(int));
        ar->mixer_state[i].reset_value = malloc(num_values * sizeof(int));

        if (type == MIXER_CTL_TYPE_ENUM)
            ar->mixer_state[i].old_value[0] = mixer_ctl_get_value(ctl, 0);
        else
            mixer_ctl_get_array(ctl, ar->mixer_state[i].old_value, num_values);
        memcpy(ar->mixer_state[i].new_value, ar->mixer_state[i].old_value,
               num_values * sizeof(int));
    }

    return 0;
}
/* Update the mixer with any changed values */
int audio_route_update_mixer(struct audio_route *ar)
{
    unsigned int i;
    unsigned int j;
    struct mixer_ctl *ctl;

    for (i = 0; i < ar->num_mixer_ctls; i++) {
        unsigned int num_values = ar->mixer_state[i].num_values;
        enum mixer_ctl_type type;

        ctl = ar->mixer_state[i].ctl;

        /* Skip unsupported types */
        type = mixer_ctl_get_type(ctl);
        if ((type != MIXER_CTL_TYPE_BOOL) && (type != MIXER_CTL_TYPE_INT) &&
            (type != MIXER_CTL_TYPE_ENUM))
            continue;

        /* if the value has changed, update the mixer */
        bool changed = false;
        for (j = 0; j < num_values; j++) {
            if (ar->mixer_state[i].old_value[j] != ar->mixer_state[i].new_value[j]) {
                changed = true;
                break;
            }
        }
        if (changed) {
            if (type == MIXER_CTL_TYPE_ENUM)
                mixer_ctl_set_value(ctl, 0, ar->mixer_state[i].new_value[0]);
            else
                mixer_ctl_set_array(ctl, ar->mixer_state[i].new_value, num_values);
            memcpy(ar->mixer_state[i].old_value, ar->mixer_state[i].new_value,
                   num_values * sizeof(int));
        }
    }

    return 0;
}
Пример #17
0
static void tinymix_detail_control(struct mixer *mixer, const char *control)
{
    struct mixer_ctl *ctl;
    enum mixer_ctl_type type;
    unsigned int num_values;
    unsigned int i;
    int min, max;
    int ret;
    char *buf = NULL;
    unsigned int tlv_header_size = 0;

    if (isdigit(control[0]))
        ctl = mixer_get_ctl(mixer, atoi(control));
    else
        ctl = mixer_get_ctl_by_name(mixer, control);

    if (!ctl) {
        fprintf(stderr, "Invalid mixer control\n");
        return;
    }

    type = mixer_ctl_get_type(ctl);
    num_values = mixer_ctl_get_num_values(ctl);

    if ((type == MIXER_CTL_TYPE_BYTE) && (num_values > 0)) {
        if (mixer_ctl_is_access_tlv_rw(ctl) != 0) {
            tlv_header_size = TLV_HEADER_SIZE;
        }
        buf = calloc(1, num_values + tlv_header_size);
        if (buf == NULL) {
            fprintf(stderr, "Failed to alloc mem for bytes %u\n", num_values);
            return;
        }

        ret = mixer_ctl_get_array(ctl, buf, num_values + tlv_header_size);
        if (ret < 0) {
            fprintf(stderr, "Failed to mixer_ctl_get_array\n");
            free(buf);
            return;
        }
    }

    for (i = 0; i < num_values; i++) {
        switch (type)
        {
        case MIXER_CTL_TYPE_INT:
            printf("%d", mixer_ctl_get_value(ctl, i));
            break;
        case MIXER_CTL_TYPE_BOOL:
            printf("%s", mixer_ctl_get_value(ctl, i) ? "On" : "Off");
            break;
        case MIXER_CTL_TYPE_ENUM:
            tinymix_print_enum(ctl);
            break;
        case MIXER_CTL_TYPE_BYTE:
            /* skip printing TLV header if exists */
            printf(" %02x", buf[i + tlv_header_size]);
            break;
        default:
            printf("unknown");
            break;
        };
        if ((i + 1) < num_values) {
           printf(", ");
        }
    }

    if (type == MIXER_CTL_TYPE_INT) {
        min = mixer_ctl_get_range_min(ctl);
        max = mixer_ctl_get_range_max(ctl);
        printf(" (range %d->%d)", min, max);
    }

    free(buf);
}
Пример #18
0
int mixer_cache_populate(struct audio_tool_mixer_cache *cache, struct mixer *mixer)
{
    struct mixer_ctl *ctl;
    struct audio_tool_mixer_control_info *cur;
    const char* name;
    size_t count, n, v;
    int tmp;

    if (!cache)
        return EINVAL;

    if (!mixer)
        return EINVAL;

    if (cache->ctrls)
        free(cache->ctrls);

    count = mixer_get_num_ctls(mixer);
    cache->count = count;

    if (count) {
        cache->ctrls = calloc(count, sizeof(struct audio_tool_mixer_control_info));
        if (! cache->ctrls)
            return -ENOMEM;
    }

    for (n = 0, cur = cache->ctrls ; n < count ; ++n, ++cur) {
        ctl = mixer_get_ctl(mixer, n);
        if (!ctl)
            return ENODEV;
        name = mixer_ctl_get_name(ctl);
        if (!name)
            return ENODEV;

        cur->id = n;
        cur->type = mixer_ctl_get_type(ctl);
        strcpy(cur->name, name);
        cur->num_values = mixer_ctl_get_num_values(ctl);
        if (cur->num_values > MAX_NUM_VALUES)
            cur->num_values = MAX_NUM_VALUES;
        for (v = 0 ; v < cur->num_values ; ++v) {
            switch (cur->type) {
            case MIXER_CTL_TYPE_BOOL:
            case MIXER_CTL_TYPE_INT:
                cur->value.integer[v] = mixer_ctl_get_value(ctl, v);
                break;
            case MIXER_CTL_TYPE_ENUM:
                tmp = mixer_ctl_get_value(ctl, v);
                name = mixer_ctl_get_enum_string(ctl, tmp);
                // null value names were causing seg fault here
                if (name)
                    strcpy(cur->value.enumerated[v], name);
                else
                    printf("Skipping ENUM due to null setting for %s\n", cur->name);
                break;
            case MIXER_CTL_TYPE_BYTE:
                cur->value.byte[v] = mixer_ctl_get_value(ctl, v);
                break;
            case MIXER_CTL_TYPE_INT64:
                cur->value.integer64[v] = mixer_ctl_get_value(ctl, v);
                break;
            default:
                (void)0;
            }
        }
    }

    return 0;
}
Пример #19
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;
    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++;
}
Пример #20
0
static void tinymix_detail_control(struct mixer *mixer, const char *control,
                                   int print_all)
{
    struct mixer_ctl *ctl;
    enum mixer_ctl_type type;
    unsigned int num_values;
    unsigned int i;
    int min, max;
    int ret;
    char *buf = NULL;

    if (isdigit(control[0]))
        ctl = mixer_get_ctl(mixer, atoi(control));
    else
        ctl = mixer_get_ctl_by_name(mixer, control);

    if (!ctl) {
        fprintf(stderr, "Invalid mixer control\n");
        return;
    }

    type = mixer_ctl_get_type(ctl);
    num_values = mixer_ctl_get_num_values(ctl);

    if ((type == MIXER_CTL_TYPE_BYTE) && (num_values > 0)) {
        buf = calloc(1, num_values);
        if (buf == NULL) {
            fprintf(stderr, "Failed to alloc mem for bytes %d\n", num_values);
            return;
        }

        ret = mixer_ctl_get_array(ctl, buf, num_values);
        if (ret < 0) {
            fprintf(stderr, "Failed to mixer_ctl_get_array\n");
            free(buf);
            return;
        }
    }

    if (print_all)
        printf("%s:", mixer_ctl_get_name(ctl));

    for (i = 0; i < num_values; i++) {
        switch (type)
        {
        case MIXER_CTL_TYPE_INT:
            printf(" %d", mixer_ctl_get_value(ctl, i));
            break;
        case MIXER_CTL_TYPE_BOOL:
            printf(" %s", mixer_ctl_get_value(ctl, i) ? "On" : "Off");
            break;
        case MIXER_CTL_TYPE_ENUM:
            tinymix_print_enum(ctl, print_all);
            break;
        case MIXER_CTL_TYPE_BYTE:
            printf("%02x", buf[i]);
            break;
        default:
            printf(" unknown");
            break;
        };
    }

    if (print_all) {
        if (type == MIXER_CTL_TYPE_INT) {
            min = mixer_ctl_get_range_min(ctl);
            max = mixer_ctl_get_range_max(ctl);
            printf(" (range %d->%d)", min, max);
        }
    }

    free(buf);

    printf("\n");
}
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++;
}
Пример #22
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++;
}
Пример #23
0
static void tinymix_detail_control(struct mixer *mixer, const char *control,
                                   int print_all)
{
    struct mixer_ctl *ctl;
    enum mixer_ctl_type type;
    unsigned int num_values;
    unsigned int i;
    int min, max;
    int ret;
    char buf[512] = { 0 };
    size_t len;

    if (isdigit(control[0]))
        ctl = mixer_get_ctl(mixer, atoi(control));
    else
        ctl = mixer_get_ctl_by_name(mixer, control);

    if (!ctl) {
        fprintf(stderr, "Invalid mixer control\n");
        return;
    }

    type = mixer_ctl_get_type(ctl);
    num_values = mixer_ctl_get_num_values(ctl);

    if (type == MIXER_CTL_TYPE_BYTE) {
        len = num_values;
        if (len > sizeof(buf)) {
            fprintf(stderr, "Truncating get to %zu bytes\n", sizeof(buf));
            len = sizeof(buf);
        }
        ret = mixer_ctl_get_array(ctl, buf, len);
        if (ret < 0) {
            fprintf(stderr, "Failed to mixer_ctl_get_array\n");
            return;
        }
    }

    if (print_all)
        printf("%s:", mixer_ctl_get_name(ctl));

    for (i = 0; i < num_values; i++) {
        switch (type)
        {
        case MIXER_CTL_TYPE_INT:
            printf(" %d", mixer_ctl_get_value(ctl, i));
            break;
        case MIXER_CTL_TYPE_BOOL:
            printf(" %s", mixer_ctl_get_value(ctl, i) ? "On" : "Off");
            break;
        case MIXER_CTL_TYPE_ENUM:
            tinymix_print_enum(ctl, print_all);
            break;
        case MIXER_CTL_TYPE_BYTE:
            printf("%02x", buf[i]);
            break;
        default:
            printf(" unknown");
            break;
        };
    }

    if (print_all) {
        if (type == MIXER_CTL_TYPE_INT) {
            min = mixer_ctl_get_range_min(ctl);
            max = mixer_ctl_get_range_max(ctl);
            printf(" (range %d->%d)", min, max);
        }
    }
    printf("\n");
}