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 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");
        }
    }
}
Beispiel #4
0
static void tinymix_list_controls(struct mixer *mixer, int print_all)
{
    struct mixer_ctl *ctl;
    const char *name, *type;
    unsigned int num_ctls, num_values;
    unsigned int i;

    num_ctls = mixer_get_num_ctls(mixer);

    printf("Number of controls: %u\n", num_ctls);

    if (print_all)
        printf("ctl\ttype\tnum\t%-40svalue\n", "name");
    else
        printf("ctl\ttype\tnum\t%-40s\n", "name");

    for (i = 0; i < num_ctls; i++) {
        ctl = mixer_get_ctl(mixer, i);

        name = mixer_ctl_get_name(ctl);
        type = mixer_ctl_get_type_string(ctl);
        num_values = mixer_ctl_get_num_values(ctl);
        printf("%u\t%s\t%u\t%-40s", i, type, num_values, name);
        if (print_all)
            tinymix_detail_control(mixer, name);
        printf("\n");
    }
}
Beispiel #5
0
static int alloc_mixer_state(struct audio_route *ar)
{
    unsigned int i;
    unsigned int j;

    if (!ar) {
		ALOGE("%s: invalid audio_route", __func__);
        return -1;
    }
    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++) {
        ar->mixer_state[i].ctl = mixer_get_ctl(ar->mixer, i);
		ar->mixer_state[i].ctl_vals = mixer_ctl_get_num_values(ar->mixer_state[i].ctl);
		ar->mixer_state[i].ignored = 0;
		if (ar->mixer_state[i].ctl_vals > MAX_CTL_VALS) {
			ar->mixer_state[i].ctl_vals = MAX_CTL_VALS;
		}
		for (j = 0; j < ar->mixer_state[i].ctl_vals; j++) {
        	ar->mixer_state[i].old_value[j] =
				mixer_ctl_get_value(ar->mixer_state[i].ctl, j);
        	ar->mixer_state[i].new_value[j] = ar->mixer_state[i].old_value[j];
		}
    }

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

    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");
}
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;
}
Beispiel #9
0
static int path_add_value(struct mixer_path *path,
                          struct mixer_value *mixer_value)
{
    unsigned int i;
    int path_index;
    unsigned int num_values;

    /* Check that mixer value index is within range */
    num_values = mixer_ctl_get_num_values(mixer_value->ctl);
    if (mixer_value->index >= (int)num_values) {
        ALOGE("mixer index %d is out of range for '%s'", mixer_value->index,
              mixer_ctl_get_name(mixer_value->ctl));
        return -1;
    }

    path_index = find_ctl_in_path(path, mixer_value->ctl);
    if (path_index < 0) {
        /* New path */

        path_index = alloc_path_setting(path);
        if (path_index < 0)
            return -1;

        /* initialise the new path setting */
        path->setting[path_index].ctl = mixer_value->ctl;
        path->setting[path_index].num_values = num_values;
        path->setting[path_index].value = malloc(num_values * sizeof(int));
        path->setting[path_index].linked = true;
        path->setting[path_index].value[0] = mixer_value->value;
    }

    if (mixer_value->index == -1) {
        /* Linked, so only set the first value */
        path->setting[path_index].linked = true;
        path->setting[path_index].value[0] = mixer_value->value;
    } else {
        if (path->setting[path_index].linked && (num_values > 1)) {
            /* Unlinking the values, so duplicate them across */
            for (i = 1; i < num_values; i++) {
                path->setting[path_index].value[i] =
                        path->setting[path_index].value[0];
            }
            path->setting[path_index].linked = false;
        }
        path->setting[path_index].value[mixer_value->index] = mixer_value->value;
    }

