Example #1
0
int snd_timer_query_hw_open(snd_timer_query_t **handle, const char *name, int mode)
{
	int fd, ver, tmode;
	snd_timer_query_t *tmr;

	*handle = NULL;

	tmode = O_RDONLY;
	if (mode & SND_TIMER_OPEN_NONBLOCK)
		tmode |= O_NONBLOCK;	
	fd = snd_open_device(SNDRV_FILE_TIMER, tmode);
	if (fd < 0)
		return -errno;
	if (ioctl(fd, SNDRV_TIMER_IOCTL_PVERSION, &ver) < 0) {
		close(fd);
		return -errno;
	}
	if (SNDRV_PROTOCOL_INCOMPATIBLE(ver, SNDRV_TIMER_VERSION_MAX)) {
		close(fd);
		return -SND_ERROR_INCOMPATIBLE_VERSION;
	}
	tmr = (snd_timer_query_t *) calloc(1, sizeof(snd_timer_t));
	if (tmr == NULL) {
		close(fd);
		return -ENOMEM;
	}
	tmr->type = SND_TIMER_TYPE_HW;
	tmr->mode = tmode;
	tmr->name = strdup(name);
	tmr->poll_fd = fd;
	tmr->ops = &snd_timer_query_hw_ops;
	*handle = tmr;
	return 0;
}
Example #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;
}
Example #3
0
int snd_seq_hw_open(snd_seq_t **handle, const char *name, int streams, int mode)
{
	int fd, ver, client, fmode, ret;
	const char *filename;
	snd_seq_t *seq;
	snd_seq_hw_t *hw;

	*handle = NULL;

	switch (streams) {
	case SND_SEQ_OPEN_OUTPUT:
		fmode = O_WRONLY;
		break;
	case SND_SEQ_OPEN_INPUT:
		fmode = O_RDONLY;
		break;
	case SND_SEQ_OPEN_DUPLEX:
		fmode = O_RDWR;
		break;
	default:
		assert(0);
		return -EINVAL;
	}
	
	if (mode & SND_SEQ_NONBLOCK)
		fmode |= O_NONBLOCK;

	filename = SNDRV_FILE_SEQ;
	fd = snd_open_device(filename, fmode);
#ifdef SUPPORT_ALOAD
	if (fd < 0) {
		fd = snd_open_device(SNDRV_FILE_ALOADSEQ, fmode);
		if (fd >= 0)
			close(fd);
		fd = snd_open_device(filename, fmode);
	}
#endif
	if (fd < 0) {
		SYSERR("open %s failed", filename);
		return -errno;
	}
	if (ioctl(fd, SNDRV_SEQ_IOCTL_PVERSION, &ver) < 0) {
		SYSERR("SNDRV_SEQ_IOCTL_PVERSION failed");
		ret = -errno;
		close(fd);
		return ret;
	}
	if (SNDRV_PROTOCOL_INCOMPATIBLE(ver, SNDRV_SEQ_VERSION_MAX)) {
		close(fd);
		return -SND_ERROR_INCOMPATIBLE_VERSION;
	}
	hw = calloc(1, sizeof(snd_seq_hw_t));
	if (hw == NULL) {
		close(fd);
		return -ENOMEM;
	}

	seq = calloc(1, sizeof(snd_seq_t));
	if (seq == NULL) {
		free(hw);
		close(fd);
		return -ENOMEM;
	}
	hw->fd = fd;
	hw->version = ver;
	if (streams & SND_SEQ_OPEN_OUTPUT) {
		seq->obuf = (char *) malloc(seq->obufsize = SND_SEQ_OBUF_SIZE);
		if (!seq->obuf) {
			free(hw);
			free(seq);
			close(fd);
			return -ENOMEM;
		}
	}
	if (streams & SND_SEQ_OPEN_INPUT) {
		seq->ibuf = (snd_seq_event_t *) calloc(sizeof(snd_seq_event_t), seq->ibufsize = SND_SEQ_IBUF_SIZE);
		if (!seq->ibuf) {
			free(seq->obuf);
			free(hw);
			free(seq);
			close(fd);
			return -ENOMEM;
		}
	}
	if (name)
		seq->name = strdup(name);
	seq->type = SND_SEQ_TYPE_HW;
	seq->streams = streams;
	seq->mode = mode;
	seq->tmpbuf = NULL;
	seq->tmpbufsize = 0;
	seq->poll_fd = fd;
	seq->ops = &snd_seq_hw_ops;
	seq->private_data = hw;
	client = snd_seq_hw_client_id(seq);
	if (client < 0) {
		snd_seq_close(seq);
		return client;
	} else
		seq->client = client;

#ifdef SNDRV_SEQ_IOCTL_RUNNING_MODE
	{
		struct snd_seq_running_info run_mode;
		/* check running mode */
		memset(&run_mode, 0, sizeof(run_mode));
		run_mode.client = client;
#ifdef SNDRV_BIG_ENDIAN
		run_mode.big_endian = 1;
#else
		run_mode.big_endian = 0;
#endif
		run_mode.cpu_mode = sizeof(long);
		ioctl(fd, SNDRV_SEQ_IOCTL_RUNNING_MODE, &run_mode);
	}
#endif

	*handle = seq;
	return 0;
}
Example #4
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;
}
Example #6
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;
}
Example #7
0
int snd_timer_hw_open(snd_timer_t **handle, const char *name, int dev_class, int dev_sclass, int card, int device, int subdevice, int mode)
{
	int fd, ver, tmode, ret;
	snd_timer_t *tmr;
	struct snd_timer_select sel;

	*handle = NULL;

	tmode = O_RDONLY;
	if (mode & SND_TIMER_OPEN_NONBLOCK)
		tmode |= O_NONBLOCK;	
	fd = snd_open_device(SNDRV_FILE_TIMER, tmode);
	if (fd < 0)
		return -errno;
	if (ioctl(fd, SNDRV_TIMER_IOCTL_PVERSION, &ver) < 0) {
		ret = -errno;
		close(fd);
		return ret;
	}
	if (SNDRV_PROTOCOL_INCOMPATIBLE(ver, SNDRV_TIMER_VERSION_MAX)) {
		close(fd);
		return -SND_ERROR_INCOMPATIBLE_VERSION;
	}
	if (mode & SND_TIMER_OPEN_TREAD) {
		int arg = 1;
		if (ver < SNDRV_PROTOCOL_VERSION(2, 0, 3)) {
			ret = -ENOTTY;
			goto __no_tread;
		}
		if (ioctl(fd, SNDRV_TIMER_IOCTL_TREAD, &arg) < 0) {
			ret = -errno;
		      __no_tread:
			close(fd);
			SNDMSG("extended read is not supported (SNDRV_TIMER_IOCTL_TREAD)");
			return ret;
		}
	}
	memset(&sel, 0, sizeof(sel));
	sel.id.dev_class = dev_class;
	sel.id.dev_sclass = dev_sclass;
	sel.id.card = card;
	sel.id.device = device;
	sel.id.subdevice = subdevice;
	if (ioctl(fd, SNDRV_TIMER_IOCTL_SELECT, &sel) < 0) {
		ret = -errno;
		close(fd);
		return ret;
	}
	tmr = (snd_timer_t *) calloc(1, sizeof(snd_timer_t));
	if (tmr == NULL) {
		close(fd);
		return -ENOMEM;
	}
	tmr->type = SND_TIMER_TYPE_HW;
	tmr->version = ver;
	tmr->mode = tmode;
	tmr->name = strdup(name);
	tmr->poll_fd = fd;
	tmr->ops = &snd_timer_hw_ops;
	INIT_LIST_HEAD(&tmr->async_handlers);
	*handle = tmr;
	return 0;
}