}
#ifndef DOC_HIDDEN
-/* locked version */
-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)
+int __snd_pcm_mmap_begin_generic(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;
assert(pcm && areas && offset && frames);
- if (pcm->fast_ops->mmap_begin)
- return pcm->fast_ops->mmap_begin(pcm->fast_op_arg, areas, offset, frames);
-
/* fallback for plugins that do not specify new callback */
xareas = snd_pcm_mmap_areas(pcm);
if (xareas == NULL)
*frames = f;
return 0;
}
+
+/* locked version */
+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)
+{
+ assert(pcm && areas && offset && frames);
+
+ if (pcm->fast_ops->mmap_begin)
+ return pcm->fast_ops->mmap_begin(pcm->fast_op_arg, areas, offset, frames);
+
+ return __snd_pcm_mmap_begin_generic(pcm, areas, offset, frames);
+}
#endif
/**
}
}
+static int snd_pcm_ioplug_mmap_begin_capture(snd_pcm_t *pcm,
+ const snd_pcm_channel_area_t **areas,
+ snd_pcm_uframes_t *offset,
+ snd_pcm_uframes_t *frames)
+{
+ ioplug_priv_t *io = pcm->private_data;
+ int err;
+
+ err = __snd_pcm_mmap_begin_generic(pcm, areas, offset, frames);
+ if (err < 0)
+ return err;
+
+ if (io->data->callback->transfer &&
+ pcm->access != SND_PCM_ACCESS_RW_INTERLEAVED &&
+ pcm->access != SND_PCM_ACCESS_RW_NONINTERLEAVED) {
+ snd_pcm_sframes_t result;
+ result = io->data->callback->transfer(io->data, *areas, *offset, *frames);
+ if (result < 0)
+ return result;
+ }
+
+ return err;
+}
+
+static int snd_pcm_ioplug_mmap_begin(snd_pcm_t *pcm, const snd_pcm_channel_area_t **areas,
+ snd_pcm_uframes_t *offset, snd_pcm_uframes_t *frames)
+{
+ if (pcm->stream == SND_PCM_STREAM_PLAYBACK)
+ return __snd_pcm_mmap_begin_generic(pcm, areas, offset, frames);
+ return snd_pcm_ioplug_mmap_begin_capture(pcm, areas, offset, frames);
+}
+
static snd_pcm_sframes_t snd_pcm_ioplug_mmap_commit(snd_pcm_t *pcm,
snd_pcm_uframes_t offset,
snd_pcm_uframes_t size)
const snd_pcm_channel_area_t *areas;
snd_pcm_uframes_t ofs, frames = size;
- __snd_pcm_mmap_begin(pcm, &areas, &ofs, &frames);
+ __snd_pcm_mmap_begin_generic(pcm, &areas, &ofs, &frames);
if (ofs != offset)
return -EIO;
return ioplug_priv_transfer_areas(pcm, areas, offset, frames);
return -EPIPE;
avail = snd_pcm_mmap_avail(pcm);
- 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;
-
- /* If the available data doesn't fit in the
- contiguous area at the end of the mmap we
- must transfer the remaining data to the
- beginning of the mmap. */
- if (size < avail) {
- result = io->data->callback->transfer(io->data, areas,
- 0, avail - size);
- if (result < 0)
- return result;
- }
- }
- }
if (avail > io->avail_max)
io->avail_max = avail;
return (snd_pcm_sframes_t)avail;
.poll_descriptors_count = snd_pcm_ioplug_poll_descriptors_count,
.poll_descriptors = snd_pcm_ioplug_poll_descriptors,
.poll_revents = snd_pcm_ioplug_poll_revents,
+ .mmap_begin = snd_pcm_ioplug_mmap_begin,
};
#endif /* !DOC_HIDDEN */