    return 0;
}
void update_mixer_state(struct audio_route *ar)
{
    unsigned int i;
    unsigned int j;

    for (i = 0; i < ar->num_mixer_ctls; i++) {
        /* if the value has changed, update the mixer */
        if (ar->mixer_state[i].old_value != ar->mixer_state[i].new_value) {
            /* set all ctl values the same */
            for (j = 0; j < mixer_ctl_get_num_values(ar->mixer_state[i].ctl); j++)
                mixer_ctl_set_value(ar->mixer_state[i].ctl, j,
                                    ar->mixer_state[i].new_value);
            ar->mixer_state[i].old_value = ar->mixer_state[i].new_value;
        }
    }
}
Beispiel #11
0
static int alloc_mixer_state(struct audio_route *ar)
{
    unsigned int i;
    unsigned int j;
    unsigned int num_values;
    struct mixer_ctl *ctl;
    bool linked;

    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].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));

        /*
         * Get all mixer values for controls with multiple values. If all
         * values are the same, set the linked flag.
         */
        linked = true;
        for (j = 0; j < num_values; j++) {
            ar->mixer_state[i].old_value[j] = mixer_ctl_get_value(ctl, j);
            ar->mixer_state[i].new_value[j] = ar->mixer_state[i].old_value[j];

            /*
             * If the next value is different from the last, set linked to
             * false.
             */
            if ((j > 0) && (ar->mixer_state[i].old_value[j - 1] !=
                            ar->mixer_state[i].old_value[j])) {
                linked = false;
            }
        }
        ar->mixer_state[i].ctl = ctl;
        ar->mixer_state[i].old_linked = linked;
        ar->mixer_state[i].new_linked = linked;
        ar->mixer_state[i].num_values = num_values;
    }

    return 0;
}
int audio_route_control_set_number(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 */
            value = atoi(string);
            num_values = mixer_ctl_get_num_values(ctl);
            for (j = 0; j < num_values; j++) {
                mixer_ret = mixer_ctl_set_value(ctl, j, value);
                if (mixer_ret) {
                    ALOGE("Error: invalid value (%s to %d)", name, value);
                    mixer_close(control_mixer);
                    /* Add up the number of failed controller values */
                    ret += -1;
                }
            }
            if (ret == 0)
                ALOGV("Setting %s to int %d", name, value);
            break;
        }
    }

    return ret;
}
Beispiel #13
0
static bool
do_set_volume(struct mixer *mixer, const char *name, unsigned volume)
{
    struct mixer_ctl *ctl;
    unsigned i;

    ctl = mixer_get_ctl_by_name(mixer, name);
    if (! ctl) {
	fprintf(stderr, "Failed to find control: %s\n", name);
	mixer_close(mixer);
	return false;
    }

    for (i = 0; i < mixer_ctl_get_num_values(ctl); i++) {
        mixer_ctl_set_percent(ctl, i, volume);
    }

    return true;
}
static int path_add_value(struct audio_route *ar, struct mixer_path *path,
                          struct mixer_value *mixer_value)
{
    unsigned int i;
    int path_index;
    unsigned int num_values;
    struct mixer_ctl *ctl;

    /* Check that mixer value index is within range */
    ctl = index_to_ctl(ar, mixer_value->ctl_index);
    num_values = mixer_ctl_get_num_values(ctl);
    if (mixer_value->index >= (int)num_values) {
        ALOGE("mixer index %d is out of range for '%s'", mixer_value->index,
              mixer_ctl_get_name(ctl));
        return -1;
    }

    path_index = find_ctl_index_in_path(path, mixer_value->ctl_index);
    if (path_index < 0) {
        /* New path */

        path_index = alloc_path_setting(path);
        if (path_index < 0)
            return -1;

        /* initialise the new path setting */
        path->setting[path_index].ctl_index = mixer_value->ctl_index;
        path->setting[path_index].num_values = num_values;
        path->setting[path_index].value = malloc(num_values * sizeof(int));
        path->setting[path_index].value[0] = mixer_value->value;
    }

    if (mixer_value->index == -1) {
        /* set all values the same */
        for (i = 0; i < num_values; i++)
            path->setting[path_index].value[i] = mixer_value->value;
    } else {
        /* set only one value */
        path->setting[path_index].value[mixer_value->index] = mixer_value->value;
    }

