コード例 #1
0
ファイル: patchbay.c プロジェクト: rocketsquawk/mudita24
void patchbay_init(void)
{
	int i;
	int nb_active_channels;
	snd_ctl_elem_value_t *val;

	snd_ctl_elem_value_alloca(&val);
	snd_ctl_elem_value_set_interface(val, SND_CTL_ELEM_IFACE_MIXER);
	snd_ctl_elem_value_set_name(val, ANALOG_PLAYBACK_ROUTE_NAME);
	memset (stream_active, 0, (MAX_OUTPUT_CHANNELS + MAX_SPDIF_CHANNELS) * sizeof(int));
	nb_active_channels = 0;
	for (i = 0; i < output_channels; i++) {
		snd_ctl_elem_value_set_numid(val, 0);
		snd_ctl_elem_value_set_index(val, i);
		if (snd_ctl_elem_read(ctl, val) < 0)
			continue;

		stream_active[i] = 1;
		nb_active_channels++;
	}
	output_channels = nb_active_channels;
	snd_ctl_elem_value_set_name(val, SPDIF_PLAYBACK_ROUTE_NAME);
	nb_active_channels = 0;
	for (i = 0; i < spdif_channels; i++) {
		snd_ctl_elem_value_set_numid(val, 0);
		snd_ctl_elem_value_set_index(val, i);
 		if (snd_ctl_elem_read(ctl, val) < 0)
			continue;
		stream_active[i + MAX_OUTPUT_CHANNELS] = 1;
		nb_active_channels++;
	}
	spdif_channels = nb_active_channels;
}
コード例 #2
0
ファイル: volume.c プロジェクト: Distrotech/alsa-tools
void ipga_volume_update(int idx)
{
	snd_ctl_elem_value_t *val;
	int err, ipga_vol;
	snd_ctl_elem_value_alloca(&val);
	snd_ctl_elem_value_set_interface(val, SND_CTL_ELEM_IFACE_MIXER);
	snd_ctl_elem_value_set_name(val, IPGA_VOLUME_NAME);
	snd_ctl_elem_value_set_index(val, idx);
	if ((err = snd_ctl_elem_read(ctl, val)) < 0) {
		g_print("Unable to read ipga volume: %s\n", snd_strerror(err));
		return;
	}
	gtk_adjustment_set_value(GTK_ADJUSTMENT(av_ipga_volume_adj[idx]),
				 -(ipga_vol = snd_ctl_elem_value_get_integer(val, 0)));
	snd_ctl_elem_value_set_name(val, ADC_VOLUME_NAME);
	snd_ctl_elem_value_set_index(val, idx);
	if ((err = snd_ctl_elem_read(ctl, val)) < 0) {
		g_print("Unable to read adc volume: %s\n", snd_strerror(err));
		return;
	}
	// set ADC volume to max if IPGA volume greater 0
	if (ipga_vol)
		gtk_adjustment_set_value(GTK_ADJUSTMENT(av_adc_volume_adj[idx]),
					 -adc_max);
}
コード例 #3
0
ファイル: hammerfall.c プロジェクト: Barrett17/jack2
static void *
hammerfall_monitor_controls (void *arg)
{
	jack_hardware_t *hw = (jack_hardware_t *) arg;
	hammerfall_t *h = (hammerfall_t *) hw->private_hw;
	snd_ctl_elem_id_t *switch_id[3];
	snd_ctl_elem_value_t *sw[3];

	pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL);

	snd_ctl_elem_id_malloc (&switch_id[0]);
	snd_ctl_elem_id_malloc (&switch_id[1]);
	snd_ctl_elem_id_malloc (&switch_id[2]);

	snd_ctl_elem_value_malloc (&sw[0]);
	snd_ctl_elem_value_malloc (&sw[1]);
	snd_ctl_elem_value_malloc (&sw[2]);

	set_control_id (switch_id[0], "ADAT1 Sync Check");
	set_control_id (switch_id[1], "ADAT2 Sync Check");
	set_control_id (switch_id[2], "ADAT3 Sync Check");

	snd_ctl_elem_value_set_id (sw[0], switch_id[0]);
	snd_ctl_elem_value_set_id (sw[1], switch_id[1]);
	snd_ctl_elem_value_set_id (sw[2], switch_id[2]);

	while (1) {
		if (snd_ctl_elem_read (h->driver->ctl_handle, sw[0])) {
			jack_error ("cannot read control switch 0 ...");
		}
		hammerfall_check_sync (h, sw[0]);

		if (snd_ctl_elem_read (h->driver->ctl_handle, sw[1])) {
			jack_error ("cannot read control switch 0 ...");
		}
		hammerfall_check_sync (h, sw[1]);

		if (snd_ctl_elem_read (h->driver->ctl_handle, sw[2])) {
			jack_error ("cannot read control switch 0 ...");
		}
		hammerfall_check_sync (h, sw[2]);
		
		if (nanosleep (&h->monitor_interval, 0)) {
			break;
		}
	}

	pthread_exit (0);
}
コード例 #4
0
ファイル: patchbay.c プロジェクト: rocketsquawk/mudita24
static int get_toggle_index(int stream)
{
	int err, out;
	snd_ctl_elem_value_t *val;

	stream--;
	if (stream < 0 || stream > 9) {
		g_print("get_toggle_index (1)\n");
		return 0;
	}
	snd_ctl_elem_value_alloca(&val);
	snd_ctl_elem_value_set_interface(val, SND_CTL_ELEM_IFACE_MIXER);
	if (stream >= MAX_OUTPUT_CHANNELS) {
		snd_ctl_elem_value_set_name(val, SPDIF_PLAYBACK_ROUTE_NAME);
		snd_ctl_elem_value_set_index(val, stream - MAX_OUTPUT_CHANNELS);
	} else {
		snd_ctl_elem_value_set_name(val, ANALOG_PLAYBACK_ROUTE_NAME);
		snd_ctl_elem_value_set_index(val, stream);
	}
	if ((err = snd_ctl_elem_read(ctl, val)) < 0)
		return 0;
	out = snd_ctl_elem_value_get_enumerated(val, 0);
	if (out >= MAX_INPUT_CHANNELS + MAX_SPDIF_CHANNELS + 1) {
		if (stream >= MAX_PCM_OUTPUT_CHANNELS || stream < MAX_SPDIF_CHANNELS)
			return 1; /* digital mixer */
	} else if (out >= MAX_INPUT_CHANNELS + 1)
		return out - (MAX_INPUT_CHANNELS + 1) + 2; /* spdif left (=2) / right (=3) */
	else if (out >= 1)
		return out + spdif_channels + 1; /* analog (4-) */

	return 0; /* pcm */
}
コード例 #5
0
/**
 * \brief Get value for an HCTL element
 * \param elem HCTL element
 * \param value HCTL element value
 * \return 0 otherwise a negative error code on failure
 */
