int main(int argc, char **argv)
{
    int hwdep_fd;
    snd_ctl_t *ctl;

    (void) argc;
    (void) argv;

    // Setup the signal handler
    struct sigaction sa = { 0 };
    sa.sa_handler = &handle_signal;

    // Handle standard signals to quit properly
    sigemptyset(&sa.sa_mask);
    sigaction(SIGINT,  &sa, NULL);
    sigaction(SIGHUP,  &sa, NULL);
    sigaction(SIGTERM, &sa, NULL);

    // Open control and hwdep devices
    if (open_hwdep(Y50_HWDEP_DEVICE, &hwdep_fd) != 0
            || open_ctl(Y50_CTL_NAME, &ctl) != 0) {
        return 1;
    }

    // Initialize subwoofer
    lfe_initialize(hwdep_fd);

    // Set initial values
    set_headphones_plugged(&headphones_plugged);
    set_lfe_volume(hwdep_fd, headphones_plugged ? 0 : get_master_volume());

    // Poll events
    while (!doneflag) {
        struct pollfd fds;
        snd_ctl_poll_descriptors(ctl, &fds, 1);

        if (poll(&fds, 1, -1) <= 0) {
            if (errno == EINTR) {
                continue;
            } else {
                perror("poll");
                break;
            }
        }

        unsigned short revents;
        snd_ctl_poll_descriptors_revents(ctl, &fds, 1, &revents);
        if (revents & POLLIN) {
            handle_event(hwdep_fd, ctl);
        }
    }

    // Close resources
    close(hwdep_fd);
    snd_ctl_close(ctl);

    return EXIT_SUCCESS;
}
static int check_event(struct elem_set_trial *trial, unsigned int mask,
		       unsigned int expected_count)
{
	struct pollfd pfds;
	int count;
	unsigned short revents;
	snd_ctl_event_t *event;
	int err;

	snd_ctl_event_alloca(&event);

	if (snd_ctl_poll_descriptors_count(trial->handle) != 1)
		return -ENXIO;

	if (snd_ctl_poll_descriptors(trial->handle, &pfds, 1) != 1)
		return -ENXIO;

	while (expected_count > 0) {
		count = poll(&pfds, 1, 1000);
		if (count < 0)
			return errno;
		/* Some events are already supplied. */
		if (count == 0)
			return -ETIMEDOUT;

		err = snd_ctl_poll_descriptors_revents(trial->handle, &pfds,
						       count, &revents);
		if (err < 0)
			return err;
		if (revents & POLLERR)
			return -EIO;
		if (!(revents & POLLIN))
			continue;

		err = snd_ctl_read(trial->handle, event);
		if (err < 0)
			return err;
		if (snd_ctl_event_get_type(event) != SND_CTL_EVENT_ELEM)
			continue;
		/*
		 * I expect each event is generated separately to the same
		 * element.
		 */
		if (!(snd_ctl_event_elem_get_mask(event) & mask))
			continue;
		--expected_count;
	}

	if (expected_count != 0)
		return -EIO;

	return 0;
}
/**
 * \brief get returned events from poll descriptors
 * \param hctl HCTL handle
 * \param pfds array of poll descriptors
 * \param nfds count of poll descriptors
 * \param revents returned events
 * \return zero if success, otherwise a negative error code
 */
int snd_hctl_poll_descriptors_revents(snd_hctl_t *hctl, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
{
	assert(hctl);
	return snd_ctl_poll_descriptors_revents(hctl->ctl, pfds, nfds, revents);
}