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 int snd_pcm_dshare_status(snd_pcm_t *pcm, snd_pcm_status_t * status) { snd_pcm_direct_t *dshare = pcm->private_data; switch (dshare->state) { case SNDRV_PCM_STATE_DRAINING: case SNDRV_PCM_STATE_RUNNING: snd_pcm_dshare_sync_ptr(pcm); break; default: break; } memset(status, 0, sizeof(*status)); status->state = snd_pcm_state(dshare->spcm); status->trigger_tstamp = dshare->trigger_tstamp; status->tstamp = snd_pcm_hw_fast_tstamp(dshare->spcm); status->avail = snd_pcm_mmap_playback_avail(pcm); status->avail_max = status->avail > dshare->avail_max ? status->avail : dshare->avail_max; dshare->avail_max = 0; return 0; }