status_t ALSAControl::getmax(const char *name, unsigned int &max)
{
    if (!mHandle) {
        LOGE("Control not initialized");
        return NO_INIT;
    }

    LOGV("%s(%s, %d)", __FUNCTION__, name, max);

    snd_ctl_elem_id_t *id;
    snd_ctl_elem_info_t *info;

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

    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) {
        LOGE("Control '%s' cannot get element info: %d", name, ret);
        return BAD_VALUE;
    }

    max = snd_ctl_elem_info_get_max(info);

    return NO_ERROR;
}
Example #2
0
bool CALSAHControlMonitor::Add(const std::string& ctlHandleName,
                               snd_ctl_elem_iface_t interface,
                               unsigned int device,
                               const std::string& name)
{
  snd_hctl_t *hctl = GetHandle(ctlHandleName);

  if (!hctl)
  {
    return false;
  }

  snd_ctl_elem_id_t *id;

  snd_ctl_elem_id_alloca(&id);

  snd_ctl_elem_id_set_interface(id, interface);
  snd_ctl_elem_id_set_name     (id, name.c_str());
  snd_ctl_elem_id_set_device   (id, device);

  snd_hctl_elem_t *elem = snd_hctl_find_elem(hctl, id);

  if (!elem)
  {
    PutHandle(ctlHandleName);
    return false;
  }

  snd_hctl_elem_set_callback(elem, HCTLCallback);

  return true;
}
Example #3
0
static void 
set_control_id (snd_ctl_elem_id_t *ctl, const char *name)
{
	snd_ctl_elem_id_set_name (ctl, name);
	snd_ctl_elem_id_set_numid (ctl, 0);
	snd_ctl_elem_id_set_interface (ctl, SND_CTL_ELEM_IFACE_MIXER);
	snd_ctl_elem_id_set_device (ctl, 0);
	snd_ctl_elem_id_set_subdevice (ctl, 0);
	snd_ctl_elem_id_set_index (ctl, 0);
}
static snd_hctl_elem_t *
_phoneui_utils_sound_init_get_control_by_name(const char *ctl_name)
{
	snd_ctl_elem_id_t *id;

	snd_ctl_elem_id_alloca(&id);
	snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER);
	snd_ctl_elem_id_set_name(id, ctl_name);

	return snd_hctl_find_elem(hctl, id);
}
Example #5
0
static int pulse_elem_list(snd_ctl_ext_t * ext, unsigned int offset,
			   snd_ctl_elem_id_t * id)
{
	snd_ctl_pulse_t *ctl = ext->private_data;
	int err;

	assert(ctl);

	if (!ctl->p || !ctl->p->mainloop)
		return -EBADFD;

	snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER);

	pa_threaded_mainloop_lock(ctl->p->mainloop);

	err = pulse_check_connection(ctl->p);
	if (err < 0)
		goto finish;

	if (ctl->source) {
		if (offset == 0)
			snd_ctl_elem_id_set_name(id, SOURCE_VOL_NAME);
		else if (offset == 1)
			snd_ctl_elem_id_set_name(id, SOURCE_MUTE_NAME);
	} else
		offset += 2;

	err = 0;

