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; }
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; }
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; }
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; }
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); }