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 Handle pending HCTL events invoking callbacks
 * \param hctl HCTL handle
 * \return 0 otherwise a negative error code on failure
 */
int snd_hctl_handle_events(snd_hctl_t *hctl)
{
	snd_ctl_event_t event;
	int res;
	unsigned int count = 0;
	
	assert(hctl);
	assert(hctl->ctl);
	while ((res = snd_ctl_read(hctl->ctl, &event)) != 0 &&
	       res != -EAGAIN) {
		if (res < 0)
			return res;
		res = snd_hctl_handle_event(hctl, &event);
		if (res < 0)
			return res;
		count++;
	}
	return count;
}
static int handle_event(int hwdep_fd, snd_ctl_t *ctl)
{
    snd_ctl_event_t *event;
    unsigned int mask;
    int err;

    snd_ctl_event_alloca(&event);
    err = snd_ctl_read(ctl, event);
    if (err < 0) {
        fprintf(stderr, "Cannot read event from ctl %s\n", snd_ctl_name(ctl));
        return err;
    }

    if (snd_ctl_event_get_type(event) != SND_CTL_EVENT_ELEM) {
        return 0;
    }

    // Filter events
    mask = snd_ctl_event_elem_get_mask(event);
    if (mask & SND_CTL_EVENT_MASK_VALUE) {
        const char *event_name = snd_ctl_event_elem_get_name(event);

        if (!strcmp(event_name, HEADPHONE_SWITCH_NAME)) {
            // If headphones were plugged, mute LFE
            set_headphones_plugged(&headphones_plugged);
            if (headphones_plugged) {
                set_lfe_volume(hwdep_fd, 0);
            }
        } else if (!headphones_plugged && !strcmp(event_name, MASTER_VOLUME_NAME)) {
            // If headphones are unplugged and master volume changed, adjust LFE volume
            set_lfe_volume(hwdep_fd, get_master_volume());
        }
    }

    return 0;
}
Beispiel #4
0
void control_input_callback(gpointer data, gint source, GdkInputCondition condition)
{
	snd_ctl_t *ctl = (snd_ctl_t *)data;
	snd_ctl_event_t *ev;
	const char *name;
	int index;
	unsigned int mask;

	snd_ctl_event_alloca(&ev);
	if (snd_ctl_read(ctl, ev) < 0)
		return;
	name = snd_ctl_event_elem_get_name(ev);
	index = snd_ctl_event_elem_get_index(ev);
	mask = snd_ctl_event_elem_get_mask(ev);
	if (! (mask & (SND_CTL_EVENT_MASK_VALUE | SND_CTL_EVENT_MASK_INFO)))
		return;

	switch (snd_ctl_event_elem_get_interface(ev)) {
	case SND_CTL_ELEM_IFACE_MIXER:
		if (!strcmp(name, "Word Clock Sync"))
			master_clock_update();
		else if (!strcmp(name, "Multi Track Volume Rate"))
			volume_change_rate_update();
		else if (!strcmp(name, "IEC958 Input Optical"))
			spdif_input_update();
		else if (!strcmp(name, "Delta IEC958 Output Defaults"))
			spdif_output_update();
		else if (!strcmp(name, "Multi Track Internal Clock"))
			master_clock_update();
		else if (!strcmp(name, "Multi Track Internal Clock Default"))
			master_clock_update();
		else if (!strcmp(name, "Multi Track Rate Locking"))
			rate_locking_update();
		else if (!strcmp(name, "Multi Track Rate Reset"))
			rate_reset_update();
		else if (!strcmp(name, "Multi Playback Volume"))
			mixer_update_stream(index + 1, 1, 0);
		else if (!strcmp(name, "H/W Multi Capture Volume"))
			mixer_update_stream(index + 11, 1, 0);
		else if (!strcmp(name, "IEC958 Multi Capture Volume"))
			mixer_update_stream(index + 19, 1, 0);
		else if (!strcmp(name, "Multi Playback Switch"))
			mixer_update_stream(index + 1, 0, 1);
		else if (!strcmp(name, "H/W Multi Capture Switch"))
			mixer_update_stream(index + 11, 0, 1);
		else if (!strcmp(name, "IEC958 Multi Capture Switch"))
			mixer_update_stream(index + 19, 0, 1);
		else if (!strcmp(name, "H/W Playback Route"))
			patchbay_update();
		else if (!strcmp(name, "IEC958 Playback Route"))
			patchbay_update();
		else if (!strcmp(name, "DAC Volume"))
			dac_volume_update(index);
		else if (!strcmp(name, "ADC Volume"))
			adc_volume_update(index);
		else if (!strcmp(name, "IPGA Analog Capture Volume"))
			ipga_volume_update(index);
		else if (!strcmp(name, "Output Sensitivity Switch"))
			dac_sense_update(index);
		else if (!strcmp(name, "Input Sensitivity Switch"))
			adc_sense_update(index);
		break;
	default:
		break;
	}
}