コード例 #1
0
ファイル: audio_route.c プロジェクト: Kratos1982/UbuntuTouch
void update_mixer_state(struct audio_route *ar)
{
    unsigned int i;
    unsigned int j;

    if (!ar) {
		ALOGE("%s: invalid audio_route", __func__);
        return;
    }
    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) {
			if (!(ar->mixer_state[i].ignored)) {
				for (j = 0; j < ar->mixer_state[i].ctl_vals; j++) {
#if 0
				  ALOGV("%s: '%s'[%u] -> %d", __func__,
						  mixer_ctl_get_name(ar->mixer_state[i].ctl), j, 
						  ar->mixer_state[i].new_value[j]);
#endif
#if 0
					mixer_ctl_set_value(ar->mixer_state[i].ctl, j,
										ar->mixer_state[i].new_value[j]);
#endif
					ar->mixer_state[i].old_value[j] = ar->mixer_state[i].new_value[j];
				}
			}
        }
    }
}
コード例 #2
0
static int path_add_setting(struct mixer_path *path,
                            struct mixer_setting *setting)
{
    unsigned int i;
    int path_index;

    if (find_ctl_in_path(path, setting->ctl) != -1) {
        ALOGE("Control '%s' already exists in path '%s'",
              mixer_ctl_get_name(setting->ctl), path->name);
        return -1;
    }

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

    path->setting[path_index].ctl = setting->ctl;
    path->setting[path_index].num_values = setting->num_values;
    path->setting[path_index].value = malloc(setting->num_values * sizeof(int));
    path->setting[path_index].linked = setting->linked;
    if (setting->linked) {
        path->setting[path_index].value[0] = setting->value[0];
    } else {
        for (i = 0; i < setting->num_values; i++)
            path->setting[path_index].value[i] = setting->value[i];
    }

    return 0;
}
コード例 #3
0
ファイル: tinymix.c プロジェクト: ricardobiehl/tinyalsa
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");
    }
}
コード例 #4
0
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;
}
コード例 #5
0
static int path_add_setting(struct mixer_path *path,
                            struct mixer_setting *setting)
{
    struct mixer_setting *new_path_setting;

    if (path_setting_exists(path, setting)) {
        ALOGE("Duplicate path setting '%s'",
              mixer_ctl_get_name(setting->ctl));
        return -1;
    }

    /* check if we need to allocate more space for path settings */
    if (path->size <= path->length) {
        if (path->size == 0)
            path->size = INITIAL_MIXER_PATH_SIZE;
        else
            path->size *= 2;

        new_path_setting = realloc(path->setting,
                                   path->size * sizeof(struct mixer_setting));
        if (new_path_setting == NULL) {
            ALOGE("Unable to allocate more path settings");
            return -1;
        } else {
            path->setting = new_path_setting;
        }
    }

    /* initialise the new path setting */
    path->setting[path->length].ctl = setting->ctl;
    path->setting[path->length].value = setting->value;
    path->length++;

    return 0;
}
コード例 #6
0
static int path_add_setting(struct audio_route *ar, struct mixer_path *path,
                            struct mixer_setting *setting)
{
    int path_index;

    if (find_ctl_index_in_path(path, setting->ctl_index) != -1) {
        struct mixer_ctl *ctl = index_to_ctl(ar, setting->ctl_index);

        ALOGE("Control '%s' already exists in path '%s'",
              mixer_ctl_get_name(ctl), path->name);
        return -1;
    }

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

    path->setting[path_index].ctl_index = setting->ctl_index;
    path->setting[path_index].num_values = setting->num_values;
    path->setting[path_index].value = malloc(setting->num_values * sizeof(int));
    /* copy all values */
    memcpy(path->setting[path_index].value, setting->value,
           setting->num_values * sizeof(int));

