示例#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;
}
示例#2
0
static int get_ctl_enum_item_index(snd_ctl_t *handle, snd_ctl_elem_info_t *info,
                                   char **ptrp)
{
    char *ptr = *ptrp;
    int items, i, len;
    const char *name;

    items = snd_ctl_elem_info_get_items(info);
    if (items <= 0)
        return -1;

    for (i = 0; i < items; i++)
    {
        snd_ctl_elem_info_set_item(info, i);
        if (snd_ctl_elem_info(handle, info) < 0)
            return -1;
        name = snd_ctl_elem_info_get_item_name(info);
        len = strlen(name);
        if (! strncmp(name, ptr, len))
        {
            if (! ptr[len] || ptr[len] == ',' || ptr[len] == '\n')
            {
                ptr += len;
                *ptrp = ptr;
                return i;
            }
        }
    }
    return -1;
}
static int check_enum_elem_props(struct elem_set_trial *trial,
				 snd_ctl_elem_info_t *info)
{
	unsigned int items;
	unsigned int i;
	const char *label;
	int err;

	items = snd_ctl_elem_info_get_items(info);
	if (items != sizeof(labels) / sizeof(labels[0]))
		return -EIO;

	/* Enumerate and validate all of labels registered to this element. */
	for (i = 0; i < items; ++i) {
		snd_ctl_elem_info_set_item(info, i);
		err = snd_ctl_elem_info(trial->handle, info);
		if (err < 0)
			return err;

		label = snd_ctl_elem_info_get_item_name(info);
		if (strncmp(label, labels[i], strlen(labels[i])) != 0)
			return -EIO;
	}

	return 0;
}
static int config_enumerated(snd_config_t *n, snd_ctl_t *handle,
			     snd_ctl_elem_info_t *info, int doit)
{
	const char *str;
	long val;
	long long lval;
	unsigned int idx, items;

	switch (snd_config_get_type(n)) {
	case SND_CONFIG_TYPE_INTEGER:
		snd_config_get_integer(n, &val);
		return val;
	case SND_CONFIG_TYPE_INTEGER64:
		snd_config_get_integer64(n, &lval);
		return (int) lval;
	case SND_CONFIG_TYPE_STRING:
		snd_config_get_string(n, &str);
		break;
	case SND_CONFIG_TYPE_COMPOUND:
		if (!force_restore || !doit)
			return -1;
		n = snd_config_iterator_entry(snd_config_iterator_first(n));
		return config_enumerated(n, handle, info, doit);
	default:
		return -1;
	}
	items = snd_ctl_elem_info_get_items(info);
	for (idx = 0; idx < items; idx++) {
		int err;
		snd_ctl_elem_info_set_item(info, idx);
		err = snd_ctl_elem_info(handle, info);
		if (err < 0) {
			error("snd_ctl_elem_info: %s", snd_strerror(err));
			return err;
		}
		if (strcmp(str, snd_ctl_elem_info_get_item_name(info)) == 0)
			return idx;
	}
	return -1;
}
示例#5
0
int V4LRadioControl::getEnumItemIndex(snd_ctl_t *handle, snd_ctl_elem_info_t *info,
       const QString &value)
{
    int items, i;

    items = snd_ctl_elem_info_get_items(info);
    if (items <= 0)
        return -1;

    for (i = 0; i < items; i++)
    {
        snd_ctl_elem_info_set_item(info, i);
        if (snd_ctl_elem_info(handle, info) < 0)
            return -1;
        QString name = snd_ctl_elem_info_get_item_name(info);
        if(name == value)
        {
            return i;
        }
    }
    return -1;
}
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;
}
示例#7
0
文件: amixer.c 项目: IcaroL2ORK/pd
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;
}
示例#8
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 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;
}
示例#10
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;
}
示例#11
0
文件: utils.c 项目: amipro/sphone
/*
 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;
}