[alsa-devel] dsnoop, hwpointer and avail
Henrik Eriksson
henrik.eriksson at axis.com
Tue Nov 14 17:29:36 CET 2017
On Mon, Nov 13, 2017 at 11:12:43 +0100, Henrik Eriksson wrote:
> On Fri, Nov 10, 2017 at 13:29:43 +0100, Henrik Eriksson wrote:
> > Is there any documentation/rationale for how pcm_dsnoop works in
> > snd_pcm_{dsnoop_}status? I am particularly wondering about the ordering
> > of the snd_pcm_dsnoop_sync_ptr and the snd_pcm_status call on the slave
> > pcm.
> >
> > I see occasional spikes (>1000 frames) of difference between the slave
> > pcm hwpointer after the snd_pcm_status call on it and the pointers in
> > the dsnoop pcm, and a correspondingly bad avail count. I suspect the
> > mismatches are due to process scheduling (the slave pcm status is
> > delayed because the application process not running and the hardware
> > progresses during that delay). Does this seem plausible? If so, could
> > the code be simplified to reduce the the number of systemcalls needed?
> > The status of the slave pcm seems to provide much of the information
> > used to sync the pointers. Or is there some other way to get a tighter
> > coupling between the dsnoop status htstamp and avail count?
>
> Or, rather, in snd_pcm_dnsoop_status() would it not make more sense to
> use the dsnoop->update_tstamp as tstamp in the returned status, at least
> when the state is SNDRV_PCM_STATE_RUNNING? The returned status->avail
> count originates from snd_pcm_dsnoop_sync_ptr() and it seems sensible to
> me that the tstamp would match that.
>
> For background, this is on a machine with not mmap'ed status and control
> (in pcm_hw.c) and using slowptr in dsnoop.
Well, this change makes the linearity of repeated calls to
snd_pcm_status() and calculating status->tstamp - status->avail *
{sample rate} better when using dsnoop. Does anyone have any input on
if something like this is reasonable? Thanks.
Regards,
/henrik
From: Henrik Eriksson <henrik.eriksson at axis.com>
Subject: [PATCH] pcm: dsnoop: use tstamp from ptr sync in status
When snd_pcm_dsnoop_status() syncs the pointers it stores the tstamp
of its slave PCM. Since the avail count returned in the status is
calculated on the mmap that is synced to the pointers use that tstamp
as status->tstamp. This makes the returned avail count and tstamp match
closer than if tstamp is fetched from the subsequent status call on the
slave PCM, since this status call may be delayed due to the process
not being scheduled.
Signed-off-by: Henrik Eriksson <henrik.eriksson at axis.com>
---
src/pcm/pcm_dsnoop.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/src/pcm/pcm_dsnoop.c b/src/pcm/pcm_dsnoop.c
index 539b6711..c3600e74 100644
--- a/src/pcm/pcm_dsnoop.c
+++ b/src/pcm/pcm_dsnoop.c
@@ -30,6 +30,7 @@
#include <stdlib.h>
#include <stddef.h>
#include <unistd.h>
+#include <stdbool.h>
#include <signal.h>
#include <string.h>
#include <fcntl.h>
@@ -184,11 +185,13 @@ static int snd_pcm_dsnoop_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
{
snd_pcm_direct_t *dsnoop = pcm->private_data;
snd_pcm_state_t state;
+ bool synced = false;
switch(dsnoop->state) {
case SNDRV_PCM_STATE_DRAINING:
case SNDRV_PCM_STATE_RUNNING:
snd_pcm_dsnoop_sync_ptr(pcm);
+ synced = true;
break;
default:
break;
@@ -196,6 +199,8 @@ static int snd_pcm_dsnoop_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
memset(status, 0, sizeof(*status));
snd_pcm_status(dsnoop->spcm, status);
state = snd_pcm_state(dsnoop->spcm);
+ if (synced)
+ status->tstamp = dsnoop->update_tstamp;
status->state = state == SND_PCM_STATE_RUNNING ? dsnoop->state : state;
status->trigger_tstamp = dsnoop->trigger_tstamp;
status->avail = snd_pcm_mmap_capture_avail(pcm);
--
2.11.0
More information about the Alsa-devel
mailing list