Example #1
0
static int execute_cset(snd_ctl_t *ctl, const char *cset)
{
	const char *pos;
	int err;
	snd_ctl_elem_id_t *id;
	snd_ctl_elem_value_t *value;
	snd_ctl_elem_info_t *info;

	snd_ctl_elem_id_malloc(&id);
	snd_ctl_elem_value_malloc(&value);
	snd_ctl_elem_info_malloc(&info);

	err = __snd_ctl_ascii_elem_id_parse(id, cset, &pos);
	if (err < 0)
		goto __fail;
	while (*pos && isspace(*pos))
		pos++;
	if (!*pos) {
		uc_error("undefined value for cset >%s<", cset);
		err = -EINVAL;
		goto __fail;
	}
	snd_ctl_elem_value_set_id(value, id);
	snd_ctl_elem_info_set_id(info, id);
	err = snd_ctl_elem_read(ctl, value);
	if (err < 0)
		goto __fail;
	err = snd_ctl_elem_info(ctl, info);
	if (err < 0)
		goto __fail;
	err = snd_ctl_ascii_value_parse(ctl, value, info, pos);
	if (err < 0)
		goto __fail;
	err = snd_ctl_elem_write(ctl, value);
	if (err < 0)
		goto __fail;
	err = 0;
      __fail:
	if (id != NULL)
		free(id);
	if (value != NULL)
		free(value);
	if (info != NULL)
		free(info);

	return err;
}
Example #2
0
static int init_mixer_control(struct loopback_control *control,
			      char *id)
{
	int err;

	err = snd_ctl_elem_id_malloc(&control->id);
	if (err < 0)
		return err;
	err = snd_ctl_elem_info_malloc(&control->info);
	if (err < 0)
		return err;
	err = snd_ctl_elem_value_malloc(&control->value);
	if (err < 0)
		return err;
	err = control_parse_id(id, control->id);
	if (err < 0)
		return err;
	return 0;
}
Example #3
0
int main(int argc, char *argv[])
{
    char *format = FORMAT;
    char *device = DEVICE;
    char *volume_control = VOLUME_CONTROL;
    char *mute_control = MUTE_CONTROL;
    int interval = INTERVAL;
    bool snoop = false;

    int opt;
    while ((opt = getopt(argc, argv, "hsf:i:d:v:m:")) != -1) {
        switch (opt) {
            case 'h':
                printf("volume [-h|-s|-f FORMAT|-i INTERVAL|-d DEVICE|-v VOLUME_CONTROL|-m MUTE_CONTROL]\n");
                exit(EXIT_SUCCESS);
                break;
            case 's':
                snoop = true;
                break;
            case 'f':
                format = optarg;
                break;
            case 'd':
                device = optarg;
                break;
            case 'i':
                interval = atoi(optarg);
                break;
            case 'v':
                volume_control = optarg;
                break;
            case 'm':
                mute_control = optarg;
                break;
        }
    }

    int exit_code;

    snd_hctl_t *hctl;
    snd_ctl_elem_id_t *volume_id;
    snd_ctl_elem_id_t *mute_id;
    snd_ctl_elem_value_t *volume_ctl;
    snd_ctl_elem_value_t *mute_ctl;
    snd_ctl_elem_info_t *volume_info;
    snd_hctl_elem_t *volume_elem;
    snd_hctl_elem_t *mute_elem;
    int vol_max, vol_min;

    if (snd_hctl_open(&hctl, device, 0) || snd_hctl_load(hctl)) {
        return EXIT_FAILURE;
    }

    snd_ctl_elem_id_malloc(&volume_id);
    snd_ctl_elem_id_malloc(&mute_id);
    snd_ctl_elem_value_malloc(&volume_ctl);
    snd_ctl_elem_value_malloc(&mute_ctl);
    snd_ctl_elem_info_malloc(&volume_info);

    snd_ctl_elem_id_set_interface(volume_id, SND_CTL_ELEM_IFACE_MIXER);
    snd_ctl_elem_id_set_interface(mute_id, SND_CTL_ELEM_IFACE_MIXER);
    snd_ctl_elem_id_set_name(volume_id, volume_control);
    snd_ctl_elem_id_set_name(mute_id, mute_control);

    snd_ctl_elem_value_set_id(volume_ctl, volume_id);
    snd_ctl_elem_value_set_id(mute_ctl, mute_id);
    volume_elem = snd_hctl_find_elem(hctl, volume_id);
    mute_elem = snd_hctl_find_elem(hctl, mute_id);

    snd_ctl_elem_info_set_id(volume_info, volume_id);
    snd_hctl_elem_info(volume_elem, volume_info);
    vol_min = (int)snd_ctl_elem_info_get_min(volume_info);
    vol_max = (int)snd_ctl_elem_info_get_max(volume_info);

    if (volume_elem == NULL || mute_elem == NULL) {
        snd_hctl_close(hctl);
        return EXIT_FAILURE;
    }

    struct sigaction action = {.sa_handler = &sig_handler};
    sigaction(SIGUSR1, &action, NULL);

    if (snoop)
        for (;;) {
            if (update) {
                update = false;
                continue;
            }

            if ((exit_code = put_infos(vol_min, vol_max, volume_elem, mute_elem,
                volume_ctl, mute_ctl, format)) == EXIT_FAILURE)
                break;

            sleep(interval);
        }
    else
        exit_code = put_infos(vol_min, vol_max, volume_elem, mute_elem,
            volume_ctl, mute_ctl, format);

    snd_hctl_close(hctl);
    snd_ctl_elem_id_free(volume_id);
    snd_ctl_elem_id_free(mute_id);
    snd_ctl_elem_value_free(volume_ctl);
    snd_ctl_elem_value_free(mute_ctl);
    snd_ctl_elem_info_free(volume_info);
    return exit_code;
}
Example #4
0
/**************************************************************************
 * 			ALSA_CheckSetVolume		[internal]
 *
 *  Helper function for Alsa volume queries.  This tries to simplify
 * the process of managing the volume.  All parameters are optional
 * (pass NULL to ignore or not use).
 *  Return values are MMSYSERR_NOERROR on success, or !0 on failure;
 * error codes are normalized into the possible documented return
 * values from waveOutGetVolume.
 */