    return 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;
		}
	}
}
Beispiel #16
0
TEST_F(MixerTest, tryTinyAlsaTest) {
    int hwId = AudioHardware::detectAudioHw();
    ASSERT_TRUE(hwId >= 0);
    struct mixer* mixerp = mixer_open(hwId);
    ASSERT_TRUE(mixerp != NULL);
    int num_ctls = mixer_get_num_ctls(mixerp);
    LOGI("Number of mixel control %d", num_ctls);
    for (int i = 0; i < num_ctls; i++) {
        struct mixer_ctl* control = mixer_get_ctl(mixerp, i);
        ASSERT_TRUE(control != NULL);
        LOGI("Mixer control %s type %s value %d", mixer_ctl_get_name(control),
                mixer_ctl_get_type_string(control), mixer_ctl_get_num_values(control));
        free(control);
    }
    // no mixer control for MobilePre. If this assumption fails,
    // mixer control should be added.
    ASSERT_TRUE(num_ctls == 0);
    mixer_close(mixerp);
}
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;
}
static void tinymix_list_controls(struct mixer *mixer)
{
    struct mixer_ctl *ctl;
    const char *type;
    unsigned int num_ctls, num_values;
    char buffer[256];
    unsigned int i;

    num_ctls = mixer_get_num_ctls(mixer);

    printf("Number of controls: %d\n", num_ctls);

    printf("ctl\ttype\tnum\t%-40s value\n", "name");
    for (i = 0; i < num_ctls; i++) {
        ctl = mixer_get_ctl(mixer, i);

        mixer_ctl_get_name(ctl, buffer, sizeof(buffer));
        type = mixer_ctl_get_type_string(ctl);
        num_values = mixer_ctl_get_num_values(ctl);
        printf("%d\t%s\t%d\t%-40s", i, type, num_values, buffer);
        tinymix_detail_control(mixer, i, 0);
    }
}
Beispiel #19
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");
}
Beispiel #20
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;
}
Beispiel #21
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");
}
uint32_t TinyAmixerControl::getNumValues(struct mixer_ctl *mixerControl)
{
    return mixer_ctl_get_num_values(mixerControl);
}
Beispiel #23
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);
}
Beispiel #24
0
/* Notes:
 *   - param 'line' is modified by this function
 *   - param 'db' has mixer_cache_touch() called on it.
 */
static void process_line(char* line, struct audio_tool_mixer_cache *db, struct mixer *mixer)
{
	size_t length = strlen(line);
	size_t pos = 0, sep;
	const char* sep_ptr;
	enum field_t { FNAME=0, FTYPE, FCOUNT, FVALS } field = FNAME;
	unsigned control_id, val, val_no;
	const char *ctl_type;
	unsigned file_count, ctl_count;
	struct mixer_ctl *ctl;

	if (!length)
		return;

	if (line[0] == '#')
		return;

	control_id = -1;
	val_no = 0;
	while (pos < length) {
		sep_ptr = strstr(&line[pos], "\t");
		if (sep_ptr)
			sep = (size_t) (sep_ptr - line);
		else
			sep = length;
		if (sep < length)
			line[sep] = '\0';
		switch(field) {
		case FNAME:
			control_id = mixer_cache_get_id_by_name(db, &line[pos]);
			if (control_id == -1) {
				printf("Error: could not find control %s\n", &line[pos]);
				pos = length;
			}
			ctl = mixer_get_ctl(mixer, control_id);
			break;
		case FTYPE:
			ctl_type = mixer_ctl_get_type_string(ctl);
			if (0 != strcmp(ctl_type, &line[pos])) {
				printf("Error: type mismatch for control #%d: file=%s card=%s\n",
				       control_id, &line[pos], ctl_type);
				pos = length;
			}
			break;
		case FCOUNT:
			ctl_count = mixer_ctl_get_num_values(ctl);
			file_count = atoi(&line[pos]);
			if (ctl_count != file_count) {
				printf("Error: mismatch in the count of control #%d's values: "
				       "file=%d card=%d\n", control_id, file_count, ctl_count);
				pos = length;
			}
			break;
		case FVALS:
			if (0 == strcmp("#N/A", &line[pos])) {
				pos = length;
			} else if (0 == strcmp("ENUM", ctl_type)) {
				mixer_ctl_set_enum_by_string(ctl, &line[pos]);
			} else {
				val = atoi(&line[pos]);
				mixer_ctl_set_value(ctl, val_no, val);
			}
			++val_no;
			break;
		}

		if (field != FVALS)
			++field;

		pos = sep + 1;
	}
	mixer_cache_touch(db, control_id);
}