*/
#define SND_PCM_IOPLUG_FLAG_LISTED (1<<0) /**< list up this PCM */
#define SND_PCM_IOPLUG_FLAG_MONOTONIC (1<<1) /**< monotonic timestamps */
+/** hw pointer wrap around at boundary instead of buffer_size */
+#define SND_PCM_IOPLUG_FLAG_BOUNDARY_WA (1<<2)
/*
* Protocol version
int (*stop)(snd_pcm_ioplug_t *io);
/**
* get the current DMA position; required, called inside mutex lock
+ * \return buffer position up to buffer_size or
+ * when #SND_PCM_IOPLUG_FLAG_BOUNDARY_WA flag is set up to boundary or
+ * a negative error code for Xrun
*/
snd_pcm_sframes_t (*pointer)(snd_pcm_ioplug_t *io);
/**
typedef struct snd_pcm_ioplug_priv {
snd_pcm_ioplug_t *data;
struct snd_ext_parm params[SND_PCM_IOPLUG_HW_PARAMS];
- unsigned int last_hw;
+ snd_pcm_uframes_t last_hw;
snd_pcm_uframes_t avail_max;
snd_htimestamp_t trigger_tstamp;
} ioplug_priv_t;
hw = io->data->callback->pointer(io->data);
if (hw >= 0) {
- unsigned int delta;
- if ((unsigned int)hw >= io->last_hw)
+ snd_pcm_uframes_t delta;
+
+ if ((snd_pcm_uframes_t)hw >= io->last_hw)
delta = hw - io->last_hw;
- else
- delta = pcm->buffer_size + hw - io->last_hw;
+ else {
+ const snd_pcm_uframes_t wrap_point =
+ (io->data->flags & SND_PCM_IOPLUG_FLAG_BOUNDARY_WA) ?
+ pcm->boundary : pcm->buffer_size;
+ delta = wrap_point + hw - io->last_hw;
+ }
snd_pcm_mmap_hw_forward(io->data->pcm, delta);
- io->last_hw = hw;
+ io->last_hw = (snd_pcm_uframes_t)hw;
} else
io->data->state = SNDRV_PCM_STATE_XRUN;
}