Пример #1
0
/**
 * \brief Creates a new File PCM
 * \param pcmp Returns created PCM handle
 * \param name Name of PCM
 * \param fname Output filename (or NULL if file descriptor fd is available)
 * \param fd Output file descriptor
 * \param ifname Input filename (or NULL if file descriptor ifd is available)
 * \param ifd Input file descriptor (if (ifd < 0) && (ifname == NULL), no input
 *            redirection will be performed)
 * \param trunc Truncate the file if it already exists
 * \param fmt File format ("raw" or "wav" are available)
 * \param perm File permission
 * \param slave Slave PCM handle
 * \param close_slave When set, the slave PCM handle is closed with copy PCM
 * \param stream the direction of PCM stream
 * \retval zero on success otherwise a negative error code
 * \warning Using of this function might be dangerous in the sense
 *          of compatibility reasons. The prototype might be freely
 *          changed in future.
 */
int snd_pcm_file_open(snd_pcm_t **pcmp, const char *name,
		      const char *fname, int fd, const char *ifname, int ifd,
		      int trunc,
		      const char *fmt, int perm, snd_pcm_t *slave, int close_slave,
		      snd_pcm_stream_t stream)
{
	snd_pcm_t *pcm;
	snd_pcm_file_t *file;
	snd_pcm_file_format_t format;
	struct timespec timespec;
	int err;

	assert(pcmp);
	if (fmt == NULL ||
	    strcmp(fmt, "raw") == 0)
		format = SND_PCM_FILE_FORMAT_RAW;
	else if (!strcmp(fmt, "wav"))
		format = SND_PCM_FILE_FORMAT_WAV;
	else {
		SNDERR("file format %s is unknown", fmt);
		return -EINVAL;
	}
	file = calloc(1, sizeof(snd_pcm_file_t));
	if (!file) {
		return -ENOMEM;
	}

	/* opening output fname is delayed until writing,
	 when PCM params are known */
	if (fname)
		file->fname = strdup(fname);
	file->trunc = trunc;
	file->perm = perm;

	if (ifname && (stream == SND_PCM_STREAM_CAPTURE)) {
		ifd = open(ifname, O_RDONLY);	/* TODO: mind blocking mode */
		if (ifd < 0) {
			SYSERR("open %s for reading failed", ifname);
			free(file->fname);
			free(file);
			return -errno;
		}
		file->ifname = strdup(ifname);
	}
	file->fd = fd;
	file->ifd = ifd;
	file->format = format;
	file->gen.slave = slave;
	file->gen.close_slave = close_slave;

	err = snd_pcm_new(&pcm, SND_PCM_TYPE_FILE, name, slave->stream, slave->mode);
	if (err < 0) {
		free(file->fname);
		free(file->ifname);
		free(file);
		return err;
	}
	pcm->ops = &snd_pcm_file_ops;
	pcm->fast_ops = &snd_pcm_file_fast_ops;
	pcm->private_data = file;
	pcm->poll_fd = slave->poll_fd;
	pcm->poll_events = slave->poll_events;
	pcm->mmap_shadow = 1;
	pcm->tstamp_type = SND_PCM_TSTAMP_TYPE_GETTIMEOFDAY;
#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
	if (clock_gettime(CLOCK_MONOTONIC, &timespec) == 0)
		pcm->tstamp_type = SND_PCM_TSTAMP_TYPE_MONOTONIC;
#endif
	pcm->stream = stream;
	snd_pcm_link_hw_ptr(pcm, slave);
	snd_pcm_link_appl_ptr(pcm, slave);
	*pcmp = pcm;
	return 0;
}
Пример #2
0
/**
 * \brief Creates a new File PCM
 * \param pcmp Returns created PCM handle
 * \param name Name of PCM
 * \param fname Output filename (or NULL if file descriptor fd is available)
 * \param fd Output file descriptor
 * \param ifname Input filename (or NULL if file descriptor ifd is available)
 * \param ifd Input file descriptor (if (ifd < 0) && (ifname == NULL), no input
 *            redirection will be performed)
 * \param trunc Truncate the file if it already exists
 * \param fmt File format ("raw" or "wav" are available)
 * \param perm File permission
 * \param slave Slave PCM handle
 * \param close_slave When set, the slave PCM handle is closed with copy PCM
 * \retval zero on success otherwise a negative error code
 * \warning Using of this function might be dangerous in the sense
 *          of compatibility reasons. The prototype might be freely
 *          changed in future.
 */