int snd_hctl_elem_read(snd_hctl_elem_t *elem, snd_ctl_elem_value_t * value)
{
	assert(elem);
	assert(elem->hctl);
	assert(value);
	value->id = elem->id;
	return snd_ctl_elem_read(elem->hctl->ctl, value);
}
コード例 #6
0
ファイル: levelmeters.c プロジェクト: rocketsquawk/mudita24
void level_meters_init(void) {
	int err;

	snd_ctl_elem_value_malloc(&peaks);
	snd_ctl_elem_value_set_interface(peaks, SND_CTL_ELEM_IFACE_PCM);
	snd_ctl_elem_value_set_name(peaks, "Multi Track Peak");
	if ((err = snd_ctl_elem_read(ctl, peaks)) < 0)
		/* older ALSA driver, using MIXER type */
		snd_ctl_elem_value_set_interface(peaks,
			SND_CTL_ELEM_IFACE_MIXER);
}
コード例 #7
0
ファイル: hdspm_mixer.c プロジェクト: IcaroL2ORK/pd
int get_gain(int idx, int src, int dst)
{
  int err;
  int val = HDSPMM_ERROR_NO_CARD;

  snd_ctl_elem_id_t *id;
  snd_ctl_elem_value_t *ctl;
  snd_ctl_t *handle;

  if(idx >= HDSPMM_MAX_CARDS || idx < 0)
	return HDSPMM_ERROR_WRONG_IDX;


  snd_ctl_elem_value_alloca(&ctl);
  snd_ctl_elem_id_alloca(&id);
  snd_ctl_elem_id_set_name(id, "Mixer");
  snd_ctl_elem_id_set_numid(id, 0);
  snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_HWDEP);
  snd_ctl_elem_id_set_device(id, 0);
  snd_ctl_elem_id_set_subdevice(id, 0);
  snd_ctl_elem_id_set_index(id, 0);
  snd_ctl_elem_value_set_id(ctl, id);

  if ((err = snd_ctl_open(&handle, card_name[cardid], SND_CTL_NONBLOCK)) < 0) {
#ifndef QUIET
    fprintf(stderr, "Alsa error: %s\n", snd_strerror(err));
#endif
    return HDSPMM_ERROR_ALSA_OPEN;
  }

  snd_ctl_elem_value_set_integer(ctl, 0, src);
  snd_ctl_elem_value_set_integer(ctl, 1, dst);

  if ((err = snd_ctl_elem_read(handle, ctl)) < 0) {
#ifndef QUIET
    fprintf(stderr, "Alsa error: %s\n", snd_strerror(err));
#endif
    return HDSPMM_ERROR_ALSA_READ;
  }
  val = snd_ctl_elem_value_get_integer(ctl, 2);

  snd_ctl_close(handle);

  return val;
  
  SETFLOAT(x->x_at+1, delta);
  SETFLOAT(x->x_at+2, phi);
  outlet_list(x->x_out_para, &s_list, 3, x->x_at);
  outlet_anything(x->x_obj.ob_outlet, s, x->x_size2d+1, x->x_at);
}
コード例 #8
0
ファイル: pcm_softvol.c プロジェクト: xenyinzen/lx_toolset
/*
 * get the current volume value from driver
 *
 * TODO: mmap support?
 */