finish:
	pa_threaded_mainloop_unlock(ctl->p->mainloop);

	if (err >= 0) {
		if (offset == 2)
			snd_ctl_elem_id_set_name(id, SINK_VOL_NAME);
		else if (offset == 3)
			snd_ctl_elem_id_set_name(id, SINK_MUTE_NAME);
	}

	return err;
}
Example #6
0
int V4LRadioControl::volume() const
{
    const QString ctlName("Line DAC Playback Volume");
    const QString card("hw:0");

    int volume = 0;
    int err;
    static snd_ctl_t *handle = NULL;
    snd_ctl_elem_info_t *info;
    snd_ctl_elem_id_t *id;
    snd_ctl_elem_value_t *control;

    snd_ctl_elem_info_alloca(&info);
    snd_ctl_elem_id_alloca(&id);
    snd_ctl_elem_value_alloca(&control);
    snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER);	/* MIXER */

    snd_ctl_elem_id_set_name(id, ctlName.toAscii());

    if ((err = snd_ctl_open(&handle, card.toAscii(), 0)) < 0) {
        return 0;
    }

    snd_ctl_elem_info_set_id(info, id);
    if ((err = snd_ctl_elem_info(handle, info)) < 0) {
        snd_ctl_close(handle);
        handle = NULL;
        return 0;
    }

    snd_ctl_elem_info_get_id(info, id);	/* FIXME: Remove it when hctl find works ok !!! */
    snd_ctl_elem_value_set_id(control, id);

    snd_ctl_close(handle);
    handle = NULL;

    snd_hctl_t *hctl;
    snd_hctl_elem_t *elem;
    if ((err = snd_hctl_open(&hctl, card.toAscii(), 0)) < 0) {
        return 0;
    }
    if ((err = snd_hctl_load(hctl)) < 0) {
        return 0;
    }
    elem = snd_hctl_find_elem(hctl, id);
    if (elem)
        volume = vol(elem);

    snd_hctl_close(hctl);

    return (volume/118.0) * 100;
}
Example #7
0
static int sco_ctl_write_integer(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, long *value)
{
	snd_ctl_sco_t *bt_headset = ext->private_data;
	long curvalue;

	sco_ctl_read_integer(ext, key, &curvalue);

	if(*value == curvalue) {
		return 0;
	}
	else {
		ctl_packet_t pkt = {.type = PKT_TYPE_CTL_CMD_SET, .volvalue = (unsigned char)*value};
		if(key == HS_SPEAKER) {
			pkt.voltype = SPEAKER;
		}
		else if(key == HS_MICROPHONE) {
			pkt.voltype = MICROPHONE;
		}
		else {
			return -EINVAL;
		}
		if(send(bt_headset->serverfd, &pkt, sizeof(pkt), MSG_NOSIGNAL) != sizeof(pkt)) {
			SYSERR("Unable to send new volume value to server");			
		}
		return 1;
	}

}