int snd_pcm_file_open(snd_pcm_t **pcmp, const char *name,
		      const char *fname, int fd, const char *ifname, int ifd,
		      int trunc,
		      const char *fmt, int perm, snd_pcm_t *slave, int close_slave)
{
	snd_pcm_t *pcm;
	snd_pcm_file_t *file;
	snd_pcm_file_format_t format;
	struct timespec timespec;
	char *tmpname = NULL;
	int err;

	assert(pcmp);
	if (fmt == NULL ||
	    strcmp(fmt, "raw") == 0)
		format = SND_PCM_FILE_FORMAT_RAW;
	else if (!strcmp(fmt, "wav"))
		format = SND_PCM_FILE_FORMAT_WAV;
	else {
		SNDERR("file format %s is unknown", fmt);
		return -EINVAL;
	}
	if (fname) {
		if (trunc)
			fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC, perm);
		else {
			fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, perm);
			if (fd < 0) {
				int idx, len;
				len = strlen(fname) + 6;
				tmpname = malloc(len);
				if (!tmpname)
					return -ENOMEM;
				for (idx = 1; idx < 10000; idx++) {
					snprintf(tmpname, len,
						 "%s.%04d", fname, idx);
					fd = open(tmpname, O_WRONLY|O_CREAT|O_EXCL, perm);
					if (fd >= 0) {
						fname = tmpname;
						break;
					}
				}
			}
		}
		if (fd < 0) {
			SYSERR("open %s for writing failed", fname);
			free(tmpname);
			return -errno;
		}
	}
	file = calloc(1, sizeof(snd_pcm_file_t));
	if (!file) {
		if (fname)
			close(fd);
		free(tmpname);
		return -ENOMEM;
	}

	if (ifname) {
		ifd = open(ifname, O_RDONLY);	/* TODO: mind blocking mode */
		if (ifd < 0) {
			SYSERR("open %s for reading failed", ifname);
			if (fname)
				close(fd);
			free(file);
			free(tmpname);
			return -errno;
		}
	}

	if (fname)
		file->fname = strdup(fname);
	if (ifname)
		file->ifname = strdup(ifname);
	file->fd = fd;
	file->ifd = ifd;
	file->format = format;
	file->gen.slave = slave;
	file->gen.close_slave = close_slave;

	err = snd_pcm_new(&pcm, SND_PCM_TYPE_FILE, name, slave->stream, slave->mode);
	if (err < 0) {
		free(file->fname);
		free(file);
		free(tmpname);
		return err;
	}
	pcm->ops = &snd_pcm_file_ops;
	pcm->fast_ops = &snd_pcm_file_fast_ops;
	pcm->private_data = file;
	pcm->poll_fd = slave->poll_fd;
	pcm->poll_events = slave->poll_events;
	pcm->mmap_shadow = 1;
#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
	pcm->monotonic = clock_gettime(CLOCK_MONOTONIC, &timespec) == 0;
#else
	pcm->monotonic = 0;
#endif
	snd_pcm_link_hw_ptr(pcm, slave);
	snd_pcm_link_appl_ptr(pcm, slave);
	*pcmp = pcm;

	free(tmpname);
	return 0;
}
Пример #3
0
/**
 * \brief Creates a new File PCM
 * \param pcmp Returns created PCM handle
 * \param name Name of PCM
 * \param fname Output filename (or NULL if file descriptor fd is available)
 * \param fd Output file descriptor
 * \param ifname Input filename (or NULL if file descriptor ifd is available)
 * \param ifd Input file descriptor (if (ifd < 0) && (ifname == NULL), no input
 *            redirection will be performed)
 * \param fmt File format ("raw" is supported only)
 * \param perm File permission
 * \param slave Slave PCM handle
 * \param close_slave When set, the slave PCM handle is closed with copy PCM
 * \retval zero on success otherwise a negative error code
 * \warning Using of this function might be dangerous in the sense
 *          of compatibility reasons. The prototype might be freely
 *          changed in future.
 */
int snd_pcm_file_open(snd_pcm_t **pcmp, const char *name,
		      const char *fname, int fd, const char *ifname, int ifd, 
		      const char *fmt, int perm, snd_pcm_t *slave, int close_slave)
{
	snd_pcm_t *pcm;
	snd_pcm_file_t *file;
	snd_pcm_file_format_t format;
	int err;
	assert(pcmp);
	if (fmt == NULL ||
	    strcmp(fmt, "raw") == 0)
		format = SND_PCM_FILE_FORMAT_RAW;
	else {
		SNDERR("file format %s is unknown", fmt);
		return -EINVAL;
	}
	if (fname) {
		fd = open(fname, O_WRONLY|O_CREAT, perm);
		if (fd < 0) {
			SYSERR("open %s for writing failed", fname);
			return -errno;
		}
	}
	file = calloc(1, sizeof(snd_pcm_file_t));
	if (!file) {
		if (fname)
			close(fd);
		return -ENOMEM;
	}

	if (ifname) {
		ifd = open(ifname, O_RDONLY);	/* TODO: mind blocking mode */
		if (ifd < 0) {
			SYSERR("open %s for reading failed", ifname);
			if (fname)
				close(fd);
			return -errno;
		}
	}

	if (fname)
		file->fname = strdup(fname);
	if (ifname)
		file->ifname = strdup(ifname);
	file->fd = fd;
	file->ifd = ifd;
	file->format = format;
	file->gen.slave = slave;
	file->gen.close_slave = close_slave;

	err = snd_pcm_new(&pcm, SND_PCM_TYPE_FILE, name, slave->stream, slave->mode);
	if (err < 0) {
		free(file->fname);
		free(file);
		return err;
	}
	pcm->ops = &snd_pcm_file_ops;
	pcm->fast_ops = &snd_pcm_file_fast_ops;
	pcm->private_data = file;
	pcm->poll_fd = slave->poll_fd;
	pcm->poll_events = slave->poll_events;
	pcm->mmap_shadow = 1;
	snd_pcm_link_hw_ptr(pcm, slave);
	snd_pcm_link_appl_ptr(pcm, slave);
	*pcmp = pcm;

	return 0;
}