From 6d06fcc285babd19afba3d3c14206f17e1b2583b Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Tue, 13 Oct 2020 20:10:49 +0200 Subject: [PATCH] pcm: introduce pcm_frame_diff and pcm_frame_diff2 helpers Signed-off-by: Jaroslav Kysela --- src/pcm/pcm_dmix.c | 33 +++++++-------------------------- src/pcm/pcm_dshare.c | 11 ++--------- src/pcm/pcm_dsnoop.c | 6 +----- src/pcm/pcm_local.h | 20 ++++++++++++++++++++ 4 files changed, 30 insertions(+), 40 deletions(-) diff --git a/src/pcm/pcm_dmix.c b/src/pcm/pcm_dmix.c index 8bce7aca..bcac273b 100644 --- a/src/pcm/pcm_dmix.c +++ b/src/pcm/pcm_dmix.c @@ -319,18 +319,13 @@ static void snd_pcm_dmix_sync_area(snd_pcm_t *pcm) /* check the available size in the local buffer * last_appl_ptr keeps the last updated position */ - size = dmix->appl_ptr - dmix->last_appl_ptr; + size = pcm_frame_diff2(dmix->appl_ptr, dmix->last_appl_ptr, pcm->boundary); if (! size) return; - if (size >= pcm->boundary / 2) - size = pcm->boundary - size; /* the slave_app_ptr can be far behind the slave_hw_ptr */ /* reduce mixing and errors here - just skip not catched writes */ - if (dmix->slave_hw_ptr <= dmix->slave_appl_ptr) - slave_size = dmix->slave_appl_ptr - dmix->slave_hw_ptr; - else - slave_size = dmix->slave_appl_ptr + (dmix->slave_boundary - dmix->slave_hw_ptr); + slave_size = pcm_frame_diff(dmix->slave_appl_ptr, dmix->slave_hw_ptr, dmix->slave_boundary); if (slave_size > dmix->slave_buffer_size) { transfer = dmix->slave_buffer_size - slave_size; if (transfer > size) @@ -339,11 +334,9 @@ static void snd_pcm_dmix_sync_area(snd_pcm_t *pcm) dmix->last_appl_ptr %= pcm->boundary; dmix->slave_appl_ptr += transfer; dmix->slave_appl_ptr %= dmix->slave_boundary; - size = dmix->appl_ptr - dmix->last_appl_ptr; + size = pcm_frame_diff2(dmix->appl_ptr, dmix->last_appl_ptr, pcm->boundary); if (! size) return; - if (size >= pcm->boundary / 2) - size = pcm->boundary - size; } /* check the available size in the slave PCM buffer */ @@ -355,10 +348,7 @@ static void snd_pcm_dmix_sync_area(snd_pcm_t *pcm) slave_hw_ptr += dmix->slave_buffer_size; if (slave_hw_ptr >= dmix->slave_boundary) slave_hw_ptr -= dmix->slave_boundary; - if (slave_hw_ptr < dmix->slave_appl_ptr) - slave_size = slave_hw_ptr + (dmix->slave_boundary - dmix->slave_appl_ptr); - else - slave_size = slave_hw_ptr - dmix->slave_appl_ptr; + slave_size = pcm_frame_diff(slave_hw_ptr, dmix->slave_appl_ptr, dmix->slave_boundary); if (slave_size < size) size = slave_size; if (! size) @@ -726,10 +716,7 @@ static snd_pcm_sframes_t snd_pcm_dmix_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t f * So they can be remixed. */ - if (dmix->last_appl_ptr < dmix->appl_ptr) - size = dmix->appl_ptr - dmix->last_appl_ptr; - else - size = dmix->appl_ptr + (pcm->boundary - dmix->last_appl_ptr); + size = pcm_frames_diff(dmix->last_appl_ptr, dmix->appl_ptr, pcm->boundary); if (frames < size) size = frames; snd_pcm_mmap_appl_backward(pcm, size); @@ -741,16 +728,10 @@ static snd_pcm_sframes_t snd_pcm_dmix_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t f /* Always at this point last_appl_ptr == appl_ptr * So (appl_ptr - hw_ptr) indicates the frames which can be remixed */ - if (dmix->hw_ptr < dmix->appl_ptr) - size = dmix->appl_ptr - dmix->hw_ptr; - else - size = dmix->appl_ptr + (pcm->boundary - dmix->hw_ptr); + size = pcm_frames_diff(dmix->appl_ptr, dmix->hw_ptr, pcm->boundary); if (size > frames) size = frames; - if (dmix->slave_hw_ptr < dmix->slave_appl_ptr) - slave_size = dmix->slave_appl_ptr - dmix->slave_hw_ptr; - else - slave_size = dmix->slave_appl_ptr + (pcm->boundary - dmix->slave_hw_ptr); + slave_size = pcm_frames_diff(dmix->slave_appl_ptr, dmix->slave_hw_ptr, pcm->boundary); if (slave_size < size) size = slave_size; diff --git a/src/pcm/pcm_dshare.c b/src/pcm/pcm_dshare.c index 6a99452b..88fb8bf9 100644 --- a/src/pcm/pcm_dshare.c +++ b/src/pcm/pcm_dshare.c @@ -123,10 +123,7 @@ static void snd_pcm_dshare_sync_area(snd_pcm_t *pcm) slave_hw_ptr += dshare->slave_buffer_size; if (slave_hw_ptr >= dshare->slave_boundary) slave_hw_ptr -= dshare->slave_boundary; - if (slave_hw_ptr < dshare->slave_appl_ptr) - slave_size = slave_hw_ptr + (dshare->slave_boundary - dshare->slave_appl_ptr); - else - slave_size = slave_hw_ptr - dshare->slave_appl_ptr; + slave_size = pcm_frames_diff(slave_hw_ptr, dshare->slave_appl_ptr, dshare->slave_boundary); if (slave_size < size) size = slave_size; if (! size) @@ -169,17 +166,13 @@ static int snd_pcm_dshare_sync_ptr0(snd_pcm_t *pcm, snd_pcm_uframes_t slave_hw_p old_slave_hw_ptr = dshare->slave_hw_ptr; dshare->slave_hw_ptr = slave_hw_ptr; - diff = slave_hw_ptr - old_slave_hw_ptr; + diff = pcm_frames_diff(slave_hw_ptr, old_slave_hw_ptr, dshare->slave_boundary); if (diff == 0) /* fast path */ return 0; if (dshare->state != SND_PCM_STATE_RUNNING && dshare->state != SND_PCM_STATE_DRAINING) /* not really started yet - don't update hw_ptr */ return 0; - if (diff < 0) { - slave_hw_ptr += dshare->slave_boundary; - diff = slave_hw_ptr - old_slave_hw_ptr; - } dshare->hw_ptr += diff; dshare->hw_ptr %= pcm->boundary; // printf("sync ptr diff = %li\n", diff); diff --git a/src/pcm/pcm_dsnoop.c b/src/pcm/pcm_dsnoop.c index 7904314c..bafb6ddd 100644 --- a/src/pcm/pcm_dsnoop.c +++ b/src/pcm/pcm_dsnoop.c @@ -152,13 +152,9 @@ static int snd_pcm_dsnoop_sync_ptr(snd_pcm_t *pcm) old_slave_hw_ptr = dsnoop->slave_hw_ptr; snoop_timestamp(pcm); slave_hw_ptr = dsnoop->slave_hw_ptr; - diff = slave_hw_ptr - old_slave_hw_ptr; + diff = pcm_frames_diff(slave_hw_ptr, old_slave_hw_ptr, dsnoop->slave_boundary); if (diff == 0) /* fast path */ return 0; - if (diff < 0) { - slave_hw_ptr += dsnoop->slave_boundary; - diff = slave_hw_ptr - old_slave_hw_ptr; - } snd_pcm_dsnoop_sync_area(pcm, old_slave_hw_ptr, diff); dsnoop->hw_ptr += diff; dsnoop->hw_ptr %= pcm->boundary; diff --git a/src/pcm/pcm_local.h b/src/pcm/pcm_local.h index aae58ed3..fe77e50d 100644 --- a/src/pcm/pcm_local.h +++ b/src/pcm/pcm_local.h @@ -1170,6 +1170,26 @@ static inline void sw_set_period_event(snd_pcm_sw_params_t *params, int val) #define PCMINABORT(pcm) (((pcm)->mode & SND_PCM_ABORT) != 0) +static inline snd_pcm_sframes_t pcm_frame_diff(snd_pcm_uframes_t ptr1, + snd_pcm_uframes_t ptr2, + snd_pcm_uframes_t boundary) +{ + if (ptr1 < ptr2) + return ptr1 + (boundary - ptr2); + else + return ptr1 - ptr2; +} + +static inline snd_pcm_sframes_t pcm_frame_diff2(snd_pcm_uframes_t ptr1, + snd_pcm_uframes_t ptr2, + snd_pcm_uframes_t boundary) +{ + snd_pcm_sframes_t r = ptr1 - ptr2; + if (r >= (snd_pcm_sframes_t)boundary / 2) + return boundary - r; + return r; +} + #ifdef THREAD_SAFE_API /* * __snd_pcm_lock() and __snd_pcm_unlock() are used to lock/unlock the plugin -- 2.47.1