static int sco_ctl_read_event(snd_ctl_ext_t *ext, snd_ctl_elem_id_t *id,
			  unsigned int *event_mask)
{
	snd_ctl_sco_t *bt_headset = ext->private_data;
	ctl_packet_t pkt;

	DBG("");
	if(recv(bt_headset->serverfd, &pkt, sizeof(pkt), MSG_DONTWAIT) == sizeof(pkt)) {
		if(pkt.type == PKT_TYPE_CTL_NTFY) {
			snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER);
			snd_ctl_elem_id_set_name(id, pkt.voltype == SPEAKER ? vol_devices[HS_SPEAKER] : vol_devices[HS_MICROPHONE]);
			*event_mask = SND_CTL_EVENT_MASK_VALUE;
			return 1;
		}
		else {
			SNDERR("Unexpected packet type %d received!", pkt.type);
			return -EAGAIN;
		}
	}
	else {
		return -errno;
	}
}
Example #8
0
bool CAESinkALSA::GetELD(snd_hctl_t *hctl, int device, CAEDeviceInfo& info, bool& badHDMI)
{
  badHDMI = false;

  snd_ctl_elem_id_t    *id;
  snd_ctl_elem_info_t  *einfo;
  snd_ctl_elem_value_t *control;
  snd_hctl_elem_t      *elem;

  snd_ctl_elem_id_alloca(&id);
  memset(id, 0, snd_ctl_elem_id_sizeof());

  snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_PCM);
  snd_ctl_elem_id_set_name     (id, "ELD" );
  snd_ctl_elem_id_set_device   (id, device);
  elem = snd_hctl_find_elem(hctl, id);
  if (!elem)
    return false;

  snd_ctl_elem_info_alloca(&einfo);
  memset(einfo, 0, snd_ctl_elem_info_sizeof());

  if (snd_hctl_elem_info(elem, einfo) < 0)
    return false;

  if (!snd_ctl_elem_info_is_readable(einfo))
    return false;

  if (snd_ctl_elem_info_get_type(einfo) != SND_CTL_ELEM_TYPE_BYTES)
    return false;

  snd_ctl_elem_value_alloca(&control);
  memset(control, 0, snd_ctl_elem_value_sizeof());

  if (snd_hctl_elem_read(elem, control) < 0)
    return false;

  int dataLength = snd_ctl_elem_info_get_count(einfo);
  /* if there is no ELD data, then its a bad HDMI device, either nothing attached OR an invalid nVidia HDMI device
   * OR the driver doesn't properly support ELD (notably ATI/AMD, 2012-05) */
  if (!dataLength)
    badHDMI = true;
  else
    CAEELDParser::Parse(
      (const uint8_t*)snd_ctl_elem_value_get_bytes(control),
      dataLength,
      info
    );

  info.m_deviceType = AE_DEVTYPE_HDMI;
  return true;
}
Example #9
0
static int sco_ctl_elem_list(snd_ctl_ext_t *ext, unsigned int offset, snd_ctl_elem_id_t *id)
{
	DBG("");

	snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER);
	if (offset < 2) {
		snd_ctl_elem_id_set_name(id, vol_devices[offset]);
		return 0;
	}
	else {
		return -EINVAL;
	}
}
Example #10
0
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);
}
Example #11
0
static int setamixer(int devnum,char *param, int v1, int v2)
{
    int	type;
    char	str[100];
    snd_hctl_t *hctl;
    snd_ctl_elem_id_t *id;
    snd_ctl_elem_value_t *control;
    snd_hctl_elem_t *elem;
    snd_ctl_elem_info_t *info;

    sprintf(str,"hw:%d",devnum);
    if (snd_hctl_open(&hctl, str, 0)) return(-1);
    snd_hctl_load(hctl);
    snd_ctl_elem_id_alloca(&id);
    snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER);
    snd_ctl_elem_id_set_name(id, param);
    elem = snd_hctl_find_elem(hctl, id);
    if (!elem)
    {
        snd_hctl_close(hctl);
        return(-1);
    }
    snd_ctl_elem_info_alloca(&info);
    snd_hctl_elem_info(elem,info);
    type = snd_ctl_elem_info_get_type(info);
    snd_ctl_elem_value_alloca(&control);
    snd_ctl_elem_value_set_id(control, id);
    switch(type)
    {
    case SND_CTL_ELEM_TYPE_INTEGER:
        snd_ctl_elem_value_set_integer(control, 0, v1);
        if (v2 > 0) snd_ctl_elem_value_set_integer(control, 1, v2);
        break;
    case SND_CTL_ELEM_TYPE_BOOLEAN:
        snd_ctl_elem_value_set_integer(control, 0, (v1 != 0));
        break;
    }
    if (snd_hctl_elem_write(elem, control))
    {
        snd_hctl_close(hctl);
        return(-1);
    }
    snd_hctl_close(hctl);
    return(0);
}
Example #12
0
int set_gain(int idx, int src, int dst, int val)
{
  int err;


  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[idx], 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);
  snd_ctl_elem_value_set_integer(ctl, 2, val);

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

  val = snd_ctl_elem_value_get_integer(ctl, 2);

  snd_ctl_close(handle);
  return val;
}
status_t ALSAControl::set(const char *name, const char *value)
{
    if (!mHandle) {
        LOGE("Control not initialized");
        return NO_INIT;
    }

    LOGV("%s(%s, %s)", __FUNCTION__, name, value);

    snd_ctl_elem_id_t *id;
    snd_ctl_elem_info_t *info;

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

    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) {
        LOGE("Control '%s' cannot get element info: %d", name, ret);
        return BAD_VALUE;
    }

    int items = snd_ctl_elem_info_get_items(info);
    for (int i = 0; i < items; i++) {
        snd_ctl_elem_info_set_item(info, i);
        ret = snd_ctl_elem_info(mHandle, info);
        if (ret < 0) continue;
        if (strcmp(value, snd_ctl_elem_info_get_item_name(info)) == 0)
            return set(name, i, -1);
    }

    LOGE("Control '%s' has no enumerated value of '%s'", name, value);

    return BAD_VALUE;
}
Example #14
0
/******************************************************************************
 *   setMixerInput
 *****************************************************************************/