static void get_current_volume(snd_pcm_softvol_t *svol)
{
	unsigned int val;
	unsigned int i;

	if (snd_ctl_elem_read(svol->ctl, &svol->elem) < 0)
		return;
	for (i = 0; i < svol->cchannels; i++) {
		val = svol->elem.value.integer.value[i];
		if (val > svol->max_val)
			val = svol->max_val;
		svol->cur_vol[i] = val;
	}
}
コード例 #9
0
ファイル: volume.c プロジェクト: Distrotech/alsa-tools
void dac_volume_update(int idx)
{
	snd_ctl_elem_value_t *val;
	int err;
	snd_ctl_elem_value_alloca(&val);
	snd_ctl_elem_value_set_interface(val, SND_CTL_ELEM_IFACE_MIXER);
	snd_ctl_elem_value_set_name(val, DAC_VOLUME_NAME);
	snd_ctl_elem_value_set_index(val, idx);
	if ((err = snd_ctl_elem_read(ctl, val)) < 0) {
		g_print("Unable to read dac volume: %s\n", snd_strerror(err));
		return;
	}
	gtk_adjustment_set_value(GTK_ADJUSTMENT(av_dac_volume_adj[idx]),
				 -snd_ctl_elem_value_get_integer(val, 0));
}
コード例 #10
0
ファイル: volume.c プロジェクト: Distrotech/alsa-tools
void adc_sense_update(int idx)
{
	snd_ctl_elem_value_t *val;
	int err;
	int state;
	snd_ctl_elem_value_alloca(&val);
	snd_ctl_elem_value_set_interface(val, SND_CTL_ELEM_IFACE_MIXER);
	snd_ctl_elem_value_set_name(val, ADC_SENSE_NAME);
	snd_ctl_elem_value_set_index(val, idx);
	if ((err = snd_ctl_elem_read(ctl, val)) < 0) {
		g_print("Unable to read adc sense: %s\n", snd_strerror(err));
		return;
	}
	state = snd_ctl_elem_value_get_enumerated(val, 0);
	toggle_set(av_adc_sense_radio[idx][state], TRUE);
}
コード例 #11
0
ファイル: main.c プロジェクト: Blackrose/mini2440-bsp
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;
}
コード例 #12
0
static int check_elems(struct elem_set_trial *trial)
{
	snd_ctl_elem_value_t *data;
	unsigned int numid;
	unsigned int index;
	unsigned int i;
	int err;

	snd_ctl_elem_value_alloca(&data);

	snd_ctl_elem_value_set_id(data, trial->id);
	numid = snd_ctl_elem_id_get_numid(trial->id);
	index = snd_ctl_elem_id_get_index(trial->id);

	for (i = 0; i < trial->element_count; ++i) {
		snd_ctl_elem_value_set_index(data, index + i);

		/*
		 * In Linux 4.0 or former, ioctl(SNDRV_CTL_IOCTL_ELEM_ADD)
		 * doesn't fill all of fields for identification.
		 */
		if (numid > 0)
			snd_ctl_elem_value_set_numid(data, numid + i);

		err = snd_ctl_elem_read(trial->handle, data);
		if (err < 0)
			return err;

		/* Change members of an element in this element set. */
		trial->change_elem_members(trial, data);

		err = snd_ctl_elem_write(trial->handle, data);
		if (err < 0)
			return err;
	}

	return 0;
}
コード例 #13
0
bool LegacyAmixerControl::accessHW(bool receive, string &error)
{
    CAutoLog autoLog(getConfigurableElement(), "ALSA", isDebugEnabled());

#ifdef SIMULATION
    if (receive) {

        memset(getBlackboardLocation(), 0, getSize());
    }
    log_info("%s ALSA Element Instance: %s\t\t(Control Element: %s)",
             receive ? "Reading" : "Writing",
             getConfigurableElement()->getPath().c_str(),
             getControlName().c_str());

    return true;
#endif

    int ret;
    // Mixer handle
    snd_ctl_t *sndCtrl;
    uint32_t value;
    uint32_t index;
    uint32_t elementCount;
    snd_ctl_elem_id_t *id;
    snd_ctl_elem_info_t *info;
    snd_ctl_elem_value_t *control;

    logControlInfo(receive);

    // Check parameter type is ok (deferred error, no exceptions available :-()
    if (!isTypeSupported()) {

        error = "Parameter type not supported.";

        return false;
    }

    int cardNumber = getCardNumber();

    if (cardNumber < 0) {

        error = "Card " + getCardName() + " not found. Error: " + strerror(cardNumber);

        return false;
    }
#ifdef ANDROID
    if ((ret = snd_ctl_hw_open(&sndCtrl, NULL, cardNumber, 0)) < 0) {

        error = snd_strerror(ret);

        return false;
    }
#else
    // Create device name
    ostringstream deviceName;

    deviceName << "hw:" << cardNumber;

    // Open sound control
    if ((ret = snd_ctl_open(&sndCtrl, deviceName.str().c_str(), 0)) < 0) {

        error = snd_strerror(ret);

        return false;
    }
#endif

    // Allocate in stack
    snd_ctl_elem_id_alloca(&id);
    snd_ctl_elem_info_alloca(&info);
    snd_ctl_elem_value_alloca(&control);

    // Set interface
    snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER);

    string controlName = getControlName();

    // Set name or id
    if (isdigit(controlName[0])) {

        snd_ctl_elem_id_set_numid(id, asInteger(controlName));
    } else {

        snd_ctl_elem_id_set_name(id, controlName.c_str());
    }
    // Init info id
    snd_ctl_elem_info_set_id(info, id);

    // Get info
    if ((ret = snd_ctl_elem_info(sndCtrl, info)) < 0) {

        error = "ALSA: Unable to get element info " + controlName +
                ": " + snd_strerror(ret);

        // Close sound control
        snd_ctl_close(sndCtrl);

        return false;
    }
    // Get type
    snd_ctl_elem_type_t eType = snd_ctl_elem_info_get_type(info);

    // Get element count
    elementCount = snd_ctl_elem_info_get_count(info);

    uint32_t scalarSize = getScalarSize();

    // If size defined in the PFW different from alsa mixer control size, return an error
    if (elementCount * scalarSize != getSize()) {

        error = "ALSA: Control element count (" + asString(elementCount) +
                ") and configurable scalar element count (" +
                asString(getSize() / scalarSize) + ") mismatch";

        // Close sound control
        snd_ctl_close(sndCtrl);

        return false;
    }
    // Set value id
    snd_ctl_elem_value_set_id(control, id);

    if (receive) {

        // Read element
        if ((ret = snd_ctl_elem_read(sndCtrl, control)) < 0) {

            error = "ALSA: Unable to read element " + controlName +
                    ": " + snd_strerror(ret);

            // Close sound control
            snd_ctl_close(sndCtrl);

            return false;
        }
        // Go through all indexes
        for (index = 0; index < elementCount; index++) {

            switch (eType) {
            case SND_CTL_ELEM_TYPE_BOOLEAN:
                value = snd_ctl_elem_value_get_boolean(control, index);
                break;
            case SND_CTL_ELEM_TYPE_INTEGER:
                value = snd_ctl_elem_value_get_integer(control, index);
                break;
            case SND_CTL_ELEM_TYPE_INTEGER64:
                value = snd_ctl_elem_value_get_integer64(control, index);
                break;
            case SND_CTL_ELEM_TYPE_ENUMERATED:
                value = snd_ctl_elem_value_get_enumerated(control, index);
                break;
            case SND_CTL_ELEM_TYPE_BYTES:
                value = snd_ctl_elem_value_get_byte(control, index);
                break;
            default:
                error = "ALSA: Unknown control element type while reading alsa element " +
                        controlName;
                return false;
            }

            if (isDebugEnabled()) {

                log_info("Reading alsa element %s, index %u with value %u",
                         controlName.c_str(), index, value);
            }

            // Write data to blackboard (beware this code is OK on Little Endian machines only)
            toBlackboard(value);
        }

    } else {

        // Go through all indexes
        for (index = 0; index < elementCount; index++) {

            // Read data from blackboard (beware this code is OK on Little Endian machines only)
            value = fromBlackboard();

            if (isDebugEnabled()) {

                log_info("Writing alsa element %s, index %u with value %u",
                         controlName.c_str(), index, value);
            }

            switch (eType) {
            case SND_CTL_ELEM_TYPE_BOOLEAN:
                snd_ctl_elem_value_set_boolean(control, index, value);
                break;
            case SND_CTL_ELEM_TYPE_INTEGER:
                snd_ctl_elem_value_set_integer(control, index, value);
                break;
            case SND_CTL_ELEM_TYPE_INTEGER64:
                snd_ctl_elem_value_set_integer64(control, index, value);
                break;
            case SND_CTL_ELEM_TYPE_ENUMERATED:
                snd_ctl_elem_value_set_enumerated(control, index, value);
                break;
            case SND_CTL_ELEM_TYPE_BYTES:
                snd_ctl_elem_value_set_byte(control, index, value);
                break;
            default:
                error = "ALSA: Unknown control element type while writing alsa element " +
                        controlName;
                return false;
            }
        }

        // Write element
        if ((ret = snd_ctl_elem_write(sndCtrl, control)) < 0) {

            error = "ALSA: Unable to write element " + controlName +
                    ": " + snd_strerror(ret);


            // Close sound control
            snd_ctl_close(sndCtrl);

            return false;
        }
    }
    // Close sound control
    snd_ctl_close(sndCtrl);

    return true;
}
コード例 #14
0
static int get_control(snd_ctl_t *handle, snd_ctl_elem_id_t *id, snd_config_t *top)
{
	snd_ctl_elem_value_t *ctl;
	snd_ctl_elem_info_t *info;
	snd_config_t *control, *comment, *item, *value;
	const char *s;
	char buf[256];
	unsigned int idx;
	int err;
	unsigned int device, subdevice, index;
	const char *name;
	snd_ctl_elem_type_t type;
	unsigned int count;
	snd_ctl_elem_value_alloca(&ctl);
	snd_ctl_elem_info_alloca(&info);
	snd_ctl_elem_info_set_id(info, id);
	err = snd_ctl_elem_info(handle, info);
	if (err < 0) {
		error("Cannot read control info '%s': %s", id_str(id), snd_strerror(err));
		return err;
	}

	if (snd_ctl_elem_info_is_inactive(info) ||
				!snd_ctl_elem_info_is_readable(info))
		return 0;
	snd_ctl_elem_value_set_id(ctl, id);
	err = snd_ctl_elem_read(handle, ctl);
	if (err < 0) {
		error("Cannot read control '%s': %s", id_str(id), snd_strerror(err));
		return err;
	}

	err = snd_config_compound_add(top, num_str(snd_ctl_elem_info_get_numid(info)), 0, &control);
	if (err < 0) {
		error("snd_config_compound_add: %s", snd_strerror(err));
		return err;
	}
	err = snd_config_compound_add(control, "comment", 1, &comment);
	if (err < 0) {
		error("snd_config_compound_add: %s", snd_strerror(err));
		return err;
	}

	buf[0] = '\0';
	buf[1] = '\0';
	if (snd_ctl_elem_info_is_readable(info))
		strcat(buf, " read");
	if (snd_ctl_elem_info_is_writable(info))
		strcat(buf, " write");
	if (snd_ctl_elem_info_is_inactive(info))
		strcat(buf, " inactive");
	if (snd_ctl_elem_info_is_volatile(info))
		strcat(buf, " volatile");
	if (snd_ctl_elem_info_is_locked(info))
		strcat(buf, " locked");
	if (snd_ctl_elem_info_is_user(info))
		strcat(buf, " user");
	err = snd_config_string_add(comment, "access", buf + 1);
	if (err < 0) {
		error("snd_config_string_add: %s", snd_strerror(err));
		return err;
	}

	type = snd_ctl_elem_info_get_type(info);
	device = snd_ctl_elem_info_get_device(info);
	subdevice = snd_ctl_elem_info_get_subdevice(info);
	index = snd_ctl_elem_info_get_index(info);
	name = snd_ctl_elem_info_get_name(info);
	count = snd_ctl_elem_info_get_count(info);
	s = snd_ctl_elem_type_name(type);
	err = snd_config_string_add(comment, "type", s);
	if (err < 0) {
		error("snd_config_string_add: %s", snd_strerror(err));
		return err;
	}
	err = snd_config_integer_add(comment, "count", count);
	if (err < 0) {
		error("snd_config_integer_add: %s", snd_strerror(err));
		return err;
	}

	switch (type) {
	case SND_CTL_ELEM_TYPE_BOOLEAN:
		break;
	case SND_CTL_ELEM_TYPE_INTEGER:
	{
		long min = snd_ctl_elem_info_get_min(info);
		long max = snd_ctl_elem_info_get_max(info);
		long step = snd_ctl_elem_info_get_step(info);
		if (step)
			sprintf(buf, "%li - %li (step %li)", min, max, step);
		else
			sprintf(buf, "%li - %li", min, max);
		err = snd_config_string_add(comment, "range", buf);
		if (err < 0) {
			error("snd_config_string_add: %s", snd_strerror(err));
			return err;
		}
		if (snd_ctl_elem_info_is_tlv_readable(info)) {
			err = add_tlv_comments(handle, id, info, comment);
			if (err < 0)
				return err;
		}
		break;
	}
	case SND_CTL_ELEM_TYPE_INTEGER64:
	{
		long long min = snd_ctl_elem_info_get_min64(info);
		long long max = snd_ctl_elem_info_get_max64(info);
		long long step = snd_ctl_elem_info_get_step64(info);
		if (step)
			sprintf(buf, "%Li - %Li (step %Li)", min, max, step);
		else
			sprintf(buf, "%Li - %Li", min, max);
		err = snd_config_string_add(comment, "range", buf);
		if (err < 0) {
			error("snd_config_string_add: %s", snd_strerror(err));
			return err;
		}
		break;
	}
	case SND_CTL_ELEM_TYPE_ENUMERATED:
	{
		unsigned int items;
		err = snd_config_compound_add(comment, "item", 1, &item);
		if (err < 0) {
			error("snd_config_compound_add: %s", snd_strerror(err));
			return err;
		}
		items = snd_ctl_elem_info_get_items(info);
		for (idx = 0; idx < items; idx++) {
			snd_ctl_elem_info_set_item(info, idx);
			err = snd_ctl_elem_info(handle, info);
			if (err < 0) {
				error("snd_ctl_card_info: %s", snd_strerror(err));
				return err;
			}
			err = snd_config_string_add(item, num_str(idx), snd_ctl_elem_info_get_item_name(info));
			if (err < 0) {
				error("snd_config_string_add: %s", snd_strerror(err));
				return err;
			}
		}
		break;
	}
	default:
		break;
	}
	s = snd_ctl_elem_iface_name(snd_ctl_elem_info_get_interface(info));
	err = snd_config_string_add(control, "iface", s);
	if (err < 0) {
		error("snd_config_string_add: %s", snd_strerror(err));
		return err;
	}
	if (device != 0) {
		err = snd_config_integer_add(control, "device", device);
		if (err < 0) {
			error("snd_config_integer_add: %s", snd_strerror(err));
			return err;
		}
	}
	if (subdevice != 0) {
		err = snd_config_integer_add(control, "subdevice", subdevice);
		if (err < 0) {
			error("snd_config_integer_add: %s", snd_strerror(err));
			return err;
		}
	}
	err = snd_config_string_add(control, "name", name);
	if (err < 0) {
		error("snd_config_string_add: %s", snd_strerror(err));
		return err;
	}
	if (index != 0) {
		err = snd_config_integer_add(control, "index", index);
		if (err < 0) {
			error("snd_config_integer_add: %s", snd_strerror(err));
			return err;
		}
	}

	switch (type) {
	case SND_CTL_ELEM_TYPE_BYTES:
	case SND_CTL_ELEM_TYPE_IEC958:
	{
		size_t size = type == SND_CTL_ELEM_TYPE_BYTES ?
			count : sizeof(snd_aes_iec958_t);
		char buf[size * 2 + 1];
		char *p = buf;
		char *hex = "0123456789abcdef";
		const unsigned char *bytes = 
		  (const unsigned char *)snd_ctl_elem_value_get_bytes(ctl);
		for (idx = 0; idx < size; idx++) {
			int v = bytes[idx];
			*p++ = hex[v >> 4];
			*p++ = hex[v & 0x0f];
		}
		*p = '\0';
		err = snd_config_string_add(control, "value", buf);
		if (err < 0) {
			error("snd_config_string_add: %s", snd_strerror(err));
			return err;
		}
		return 0;
	}
	default:
		break;
	}

	if (count == 1) {
		switch (type) {
		case SND_CTL_ELEM_TYPE_BOOLEAN:
			err = snd_config_string_add(control, "value", snd_ctl_elem_value_get_boolean(ctl, 0) ? "true" : "false");
			if (err < 0) {
				error("snd_config_string_add: %s", snd_strerror(err));
				return err;
			}
			return 0;
		case SND_CTL_ELEM_TYPE_INTEGER:
			err = snd_config_integer_add(control, "value", snd_ctl_elem_value_get_integer(ctl, 0));
			if (err < 0) {
				error("snd_config_integer_add: %s", snd_strerror(err));
				return err;
			}
			return 0;
		case SND_CTL_ELEM_TYPE_INTEGER64:
			err = snd_config_integer64_add(control, "value", snd_ctl_elem_value_get_integer64(ctl, 0));
			if (err < 0) {
				error("snd_config_integer64_add: %s", snd_strerror(err));
				return err;
			}
			return 0;
		case SND_CTL_ELEM_TYPE_ENUMERATED:
		{
			unsigned int v = snd_ctl_elem_value_get_enumerated(ctl, 0);
			snd_config_t *c;
			err = snd_config_search(item, num_str(v), &c);
			if (err == 0) {
				err = snd_config_get_string(c, &s);
				assert(err == 0);
				err = snd_config_string_add(control, "value", s);
			} else {
				err = snd_config_integer_add(control, "value", v);
			}
			if (err < 0)
				error("snd_config add: %s", snd_strerror(err));
			return 0;
		}
		default:
			error("Unknown control type: %d\n", type);
			return -EINVAL;
		}
	}

	err = snd_config_compound_add(control, "value", 1, &value);
	if (err < 0) {
		error("snd_config_compound_add: %s", snd_strerror(err));
		return err;
	}

	switch (type) {
	case SND_CTL_ELEM_TYPE_BOOLEAN:
		for (idx = 0; idx < count; idx++) {
			err = snd_config_string_add(value, num_str(idx), snd_ctl_elem_value_get_boolean(ctl, idx) ? "true" : "false");
			if (err < 0) {
				error("snd_config_string_add: %s", snd_strerror(err));
				return err;
			}
		}
		break;
	case SND_CTL_ELEM_TYPE_INTEGER:
		for (idx = 0; idx < count; idx++) {
			err = snd_config_integer_add(value, num_str(idx), snd_ctl_elem_value_get_integer(ctl, idx));
			if (err < 0) {
				error("snd_config_integer_add: %s", snd_strerror(err));
				return err;
			}
		}
		break;
	case SND_CTL_ELEM_TYPE_INTEGER64:
		for (idx = 0; idx < count; idx++) {
			err = snd_config_integer64_add(value, num_str(idx), snd_ctl_elem_value_get_integer64(ctl, idx));
			if (err < 0) {
				error("snd_config_integer64_add: %s", snd_strerror(err));
				return err;
			}
		}
		break;
	case SND_CTL_ELEM_TYPE_ENUMERATED:
		for (idx = 0; idx < count; idx++) {
			unsigned int v = snd_ctl_elem_value_get_enumerated(ctl, idx);
			snd_config_t *c;
			err = snd_config_search(item, num_str(v), &c);
			if (err == 0) {
				err = snd_config_get_string(c, &s);
				assert(err == 0);
				err = snd_config_string_add(value, num_str(idx), s);
			} else {
				err = snd_config_integer_add(value, num_str(idx), v);
			}
			if (err < 0) {
				error("snd_config add: %s", snd_strerror(err));
				return err;
			}
		}
		break;
	default:
		error("Unknown control type: %d\n", type);
		return -EINVAL;
	}
	
	return 0;
}
コード例 #15
0
ファイル: tvtester.c プロジェクト: bitgothic/h3_lichee
static int check_audio_route()
{
	int err, idx, i;
	snd_ctl_t *handle;
	const char *route_ctrl_name = "Speaker Function";
	snd_ctl_elem_value_t * elem_value;
	snd_ctl_elem_info_t *info;

	snd_ctl_elem_list_t elist;
	snd_ctl_elem_id_t *eid;

	snd_ctl_elem_value_alloca(&elem_value);
	snd_ctl_elem_info_alloca(&info);
	//snd_ctl_elem_value_set_numid(elem_value, 54);

	if ((err = snd_ctl_open(&handle, "hw:0", 0)) < 0) {
		  db_msg("Open control error: %s\n", snd_strerror(err));
		  goto check_audio_route_err;
	}

	db_msg("card=%d\n", handle->card);

	memset(&elist, 0, sizeof(elist));
	if (snd_ctl_elem_list(handle, &elist) < 0) {
		db_msg("snd_ctl_elem_list 1 failed\n");
		goto check_audio_route_err;
	}

	eid = calloc(elist.count, sizeof(snd_ctl_elem_id_t));
	elist.space = elist.count;
	elist.pids = eid;
	if (snd_ctl_elem_list(handle, &elist) < 0) {
		db_msg("snd_ctl_elem_list 2 failed\n");
		goto check_audio_route_err;
	}

	for (i = 0; i < elist.count; ++i) {
		info->id.numid = eid[i].numid;
		if ((err = snd_ctl_elem_info(handle, info)) < 0) {
			db_msg("Cannot find the given element from control\n");
			goto check_audio_route_err;
		}
		//db_msg("name[%d]=%s\n", i, snd_ctl_elem_info_get_name(info));

		if (!strcmp(snd_ctl_elem_info_get_name(info), route_ctrl_name)) {
			db_msg("route ctrl found!!!\n");
			break;
		}
	}

	snd_ctl_elem_value_set_numid(elem_value, info->id.numid);
	if ((err = snd_ctl_elem_read(handle,elem_value)) < 0) {
		  db_msg("snd_ctl_elem_read error: %s\n", snd_strerror(err));
		  goto check_audio_route_err;
	}

	db_msg("numid=%d\n", snd_ctl_elem_value_get_numid(elem_value));
	db_msg("name=%s\n", snd_ctl_elem_value_get_name(elem_value));

	//to set the new value
	snd_ctl_elem_value_set_enumerated(elem_value,0, 1);
	if ((err = snd_ctl_elem_write(handle,elem_value)) < 0) {
		  db_msg("snd_ctl_elem_write error: %s\n", snd_strerror(err));
		  goto check_audio_route_err;
	}

	//read it out again to check if we did set the registers.
	if ((err = snd_ctl_elem_read(handle,elem_value)) < 0) {
		  db_msg("snd_ctl_elem_read error: %s\n", snd_strerror(err));
		  goto check_audio_route_err;
	}

	db_msg("after: %d\n", snd_ctl_elem_value_get_enumerated(elem_value, 0));

	snd_ctl_close(handle);
	return 0;

check_audio_route_err:
	snd_ctl_close(handle);
	return -1;
}
コード例 #16
0
ファイル: levelmeters.c プロジェクト: rocketsquawk/mudita24
static void update_peak_switch(void) {
	int err;

	if ((err = snd_ctl_elem_read(ctl, peaks)) < 0)
		g_print("Unable to read peaks: %s\n", snd_strerror(err));
}
コード例 #17
0
status_t ALSAControl::get(const char *name, unsigned int &value, int index)
{
    if (!mHandle) {
        ALOGE("Control not initialized");
        return NO_INIT;
    }

    snd_ctl_elem_id_t *id;
    snd_ctl_elem_info_t *info;
    snd_ctl_elem_value_t *control;

    snd_ctl_elem_id_alloca(&id);
    snd_ctl_elem_info_alloca(&info);
    snd_ctl_elem_value_alloca(&control);

    snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER);
    snd_ctl_elem_id_set_name(id, name);
    snd_ctl_elem_info_set_id(info, id);

    int ret = snd_ctl_elem_info(mHandle, info);
    if (ret < 0) {
        ALOGE("Control '%s' cannot get element info: %d", name, ret);
        return BAD_VALUE;
    }

    int count = snd_ctl_elem_info_get_count(info);
    if (index >= count) {
        ALOGE("Control '%s' index is out of range (%d >= %d)", name, index, count);
        return BAD_VALUE;
    }

    snd_ctl_elem_info_get_id(info, id);
    snd_ctl_elem_value_set_id(control, id);

    ret = snd_ctl_elem_read(mHandle, control);
    if (ret < 0) {
        ALOGE("Control '%s' cannot read element value: %d", name, ret);
        return BAD_VALUE;
    }

    snd_ctl_elem_type_t type = snd_ctl_elem_info_get_type(info);
    switch (type) {
        case SND_CTL_ELEM_TYPE_BOOLEAN:
            value = snd_ctl_elem_value_get_boolean(control, index);
            break;
        case SND_CTL_ELEM_TYPE_INTEGER:
            value = snd_ctl_elem_value_get_integer(control, index);
            break;
        case SND_CTL_ELEM_TYPE_INTEGER64:
            value = snd_ctl_elem_value_get_integer64(control, index);
            break;
        case SND_CTL_ELEM_TYPE_ENUMERATED:
            value = snd_ctl_elem_value_get_enumerated(control, index);
            break;
        case SND_CTL_ELEM_TYPE_BYTES:
            value = snd_ctl_elem_value_get_byte(control, index);
            break;
        default:
            return BAD_VALUE;
    }

    return NO_ERROR;
}
コード例 #18
0
ファイル: main.c プロジェクト: eballetbo/alsa-lib
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;
}