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_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"); } }
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; }
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 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_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; }
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; }
static int alloc_mixer_state(struct audio_route *ar) { unsigned int i; 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); /* only get value 0, assume multiple ctl values are the same */ ar->mixer_state[i].old_value = mixer_ctl_get_value(ar->mixer_state[i].ctl, 0); ar->mixer_state[i].new_value = ar->mixer_state[i].old_value; } return 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); } }
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; }