[alsa-devel] [PATCH IO plug API 1/1] ioplug: Use boundary for wrap around
twischer at de.adit-jv.com
twischer at de.adit-jv.com
Fri Feb 23 10:28:51 CET 2018
From: Timo Wischer <twischer at de.adit-jv.com>
if requested by the IO plugin
Without this changes an IO plugin is not able to report
that buffer_size frames were read from the buffer.
When the buffer was full this is a valid action and
has not to be handled as an under run.
For example when the hw_ptr will be updated with
hw_ptr += buffer_size
and it is using the buffer_size as wrap around
hw_ptr %= buffer_size
would result in the same value as before the add operation.
Signed-off-by: Timo Wischer <twischer at de.adit-jv.com>
---
Hello Takashi,
> If you need to improve such a situation, you'd have to fix in the
> ioplug implementation itself, not the jack plugin.
A have attached a patch which improves the IO plug API.
If you are happy with this solution I would also adapt the pending
JACK plugin patch and set the SND_PCM_IOPLUG_FLAG_BOUNDARY_WA flag.
diff --git a/include/pcm_ioplug.h b/include/pcm_ioplug.h
index 1c84594..e75f973 100644
--- a/include/pcm_ioplug.h
+++ b/include/pcm_ioplug.h
@@ -65,6 +65,8 @@ typedef snd_pcm_ioplug_callback snd_pcm_ioplug_callback_t;
*/
#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
@@ -133,6 +135,9 @@ struct snd_pcm_ioplug_callback {
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);
/**
diff --git a/src/pcm/pcm_ioplug.c b/src/pcm/pcm_ioplug.c
index 7a782e6..9970646 100644
--- a/src/pcm/pcm_ioplug.c
+++ b/src/pcm/pcm_ioplug.c
@@ -42,7 +42,7 @@ const char *_snd_module_pcm_ioplug = "";
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;
@@ -56,13 +56,18 @@ static void snd_pcm_ioplug_hw_ptr_update(snd_pcm_t *pcm)
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;
}
--
2.7.4
More information about the Alsa-devel
mailing list