Esempio n. 1
0
/**
 * \brief Load an HCTL with all elements and sort them
 * \param hctl HCTL handle
 * \return 0 on success otherwise a negative error code
 */
int snd_hctl_load(snd_hctl_t *hctl)
{
	snd_ctl_elem_list_t list;
	int err = 0;
	unsigned int idx;

	assert(hctl);
	assert(hctl->ctl);
	assert(hctl->count == 0);
	assert(list_empty(&hctl->elems));
	memset(&list, 0, sizeof(list));
	if ((err = snd_ctl_elem_list(hctl->ctl, &list)) < 0)
		goto _end;
	while (list.count != list.used) {
		err = snd_ctl_elem_list_alloc_space(&list, list.count);
		if (err < 0)
			goto _end;
		if ((err = snd_ctl_elem_list(hctl->ctl, &list)) < 0)
			goto _end;
	}
	if (hctl->alloc < list.count) {
		hctl->alloc = list.count;
		free(hctl->pelems);
		hctl->pelems = malloc(hctl->alloc * sizeof(*hctl->pelems));
		if (!hctl->pelems) {
			err = -ENOMEM;
			goto _end;
		}
	}
	for (idx = 0; idx < list.count; idx++) {
		snd_hctl_elem_t *elem;
		elem = calloc(1, sizeof(snd_hctl_elem_t));
		if (elem == NULL) {
			snd_hctl_free(hctl);
			err = -ENOMEM;
			goto _end;
		}
		elem->id = list.pids[idx];
		elem->hctl = hctl;
		elem->compare_weight = get_compare_weight(&elem->id);
		hctl->pelems[idx] = elem;
		list_add_tail(&elem->list, &hctl->elems);
		hctl->count++;
	}
	if (!hctl->compare)
		hctl->compare = snd_hctl_compare_default;
	snd_hctl_sort(hctl);
	for (idx = 0; idx < hctl->count; idx++) {
		int res = snd_hctl_throw_event(hctl, SNDRV_CTL_EVENT_MASK_ADD,
					       hctl->pelems[idx]);
		if (res < 0)
			return res;
	}
	err = snd_ctl_subscribe_events(hctl->ctl, 1);
 _end:
	free(list.pids);
	return err;
}
Esempio n. 2
0
static int open_ctl(const char *name, snd_ctl_t **ctlp)
{
    snd_ctl_t *ctl;

    if (snd_ctl_open(&ctl, name, SND_CTL_READONLY) < 0) {
        fprintf(stderr, "Cannot open ctl %s\n", name);
        return 1;
    }

    if (snd_ctl_subscribe_events(ctl, 1) < 0) {
        fprintf(stderr, "Cannot open subscribe events to ctl %s\n", name);
        snd_ctl_close(ctl);
        return 1;
    }

    *ctlp = ctl;
    return 0;
}
int main(void)
{
	struct elem_set_trial trial = {0};
	unsigned int i;
	int err;

	snd_ctl_elem_id_alloca(&trial.id);

	err = snd_ctl_open(&trial.handle, "hw:0", 0);
	if (err < 0)
		return EXIT_FAILURE;

	err = snd_ctl_subscribe_events(trial.handle, 1);
	if (err < 0)
		return EXIT_FAILURE;

	/* Test all of types. */
	for (i = 0; i < SND_CTL_ELEM_TYPE_LAST; ++i) {
		trial.type = i + 1;

		/* Assign type-dependent operations. */
		switch (trial.type) {
		case SND_CTL_ELEM_TYPE_BOOLEAN:
			trial.element_count = 900;
			trial.member_count = 128;
			trial.dimension[0] = 4;
			trial.dimension[1] = 4;
			trial.dimension[2] = 8;
			trial.dimension[3] = 0;
			trial.add_elem_set = add_bool_elem_set;
			trial.check_elem_props = NULL;
			trial.change_elem_members = change_bool_elem_members;
			break;
		case SND_CTL_ELEM_TYPE_INTEGER:
			trial.element_count = 900;
			trial.member_count = 128;
			trial.dimension[0] = 128;
			trial.dimension[1] = 0;
			trial.dimension[2] = 0;
			trial.dimension[3] = 0;
			trial.add_elem_set = add_int_elem_set;
			trial.check_elem_props = check_int_elem_props;
			trial.change_elem_members = change_int_elem_members;
			break;
		case SND_CTL_ELEM_TYPE_ENUMERATED:
			trial.element_count = 900;
			trial.member_count = 128;
			trial.dimension[0] = 16;
			trial.dimension[1] = 8;
			trial.dimension[2] = 0;
			trial.dimension[3] = 0;
			trial.add_elem_set = add_enum_elem_set;
			trial.check_elem_props = check_enum_elem_props;
			trial.change_elem_members = change_enum_elem_members;
			break;
		case SND_CTL_ELEM_TYPE_BYTES:
			trial.element_count = 900;
			trial.member_count = 512;
			trial.dimension[0] = 8;
			trial.dimension[1] = 4;
			trial.dimension[2] = 8;
			trial.dimension[3] = 2;
			trial.add_elem_set = add_bytes_elem_set;
			trial.check_elem_props = NULL;
			trial.change_elem_members = change_bytes_elem_members;
			break;
		case SND_CTL_ELEM_TYPE_IEC958:
			trial.element_count = 1;
			trial.member_count = 1;
			trial.dimension[0] = 0;
			trial.dimension[1] = 0;
			trial.dimension[2] = 0;
			trial.dimension[3] = 0;
			trial.add_elem_set = add_iec958_elem_set;
			trial.check_elem_props = NULL;
			trial.change_elem_members = change_iec958_elem_members;
			break;
		case SND_CTL_ELEM_TYPE_INTEGER64:
		default:
			trial.element_count = 900;
			trial.member_count = 64;
			trial.dimension[0] = 0;
			trial.dimension[1] = 0;
			trial.dimension[2] = 0;
			trial.dimension[3] = 0;
			trial.add_elem_set = add_int64_elem_set;
			trial.check_elem_props = check_int64_elem_props;
			trial.change_elem_members = change_int64_elem_members;
			break;
		}

		/* Test an operation to add an element set. */
		err = add_elem_set(&trial);
		if (err < 0) {
			printf("Fail to add an element set with %s type.\n",
			       snd_ctl_elem_type_name(trial.type));
			break;
		}
		err = check_event(&trial, SND_CTL_EVENT_MASK_ADD,
				  trial.element_count);
		if (err < 0) {
			printf("Fail to check some events to add elements with "
			       "%s type.\n",
			       snd_ctl_elem_type_name(trial.type));
			break;
		}

		/* Check properties of each element in this element set. */
		err = check_elem_set_props(&trial);
		if (err < 0) {
			printf("Fail to check propetries of each element with "
			       "%s type.\n",
			       snd_ctl_elem_type_name(trial.type));
			break;
		}

		/*
		 * Test operations to change the state of members in each
		 * element in the element set.
		 */
		err = check_elems(&trial);
		if (err < 0) {
			printf("Fail to change status of each element with %s "
			       "type.\n",
			       snd_ctl_elem_type_name(trial.type));
			break;
		}
		err = check_event(&trial, SND_CTL_EVENT_MASK_VALUE,
				  trial.element_count);
		if (err < 0) {
			printf("Fail to check some events to change status of "
			       "each elements with %s type.\n",
			       snd_ctl_elem_type_name(trial.type));
			break;
		}

		/*
		 * Test an operation to change threshold data of this element set,
		 * except for IEC958 type.
		 */
		if (trial.type != SND_CTL_ELEM_TYPE_IEC958) {
			err = check_tlv(&trial);
			if (err < 0) {
				printf("Fail to change threshold level of an "
				       "element set with %s type.\n",
				       snd_ctl_elem_type_name(trial.type));
				break;
			}
			err = check_event(&trial, SND_CTL_EVENT_MASK_TLV, 1);
			if (err < 0) {
				printf("Fail to check an event to change "
				       "threshold level of an an element set "
				       "with %s type.\n",
				       snd_ctl_elem_type_name(trial.type));
				break;
			}
		}

		/* Test an operation to remove elements in this element set. */
		err = snd_ctl_elem_remove(trial.handle, trial.id);
		if (err < 0) {
			printf("Fail to remove elements with %s type.\n",
			       snd_ctl_elem_type_name(trial.type));
			break;
		}
		err = check_event(&trial, SND_CTL_EVENT_MASK_REMOVE,
						  trial.element_count);
		if (err < 0) {
			printf("Fail to check some events to remove each "
			       "element with %s type.\n",
			       snd_ctl_elem_type_name(trial.type));
			break;
		}
	}

	if (err < 0) {
		printf("%s\n", snd_strerror(err));

		/* To ensure. */
		snd_ctl_elem_remove(trial.handle, trial.id);
		return EXIT_FAILURE;
	}

	return EXIT_SUCCESS;
}