On Mon, 30 Jul 2018 20:55:45 +0200, Rob Duncan wrote:
At 08:14 on Thu, Jul 26 2018, Takashi wrote:
Maybe we can track the own applptr (e.g. transfer_ptr or such) and calculate the transfer size from it instead of snd_pcm_mmap_begin(); i.e. write some open codes of alternative snd_pcm_mmap_begin() there.
Then transfer_ptr is updated again in snd_pcm_ioplug_mmap_commit() as well when applptr is updated.
Of course, there is a smarter way, I'd happily take another approach.
Thanks for the hint. I'm not sure I 100% understand your suggestion, though.
Well, something like below (totally untested).
Takashi
--- --- a/src/pcm/pcm_ioplug.c +++ b/src/pcm/pcm_ioplug.c @@ -44,6 +44,7 @@ typedef struct snd_pcm_ioplug_priv { struct snd_ext_parm params[SND_PCM_IOPLUG_HW_PARAMS]; snd_pcm_uframes_t last_hw; snd_pcm_uframes_t avail_max; + snd_pcm_uframes_t transfer_offset; snd_htimestamp_t trigger_tstamp; } ioplug_priv_t;
@@ -154,6 +155,7 @@ static int snd_pcm_ioplug_reset(snd_pcm_t *pcm) io->data->hw_ptr = 0; io->last_hw = 0; io->avail_max = 0; + io->transfer_offset = 0; return 0; }
@@ -595,7 +597,10 @@ static snd_pcm_sframes_t snd_pcm_ioplug_rewindable(snd_pcm_t *pcm)
static snd_pcm_sframes_t snd_pcm_ioplug_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames) { + ioplug_priv_t *io = pcm->private_data; + snd_pcm_mmap_appl_backward(pcm, frames); + io->transfer_offset = io->data->appl_ptr; return frames; }
@@ -606,7 +611,10 @@ static snd_pcm_sframes_t snd_pcm_ioplug_forwardable(snd_pcm_t *pcm)
static snd_pcm_sframes_t snd_pcm_ioplug_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames) { + ioplug_priv_t *io = pcm->private_data; + snd_pcm_mmap_appl_forward(pcm, frames); + io->transfer_offset = io->data->appl_ptr; return frames; }
@@ -723,10 +731,16 @@ static snd_pcm_sframes_t snd_pcm_ioplug_avail_update(snd_pcm_t *pcm) 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_uframes_t offset, size; snd_pcm_sframes_t result;
- __snd_pcm_mmap_begin(pcm, &areas, &offset, &size); + areas = snd_pcm_mmap_areas(pcm); + if (!areas) + return -EBADFD; + offset = io->transfer_offset; + size = pcm->buffer_size - offset; + if (avail < size) + size = avail; result = io->data->callback->transfer(io->data, areas, offset, size); if (result < 0) return result; @@ -741,6 +755,9 @@ static snd_pcm_sframes_t snd_pcm_ioplug_avail_update(snd_pcm_t *pcm) if (result < 0) return result; } + + io->transfer_offset += avail; + io->transfer_offset %= pcm->buffer_size; } } if (avail > io->avail_max)