From 13b5d972d2e7a5f0e6f3c066684dbb01fafd5121 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Fri, 29 Oct 2010 17:36:41 +0200 Subject: [PATCH] pcm direct plugins: change timestamping in dsnoop Do not use own timestamps, try to sync hw.ptr with real timestamp. Signed-off-by: Jaroslav Kysela --- src/pcm/pcm_direct.h | 1 + src/pcm/pcm_dmix.c | 2 +- src/pcm/pcm_dshare.c | 2 +- src/pcm/pcm_dsnoop.c | 31 +++++++++++++++++++++++++------ 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/pcm/pcm_direct.h b/src/pcm/pcm_direct.h index 132c281c..7f16481b 100644 --- a/src/pcm/pcm_direct.h +++ b/src/pcm/pcm_direct.h @@ -137,6 +137,7 @@ struct snd_pcm_direct { int (*sync_ptr)(snd_pcm_t *pcm); snd_pcm_state_t state; snd_htimestamp_t trigger_tstamp; + snd_htimestamp_t update_tstamp; int server, client; int comm_fd; /* communication file descriptor (socket) */ int hw_fd; /* hardware file descriptor */ diff --git a/src/pcm/pcm_dmix.c b/src/pcm/pcm_dmix.c index cb62de92..434fc65b 100644 --- a/src/pcm/pcm_dmix.c +++ b/src/pcm/pcm_dmix.c @@ -852,7 +852,7 @@ static int snd_pcm_dmix_htimestamp(snd_pcm_t *pcm, if (ok && *avail == avail1) break; *avail = avail1; - *tstamp = snd_pcm_hw_fast_tstamp(pcm); + *tstamp = snd_pcm_hw_fast_tstamp(dmix->spcm); } return 0; } diff --git a/src/pcm/pcm_dshare.c b/src/pcm/pcm_dshare.c index 02782a78..77789a52 100644 --- a/src/pcm/pcm_dshare.c +++ b/src/pcm/pcm_dshare.c @@ -542,7 +542,7 @@ static int snd_pcm_dshare_htimestamp(snd_pcm_t *pcm, if (ok && *avail == avail1) break; *avail = avail1; - *tstamp = snd_pcm_hw_fast_tstamp(pcm); + *tstamp = snd_pcm_hw_fast_tstamp(dshare->spcm); } return 0; } diff --git a/src/pcm/pcm_dsnoop.c b/src/pcm/pcm_dsnoop.c index 15c727a5..988f1f4f 100644 --- a/src/pcm/pcm_dsnoop.c +++ b/src/pcm/pcm_dsnoop.c @@ -54,6 +54,23 @@ const char *_snd_module_pcm_dsnoop = ""; * */ +static int snoop_timestamp(snd_pcm_t *pcm) +{ + snd_pcm_direct_t *dsnoop = pcm->private_data; + snd_pcm_uframes_t ptr1 = -2LL /* invalid value */, ptr2; + + /* loop is required to sync hw.ptr with timestamp */ + while (1) { + ptr2 = *dsnoop->spcm->hw.ptr; + if (ptr1 == ptr2) + break; + ptr1 = ptr2; + dsnoop->update_tstamp = snd_pcm_hw_fast_tstamp(dsnoop->spcm); + } + dsnoop->slave_hw_ptr = ptr1; + return 0; +} + static void snoop_areas(snd_pcm_direct_t *dsnoop, const snd_pcm_channel_area_t *src_areas, const snd_pcm_channel_area_t *dst_areas, @@ -126,7 +143,8 @@ static int snd_pcm_dsnoop_sync_ptr(snd_pcm_t *pcm) if (dsnoop->slowptr) snd_pcm_hwsync(dsnoop->spcm); old_slave_hw_ptr = dsnoop->slave_hw_ptr; - slave_hw_ptr = dsnoop->slave_hw_ptr = *dsnoop->spcm->hw.ptr; + snoop_timestamp(pcm); + slave_hw_ptr = dsnoop->slave_hw_ptr; diff = slave_hw_ptr - old_slave_hw_ptr; if (diff == 0) /* fast path */ return 0; @@ -172,7 +190,7 @@ static int snd_pcm_dsnoop_status(snd_pcm_t *pcm, snd_pcm_status_t * status) state = snd_pcm_state(dsnoop->spcm); status->state = state == SND_PCM_STATE_RUNNING ? dsnoop->state : state; status->trigger_tstamp = dsnoop->trigger_tstamp; - gettimestamp(&status->tstamp, pcm->monotonic); + status->tstamp = dsnoop->update_tstamp; status->avail = snd_pcm_mmap_capture_avail(pcm); status->avail_max = status->avail > dsnoop->avail_max ? status->avail : dsnoop->avail_max; dsnoop->avail_max = 0; @@ -254,7 +272,7 @@ static int snd_pcm_dsnoop_reset(snd_pcm_t *pcm) snd_pcm_direct_t *dsnoop = pcm->private_data; dsnoop->hw_ptr %= pcm->period_size; dsnoop->appl_ptr = dsnoop->hw_ptr; - dsnoop->slave_appl_ptr = dsnoop->slave_hw_ptr = *dsnoop->spcm->hw.ptr; + dsnoop->slave_appl_ptr = dsnoop->slave_hw_ptr; return 0; } @@ -266,12 +284,13 @@ static int snd_pcm_dsnoop_start(snd_pcm_t *pcm) if (dsnoop->state != SND_PCM_STATE_PREPARED) return -EBADFD; snd_pcm_hwsync(dsnoop->spcm); - dsnoop->slave_appl_ptr = dsnoop->slave_hw_ptr = *dsnoop->spcm->hw.ptr; + snoop_timestamp(pcm); + dsnoop->slave_appl_ptr = dsnoop->slave_hw_ptr; err = snd_timer_start(dsnoop->timer); if (err < 0) return err; dsnoop->state = SND_PCM_STATE_RUNNING; - gettimestamp(&dsnoop->trigger_tstamp, pcm->monotonic); + dsnoop->trigger_tstamp = dsnoop->update_tstamp; return 0; } @@ -437,7 +456,7 @@ static int snd_pcm_dsnoop_htimestamp(snd_pcm_t *pcm, if (ok && *avail == avail1) break; *avail = avail1; - *tstamp = snd_pcm_hw_fast_tstamp(pcm); + *tstamp = snd_pcm_hw_fast_tstamp(dsnoop->spcm); } return 0; } -- 2.47.1