static snd_pcm_sframes_t snd_pcm_ioplug_avail_update(snd_pcm_t *pcm)
{
	ioplug_priv_t *io = pcm->private_data;
	snd_pcm_uframes_t avail;

	snd_pcm_ioplug_hw_ptr_update(pcm);
	if (io->data->state == SNDRV_PCM_STATE_XRUN)
		return -EPIPE;
	if (pcm->stream == SND_PCM_STREAM_CAPTURE &&
	    pcm->access != SND_PCM_ACCESS_RW_INTERLEAVED &&
	    pcm->access != SND_PCM_ACCESS_RW_NONINTERLEAVED) {
		if (io->data->callback->transfer) {
			const snd_pcm_channel_area_t *areas;
			snd_pcm_uframes_t offset, size = UINT_MAX;
			snd_pcm_sframes_t result;

			snd_pcm_mmap_begin(pcm, &areas, &offset, &size);
			result = io->data->callback->transfer(io->data, areas, offset, size);
			if (result < 0)
				return result;
		}
	}
	avail = snd_pcm_mmap_avail(pcm);
	if (avail > io->avail_max)
		io->avail_max = avail;
	return (snd_pcm_sframes_t)avail;
}
Beispiel #2
0
int snd_pcm_wait(snd_pcm_t *pcm, int timeout)
{
	struct pollfd pfd;
	int err;
	
#if 0 /* FIXME: NEEDED? */
	_snd_pcm_sync_ptr(pcm, SNDRV_PCM_SYNC_PTR_APPL);
	if (snd_pcm_mmap_avail(pcm) >= pcm->sw_params.avail_min)
		return correct_pcm_error(pcm, 1);
#endif

	pfd = pcm->pollfd;
	for (;;) {
		err = poll(&pfd, 1, timeout);
		if (err < 0) {
			if (errno == EINTR)
				continue;
			return -errno;
                }
		if (!err)
			return 0;
		if (pfd.revents & (POLLERR | POLLNVAL))
			return correct_pcm_error(pcm, -EIO);
		if (pfd.revents & (POLLIN | POLLOUT))
			return 1;
	}
}
static int snd_pcm_ioplug_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
{
	ioplug_priv_t *io = pcm->private_data;

	memset(status, 0, sizeof(*status));
	snd_pcm_ioplug_hw_ptr_update(pcm);
	status->state = io->data->state;
	status->trigger_tstamp = io->trigger_tstamp;
	status->avail = snd_pcm_mmap_avail(pcm);
	status->avail_max = io->avail_max;
	return 0;
}
Beispiel #4
0
int snd_pcm_mmap_begin(snd_pcm_t *pcm,
		       const snd_pcm_channel_area_t **areas,
		       snd_pcm_uframes_t *offset,
		       snd_pcm_uframes_t *frames)
{
	snd_pcm_uframes_t cont;
	snd_pcm_uframes_t f;
	snd_pcm_uframes_t avail;

	*areas = pcm->running_areas;
	*offset = pcm->mmap_control->appl_ptr % pcm->buffer_size;
	avail = snd_pcm_mmap_avail(pcm);
	if (avail > pcm->buffer_size)
		avail = pcm->buffer_size;
	cont = pcm->buffer_size - *offset;
	f = *frames;
	if (f > avail)
		f = avail;
	if (f > cont)
		f = cont;
	*frames = f;
	return 0;
}
Beispiel #5
0
snd_pcm_sframes_t snd_pcm_avail_update(snd_pcm_t *pcm)
{
	snd_pcm_uframes_t avail;

	_snd_pcm_sync_ptr(pcm, 0);
	avail = snd_pcm_mmap_avail(pcm);
	switch (snd_pcm_state(pcm)) {
	case SNDRV_PCM_STATE_RUNNING:
		if (avail >= pcm->sw_params.stop_threshold) {
			if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_XRUN) < 0)
				return -errno;
			/* everything is ok,
			 * state == SND_PCM_STATE_XRUN at the moment
			 */
			return -EPIPE;
		}
		break;
	case SNDRV_PCM_STATE_XRUN:
		return -EPIPE;
	default:
		break;
	}
	return avail;
}
Beispiel #6
0
int snd_pcm_generic_may_wait_for_avail_min(snd_pcm_t *pcm, snd_pcm_uframes_t avail ATTRIBUTE_UNUSED)
{
    snd_pcm_generic_t *generic = pcm->private_data;
    return snd_pcm_may_wait_for_avail_min(generic->slave, snd_pcm_mmap_avail(generic->slave));
}
static snd_pcm_sframes_t snd_pcm_ioplug_forwardable(snd_pcm_t *pcm)
{
	return snd_pcm_mmap_avail(pcm);
}