int ALSA_CheckSetVolume(snd_hctl_t *hctl, int *out_left, int *out_right,
            int *out_min, int *out_max, int *out_step,
            int *new_left, int *new_right)
{
    int rc = MMSYSERR_NOERROR;
    int value_count = 0;
    snd_hctl_elem_t *           elem = NULL;
    snd_ctl_elem_info_t *       eleminfop = NULL;
    snd_ctl_elem_value_t *      elemvaluep = NULL;
    snd_ctl_elem_id_t *         elemidp = NULL;
    const char *names[] = {"PCM Playback Volume", "Line Playback Volume", NULL};
    const char **name;


#define EXIT_ON_ERROR(f,txt,exitcode) do \
{ \
    int err; \
    if ( (err = (f) ) < 0) \
    { \
	ERR(txt " failed: %s\n", snd_strerror(err)); \
        rc = exitcode; \
        goto out; \
    } \
} while(0)

    if (! hctl)
        return MMSYSERR_NOTSUPPORTED;

    /* Allocate areas to return information about the volume */
    EXIT_ON_ERROR(snd_ctl_elem_id_malloc(&elemidp), "snd_ctl_elem_id_malloc", MMSYSERR_NOMEM);
    EXIT_ON_ERROR(snd_ctl_elem_value_malloc (&elemvaluep), "snd_ctl_elem_value_malloc", MMSYSERR_NOMEM);
    EXIT_ON_ERROR(snd_ctl_elem_info_malloc (&eleminfop), "snd_ctl_elem_info_malloc", MMSYSERR_NOMEM);
    snd_ctl_elem_id_clear(elemidp);
    snd_ctl_elem_value_clear(elemvaluep);
    snd_ctl_elem_info_clear(eleminfop);

    /* Setup and find an element id that exactly matches the characteristic we want
    ** FIXME:  It is probably short sighted to hard code and fixate on PCM Playback Volume */

    for( name = names; *name; name++ )
    {
	snd_ctl_elem_id_set_name(elemidp, *name);
	snd_ctl_elem_id_set_interface(elemidp, SND_CTL_ELEM_IFACE_MIXER);
	elem = snd_hctl_find_elem(hctl, elemidp);
	if (elem)
	{
	    /* Read and return volume information */
	    EXIT_ON_ERROR(snd_hctl_elem_info(elem, eleminfop), "snd_hctl_elem_info", MMSYSERR_NOTSUPPORTED);
	    value_count = snd_ctl_elem_info_get_count(eleminfop);
	    if (out_min || out_max || out_step)
	    {
		if (!snd_ctl_elem_info_is_readable(eleminfop))
		{
		    ERR("snd_ctl_elem_info_is_readable returned false; cannot return info\n");
		    rc = MMSYSERR_NOTSUPPORTED;
		    goto out;
		}

		if (out_min)
		    *out_min = snd_ctl_elem_info_get_min(eleminfop);

		if (out_max)
		    *out_max = snd_ctl_elem_info_get_max(eleminfop);

		if (out_step)
		    *out_step = snd_ctl_elem_info_get_step(eleminfop);
	    }

	    if (out_left || out_right)
	    {
		EXIT_ON_ERROR(snd_hctl_elem_read(elem, elemvaluep), "snd_hctl_elem_read", MMSYSERR_NOTSUPPORTED);

		if (out_left)
		    *out_left = snd_ctl_elem_value_get_integer(elemvaluep, 0);

		if (out_right)
		{
		    if (value_count == 1)
			*out_right = snd_ctl_elem_value_get_integer(elemvaluep, 0);
		    else if (value_count == 2)
			*out_right = snd_ctl_elem_value_get_integer(elemvaluep, 1);
		    else
		    {
			ERR("Unexpected value count %d from snd_ctl_elem_info_get_count while getting volume info\n", value_count);
			rc = -1;
			goto out;
		    }
		}
	    }

	    /* Set the volume */
	    if (new_left || new_right)
	    {
		EXIT_ON_ERROR(snd_hctl_elem_read(elem, elemvaluep), "snd_hctl_elem_read", MMSYSERR_NOTSUPPORTED);
		if (new_left)
		    snd_ctl_elem_value_set_integer(elemvaluep, 0, *new_left);
		if (new_right)
		{
		    if (value_count == 1)
			snd_ctl_elem_value_set_integer(elemvaluep, 0, *new_right);
		    else if (value_count == 2)
			snd_ctl_elem_value_set_integer(elemvaluep, 1, *new_right);
		    else
		    {
			ERR("Unexpected value count %d from snd_ctl_elem_info_get_count while setting volume info\n", value_count);
			rc = -1;
			goto out;
		    }
		}

		EXIT_ON_ERROR(snd_hctl_elem_write(elem, elemvaluep), "snd_hctl_elem_write", MMSYSERR_NOTSUPPORTED);
	    }

	    break;
	}
    }

    if( !*name )
    {
        ERR("Could not find '{PCM,Line} Playback Volume' element\n");
        rc = MMSYSERR_NOTSUPPORTED;
    }


#undef EXIT_ON_ERROR

out:

    if (elemvaluep)
        snd_ctl_elem_value_free(elemvaluep);
    if (eleminfop)
        snd_ctl_elem_info_free(eleminfop);
    if (elemidp)
        snd_ctl_elem_id_free(elemidp);

    return rc;
}
Example #5
0
static int execute_cset(snd_ctl_t *ctl, const char *cset, unsigned int type)
{
	const char *pos;
	int err;
	snd_ctl_elem_id_t *id;
	snd_ctl_elem_value_t *value;
	snd_ctl_elem_info_t *info;
	unsigned int *res = NULL;

	snd_ctl_elem_id_malloc(&id);
	snd_ctl_elem_value_malloc(&value);
	snd_ctl_elem_info_malloc(&info);

	err = __snd_ctl_ascii_elem_id_parse(id, cset, &pos);
	if (err < 0)
		goto __fail;
	while (*pos && isspace(*pos))
		pos++;
	if (!*pos) {
		uc_error("undefined value for cset >%s<", cset);
		err = -EINVAL;
		goto __fail;
	}
	snd_ctl_elem_info_set_id(info, id);
	err = snd_ctl_elem_info(ctl, info);
	if (err < 0)
		goto __fail;
	if (type == SEQUENCE_ELEMENT_TYPE_CSET_TLV) {
		if (!snd_ctl_elem_info_is_tlv_writable(info)) {
			err = -EINVAL;
			goto __fail;
		}
		err = read_tlv_file(&res, pos);
		if (err < 0)
			goto __fail;
		err = snd_ctl_elem_tlv_write(ctl, id, res);
		if (err < 0)
			goto __fail;
	} else {
		snd_ctl_elem_value_set_id(value, id);
		err = snd_ctl_elem_read(ctl, value);
		if (err < 0)
			goto __fail;
		if (type == SEQUENCE_ELEMENT_TYPE_CSET_BIN_FILE)
			err = binary_file_parse(value, info, pos);
		else
			err = snd_ctl_ascii_value_parse(ctl, value, info, pos);
		if (err < 0)
			goto __fail;
		err = snd_ctl_elem_write(ctl, value);
		if (err < 0)
			goto __fail;
	}
	err = 0;
      __fail:
	if (id != NULL)
		free(id);
	if (value != NULL)
		free(value);
	if (info != NULL)
		free(info);
	if (res != NULL)
		free(res);

	return err;
}