Beispiel #1
0
/**
 * \brief Convert card string to an integer value.
 * \param string String containing card identifier
 * \return zero if success, otherwise a negative error code
 *
 * The accepted format is an integer value in ASCII representation
 * or the card identifier (the id parameter for sound-card drivers).
 */
int snd_card_get_index(const char *string)
{
	int card;
	snd_ctl_t *handle;
	snd_ctl_card_info_t info;

	if (!string || *string == '\0')
		return -EINVAL;
	if ((isdigit(*string) && *(string + 1) == 0) ||
	    (isdigit(*string) && isdigit(*(string + 1)) && *(string + 2) == 0)) {
		if (sscanf(string, "%i", &card) != 1)
			return -EINVAL;
		if (card < 0 || card > 31)
			return -EINVAL;
		if (snd_card_load(card))
			return card;
		return -ENODEV;
	}
	for (card = 0; card < 32; card++) {
		if (! snd_card_load(card))
			continue;
		if (snd_ctl_hw_open(&handle, NULL, card, 0) < 0)
			continue;
		if (snd_ctl_card_info(handle, &info) < 0) {
			snd_ctl_close(handle);
			continue;
		}
		snd_ctl_close(handle);
		if (!strcmp((const char *)info.id, string))
			return card;
	}
	return -ENODEV;
}
Beispiel #2
0
int snd_hwdep_hw_open(snd_hwdep_t **handle, const char *name, int card, int device, int mode)
{
    int fd, ver, ret;
    char filename[sizeof(SNDRV_FILE_HWDEP) + 20];
    snd_hwdep_t *hwdep;
    assert(handle);

    *handle = NULL;

    if (card < 0 || card >= 32)
        return -EINVAL;
    sprintf(filename, SNDRV_FILE_HWDEP, card, device);
    fd = snd_open_device(filename, mode);
    if (fd < 0) {
        snd_card_load(card);
        fd = snd_open_device(filename, mode);
        if (fd < 0)
            return -errno;
    }
#if 0
    /*
     * this is bogus, an application have to care about open filedescriptors
     */
    if (fcntl(fd, F_SETFD, FD_CLOEXEC) != 0) {
        SYSERR("fcntl FD_CLOEXEC failed");
        ret = -errno;
        close(fd);
        return ret;
    }
#endif
    if (ioctl(fd, SNDRV_HWDEP_IOCTL_PVERSION, &ver) < 0) {
        ret = -errno;
        close(fd);
        return ret;
    }
    if (SNDRV_PROTOCOL_INCOMPATIBLE(ver, SNDRV_HWDEP_VERSION_MAX)) {
        close(fd);
        return -SND_ERROR_INCOMPATIBLE_VERSION;
    }
    hwdep = (snd_hwdep_t *) calloc(1, sizeof(snd_hwdep_t));
    if (hwdep == NULL) {
        close(fd);
        return -ENOMEM;
    }
    hwdep->name = strdup(name);
    hwdep->poll_fd = fd;
    hwdep->mode = mode;
    hwdep->type = SND_HWDEP_TYPE_HW;
    hwdep->ops = &snd_hwdep_hw_ops;
    *handle = hwdep;
    return 0;
}
Beispiel #3
0
/**
 * \brief Try to determine the next card.
 * \param rcard pointer to card number
 * \result zero if success, otherwise a negative error code
 *
 * Tries to determine the next card from given card number.
 * If card number is -1, then the first available card is
 * returned. If the result card number is -1, no more cards
 * are available.
 */
