[alsa-devel] More snd_pcm_ioplug_avail_update() questions
Takashi Iwai
tiwai at suse.de
Tue Jul 31 10:21:37 CEST 2018
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)
More information about the Alsa-devel
mailing list