static Int setMixerControl (const Char *name, Int value)
{
    Int status;
    snd_hctl_t *hctl;
    snd_ctl_elem_id_t *id;
    snd_hctl_elem_t *elem;
    snd_ctl_elem_value_t *control;

    if ((status = snd_hctl_open(&hctl, AUDIO_MIXER, 0)) < 0) {
        Dmai_err2("setMixerControl %s open error: %s\n", AUDIO_MIXER, snd_strerror(status));
        return Dmai_EFAIL;;
    }

    if ((status = snd_hctl_load(hctl)) < 0) {
        Dmai_err2("setMixerControl %s load error: %s\n", AUDIO_MIXER, snd_strerror(status));
        return Dmai_EFAIL;;
    }

    snd_ctl_elem_id_alloca(&id);
    snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER);
    snd_ctl_elem_id_set_name(id, name);
    elem = snd_hctl_find_elem(hctl, id);
    if (!elem) {
        Dmai_err1("setMixerControl %s find element error\n", 
            AUDIO_MIXER);
        snd_hctl_close(hctl);
        return Dmai_EFAIL;
    }

    snd_ctl_elem_value_alloca(&control);
    snd_ctl_elem_value_set_id(control, id);
    snd_ctl_elem_value_set_integer(control, 0, value);
    snd_hctl_elem_write(elem, control);

    snd_hctl_close(hctl);

    return Dmai_EOK;
}
Example #15
0
static int amixer_max(int devnum,char *param)
{
    int	rv,type;
    char	str[100];
    snd_hctl_t *hctl;
    snd_ctl_elem_id_t *id;
    snd_hctl_elem_t *elem;
    snd_ctl_elem_info_t *info;

    sprintf(str,"hw:%d",devnum);
    if (snd_hctl_open(&hctl, str, 0)) return(-1);
    snd_hctl_load(hctl);
    snd_ctl_elem_id_alloca(&id);
    snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER);
    snd_ctl_elem_id_set_name(id, param);
    elem = snd_hctl_find_elem(hctl, id);
    if (!elem)
    {
        snd_hctl_close(hctl);
        return(-1);
    }
    snd_ctl_elem_info_alloca(&info);
    snd_hctl_elem_info(elem,info);
    type = snd_ctl_elem_info_get_type(info);
    rv = 0;
    switch(type)
    {
    case SND_CTL_ELEM_TYPE_INTEGER:
        rv = snd_ctl_elem_info_get_max(info);
        break;
    case SND_CTL_ELEM_TYPE_BOOLEAN:
        rv = 1;
        break;
    }
    snd_hctl_close(hctl);
    return(rv);
}
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;
}
Example #17
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 #18
0
int hw_audio_set(const char *name, int value)
{
    static snd_ctl_t *handle = NULL;
    int err;

    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);

    if (handle == NULL &&
        (err = snd_ctl_open(&handle, "default", 0)) < 0)
    {
        LOGE("Control default open error: %s\n", snd_strerror(err));
        return 0;
    }

    int ret = snd_ctl_elem_info(handle, info);
    if (ret < 0) 
    {
        LOGE("Cannot find the given element from control default ret=%d %s ", 
                ret, snd_strerror(ret));
        return 0;
    }

    snd_ctl_elem_type_t type = snd_ctl_elem_info_get_type(info);
    snd_ctl_elem_info_get_id(info, id);
    snd_ctl_elem_value_set_id(control, id);

    switch (type) {
        case SND_CTL_ELEM_TYPE_BOOLEAN:
            snd_ctl_elem_value_set_boolean(control, 0, value);
            break;
        case SND_CTL_ELEM_TYPE_INTEGER:
            snd_ctl_elem_value_set_integer(control, 0, value);
            break;
        case SND_CTL_ELEM_TYPE_INTEGER64:
            snd_ctl_elem_value_set_integer64(control, 0, value);
            break;
        case SND_CTL_ELEM_TYPE_ENUMERATED:
            snd_ctl_elem_value_set_enumerated(control, 0, value);
            break;
        case SND_CTL_ELEM_TYPE_BYTES:
            snd_ctl_elem_value_set_byte(control, 0, value);
            break;
        default:
            break;
    }

    ret = snd_ctl_elem_write(handle, control);
    if(ret <0)
    {
        LOGE("Control default load error: %s\n", snd_strerror(ret));
    }

    return 1;
}
Example #19
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 #20
0
static int parse_control_id(const char *str, snd_ctl_elem_id_t *id)
{
  int c, size;
  char *ptr;

  while (*str == ' ' || *str == '\t')
    str++;
  if (!(*str))
    return -EINVAL;
  snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER);	/* default */
  while (*str) {
    if (!strncasecmp(str, "numid=", 6)) {
      str += 6;
      snd_ctl_elem_id_set_numid(id, atoi(str));
      while (isdigit(*str))
        str++;
    } else if (!strncasecmp(str, "iface=", 6)) {
      str += 6;
      if (!strncasecmp(str, "card", 4)) {
        snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_CARD);
        str += 4;
      } else if (!strncasecmp(str, "mixer", 5)) {
        snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER);
        str += 5;
      } else if (!strncasecmp(str, "pcm", 3)) {
        snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_PCM);
        str += 3;
      } else if (!strncasecmp(str, "rawmidi", 7)) {
        snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_RAWMIDI);
        str += 7;
      } else if (!strncasecmp(str, "timer", 5)) {
        snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_TIMER);
        str += 5;
      } else if (!strncasecmp(str, "sequencer", 9)) {
        snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_SEQUENCER);
        str += 9;
      } else {
        return -EINVAL;
      }
    } else if (!strncasecmp(str, "name=", 5)) {
      char buf[64];
      str += 5;
      ptr = buf;
      size = 0;
      if (*str == '\'' || *str == '\"') {
        c = *str++;
        while (*str && *str != c) {
          if (size < (int)sizeof(buf)) {
            *ptr++ = *str;
            size++;
          }
          str++;
        }
        if (*str == c)
          str++;
      } else {
        while (*str && *str != ',') {
          if (size < (int)sizeof(buf)) {
            *ptr++ = *str;
            size++;
          }
          str++;
        }
        *ptr = '\0';
      }
      snd_ctl_elem_id_set_name(id, buf);
    } else if (!strncasecmp(str, "index=", 6)) {
      str += 6;
      snd_ctl_elem_id_set_index(id, atoi(str));
      while (isdigit(*str))
        str++;
    } else if (!strncasecmp(str, "device=", 7)) {
      str += 7;
      snd_ctl_elem_id_set_device(id, atoi(str));
      while (isdigit(*str))
        str++;
    } else if (!strncasecmp(str, "subdevice=", 10)) {
      str += 10;
      snd_ctl_elem_id_set_subdevice(id, atoi(str));
      while (isdigit(*str))
        str++;
    }
    if (*str == ',') {
      str++;
    } else {
      if (*str)
        return -EINVAL;
    }
  }			
  return 0;
}
Example #21
0
/**
* alsa dumy codec controls interface
*/
int dummy_alsa_control_raw(char * id_string , long vol, int rw, long * value){
    int err;
    snd_hctl_t *hctl;
    snd_ctl_elem_id_t *id;
    snd_hctl_elem_t *elem;
    snd_ctl_elem_value_t *control;
    snd_ctl_elem_info_t *info;
    snd_ctl_elem_type_t type;
    unsigned int idx = 0, count;
    long tmp, min, max;
    char dev[10] = {0};
    int card = alsa_get_aml_card();
    int port = alsa_get_spdif_port();

    adec_print("card = %d, port = %d\n", card, port);
    sprintf(dev, "hw:%d,%d", (card >= 0) ? card : 0, (port >= 0) ? port : 0);

    if ((err = snd_hctl_open(&hctl, dev, 0)) < 0) {
        printf("Control %s open error: %s\n", dev, snd_strerror(err));
        return err;
    }
    if (err = snd_hctl_load(hctl)< 0) {
        printf("Control %s open error: %s\n", dev, snd_strerror(err));
        return err;
    }
    snd_ctl_elem_id_alloca(&id);
    snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER);
    snd_ctl_elem_id_set_name(id, id_string);
    elem = snd_hctl_find_elem(hctl, id);
    snd_ctl_elem_value_alloca(&control);
    snd_ctl_elem_value_set_id(control, id);
    snd_ctl_elem_info_alloca(&info);
    if ((err = snd_hctl_elem_info(elem, info)) < 0) {
        printf("Control %s snd_hctl_elem_info error: %s\n", dev, snd_strerror(err));
        return err;
    }
    count = snd_ctl_elem_info_get_count(info);
    type = snd_ctl_elem_info_get_type(info);

    for (idx = 0; idx < count; idx++) {
        switch (type) {
            case SND_CTL_ELEM_TYPE_BOOLEAN:
                if(rw){
                    tmp = 0;
                    if (vol >= 1) {
                        tmp = 1;
                    }
                    snd_ctl_elem_value_set_boolean(control, idx, tmp);
                    err = snd_hctl_elem_write(elem, control);
                }else
            *value = snd_ctl_elem_value_get_boolean(control, idx);
            break;
            case SND_CTL_ELEM_TYPE_INTEGER:
                if(rw){
            min = snd_ctl_elem_info_get_min(info);
            max = snd_ctl_elem_info_get_max(info);
                    if ((vol >= min) && (vol <= max))
                        tmp = vol;
            else if (vol < min)
                        tmp = min;
                    else if (vol > max)
                        tmp = max;
                    snd_ctl_elem_value_set_integer(control, idx, tmp);
                    err = snd_hctl_elem_write(elem, control);
                }else
                *value = snd_ctl_elem_value_get_integer(control, idx);
            break;
            default:
                printf("?");
            break;
        }
        if (err < 0){
            printf ("control%s access error=%s,close control device\n", dev, snd_strerror(err));
            snd_hctl_close(hctl);
            return err;
        }
    }

    return 0;
}
status_t ALSAControl::set(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_id_alloca(&id);
    snd_ctl_elem_info_alloca(&info);

    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;
    }

    if (index == -1)
        index = 0; // Range over all of them
    else
        count = index + 1; // Just do the one specified

    snd_ctl_elem_type_t type = snd_ctl_elem_info_get_type(info);

    snd_ctl_elem_value_t *control;
    snd_ctl_elem_value_alloca(&control);

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

    for (int i = index; i < count; i++)
        switch (type) {
            case SND_CTL_ELEM_TYPE_BOOLEAN:
                snd_ctl_elem_value_set_boolean(control, i, value);
                break;
            case SND_CTL_ELEM_TYPE_INTEGER:
                snd_ctl_elem_value_set_integer(control, i, value);
                break;
            case SND_CTL_ELEM_TYPE_INTEGER64:
                snd_ctl_elem_value_set_integer64(control, i, value);
                break;
            case SND_CTL_ELEM_TYPE_ENUMERATED:
                snd_ctl_elem_value_set_enumerated(control, i, value);
                break;
            case SND_CTL_ELEM_TYPE_BYTES:
                snd_ctl_elem_value_set_byte(control, i, value);
                break;
            default:
                break;
        }

    ret = snd_ctl_elem_write(mHandle, control);
    return (ret < 0) ? BAD_VALUE : NO_ERROR;
}
Example #23
0
void V4LRadioControl::callAmixer(const QString& target, const QString& value)
{
    int err;
    long tmp;
    unsigned int count;
    static snd_ctl_t *handle = NULL;
    QString card("hw:0");
    snd_ctl_elem_info_t *info;
    snd_ctl_elem_id_t *id;
    snd_ctl_elem_value_t *control;
    snd_ctl_elem_type_t type;

    snd_ctl_elem_info_alloca(&info);
    snd_ctl_elem_id_alloca(&id);
    snd_ctl_elem_value_alloca(&control);
    snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER);	/* MIXER */

    // in amixer parse func
    // char target[64];
    // e.g. PGA CAPTure Switch
    snd_ctl_elem_id_set_name(id, target.toAscii());

    if (handle == NULL && (err = snd_ctl_open(&handle, card.toAscii(), 0)) < 0)
    {
        return;
    }

    snd_ctl_elem_info_set_id(info, id);
    if ((err = snd_ctl_elem_info(handle, info)) < 0)
    {
        snd_ctl_close(handle);
        handle = NULL;
        return;
    }

    snd_ctl_elem_info_get_id(info, id);	/* FIXME: Remove it when hctl find works ok !!! */
    type = snd_ctl_elem_info_get_type(info);
    count = snd_ctl_elem_info_get_count(info);

    snd_ctl_elem_value_set_id(control, id);

    tmp = 0;
    for (uint idx = 0; idx < count && idx < 128; idx++)
    {
        switch (type)
        {
            case SND_CTL_ELEM_TYPE_BOOLEAN:
#ifdef MULTIMEDIA_MAEMO_DEBUG
                qDebug() << "SND_CTL_ELEM_TYPE_BOOLEAN" << SND_CTL_ELEM_TYPE_BOOLEAN;
#endif
                if ((value == "on") ||(value == "1"))
                {
                    tmp = 1;
                }
                snd_ctl_elem_value_set_boolean(control, idx, tmp);
                break;
            case SND_CTL_ELEM_TYPE_ENUMERATED:
                tmp = getEnumItemIndex(handle, info, value);
                snd_ctl_elem_value_set_enumerated(control, idx, tmp);
                break;
            case SND_CTL_ELEM_TYPE_INTEGER:
#ifdef MULTIMEDIA_MAEMO_DEBUG
                qDebug() << "SND_CTL_ELEM_TYPE_INTEGER" << SND_CTL_ELEM_TYPE_INTEGER;
#endif
                tmp = atoi(value.toAscii());
                if (tmp <  snd_ctl_elem_info_get_min(info))
                    tmp = snd_ctl_elem_info_get_min(info);
                else if (tmp > snd_ctl_elem_info_get_max(info))
                    tmp = snd_ctl_elem_info_get_max(info);
                snd_ctl_elem_value_set_integer(control, idx, tmp);
                break;
            default:
                break;

        }
    }

    if ((err = snd_ctl_elem_write(handle, control)) < 0) {
        snd_ctl_close(handle);
        handle = NULL;
        return;
    }

    snd_ctl_close(handle);
    handle = NULL;
}
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;
}
Example #25
0
/* used by UCM parser, too */
int __snd_ctl_ascii_elem_id_parse(snd_ctl_elem_id_t *dst, const char *str,
				  const char **ret_ptr)
{
	int c, size, numid;
	int err = -EINVAL;
	char *ptr;

	while (isspace(*str))
		str++;
	if (!(*str))
		goto out;
	snd_ctl_elem_id_set_interface(dst, SND_CTL_ELEM_IFACE_MIXER);	/* default */
	while (*str) {
		if (!strncasecmp(str, "numid=", 6)) {
			str += 6;
			numid = atoi(str);
			if (numid <= 0) {
				fprintf(stderr, "amixer: Invalid numid %d\n", numid);
				goto out;
			}
			snd_ctl_elem_id_set_numid(dst, atoi(str));
			while (isdigit(*str))
				str++;
		} else if (!strncasecmp(str, "iface=", 6)) {
			str += 6;
			if (!strncasecmp(str, "card", 4)) {
				snd_ctl_elem_id_set_interface(dst, SND_CTL_ELEM_IFACE_CARD);
				str += 4;
			} else if (!strncasecmp(str, "mixer", 5)) {
				snd_ctl_elem_id_set_interface(dst, SND_CTL_ELEM_IFACE_MIXER);
				str += 5;
			} else if (!strncasecmp(str, "pcm", 3)) {
				snd_ctl_elem_id_set_interface(dst, SND_CTL_ELEM_IFACE_PCM);
				str += 3;
			} else if (!strncasecmp(str, "rawmidi", 7)) {
				snd_ctl_elem_id_set_interface(dst, SND_CTL_ELEM_IFACE_RAWMIDI);
				str += 7;
			} else if (!strncasecmp(str, "timer", 5)) {
				snd_ctl_elem_id_set_interface(dst, SND_CTL_ELEM_IFACE_TIMER);
				str += 5;
			} else if (!strncasecmp(str, "sequencer", 9)) {
				snd_ctl_elem_id_set_interface(dst, SND_CTL_ELEM_IFACE_SEQUENCER);
				str += 9;
			} else {
				goto out;
			}
		} else if (!strncasecmp(str, "name=", 5)) {
			char buf[64];
			str += 5;
			ptr = buf;
			size = 0;
			if (*str == '\'' || *str == '\"') {
				c = *str++;
				while (*str && *str != c) {
					if (size < (int)sizeof(buf)) {
						*ptr++ = *str;
						size++;
					}
					str++;
				}
				if (*str == c)
					str++;
			} else {
				while (*str && *str != ',') {
					if (size < (int)sizeof(buf)) {
						*ptr++ = *str;
						size++;
					}
					str++;
				}
			}
			*ptr = '\0';
			snd_ctl_elem_id_set_name(dst, buf);
		} else if (!strncasecmp(str, "index=", 6)) {
			str += 6;
			snd_ctl_elem_id_set_index(dst, atoi(str));
			while (isdigit(*str))
				str++;
		} else if (!strncasecmp(str, "device=", 7)) {
			str += 7;
			snd_ctl_elem_id_set_device(dst, atoi(str));
			while (isdigit(*str))
				str++;
		} else if (!strncasecmp(str, "subdevice=", 10)) {
			str += 10;
			snd_ctl_elem_id_set_subdevice(dst, atoi(str));
			while (isdigit(*str))
				str++;
		}
		if (*str == ',') {
			str++;
		} else {
			/* when ret_ptr is given, allow to terminate gracefully
			 * at the next space letter
			 */
			if (ret_ptr && isspace(*str))
				break;
			if (*str)
				goto out;
		}
	}			
	err = 0;

 out:
	if (ret_ptr)
		*ret_ptr = str;
	return err;
}