    return 0;
}
コード例 #7
0
static void path_print(struct mixer_path *path)
{
    unsigned int i;

    ALOGV("Path: %s, length: %d", path->name, path->length);
    for (i = 0; i < path->length; i++)
        ALOGV("  %d: %s -> %d", i, mixer_ctl_get_name(path->setting[i].ctl),
              path->setting[i].value);
}
コード例 #8
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");
}
コード例 #9
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");
}
コード例 #10
0
ファイル: audio_route.c プロジェクト: Kratos1982/UbuntuTouch
static void path_print(struct mixer_path *path)
{
    unsigned int i;
    unsigned int j;

    ALOGV("Path: %s, length: %d", path->name, path->length);
    for (i = 0; i < path->length; i++)
		for (j = 0; j < path->setting[i].ctl_vals; j++)
        	ALOGV("  %d: %s [%d]-> %d", i,
					mixer_ctl_get_name(path->setting[i].ctl),
					j, path->setting[i].value[j]);
}
コード例 #11
0
static void path_print(struct mixer_path *path)
{
    unsigned int i;
    unsigned int j;

    ALOGE("Path: %s, length: %d", path->name, path->length);
    for (i = 0; i < path->length; i++) {
        ALOGE("  id=%d: ctl=%s linked=%c", i,
              mixer_ctl_get_name(path->setting[i].ctl),
              path->setting[i].linked ? 'y' : 'n');
        for (j = 0; j < path->setting[i].num_values; j++)
            ALOGE("    id=%d value=%d", j, path->setting[i].value[j]);
    }
}
コード例 #12
0
static void path_print(struct audio_route *ar, struct mixer_path *path)
{
    unsigned int i;
    unsigned int j;

    ALOGE("Path: %s, length: %d", path->name, path->length);
    for (i = 0; i < path->length; i++) {
        struct mixer_ctl *ctl = index_to_ctl(ar, path->setting[i].ctl_index);

        ALOGE("  id=%d: ctl=%s", i, mixer_ctl_get_name(ctl));
        for (j = 0; j < path->setting[i].num_values; j++)
            ALOGE("    id=%d value=%d", j, path->setting[i].value[j]);
    }
}
コード例 #13
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;
}
コード例 #14
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;
}
コード例 #15
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;
}
コード例 #16
0
ファイル: audio_route.c プロジェクト: Kratos1982/UbuntuTouch
static int path_apply(struct audio_route *ar, struct mixer_path *path)
{
    unsigned int i;
    unsigned int j;
    unsigned int k;

    if (!ar) {
		ALOGE("%s: invalid audio_route", __func__);
        return -1;
    }
    for (i = 0; i < path->length; i++) {
        struct mixer_ctl *ctl = path->setting[i].ctl;

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

        /* apply the new value */
#if 0
		for (k = 0; k < path->setting[i].ctl_vals; k++) {
        	ar->mixer_state[j].new_value[k] = path->setting[i].value[k];
			mixer_ctl_set_value(ctl, k, ar->mixer_state[j].new_value[k]);
		}
#else
		for (k = 0; k < path->setting[i].ctl_vals; k++) {
        	ar->mixer_state[j].new_value[k] = path->setting[i].value[k];
		}
		ALOGV("mixer_set: '%s' %d,%d,%d\n", 
				mixer_ctl_get_name(ctl),
				path->setting[i].value[0],
				path->setting[i].value[1],
				path->setting[i].value[2]
				);

		mixer_ctl_set_multivalue(ctl, path->setting[i].ctl_vals,
				path->setting[i].value);
#endif
       	ar->mixer_state[j].ctl_vals = path->setting[i].ctl_vals;
    }

    return 0;
}
コード例 #17
0
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;
}
コード例 #18
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);
}
コード例 #19
0
int write_percentage(int argc, char **argv) {
    int nMixer = -1, nControl = -1;
    int location = -1, value = -1;

    if (argc == 6) {
        nMixer = atoi(argv[2]);
        nControl = atoi(argv[3]);
        location = atoi(argv[4]);
        value = atoi(argv[5]);
    }

    if (argc != 6 || nMixer < 0 || nMixer > 7 || nControl < 0 || location < 0) {
        printf("Usage: ainfo write-percentage <card number> <control number> <location> <value>\n"
               "where <card number> is between 0 and 7\n"
               "<control number> is the control to be written\n"
               "<location> is the location to be written\n"
               "<value> is the value to be written\n");
        return 0;
    }

    mixer *m = mixer_open(nMixer);

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

    mixer_ctl *c = mixer_get_ctl(m, nControl);

    if (c == NULL) {
        printf("Unable to open control #%d\n", nControl);
        return 0;        
    }

    char name[64], type[64];
    mixer_ctl_get_name(c, name, sizeof(name));
    mixer_ctl_set_percent(c, location, value);
    printf("Control: %s\nPercent: %d\nValue: %d\n", name, 
        mixer_ctl_get_percent(c, location), mixer_ctl_get_value(c, location));

    return 0;
}
コード例 #20
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);
    }
}
コード例 #21
0
int read_range(int argc, char **argv) {
    int nMixer = -1, nControl = -1;
    int location = -1;

    if (argc == 4) {
        nMixer = atoi(argv[2]);
        nControl = atoi(argv[3]);
    }

    if (argc != 4 || nMixer < 0 || nMixer > 7 || nControl < 0) {
        printf("Usage: ainfo read-range <card number> <control number> <location>\n"
               "where <card number> is between 0 and 7\n"
               "<control number> is the control to be read\n");
        return 0;
    }

    mixer *m = mixer_open(nMixer);

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

    mixer_ctl *c = mixer_get_ctl(m, nControl);

    if (c == NULL) {
        printf("Unable to open control #%d\n", nControl);
        return 0;        
    }

    char name[64], type[64];
    mixer_ctl_get_name(c, name, sizeof(name));
    printf("Control: %s\nMin: %d\nMax: %d\n", name, 
        mixer_ctl_get_range_min(c),  mixer_ctl_get_range_max(c));

    return 0;
}
コード例 #22
0
ファイル: tinymix.c プロジェクト: ford-prefect/tinyalsa
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");
}
コード例 #23
0
ファイル: mixer_cache.c プロジェクト: sideb0ard/audio-tool
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;
}
コード例 #24
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;
    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++;
}
コード例 #25
0
ファイル: tinymix.c プロジェクト: akibsayyed/tinyalsa-ndk
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");
}