mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-29 05:40:25 -04:00
pcm: ioplug: Use boundary for wrap around
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@de.adit-jv.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
af531606b7
commit
543a9eac5d
2 changed files with 16 additions and 6 deletions
|
|
@ -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_LISTED (1<<0) /**< list up this PCM */
|
||||||
#define SND_PCM_IOPLUG_FLAG_MONOTONIC (1<<1) /**< monotonic timestamps */
|
#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
|
* Protocol version
|
||||||
|
|
@ -133,6 +135,9 @@ struct snd_pcm_ioplug_callback {
|
||||||
int (*stop)(snd_pcm_ioplug_t *io);
|
int (*stop)(snd_pcm_ioplug_t *io);
|
||||||
/**
|
/**
|
||||||
* get the current DMA position; required, called inside mutex lock
|
* 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);
|
snd_pcm_sframes_t (*pointer)(snd_pcm_ioplug_t *io);
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ const char *_snd_module_pcm_ioplug = "";
|
||||||
typedef struct snd_pcm_ioplug_priv {
|
typedef struct snd_pcm_ioplug_priv {
|
||||||
snd_pcm_ioplug_t *data;
|
snd_pcm_ioplug_t *data;
|
||||||
struct snd_ext_parm params[SND_PCM_IOPLUG_HW_PARAMS];
|
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_pcm_uframes_t avail_max;
|
||||||
snd_htimestamp_t trigger_tstamp;
|
snd_htimestamp_t trigger_tstamp;
|
||||||
} ioplug_priv_t;
|
} 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);
|
hw = io->data->callback->pointer(io->data);
|
||||||
if (hw >= 0) {
|
if (hw >= 0) {
|
||||||
unsigned int delta;
|
snd_pcm_uframes_t delta;
|
||||||
if ((unsigned int)hw >= io->last_hw)
|
|
||||||
|
if ((snd_pcm_uframes_t)hw >= io->last_hw)
|
||||||
delta = hw - io->last_hw;
|
delta = hw - io->last_hw;
|
||||||
else
|
else {
|
||||||
delta = pcm->buffer_size + hw - io->last_hw;
|
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);
|
snd_pcm_mmap_hw_forward(io->data->pcm, delta);
|
||||||
io->last_hw = hw;
|
io->last_hw = (snd_pcm_uframes_t)hw;
|
||||||
} else
|
} else
|
||||||
io->data->state = SNDRV_PCM_STATE_XRUN;
|
io->data->state = SNDRV_PCM_STATE_XRUN;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue