Ejemplo n.º 1
0
static int enum_item_name_ops(snd_mixer_elem_t *elem,
			      unsigned int item,
			      size_t maxlen, char *buf)
{
	selem_none_t *s = snd_mixer_elem_get_private(elem);
	snd_ctl_elem_info_t *info;
	snd_hctl_elem_t *helem;
	int type;

	type = CTL_GLOBAL_ENUM;
	helem = s->ctls[type].elem;
	if (!helem) {
		type = CTL_PLAYBACK_ENUM;
		helem = s->ctls[type].elem;
	}
	if (!helem) {
		type = CTL_CAPTURE_ENUM;
		helem = s->ctls[type].elem;
	}
	assert(helem);
	if (item >= (unsigned int)s->ctls[type].max)
		return -EINVAL;
	snd_ctl_elem_info_alloca(&info);
	snd_hctl_elem_info(helem, info);
	snd_ctl_elem_info_set_item(info, item);
	snd_hctl_elem_info(helem, info);
	strncpy(buf, snd_ctl_elem_info_get_item_name(info), maxlen);
	return 0;
}
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;
}
Ejemplo n.º 3
0
static int
_phoneui_utils_sound_volume_load_stats(struct SoundControl *control)
{
	int err;

	if (!control->element)
		return -1;

	//snd_ctl_elem_type_t element_type;
	snd_ctl_elem_info_t *info;
	snd_hctl_elem_t *elem;

	elem = control->element;
	snd_ctl_elem_info_alloca(&info);

	err = snd_hctl_elem_info(elem, info);
	if (err < 0) {
		g_warning("%s", snd_strerror(err));
		return -1;
	}

	/* verify type == integer */
	//element_type = snd_ctl_elem_info_get_type(info);

	control->min = snd_ctl_elem_info_get_min(info);
	control->max = snd_ctl_elem_info_get_max(info);
	control->count = snd_ctl_elem_info_get_count(info);
	return 0;
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
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;
}
Ejemplo n.º 6
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);
}
Ejemplo n.º 7
0
int  V4LRadioControl::vol(snd_hctl_elem_t *elem) const
{
    const QString card("hw:0");
    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);
    if ((err = snd_hctl_elem_info(elem, info)) < 0) {
        return 0;
    }

    snd_hctl_elem_get_id(elem, id);
    snd_hctl_elem_read(elem, control);

    return snd_ctl_elem_value_get_integer(control, 0);
}
/* Common operations. */
static int add_elem_set(struct elem_set_trial *trial)
{
	snd_ctl_elem_info_t *info;
	char name[64] = {0};
	int err;

	snprintf(name, 64, "userspace-control-element-%s",
		 snd_ctl_elem_type_name(trial->type));

	snd_ctl_elem_info_alloca(&info);
	snd_ctl_elem_info_set_interface(info, SND_CTL_ELEM_IFACE_MIXER);
	snd_ctl_elem_info_set_name(info, name);
	snd_ctl_elem_info_set_dimension(info, trial->dimension);

	err = trial->add_elem_set(trial, info);
	if (err >= 0)
		snd_ctl_elem_info_get_id(info, trial->id);

	return err;
}
Ejemplo n.º 9
0
/* initialize dB range information, reading TLV via hcontrol
 */