int snd_card_next(int *rcard)
{
	int card;
	
	if (rcard == NULL)
		return -EINVAL;
	card = *rcard;
	card = card < 0 ? 0 : card + 1;
	for (; card < 32; card++) {
		if (snd_card_load(card)) {
			*rcard = card;
			return 0;
		}
	}
	*rcard = -1;
	return 0;
}
Beispiel #4
0
int snd_card_get_index(const char *string)
{
    int card;
    snd_ctl_card_info_t info;

    if (!string || *string == '\0')
        return -EINVAL;
    if (*string == '/') /* device name */
        return snd_card_load2(string);
    if (sscanf(string, "%i", &card) == 1) {
        if (card < 0 || card >= SALSA_MAX_CARDS)
            return -EINVAL;
        if (snd_card_load(card))
            return card;
        return -ENODEV;
    }
    for (card = 0; card < SALSA_MAX_CARDS; card++) {
        if (get_card_info(card, &info) < 0)
            continue;
        if (!strcmp((const char *)info.id, string))
            return card;
    }
    return -ENODEV;
}
Beispiel #5
0
int snd_ctl_hw_open(snd_ctl_t **handle, const char *name, int card, int mode)
{
	int fd, ver;
	char filename[sizeof(SNDRV_FILE_CONTROL) + 10];
	int fmode;
	snd_ctl_t *ctl;
	snd_ctl_hw_t *hw;
	int err;

	*handle = NULL;	

	assert(card >= 0 && card < 32);
	sprintf(filename, SNDRV_FILE_CONTROL, card);
	if (mode & SND_CTL_READONLY)
		fmode = O_RDONLY;
	else
		fmode = O_RDWR;
	if (mode & SND_CTL_NONBLOCK)
		fmode |= O_NONBLOCK;
	if (mode & SND_CTL_ASYNC)
		fmode |= O_ASYNC;
	fd = snd_open_device(filename, fmode);
	if (fd < 0) {
		snd_card_load(card);
		fd = snd_open_device(filename, fmode);
		if (fd < 0)
			return -errno;
	}
#if 0
	/*
	 * this is bogus, an application have to care about open filedescriptors
	 */
	if (fcntl(fd, F_SETFD, FD_CLOEXEC) != 0) {
		SYSERR("fcntl FD_CLOEXEC failed");
		err = -errno;
		close(fd);
		return err;
	}
#endif
	if (ioctl(fd, SNDRV_CTL_IOCTL_PVERSION, &ver) < 0) {
		err = -errno;
		close(fd);
		return err;
	}
	if (SNDRV_PROTOCOL_INCOMPATIBLE(ver, SNDRV_CTL_VERSION_MAX)) {
		close(fd);
		return -SND_ERROR_INCOMPATIBLE_VERSION;
	}
	hw = calloc(1, sizeof(snd_ctl_hw_t));
	if (hw == NULL) {
		close(fd);
		return -ENOMEM;
	}
	hw->card = card;
	hw->fd = fd;

	err = snd_ctl_new(&ctl, SND_CTL_TYPE_HW, name);
	if (err < 0) {
		close(fd);
		free(hw);
	}
	ctl->ops = &snd_ctl_hw_ops;
	ctl->private_data = hw;
	ctl->poll_fd = fd;
	*handle = ctl;
	return 0;
}
int snd_ctl_hw_open(snd_ctl_t **handle, const char *name, int card, int mode)
{
	int fd, ver;
	char filename[sizeof(SNDRV_FILE_CONTROL) + 10];
	int fmode;
	snd_ctl_t *ctl;
	snd_ctl_hw_t *hw;
	int err;

	*handle = NULL;	

	if (CHECK_SANITY(card < 0 || card >= 32)) {
		SNDMSG("Invalid card index %d", card);
		return -EINVAL;
	}
	sprintf(filename, SNDRV_FILE_CONTROL, card);
	if (mode & SND_CTL_READONLY)
		fmode = O_RDONLY;
	else
		fmode = O_RDWR;
	if (mode & SND_CTL_NONBLOCK)
		fmode |= O_NONBLOCK;
	if (mode & SND_CTL_ASYNC)
		fmode |= O_ASYNC;
	fd = snd_open_device(filename, fmode);
	if (fd < 0) {
		snd_card_load(card);
		fd = snd_open_device(filename, fmode);
		if (fd < 0)
			return -errno;
	}
	if (ioctl(fd, SNDRV_CTL_IOCTL_PVERSION, &ver) < 0) {
		err = -errno;
		close(fd);
		return err;
	}
	if (SNDRV_PROTOCOL_INCOMPATIBLE(ver, SNDRV_CTL_VERSION_MAX)) {
		close(fd);
		return -SND_ERROR_INCOMPATIBLE_VERSION;
	}
	hw = calloc(1, sizeof(snd_ctl_hw_t));
	if (hw == NULL) {
		close(fd);
		return -ENOMEM;
	}
	hw->card = card;
	hw->fd = fd;
	hw->protocol = ver;

	err = snd_ctl_new(&ctl, SND_CTL_TYPE_HW, name);
	if (err < 0) {
		close(fd);
		free(hw);
		return err;
	}
	ctl->ops = &snd_ctl_hw_ops;
	ctl->private_data = hw;
	ctl->poll_fd = fd;
	*handle = ctl;
	return 0;
}
Beispiel #7
0
int snd_rawmidi_hw_open(snd_rawmidi_t **inputp, snd_rawmidi_t **outputp,
			const char *name, int card, int device, int subdevice,
			int mode)
{
	int fd, ver, ret;
	int attempt = 0;
	char filename[sizeof(SNDRV_FILE_RAWMIDI) + 20];
	snd_ctl_t *ctl;
	snd_rawmidi_t *rmidi;
	snd_rawmidi_hw_t *hw = NULL;
	snd_rawmidi_info_t info;
	int fmode;

	if (inputp)
		*inputp = NULL;
	if (outputp)
		*outputp = NULL;
	
	if ((ret = snd_ctl_hw_open(&ctl, NULL, card, 0)) < 0)
		return ret;
	sprintf(filename, SNDRV_FILE_RAWMIDI, card, device);

      __again:
      	if (attempt++ > 3) {
      		snd_ctl_close(ctl);
      		return -EBUSY;
      	}
      	ret = snd_ctl_rawmidi_prefer_subdevice(ctl, subdevice);
	if (ret < 0) {
		snd_ctl_close(ctl);
		return ret;
	}

	if (!inputp)
		fmode = O_WRONLY;
	else if (!outputp)
		fmode = O_RDONLY;
	else
		fmode = O_RDWR;

	if (mode & SND_RAWMIDI_APPEND) {
		assert(outputp);
		fmode |= O_APPEND;
	}

	if (mode & SND_RAWMIDI_NONBLOCK) {
		fmode |= O_NONBLOCK;
	}
	
	if (mode & SND_RAWMIDI_SYNC) {
		fmode |= O_SYNC;
	}

	assert(!(mode & ~(SND_RAWMIDI_APPEND|SND_RAWMIDI_NONBLOCK|SND_RAWMIDI_SYNC)));

	fd = snd_open_device(filename, fmode);
	if (fd < 0) {
		snd_card_load(card);
		fd = snd_open_device(filename, fmode);
		if (fd < 0) {
			snd_ctl_close(ctl);
			SYSERR("open %s failed", filename);
			return -errno;
		}
	}
#if 0
	/*
	 * this is bogus, an application have to care about open filedescriptors
	 */
	if (fcntl(fd, F_SETFD, FD_CLOEXEC) != 0) {
		SYSERR("fcntl FD_CLOEXEC failed");
		ret = -errno;
		close(fd);
		return ret;
	}
#endif
	if (ioctl(fd, SNDRV_RAWMIDI_IOCTL_PVERSION, &ver) < 0) {
		ret = -errno;
		SYSERR("SNDRV_RAWMIDI_IOCTL_PVERSION failed");
		close(fd);
		snd_ctl_close(ctl);
		return ret;
	}
	if (SNDRV_PROTOCOL_INCOMPATIBLE(ver, SNDRV_RAWMIDI_VERSION_MAX)) {
		close(fd);
		snd_ctl_close(ctl);
		return -SND_ERROR_INCOMPATIBLE_VERSION;
	}
	if (subdevice >= 0) {
		memset(&info, 0, sizeof(info));
		info.stream = outputp ? SNDRV_RAWMIDI_STREAM_OUTPUT : SNDRV_RAWMIDI_STREAM_INPUT;
		if (ioctl(fd, SNDRV_RAWMIDI_IOCTL_INFO, &info) < 0) {
			SYSERR("SNDRV_RAWMIDI_IOCTL_INFO failed");
			ret = -errno;
			close(fd);
			snd_ctl_close(ctl);
			return ret;
		}
		if (info.subdevice != (unsigned int) subdevice) {
			close(fd);
			goto __again;
		}
	}
	snd_ctl_close(ctl);

	hw = calloc(1, sizeof(snd_rawmidi_hw_t));
	if (hw == NULL)
		goto _nomem;
	hw->card = card;
	hw->device = device;
	hw->subdevice = subdevice;
	hw->fd = fd;

	if (inputp) {
		rmidi = calloc(1, sizeof(snd_rawmidi_t));
		if (rmidi == NULL)
			goto _nomem;
		if (name)
			rmidi->name = strdup(name);
		rmidi->type = SND_RAWMIDI_TYPE_HW;
		rmidi->stream = SND_RAWMIDI_STREAM_INPUT;
		rmidi->mode = mode;
		rmidi->poll_fd = fd;
		rmidi->ops = &snd_rawmidi_hw_ops;
		rmidi->private_data = hw;
		hw->open++;
		*inputp = rmidi;
	}
	if (outputp) {
		rmidi = calloc(1, sizeof(snd_rawmidi_t));
		if (rmidi == NULL)
			goto _nomem;
		if (name)
			rmidi->name = strdup(name);
		rmidi->type = SND_RAWMIDI_TYPE_HW;
		rmidi->stream = SND_RAWMIDI_STREAM_OUTPUT;
		rmidi->mode = mode;
		rmidi->poll_fd = fd;
		rmidi->ops = &snd_rawmidi_hw_ops;
		rmidi->private_data = hw;
		hw->open++;
		*outputp = rmidi;
	}
	return 0;

 _nomem:
	close(fd);
	free(hw);
	if (inputp)
		free(*inputp);
	if (outputp)
		free(*outputp);
	return -ENOMEM;
}