static int init_db_range(snd_hctl_elem_t *ctl, struct selem_str *rec)
{
	snd_ctl_elem_info_t *info;
	unsigned int *tlv = NULL;
	const unsigned int tlv_size = 4096;
	unsigned int *dbrec;
	int db_size;

	if (rec->db_init_error)
		return -EINVAL;
	if (rec->db_initialized)
		return 0;

	snd_ctl_elem_info_alloca(&info);
	if (snd_hctl_elem_info(ctl, info) < 0)
		goto error;
	if (! snd_ctl_elem_info_is_tlv_readable(info))
		goto error;
	tlv = malloc(tlv_size);
	if (! tlv)
		return -ENOMEM;
	if (snd_hctl_elem_tlv_read(ctl, tlv, tlv_size) < 0)
		goto error;
	db_size = snd_tlv_parse_dB_info(tlv, tlv_size, &dbrec);
	if (db_size < 0)
		goto error;
	rec->db_info = malloc(db_size);
	if (!rec->db_info)
		goto error;
	memcpy(rec->db_info, dbrec, db_size);
	free(tlv);
	rec->db_initialized = 1;
	return 0;

 error:
	free(tlv);
	rec->db_init_error = 1;
	return -EINVAL;
}
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;
}
Ejemplo n.º 11
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);
}
Ejemplo n.º 12
0
static int findSoundCards(char **cardname)
{
	int idx, dev, err;
	snd_ctl_t *handle;
	snd_hctl_t *hctlhandle;
	snd_ctl_card_info_t *cardinfo;
	snd_pcm_info_t *pcminfo;
	char str[32];

	snd_ctl_card_info_alloca(&cardinfo);
	snd_pcm_info_alloca(&pcminfo);

	snd_hctl_elem_t *elem;
	snd_ctl_elem_id_t *id;
	snd_ctl_elem_info_t *info;
	snd_ctl_elem_id_alloca(&id);
	snd_ctl_elem_info_alloca(&info);

	idx = -1;
	while (1) {
		if ((err = snd_card_next(&idx)) < 0) {
			LOGE("Card next error: %s\n", snd_strerror(err));
			break;
		}
		if (idx < 0)
			break;
		sprintf(str, "hw:CARD=%i", idx);
		if ((err = snd_ctl_open(&handle, str, 0)) < 0) {
			LOGE("Open error: %s\n", snd_strerror(err));
			continue;
		}
		if ((err = snd_ctl_card_info(handle, cardinfo)) < 0) {
			LOGE("HW info error: %s\n", snd_strerror(err));
			continue;
		}
		LOGD("Soundcard #%i:\n", idx + 1);
		LOGD("  card - %i\n", snd_ctl_card_info_get_card(cardinfo));
		LOGD("  id - '%s'\n", snd_ctl_card_info_get_id(cardinfo));
		LOGD("  driver - '%s'\n", snd_ctl_card_info_get_driver(cardinfo));
		LOGD("  name - '%s'\n", snd_ctl_card_info_get_name(cardinfo));
		LOGD("  longname - '%s'\n", snd_ctl_card_info_get_longname(cardinfo));
		LOGD("  mixername - '%s'\n", snd_ctl_card_info_get_mixername(cardinfo));
		LOGD("  components - '%s'\n", snd_ctl_card_info_get_components(cardinfo));

		strcpy(cardname[idx], snd_ctl_card_info_get_name(cardinfo));
		LOGD("\n\n-----get cart name and id: %s : %d",cardname[idx],idx);
		snd_ctl_close(handle);

		if ((err = snd_hctl_open(&hctlhandle, str, 0)) < 0) {
			LOGE("Control %s open error: %s", str, snd_strerror(err));
			return err;
		}
		if ((err = snd_hctl_load(hctlhandle)) < 0) {
			LOGE("Control %s local error: %s\n", str, snd_strerror(err));
			return err;
		}

		for (elem = snd_hctl_first_elem(hctlhandle); elem; elem = snd_hctl_elem_next(elem)) {
			if ((err = snd_hctl_elem_info(elem, info)) < 0) {
				LOGE("Control %s snd_hctl_elem_info error: %s\n", str, snd_strerror(err));
				return err;
			}
			snd_hctl_elem_get_id(elem, id);
			show_control_id(id);
		}
		snd_hctl_close(hctlhandle);
	}
	snd_config_update_free_global();
	return 0;
}
Ejemplo n.º 13
0
static int amixer_control(t_amixer *x, int argc, t_atom *argv, int roflag)
{
  int err;
  snd_ctl_t *handle;
  snd_ctl_elem_info_t *info;
  snd_ctl_elem_id_t *id;
  snd_ctl_elem_value_t *control;
  char *ptr;
  unsigned int idx, count;
  long tmp;
  snd_ctl_elem_type_t type;
  snd_ctl_elem_info_alloca(&info);
  snd_ctl_elem_id_alloca(&id);
  snd_ctl_elem_value_alloca(&control);

  if (argc < 1) {
    error("Specify a full control identifier: [[iface=<iface>,][name='name',][index=<index>,][device=<device>,][subdevice=<subdevice>]]|[numid=<numid>]\n");
    return -EINVAL;
  }
  if(A_FLOAT==argv->a_type){
    snd_ctl_elem_id_set_numid(id, atom_getint(argv));
    if(0)
      {
        error("Wrong control identifier: %d\n", atom_getint(argv));
        return -EINVAL;
      }
  } else {
    if (parse_control_id(atom_getsymbol(argv)->s_name, id)) {
      error("Wrong control identifier: %s\n", atom_getsymbol(argv)->s_name);
      return -EINVAL;
    }
  }
  if ((err = snd_ctl_open(&handle, x->card, 0)) < 0) {
    error("Control %s open error: %s\n", x->card, snd_strerror(err));
    return err;
  }
  snd_ctl_elem_info_set_id(info, id);
  if ((err = snd_ctl_elem_info(handle, info)) < 0) {
    error("Control %s cinfo error: %s\n", x->card, snd_strerror(err));
    return err;
  }

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

  if (!roflag) {
    t_float atom_float = atom_getfloat(argv+1);
    int atom_isfloat = (A_FLOAT==(argv+1)->a_type);
    post("now setting");
    ptr = atom_getsymbol(argv+1)->s_name;
    for (idx = 0; idx < count && idx < 128 && ptr && *ptr; idx++) {
      switch (type) {
      case SND_CTL_ELEM_TYPE_BOOLEAN:
        tmp = 0;
        if(atom_isfloat){
          tmp=(atom_float>0)?1:0;
        } else if (!strncasecmp(ptr, "on", 2) || !strncasecmp(ptr, "up", 2)) {
          tmp = 1;
          ptr += 2;
        } else if (!strncasecmp(ptr, "yes", 3)) {
          tmp = 1;
          ptr += 3;
        } else if (!strncasecmp(ptr, "toggle", 6)) {
          tmp = snd_ctl_elem_value_get_boolean(control, idx);
          tmp = tmp > 0 ? 0 : 1;
          ptr += 6;
        } else if (isdigit(*ptr)) {
          tmp = atoi(ptr) > 0 ? 1 : 0;
          while (isdigit(*ptr))
            ptr++;
        } else {
          while (*ptr && *ptr != ',')
            ptr++;
        }
        snd_ctl_elem_value_set_boolean(control, idx, tmp);
        break;
      case SND_CTL_ELEM_TYPE_INTEGER:
        tmp = atom_isfloat?((int)atom_float):get_integer(&ptr,
                                                  snd_ctl_elem_info_get_min(info),
                                                  snd_ctl_elem_info_get_max(info));
        snd_ctl_elem_value_set_integer(control, idx, tmp);
        break;
      case SND_CTL_ELEM_TYPE_INTEGER64:
        tmp = atom_isfloat?((int)atom_float):get_integer64(&ptr,
                                                    snd_ctl_elem_info_get_min64(info),
                                                    snd_ctl_elem_info_get_max64(info));
        snd_ctl_elem_value_set_integer64(control, idx, tmp);
        break;
      case SND_CTL_ELEM_TYPE_ENUMERATED:
        tmp =  atom_isfloat?((int)atom_float):get_integer(&ptr, 0, snd_ctl_elem_info_get_items(info) - 1);
        snd_ctl_elem_value_set_enumerated(control, idx, tmp);
        break;
      case SND_CTL_ELEM_TYPE_BYTES:
        tmp =  atom_isfloat?((int)atom_float):get_integer(&ptr, 0, 255);
        snd_ctl_elem_value_set_byte(control, idx, tmp);
        break;
      default:
        break;
      }
      if (!strchr(atom_getsymbol(argv+1)->s_name, ','))
        ptr = atom_getsymbol(argv+1)->s_name;
      else if (*ptr == ',')
        ptr++;
    }
    if ((err = snd_ctl_elem_write(handle, control)) < 0) {
      error("Control %s element write error: %s\n", x->card, snd_strerror(err));
      return err;
    }
  }
  snd_ctl_close(handle);


  if (1) {
    snd_hctl_t *hctl;
    snd_hctl_elem_t *elem;
    if ((err = snd_hctl_open(&hctl, x->card, 0)) < 0) {
      error("Control %s open error: %s\n", x->card, snd_strerror(err));
      return err;
    }
    if ((err = snd_hctl_load(hctl)) < 0) {
      error("Control %s load error: %s\n", x->card, snd_strerror(err));
      return err;
    }
    elem = snd_hctl_find_elem(hctl, id);
    if (elem)
      show_control(x->card, "  ", elem, LEVEL_BASIC | LEVEL_ID);
    else
      printf("Could not find the specified element\n");
    snd_hctl_close(hctl);
  }
}
Ejemplo n.º 14
0
static int show_control(const char* card, const char *space, snd_hctl_elem_t *elem,
			int level)
{
  int err;
  unsigned int item, idx;
  unsigned int count;
  snd_ctl_elem_type_t type;
  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);
  if ((err = snd_hctl_elem_info(elem, info)) < 0) {
    error("Control %s snd_hctl_elem_info error: %s\n", card, snd_strerror(err));
    return err;
  }
  if (level & LEVEL_ID) {
    snd_hctl_elem_get_id(elem, id);
    show_control_id(id);
    printf("\n");
  }
  count = snd_ctl_elem_info_get_count(info);
  type = snd_ctl_elem_info_get_type(info);
  printf("%s; type=%s,access=%s,values=%i", space, control_type(info), control_access(info), count);
  switch (type) {
  case SND_CTL_ELEM_TYPE_INTEGER:
    printf(",min=%li,max=%li,step=%li\n", 
           snd_ctl_elem_info_get_min(info),
           snd_ctl_elem_info_get_max(info),
           snd_ctl_elem_info_get_step(info));
    break;
  case SND_CTL_ELEM_TYPE_INTEGER64:
    printf(",min=%Li,max=%Li,step=%Li\n", 
           snd_ctl_elem_info_get_min64(info),
           snd_ctl_elem_info_get_max64(info),
           snd_ctl_elem_info_get_step64(info));
    break;
  case SND_CTL_ELEM_TYPE_ENUMERATED:
    {
      unsigned int items = snd_ctl_elem_info_get_items(info);
      printf(",items=%u\n", items);
      for (item = 0; item < items; item++) {
        snd_ctl_elem_info_set_item(info, item);
        if ((err = snd_hctl_elem_info(elem, info)) < 0) {
          error("Control %s element info error: %s\n", card, snd_strerror(err));
          return err;
        }
        printf("%s; Item #%u '%s'\n", space, item, snd_ctl_elem_info_get_item_name(info));
      }
      break;
    }
  default:
    printf("\n");
    break;
  }
  if (level & LEVEL_BASIC) {
    if ((err = snd_hctl_elem_read(elem, control)) < 0) {
      error("Control %s element read error: %s\n", card, snd_strerror(err));
      return err;
    }
    printf("%s: values=", space);
    for (idx = 0; idx < count; idx++) {
      if (idx > 0)
        printf(",");
      switch (type) {
      case SND_CTL_ELEM_TYPE_BOOLEAN:
        printf("%s", snd_ctl_elem_value_get_boolean(control, idx) ? "on" : "off");
        break;
      case SND_CTL_ELEM_TYPE_INTEGER:
        printf("%li", snd_ctl_elem_value_get_integer(control, idx));
        break;
      case SND_CTL_ELEM_TYPE_INTEGER64:
        printf("%Li", snd_ctl_elem_value_get_integer64(control, idx));
        break;
      case SND_CTL_ELEM_TYPE_ENUMERATED:
        printf("%u", snd_ctl_elem_value_get_enumerated(control, idx));
        break;
      case SND_CTL_ELEM_TYPE_BYTES:
        printf("0x%02x", snd_ctl_elem_value_get_byte(control, idx));
        break;
      default:
        printf("?");
        break;
      }
    }
    printf("\n");
  }
  return 0;
}
Ejemplo n.º 15
0
void main( int argc, char *argv[] )
{

    struct structArgs cmdArgs;
    int errNum;


    // ************************************************************************
    //  ALSA control elements.
    // ************************************************************************
    snd_ctl_t *ctl;                 // Simple control handle.
    snd_ctl_elem_id_t *id;          // Simple control element id.
    snd_ctl_elem_value_t *control;  // Simple control element value.
    snd_ctl_elem_type_t type;       // Simple control element type.
    snd_ctl_elem_info_t *info;      // Simple control info container.


    // ************************************************************************
    //  Get command line parameters.
    // ************************************************************************
    argp_parse( &argp, argc, argv, 0, 0, &cmdArgs );

    printf( "Card = %i\n", cmdArgs.card );
    printf( "Control = %i\n", cmdArgs.control );
    printf( "Value 1 = %i\n", cmdArgs.value1 );
    printf( "Value 2 = %i\n", cmdArgs.value2 );


    // ************************************************************************
    //  Set up ALSA control.
    // ************************************************************************
    sprintf( cmdArgs.deviceID, "hw:%i", cmdArgs.card );
    printf( "Device ID = %s.\n", cmdArgs.deviceID );

    if ( snd_ctl_open( &ctl, cmdArgs.deviceID, 1 ) < 0 )
    {
        printf( "Error opening control.\n" );
        return;
    }
    // Initialise a simple control element id structure.
    snd_ctl_elem_id_alloca( &id );
    snd_ctl_elem_id_set_numid( id, cmdArgs.control );

    // Initialise info element.
    snd_ctl_elem_info_alloca( &info );
    snd_ctl_elem_info_set_numid( info, cmdArgs.control );

    // Is the control valid?
    if ( snd_ctl_elem_info( ctl, info ) < 0 )
    {
        printf( "Error getting control element info.\n" );
        return;
    }

    // Find type of control.
    // either:
    // SND_CTL_ELEM_TYPE_INTEGER,
    // SND_CTL_ELEM_TYPE_INTEGER64,
    // SND_CTL_ELEM_TYPE_ENUMERATED, etc.
    // Only interested in INTEGER.
    type = snd_ctl_elem_info_get_type( info );
    if ( type != SND_CTL_ELEM_TYPE_INTEGER )
    {
        printf( "Control type is not integer.\n" );
        printf( "Type = %s\n", type );
        return;
    }


    // ************************************************************************
    //  Get some information for selected control.
    // ************************************************************************
    printf( "Min value for control = %d\n", snd_ctl_elem_info_get_min( info ));
    printf( "Max value for control = %d\n", snd_ctl_elem_info_get_max( info ));
    printf( "Step value for control = %d\n", snd_ctl_elem_info_get_step( info ));

    // Initialise the control element value container.
    snd_ctl_elem_value_alloca( &control );
    snd_ctl_elem_value_set_id( control, id );


    // ************************************************************************
    //  Set values for selected control.
    // ************************************************************************
    snd_ctl_elem_value_set_integer( control, 0, cmdArgs.value1 );
    if ( snd_ctl_elem_write( ctl, control ) < 0 )
        printf( "Error setting L volume" );
    else
        printf( "Set L volume to %d.\n", cmdArgs.value1 );
    snd_ctl_elem_value_set_integer( control, 1, cmdArgs.value2 );
    if ( snd_ctl_elem_write( ctl, control ) < 0 )
        printf( "Error setting R volume" );
    else
        printf( "Set R volume to %d.\n", cmdArgs.value2 );


    // ************************************************************************
    //  Clean up.
    // ************************************************************************
    snd_ctl_close( ctl );

    return;
}
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;
}
Ejemplo n.º 17
0
/*
 Init the ALSA library:
 - Open the configured device, if none, use default device.
 - Search for the routing control
 - Search for the ringing and incall routes values
 */
static int utils_alsa_init()
{
	if(utils_alsa_hctl)
		return 0;
	debug("utils_alsa_init: start\n");

	int i;

	for(i=0;i<UTILS_AUDIO_ROUTE_COUNT;i++)utils_alsa_routes[i]=-1;
	
	char *alsa_control=utils_conf_get_string(UTILS_CONF_GROUP_ACTION_AUDIO,UTILS_CONF_ATTR_ACTION_AUDIO_ALSA_ROUTE_CONTROL_NAME);
	char *alsa_route_play=utils_conf_get_string(UTILS_CONF_GROUP_ACTION_AUDIO,UTILS_CONF_ATTR_ACTION_AUDIO_ALSA_ROUTE_CONTROL_RINGING);
	char *alsa_route_incall=utils_conf_get_string(UTILS_CONF_GROUP_ACTION_AUDIO,UTILS_CONF_ATTR_ACTION_AUDIO_ALSA_ROUTE_CONTROL_INCALL);
	char *alsa_route_speaker=utils_conf_get_string(UTILS_CONF_GROUP_ACTION_AUDIO,UTILS_CONF_ATTR_ACTION_AUDIO_ALSA_ROUTE_CONTROL_SPEAKER);
	char *alsa_route_handset=utils_conf_get_string(UTILS_CONF_GROUP_ACTION_AUDIO,UTILS_CONF_ATTR_ACTION_AUDIO_ALSA_ROUTE_CONTROL_HANDSET);
	if(!alsa_control)
		return 0;

	char *alsa_device=utils_conf_get_string(UTILS_CONF_GROUP_ACTION_AUDIO,UTILS_CONF_ATTR_ACTION_AUDIO_ALSA_ROUTE_DEVICE);
	int ret=0;

	if(alsa_device)
		ret = snd_hctl_open(&utils_alsa_hctl, alsa_device, 0);
	else
		ret = snd_hctl_open(&utils_alsa_hctl, "default", 0);
	if(ret){
		error("utils_alsa_init: Alsa control device open failed: %s\n", snd_strerror(ret));
		goto done;
	}
	
	ret = snd_hctl_load(utils_alsa_hctl);
	if(ret){
		error("utils_alsa_init: Alsa control device load failed\n");
		goto done;
	}

	snd_hctl_elem_t *elem=snd_hctl_first_elem(utils_alsa_hctl);
	snd_ctl_elem_info_t *info;
	snd_ctl_elem_info_alloca(&info);
	while(elem){
		const char *name=snd_hctl_elem_get_name(elem);
		ret=snd_hctl_elem_info(elem, info);
		if(ret){
			error("utils_alsa_init: snd_hctl_elem_info for ctrl %s error %s\n", name, snd_strerror(ret));
			continue;
		}
		
		if(!strcmp(name, alsa_control)){
			debug("utils_alsa_init: Found element %s\n", name);

			// Find the values
			for(i=0; i<snd_ctl_elem_info_get_items(info); i++){
				snd_ctl_elem_info_set_item(info, i);
				snd_hctl_elem_info(elem, info);
				const char *s=snd_ctl_elem_info_get_item_name(info);
				debug("utils_alsa_init: check control value %s:%s\n", name, s);

				if(alsa_route_play && !strcmp(alsa_route_play, s)){
					debug("utils_alsa_init: utils_alsa_route_play=%ud\n", i);
					utils_alsa_route_play=i;
				}
				if(alsa_route_incall && !strcmp(alsa_route_incall, s)){
					debug("utils_alsa_init: utils_alsa_route_incall=%ud\n", i);
					utils_alsa_route_incall=i;
				}
				if(alsa_route_speaker && !strcmp(alsa_route_speaker, s)){
					debug("utils_alsa_init: alsa_route_speaker=%ud\n", i);
					utils_alsa_routes[UTILS_AUDIO_ROUTE_SPEAKER]=i;
				}
				if(alsa_route_handset && !strcmp(alsa_route_handset, s)){
					debug("utils_alsa_init: alsa_route_handset=%ud\n", i);
					utils_alsa_routes[UTILS_AUDIO_ROUTE_HANDSET]=i;
				}
			}

			snd_ctl_elem_id_malloc(&utils_alsa_route_elem_id);
			snd_ctl_elem_info_get_id(info, utils_alsa_route_elem_id);
			utils_alsa_route_elem=elem;
		}
		elem=snd_hctl_elem_next(elem);
	}

	if(utils_alsa_route_play==-1)
		utils_alsa_route_play=utils_alsa_routes[UTILS_AUDIO_ROUTE_SPEAKER];
	if(utils_alsa_route_incall==-1)
		utils_alsa_route_incall=utils_alsa_routes[UTILS_AUDIO_ROUTE_HANDSET];
	
	debug("utils_alsa_init: ok\n");
done:
	g_free(alsa_device);
	return ret;
}
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;
}
Ejemplo n.º 19
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;
}
Ejemplo n.º 20
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;
}
Ejemplo n.º 21
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;
}
Ejemplo n.º 22
0
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;
}
Ejemplo n.º 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;
}
Ejemplo n.º 24
0
int main()
{
    int cardNumber = -1;
    int errNum;
    char *controlType;
    char deviceID[16];

    // ------------------------------------------------------------------------
    //  ALSA control elements.
    // ------------------------------------------------------------------------
    snd_ctl_t *ctl;                 // Simple control handle.
    snd_ctl_elem_id_t *id;          // Simple control element id.
    snd_ctl_elem_value_t *control;  // Simple control element value.
    snd_ctl_elem_type_t type;       // Simple control element type.
    snd_ctl_elem_info_t *info;      // Simple control element info container.
    snd_ctl_card_info_t *card;      // Simple control card info container.

    snd_hctl_t *hctl;               // High level control handle;
    snd_hctl_elem_t *elem;          // High level control element handle.

    // ------------------------------------------------------------------------
    //  Initialise ALSA card and device types.
    // ------------------------------------------------------------------------
    snd_ctl_card_info_alloca( &card );
    snd_ctl_elem_value_alloca( &control );
    snd_ctl_elem_id_alloca( &id );
    snd_ctl_elem_info_alloca( &info );

    // ------------------------------------------------------------------------
    //  Start card section.
    // ------------------------------------------------------------------------
    // For each card.
    while (1)
    {
        // Find next card number. If < 0 then returns 1st card.
        errNum = snd_card_next( &cardNumber );
        if (( errNum < 0 ) || ( cardNumber < 0 )) break;

        // Concatenate strings to get card's control interface.
        sprintf( deviceID, "hw:%i", cardNumber );

        //  Try to open card.
        if ( snd_ctl_open( &ctl, deviceID, 0 ) < 0 )
        {
            printf( "Error opening card.\n" );
            continue;
        }

        // Fill control card info element.
        if ( snd_ctl_card_info( ctl, card ) < 0 )
        {
            printf( "Error getting card info.\n" );
            continue;
        }

        // --------------------------------------------------------------------
        //  Print header block.
        // --------------------------------------------------------------------
        printf( "\t+-----------------------------" );
        printf( "-----------------------------+\n" );
        printf( "\t| Card: %d - %-46s |",
                        cardNumber,
                        snd_ctl_card_info_get_name( card ));
        printf( "\n" );
        printf( "\t+--------+------------" );
        printf( "+------------------------------------+\n" );
        printf( "\t| Device | Type       " );
        printf( "| Name                               |\n" );
        printf( "\t+--------+------------" );
        printf( "+------------------------------------+\n" );

        // --------------------------------------------------------------------
        //  Start control section.
        // --------------------------------------------------------------------
        // Open an empty high level control.
        if ( snd_hctl_open( &hctl, deviceID, 0 ) < 0 )
            printf( "Error opening high level control.\n" );

        // Load high level control element.
        if ( snd_hctl_load( hctl ) < 0 )
            printf( "Error loading high level control.\n" );

        // --------------------------------------------------------------------
        //  For each control element.
        // --------------------------------------------------------------------
        for ( elem = snd_hctl_first_elem( hctl );
                    elem;
                    elem = snd_hctl_elem_next( elem ))
        {
            // Get ID of high level control element.
            snd_hctl_elem_get_id( elem, id );

            // ----------------------------------------------------------------
            //  Determine control type.
            // ----------------------------------------------------------------
            if ( snd_hctl_elem_info( elem, info ) < 0 )
                printf( "Can't get control information.\n" );

            type = snd_ctl_elem_info_get_type( info );

            switch ( type )
            {
                case SND_CTL_ELEM_TYPE_NONE:
                    controlType = "None";
                    break;
                case SND_CTL_ELEM_TYPE_BOOLEAN:
                    controlType = "Boolean";
                    break;
                case SND_CTL_ELEM_TYPE_INTEGER:
                    controlType = "Integer";
                    break;
                case SND_CTL_ELEM_TYPE_INTEGER64:
                    controlType = "Integer64";
                    break;
                case SND_CTL_ELEM_TYPE_ENUMERATED:
                    controlType = "Enumerated";
                    break;
                case SND_CTL_ELEM_TYPE_BYTES:
                    controlType = "Bytes";
                    break;
                case SND_CTL_ELEM_TYPE_IEC958:
                    controlType = "IEC958";
                    break;
                default:
                    controlType = "Not Found";
                    break;
            }
            printf( "\t| %-6i | %-10s | %-34s |\n",
                snd_hctl_elem_get_numid( elem ),
                controlType,
                snd_hctl_elem_get_name( elem ));
        }
        printf( "\t+--------+------------" );
        printf( "+------------------------------------+\n\n" );

        // --------------------------------------------------------------------
        //  Tidy up.
        // --------------------------------------------------------------------
        snd_hctl_close( hctl );
        snd_ctl_close( ctl );
    }

    return 0;
}
Ejemplo n.º 25
0
static int show_control(const char *space, snd_hctl_elem_t *elem,
                        int level)
{
    int err;
    unsigned int item, idx, count, *tlv;
    snd_ctl_elem_type_t type;
    snd_ctl_elem_id_t *id;
    snd_ctl_elem_info_t *info;
    snd_ctl_elem_value_t *control;
    snd_aes_iec958_t iec958;
    snd_ctl_elem_id_alloca(&id);
    snd_ctl_elem_info_alloca(&info);
    snd_ctl_elem_value_alloca(&control);
    if ((err = snd_hctl_elem_info(elem, info)) < 0)
    {
        error("Control %s snd_hctl_elem_info error: %s\n", card, snd_strerror(err));
        return err;
    }
    if (level & LEVEL_ID)
    {
        snd_hctl_elem_get_id(elem, id);
        show_control_id(id);
        printf("\n");
    }
    count = snd_ctl_elem_info_get_count(info);
    type = snd_ctl_elem_info_get_type(info);
    printf("%s; type=%s,access=%s,values=%i", space, control_type(info), control_access(info), count);
    switch (type)
    {
    case SND_CTL_ELEM_TYPE_INTEGER:
        printf(",min=%li,max=%li,step=%li\n",
               snd_ctl_elem_info_get_min(info),
               snd_ctl_elem_info_get_max(info),
               snd_ctl_elem_info_get_step(info));
        break;
    case SND_CTL_ELEM_TYPE_INTEGER64:
        printf(",min=%Li,max=%Li,step=%Li\n",
               snd_ctl_elem_info_get_min64(info),
               snd_ctl_elem_info_get_max64(info),
               snd_ctl_elem_info_get_step64(info));
        break;
    case SND_CTL_ELEM_TYPE_ENUMERATED:
    {
        unsigned int items = snd_ctl_elem_info_get_items(info);
        printf(",items=%u\n", items);
        for (item = 0; item < items; item++)
        {
            snd_ctl_elem_info_set_item(info, item);
            if ((err = snd_hctl_elem_info(elem, info)) < 0)
            {
                error("Control %s element info error: %s\n", card, snd_strerror(err));
                return err;
            }
            printf("%s; Item #%u '%s'\n", space, item, snd_ctl_elem_info_get_item_name(info));
        }
        break;
    }
    default:
        printf("\n");
        break;
    }
    if (level & LEVEL_BASIC)
    {
        if (!snd_ctl_elem_info_is_readable(info))
            goto __skip_read;
        if ((err = snd_hctl_elem_read(elem, control)) < 0)
        {
            error("Control %s element read error: %s\n", card, snd_strerror(err));
            return err;
        }
        printf("%s: values=", space);
        for (idx = 0; idx < count; idx++)
        {
            if (idx > 0)
                printf(",");
            switch (type)
            {
            case SND_CTL_ELEM_TYPE_BOOLEAN:
                printf("%s", snd_ctl_elem_value_get_boolean(control, idx) ? "on" : "off");
                break;
            case SND_CTL_ELEM_TYPE_INTEGER:
                printf("%li", snd_ctl_elem_value_get_integer(control, idx));
                break;
            case SND_CTL_ELEM_TYPE_INTEGER64:
                printf("%Li", snd_ctl_elem_value_get_integer64(control, idx));
                break;
            case SND_CTL_ELEM_TYPE_ENUMERATED:
                printf("%u", snd_ctl_elem_value_get_enumerated(control, idx));
                break;
            case SND_CTL_ELEM_TYPE_BYTES:
                printf("0x%02x", snd_ctl_elem_value_get_byte(control, idx));
                break;
            case SND_CTL_ELEM_TYPE_IEC958:
                snd_ctl_elem_value_get_iec958(control, &iec958);
                printf("[AES0=0x%02x AES1=0x%02x AES2=0x%02x AES3=0x%02x]",
                       iec958.status[0], iec958.status[1],
                       iec958.status[2], iec958.status[3]);
                break;
            default:
                printf("?");
                break;
            }
        }
        printf("\n");
__skip_read:
        if (!snd_ctl_elem_info_is_tlv_readable(info))
            goto __skip_tlv;
        tlv = malloc(4096);
        if ((err = snd_hctl_elem_tlv_read(elem, tlv, 4096)) < 0)
        {
            error("Control %s element TLV read error: %s\n", card, snd_strerror(err));
            free(tlv);
            return err;
        }
        decode_tlv(strlen(space), tlv, 4096);
        free(tlv);
    }
__skip_tlv:
    return 0;
}
static int check_elem_set_props(struct elem_set_trial *trial)
{
	snd_ctl_elem_id_t *id;
	snd_ctl_elem_info_t *info;
	unsigned int numid;
	unsigned int index;
	unsigned int i;
	unsigned int j;
	int err;

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

	snd_ctl_elem_info_set_id(info, 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_info_set_index(info, 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_info_set_numid(info, numid + i);

		err = snd_ctl_elem_info(trial->handle, info);
		if (err < 0)
			return err;

		/* Check some common properties. */
		if (snd_ctl_elem_info_get_type(info) != trial->type)
			return -EIO;
		if (snd_ctl_elem_info_get_count(info) != trial->member_count)
			return -EIO;
		for (j = 0; j < 4; ++j) {
			if (snd_ctl_elem_info_get_dimension(info, j) !=
							trial->dimension[j])
				return -EIO;
		}

		/*
		 * In a case of IPC, this is the others. But in this case,
		 * it's myself.
		 */
		if (snd_ctl_elem_info_get_owner(info) != getpid())
			return -EIO;

		/*
		 * Just adding an element set by userspace applications,
		 * included elements are initially locked.
		 */
		if (!snd_ctl_elem_info_is_locked(info))
			return -EIO;

		/* Check type-specific properties. */
		if (trial->check_elem_props != NULL) {
			err = trial->check_elem_props(trial, info);
			if (err < 0)
				return err;
		}

		snd_ctl_elem_info_get_id(info, id);
		err = snd_ctl_elem_unlock(trial->handle, id);
		if (err < 0)
			return err;
	}

	return 0;
}
Ejemplo n.º 27
0
static int cset(int argc, char *argv[], int roflag, int keep_handle)
{
    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;
    char *ptr;
    unsigned int idx, count;
    long tmp;
    snd_ctl_elem_type_t type;
    snd_ctl_elem_info_alloca(&info);
    snd_ctl_elem_id_alloca(&id);
    snd_ctl_elem_value_alloca(&control);

    if (argc < 1)
        return -EINVAL;
    if (parse_control_id(argv[0], id))
        return -EINVAL;
    if (handle == NULL && (err = snd_ctl_open(&handle, card, 0)) < 0)
        return err;
    snd_ctl_elem_info_set_id(info, id);
    if ((err = snd_ctl_elem_info(handle, info)) < 0)
    {
        if (!keep_handle)
        {
            snd_ctl_close(handle);
            handle = NULL;
        }
        return err;
    }
    snd_ctl_elem_info_get_id(info, id);
    type = snd_ctl_elem_info_get_type(info);
    count = snd_ctl_elem_info_get_count(info);
    snd_ctl_elem_value_set_id(control, id);

    if (!roflag)
    {
        ptr = argv[1];
        for (idx = 0; idx < count && idx < 128 && ptr && *ptr; idx++)
        {
            switch (type)
            {
            case SND_CTL_ELEM_TYPE_BOOLEAN:
                tmp = 0;
                if (!strncasecmp(ptr, "on", 2) || !strncasecmp(ptr, "up", 2))
                {
                    tmp = 1;
                    ptr += 2;
                }
                else if (!strncasecmp(ptr, "yes", 3))
                {
                    tmp = 1;
                    ptr += 3;
                }
                else if (!strncasecmp(ptr, "toggle", 6))
                {
                    tmp = snd_ctl_elem_value_get_boolean(control, idx);
                    tmp = tmp > 0 ? 0 : 1;
                    ptr += 6;
                }
                else if (isdigit(*ptr))
                {
                    tmp = atoi(ptr) > 0 ? 1 : 0;
                    while (isdigit(*ptr))
                        ptr++;
                }
                else
                {
                    while (*ptr && *ptr != ',')
                        ptr++;
                }
                snd_ctl_elem_value_set_boolean(control, idx, tmp);
                break;
            case SND_CTL_ELEM_TYPE_INTEGER:
                tmp = get_integer(&ptr,
                                  snd_ctl_elem_info_get_min(info),
                                  snd_ctl_elem_info_get_max(info));
                snd_ctl_elem_value_set_integer(control, idx, tmp);
                break;
            case SND_CTL_ELEM_TYPE_INTEGER64:
                tmp = get_integer64(&ptr,
                                    snd_ctl_elem_info_get_min64(info),
                                    snd_ctl_elem_info_get_max64(info));
                snd_ctl_elem_value_set_integer64(control, idx, tmp);
                break;
            case SND_CTL_ELEM_TYPE_ENUMERATED:
                tmp = get_ctl_enum_item_index(handle, info, &ptr);
                if (tmp < 0)
                    tmp = get_integer(&ptr, 0, snd_ctl_elem_info_get_items(info) - 1);
                snd_ctl_elem_value_set_enumerated(control, idx, tmp);
                break;
            case SND_CTL_ELEM_TYPE_BYTES:
                tmp = get_integer(&ptr, 0, 255);
                snd_ctl_elem_value_set_byte(control, idx, tmp);
                break;
            default:
                break;
            }
            if (!strchr(argv[1], ','))
                ptr = argv[1];
            else if (*ptr == ',')
                ptr++;
        }
        if ((err = snd_ctl_elem_write(handle, control)) < 0)
        {
            if (!keep_handle)
            {
                snd_ctl_close(handle);
                handle = NULL;
            }
            return err;
        }
    }
    if (! keep_handle)
    {
        snd_ctl_close(handle);
        handle = NULL;
    }
    if (!quiet)
    {
        snd_hctl_t *hctl;
        snd_hctl_elem_t *elem;
        if ((err = snd_hctl_open(&hctl, card, 0)) < 0)
            return err;
        if ((err = snd_hctl_load(hctl)) < 0)
            return err;
        elem = snd_hctl_find_elem(hctl, id);
        if (elem)
            show_control("  ", elem, LEVEL_BASIC | LEVEL_ID);
        snd_hctl_close(hctl);
    }
    return 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;
}
Ejemplo n.º 29
0
void analog_volume_init(void)
{
	snd_ctl_elem_info_t *info;
	int i;

	snd_ctl_elem_info_alloca(&info);

	snd_ctl_elem_info_set_interface(info, SND_CTL_ELEM_IFACE_MIXER);
	for (i = 0; i < 10; i++) {
		snd_ctl_elem_info_set_name(info, DAC_VOLUME_NAME);
		snd_ctl_elem_info_set_numid(info, 0);
		snd_ctl_elem_info_set_index(info, i);
		if (snd_ctl_elem_info(ctl, info) < 0)
			break;
		dac_max = snd_ctl_elem_info_get_max(info);
	}
	if (i < output_channels - 1)
		dac_volumes = i;
	else
		dac_volumes = output_channels;

	snd_ctl_elem_info_set_name(info, DAC_SENSE_NAME);
	for (i = 0; i < dac_volumes; i++) {
		snd_ctl_elem_info_set_numid(info, 0);
		snd_ctl_elem_info_set_index(info, i);
		if (snd_ctl_elem_info(ctl, info) < 0)
			break;
	}
	dac_senses = i;
	if (dac_senses > 0) {
		snd_ctl_elem_info_set_numid(info, 0);
		snd_ctl_elem_info_set_index(info, 0);
		snd_ctl_elem_info(ctl, info);
		dac_sense_items = snd_ctl_elem_info_get_items(info);
		for (i = 0; i < dac_sense_items; i++) {
			snd_ctl_elem_info_set_item(info, i);
			snd_ctl_elem_info(ctl, info);
			dac_sense_name[i] = strdup(snd_ctl_elem_info_get_item_name(info));
		}
	}

	for (i = 0; i < 10; i++) {
		snd_ctl_elem_info_set_name(info, ADC_VOLUME_NAME);
		snd_ctl_elem_info_set_numid(info, 0);
		snd_ctl_elem_info_set_index(info, i);
		if (snd_ctl_elem_info(ctl, info) < 0)
			break;
		adc_max = snd_ctl_elem_info_get_max(info);
	}
	if (i < input_channels - 1)
		adc_volumes = i;
	else
		adc_volumes = input_channels;
	snd_ctl_elem_info_set_name(info, ADC_SENSE_NAME);
	for (i = 0; i < adc_volumes; i++) {
		snd_ctl_elem_info_set_numid(info, 0);
		snd_ctl_elem_info_set_index(info, i);
		if (snd_ctl_elem_info(ctl, info) < 0)
			break;
	}
	adc_senses = i;
	if (adc_senses > 0) {
		snd_ctl_elem_info_set_numid(info, 0);
		snd_ctl_elem_info_set_index(info, 0);
		snd_ctl_elem_info(ctl, info);
		adc_sense_items = snd_ctl_elem_info_get_items(info);
		for (i = 0; i < adc_sense_items; i++) {
			snd_ctl_elem_info_set_item(info, i);
			snd_ctl_elem_info(ctl, info);
			adc_sense_name[i] = strdup(snd_ctl_elem_info_get_item_name(info));
		}
	}

	for (i = 0; i < 10; i++) {
		snd_ctl_elem_info_set_name(info, IPGA_VOLUME_NAME);
		snd_ctl_elem_info_set_numid(info, 0);
		snd_ctl_elem_info_set_index(info, i);
		if (snd_ctl_elem_info(ctl, info) < 0)
			break;
	}
	if (i < input_channels - 1)
		ipga_volumes = i;
	else
		ipga_volumes = input_channels;
}