mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-29 05:40:25 -04:00
Add support for monotonic timestamps
This commit is contained in:
parent
a73ad3f265
commit
309a274454
28 changed files with 77 additions and 25 deletions
16
configure.in
16
configure.in
|
|
@ -241,6 +241,22 @@ else
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
dnl Check for librt
|
||||||
|
AC_MSG_CHECKING(for librt)
|
||||||
|
AC_ARG_WITH(librt,
|
||||||
|
AS_HELP_STRING([--with-librt], [Use librt for monotonic clock (default = yes)]),
|
||||||
|
[ have_librt="$withval" ], [ have_librt="yes" ])
|
||||||
|
if test "$have_librt" = "yes"; then
|
||||||
|
AC_CHECK_LIB([rt], [clock_gettime], [HAVE_LIBRT="yes"])
|
||||||
|
if test "$HAVE_LIBRT" = "yes" ; then
|
||||||
|
ALSA_DEPLIBS="$ALSA_DEPLIBS -lrt"
|
||||||
|
AC_DEFINE([HAVE_LIBRT], 1, [Have librt])
|
||||||
|
AC_DEFINE([HAVE_CLOCK_GETTIME], 1, [Have clock gettime])
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
fi
|
||||||
|
|
||||||
AC_SUBST(ALSA_DEPLIBS)
|
AC_SUBST(ALSA_DEPLIBS)
|
||||||
|
|
||||||
dnl Check for architecture
|
dnl Check for architecture
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,7 @@ typedef struct snd_pcm_ioplug_callback snd_pcm_ioplug_callback_t;
|
||||||
* bit flags for additional conditions
|
* bit flags for additional conditions
|
||||||
*/
|
*/
|
||||||
#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 */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Protocol version
|
* Protocol version
|
||||||
|
|
|
||||||
|
|
@ -576,6 +576,7 @@ int snd_pcm_adpcm_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sfor
|
||||||
pcm->private_data = adpcm;
|
pcm->private_data = adpcm;
|
||||||
pcm->poll_fd = slave->poll_fd;
|
pcm->poll_fd = slave->poll_fd;
|
||||||
pcm->poll_events = slave->poll_events;
|
pcm->poll_events = slave->poll_events;
|
||||||
|
pcm->monotonic = slave->monotonic;
|
||||||
snd_pcm_set_hw_ptr(pcm, &adpcm->plug.hw_ptr, -1, 0);
|
snd_pcm_set_hw_ptr(pcm, &adpcm->plug.hw_ptr, -1, 0);
|
||||||
snd_pcm_set_appl_ptr(pcm, &adpcm->plug.appl_ptr, -1, 0);
|
snd_pcm_set_appl_ptr(pcm, &adpcm->plug.appl_ptr, -1, 0);
|
||||||
*pcmp = pcm;
|
*pcmp = pcm;
|
||||||
|
|
|
||||||
|
|
@ -450,6 +450,7 @@ int snd_pcm_alaw_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sform
|
||||||
pcm->private_data = alaw;
|
pcm->private_data = alaw;
|
||||||
pcm->poll_fd = slave->poll_fd;
|
pcm->poll_fd = slave->poll_fd;
|
||||||
pcm->poll_events = slave->poll_events;
|
pcm->poll_events = slave->poll_events;
|
||||||
|
pcm->monotonic = slave->monotonic;
|
||||||
snd_pcm_set_hw_ptr(pcm, &alaw->plug.hw_ptr, -1, 0);
|
snd_pcm_set_hw_ptr(pcm, &alaw->plug.hw_ptr, -1, 0);
|
||||||
snd_pcm_set_appl_ptr(pcm, &alaw->plug.appl_ptr, -1, 0);
|
snd_pcm_set_appl_ptr(pcm, &alaw->plug.appl_ptr, -1, 0);
|
||||||
*pcmp = pcm;
|
*pcmp = pcm;
|
||||||
|
|
|
||||||
|
|
@ -206,6 +206,7 @@ int snd_pcm_copy_open(snd_pcm_t **pcmp, const char *name, snd_pcm_t *slave, int
|
||||||
pcm->private_data = copy;
|
pcm->private_data = copy;
|
||||||
pcm->poll_fd = slave->poll_fd;
|
pcm->poll_fd = slave->poll_fd;
|
||||||
pcm->poll_events = slave->poll_events;
|
pcm->poll_events = slave->poll_events;
|
||||||
|
pcm->monotonic = slave->monotonic;
|
||||||
snd_pcm_set_hw_ptr(pcm, ©->plug.hw_ptr, -1, 0);
|
snd_pcm_set_hw_ptr(pcm, ©->plug.hw_ptr, -1, 0);
|
||||||
snd_pcm_set_appl_ptr(pcm, ©->plug.appl_ptr, -1, 0);
|
snd_pcm_set_appl_ptr(pcm, ©->plug.appl_ptr, -1, 0);
|
||||||
*pcmp = pcm;
|
*pcmp = pcm;
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ typedef struct {
|
||||||
unsigned int period_size;
|
unsigned int period_size;
|
||||||
unsigned int period_time;
|
unsigned int period_time;
|
||||||
snd_interval_t periods;
|
snd_interval_t periods;
|
||||||
unsigned int tick_time; /* not used */
|
unsigned int monotonic;
|
||||||
snd_pcm_tstamp_t tstamp_mode;
|
snd_pcm_tstamp_t tstamp_mode;
|
||||||
unsigned int period_step;
|
unsigned int period_step;
|
||||||
unsigned int sleep_min; /* not used */
|
unsigned int sleep_min; /* not used */
|
||||||
|
|
|
||||||
|
|
@ -333,7 +333,7 @@ static int snd_pcm_dmix_sync_ptr(snd_pcm_t *pcm)
|
||||||
dmix->avail_max = avail;
|
dmix->avail_max = avail;
|
||||||
if (avail >= pcm->stop_threshold) {
|
if (avail >= pcm->stop_threshold) {
|
||||||
snd_timer_stop(dmix->timer);
|
snd_timer_stop(dmix->timer);
|
||||||
gettimestamp(&dmix->trigger_tstamp);
|
gettimestamp(&dmix->trigger_tstamp, pcm->monotonic);
|
||||||
if (dmix->state == SND_PCM_STATE_RUNNING) {
|
if (dmix->state == SND_PCM_STATE_RUNNING) {
|
||||||
dmix->state = SND_PCM_STATE_XRUN;
|
dmix->state = SND_PCM_STATE_XRUN;
|
||||||
return -EPIPE;
|
return -EPIPE;
|
||||||
|
|
@ -385,7 +385,7 @@ static int snd_pcm_dmix_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
|
||||||
if (pcm->tstamp_mode == SND_PCM_TSTAMP_MMAP)
|
if (pcm->tstamp_mode == SND_PCM_TSTAMP_MMAP)
|
||||||
status->tstamp = snd_pcm_hw_fast_tstamp(dmix->spcm);
|
status->tstamp = snd_pcm_hw_fast_tstamp(dmix->spcm);
|
||||||
else
|
else
|
||||||
gettimestamp(&status->tstamp);
|
gettimestamp(&status->tstamp, pcm->monotonic);
|
||||||
status->avail = snd_pcm_mmap_playback_avail(pcm);
|
status->avail = snd_pcm_mmap_playback_avail(pcm);
|
||||||
status->avail_max = status->avail > dmix->avail_max ? status->avail : dmix->avail_max;
|
status->avail_max = status->avail > dmix->avail_max ? status->avail : dmix->avail_max;
|
||||||
dmix->avail_max = 0;
|
dmix->avail_max = 0;
|
||||||
|
|
@ -504,7 +504,7 @@ static int snd_pcm_dmix_start(snd_pcm_t *pcm)
|
||||||
return err;
|
return err;
|
||||||
snd_pcm_dmix_sync_area(pcm);
|
snd_pcm_dmix_sync_area(pcm);
|
||||||
}
|
}
|
||||||
gettimestamp(&dmix->trigger_tstamp);
|
gettimestamp(&dmix->trigger_tstamp, pcm->monotonic);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -195,7 +195,7 @@ static int snd_pcm_dshare_sync_ptr(snd_pcm_t *pcm)
|
||||||
dshare->avail_max = avail;
|
dshare->avail_max = avail;
|
||||||
if (avail >= pcm->stop_threshold) {
|
if (avail >= pcm->stop_threshold) {
|
||||||
snd_timer_stop(dshare->timer);
|
snd_timer_stop(dshare->timer);
|
||||||
gettimestamp(&dshare->trigger_tstamp);
|
gettimestamp(&dshare->trigger_tstamp, pcm->monotonic);
|
||||||
if (dshare->state == SND_PCM_STATE_RUNNING) {
|
if (dshare->state == SND_PCM_STATE_RUNNING) {
|
||||||
dshare->state = SND_PCM_STATE_XRUN;
|
dshare->state = SND_PCM_STATE_XRUN;
|
||||||
return -EPIPE;
|
return -EPIPE;
|
||||||
|
|
@ -229,7 +229,7 @@ static int snd_pcm_dshare_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
|
||||||
if (pcm->tstamp_mode == SND_PCM_TSTAMP_MMAP)
|
if (pcm->tstamp_mode == SND_PCM_TSTAMP_MMAP)
|
||||||
status->tstamp = snd_pcm_hw_fast_tstamp(dshare->spcm);
|
status->tstamp = snd_pcm_hw_fast_tstamp(dshare->spcm);
|
||||||
else
|
else
|
||||||
gettimestamp(&status->tstamp);
|
gettimestamp(&status->tstamp, pcm->monotonic);
|
||||||
status->avail = snd_pcm_mmap_playback_avail(pcm);
|
status->avail = snd_pcm_mmap_playback_avail(pcm);
|
||||||
status->avail_max = status->avail > dshare->avail_max ? status->avail : dshare->avail_max;
|
status->avail_max = status->avail > dshare->avail_max ? status->avail : dshare->avail_max;
|
||||||
dshare->avail_max = 0;
|
dshare->avail_max = 0;
|
||||||
|
|
@ -349,7 +349,7 @@ static int snd_pcm_dshare_start(snd_pcm_t *pcm)
|
||||||
return err;
|
return err;
|
||||||
snd_pcm_dshare_sync_area(pcm);
|
snd_pcm_dshare_sync_area(pcm);
|
||||||
}
|
}
|
||||||
gettimestamp(&dshare->trigger_tstamp);
|
gettimestamp(&dshare->trigger_tstamp, pcm->monotonic);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -141,7 +141,7 @@ static int snd_pcm_dsnoop_sync_ptr(snd_pcm_t *pcm)
|
||||||
if (pcm->stop_threshold >= pcm->boundary) /* don't care */
|
if (pcm->stop_threshold >= pcm->boundary) /* don't care */
|
||||||
return 0;
|
return 0;
|
||||||
if ((avail = snd_pcm_mmap_capture_hw_avail(pcm)) >= pcm->stop_threshold) {
|
if ((avail = snd_pcm_mmap_capture_hw_avail(pcm)) >= pcm->stop_threshold) {
|
||||||
gettimestamp(&dsnoop->trigger_tstamp);
|
gettimestamp(&dsnoop->trigger_tstamp, pcm->monotonic);
|
||||||
dsnoop->state = SND_PCM_STATE_XRUN;
|
dsnoop->state = SND_PCM_STATE_XRUN;
|
||||||
dsnoop->avail_max = avail;
|
dsnoop->avail_max = avail;
|
||||||
return -EPIPE;
|
return -EPIPE;
|
||||||
|
|
@ -175,7 +175,7 @@ static int snd_pcm_dsnoop_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
|
||||||
if (pcm->tstamp_mode == SND_PCM_TSTAMP_MMAP)
|
if (pcm->tstamp_mode == SND_PCM_TSTAMP_MMAP)
|
||||||
status->tstamp = snd_pcm_hw_fast_tstamp(dsnoop->spcm);
|
status->tstamp = snd_pcm_hw_fast_tstamp(dsnoop->spcm);
|
||||||
else
|
else
|
||||||
gettimestamp(&status->tstamp);
|
gettimestamp(&status->tstamp, pcm->monotonic);
|
||||||
status->avail = snd_pcm_mmap_capture_avail(pcm);
|
status->avail = snd_pcm_mmap_capture_avail(pcm);
|
||||||
status->avail_max = status->avail > dsnoop->avail_max ? status->avail : dsnoop->avail_max;
|
status->avail_max = status->avail > dsnoop->avail_max ? status->avail : dsnoop->avail_max;
|
||||||
dsnoop->avail_max = 0;
|
dsnoop->avail_max = 0;
|
||||||
|
|
@ -274,7 +274,7 @@ static int snd_pcm_dsnoop_start(snd_pcm_t *pcm)
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
dsnoop->state = SND_PCM_STATE_RUNNING;
|
dsnoop->state = SND_PCM_STATE_RUNNING;
|
||||||
gettimestamp(&dsnoop->trigger_tstamp);
|
gettimestamp(&dsnoop->trigger_tstamp, pcm->monotonic);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -467,6 +467,7 @@ int snd_pcm_file_open(snd_pcm_t **pcmp, const char *name,
|
||||||
pcm->poll_fd = slave->poll_fd;
|
pcm->poll_fd = slave->poll_fd;
|
||||||
pcm->poll_events = slave->poll_events;
|
pcm->poll_events = slave->poll_events;
|
||||||
pcm->mmap_shadow = 1;
|
pcm->mmap_shadow = 1;
|
||||||
|
pcm->monotonic = 1;
|
||||||
snd_pcm_link_hw_ptr(pcm, slave);
|
snd_pcm_link_hw_ptr(pcm, slave);
|
||||||
snd_pcm_link_appl_ptr(pcm, slave);
|
snd_pcm_link_appl_ptr(pcm, slave);
|
||||||
*pcmp = pcm;
|
*pcmp = pcm;
|
||||||
|
|
|
||||||
|
|
@ -201,6 +201,7 @@ int snd_pcm_hooks_open(snd_pcm_t **pcmp, const char *name, snd_pcm_t *slave, int
|
||||||
pcm->poll_fd = slave->poll_fd;
|
pcm->poll_fd = slave->poll_fd;
|
||||||
pcm->poll_events = slave->poll_events;
|
pcm->poll_events = slave->poll_events;
|
||||||
pcm->mmap_shadow = 1;
|
pcm->mmap_shadow = 1;
|
||||||
|
pcm->monotonic = slave->monotonic;
|
||||||
snd_pcm_link_hw_ptr(pcm, slave);
|
snd_pcm_link_hw_ptr(pcm, slave);
|
||||||
snd_pcm_link_appl_ptr(pcm, slave);
|
snd_pcm_link_appl_ptr(pcm, slave);
|
||||||
*pcmp = pcm;
|
*pcmp = pcm;
|
||||||
|
|
|
||||||
|
|
@ -923,9 +923,8 @@ int snd_pcm_hw_open_fd(snd_pcm_t **pcmp, const char *name,
|
||||||
int fd, int mmap_emulation ATTRIBUTE_UNUSED,
|
int fd, int mmap_emulation ATTRIBUTE_UNUSED,
|
||||||
int sync_ptr_ioctl)
|
int sync_ptr_ioctl)
|
||||||
{
|
{
|
||||||
int ver;
|
int ver, mode, monotonic = 0;
|
||||||
long fmode;
|
long fmode;
|
||||||
int mode;
|
|
||||||
snd_pcm_t *pcm = NULL;
|
snd_pcm_t *pcm = NULL;
|
||||||
snd_pcm_hw_t *hw = NULL;
|
snd_pcm_hw_t *hw = NULL;
|
||||||
snd_pcm_info_t info;
|
snd_pcm_info_t info;
|
||||||
|
|
@ -980,8 +979,19 @@ int snd_pcm_hw_open_fd(snd_pcm_t **pcmp, const char *name,
|
||||||
ret = -errno;
|
ret = -errno;
|
||||||
SNDMSG("TSTAMP failed\n");
|
SNDMSG("TSTAMP failed\n");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef HAVE_CLOCK_GETTIME
|
||||||
|
else if (SNDRV_PROTOCOL_VERSION(2, 0, 9) >= ver) {
|
||||||
|
int on = SNDRV_PCM_TSTAMP_TYPE_MONOTONIC;
|
||||||
|
if (ioctl(fd, SNDRV_PCM_IOCTL_TTSTAMP, &on) < 0) {
|
||||||
|
ret = -errno;
|
||||||
|
SNDMSG("TTSTAMP failed\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
monotonic = 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
hw = calloc(1, sizeof(snd_pcm_hw_t));
|
hw = calloc(1, sizeof(snd_pcm_hw_t));
|
||||||
if (!hw) {
|
if (!hw) {
|
||||||
|
|
@ -1012,6 +1022,7 @@ int snd_pcm_hw_open_fd(snd_pcm_t **pcmp, const char *name,
|
||||||
pcm->private_data = hw;
|
pcm->private_data = hw;
|
||||||
pcm->poll_fd = fd;
|
pcm->poll_fd = fd;
|
||||||
pcm->poll_events = info.stream == SND_PCM_STREAM_PLAYBACK ? POLLOUT : POLLIN;
|
pcm->poll_events = info.stream == SND_PCM_STREAM_PLAYBACK ? POLLOUT : POLLIN;
|
||||||
|
pcm->monotonic = monotonic;
|
||||||
|
|
||||||
ret = snd_pcm_hw_mmap_status(pcm);
|
ret = snd_pcm_hw_mmap_status(pcm);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
|
|
||||||
|
|
@ -496,6 +496,7 @@ int snd_pcm_iec958_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sfo
|
||||||
pcm->private_data = iec;
|
pcm->private_data = iec;
|
||||||
pcm->poll_fd = slave->poll_fd;
|
pcm->poll_fd = slave->poll_fd;
|
||||||
pcm->poll_events = slave->poll_events;
|
pcm->poll_events = slave->poll_events;
|
||||||
|
pcm->monotonic = slave->monotonic;
|
||||||
snd_pcm_set_hw_ptr(pcm, &iec->plug.hw_ptr, -1, 0);
|
snd_pcm_set_hw_ptr(pcm, &iec->plug.hw_ptr, -1, 0);
|
||||||
snd_pcm_set_appl_ptr(pcm, &iec->plug.appl_ptr, -1, 0);
|
snd_pcm_set_appl_ptr(pcm, &iec->plug.appl_ptr, -1, 0);
|
||||||
*pcmp = pcm;
|
*pcmp = pcm;
|
||||||
|
|
|
||||||
|
|
@ -447,7 +447,7 @@ static int snd_pcm_ioplug_start(snd_pcm_t *pcm)
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
gettimestamp(&io->trigger_tstamp);
|
gettimestamp(&io->trigger_tstamp, pcm->monotonic);
|
||||||
io->data->state = SND_PCM_STATE_RUNNING;
|
io->data->state = SND_PCM_STATE_RUNNING;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -462,7 +462,7 @@ static int snd_pcm_ioplug_drop(snd_pcm_t *pcm)
|
||||||
|
|
||||||
io->data->callback->stop(io->data);
|
io->data->callback->stop(io->data);
|
||||||
|
|
||||||
gettimestamp(&io->trigger_tstamp);
|
gettimestamp(&io->trigger_tstamp, pcm->monotonic);
|
||||||
io->data->state = SND_PCM_STATE_SETUP;
|
io->data->state = SND_PCM_STATE_SETUP;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -1021,6 +1021,7 @@ int snd_pcm_ioplug_reinit_status(snd_pcm_ioplug_t *ioplug)
|
||||||
{
|
{
|
||||||
ioplug->pcm->poll_fd = ioplug->poll_fd;
|
ioplug->pcm->poll_fd = ioplug->poll_fd;
|
||||||
ioplug->pcm->poll_events = ioplug->poll_events;
|
ioplug->pcm->poll_events = ioplug->poll_events;
|
||||||
|
ioplug->pcm->monotonic = (ioplug->flags & SND_PCM_IOPLUG_FLAG_MONOTONIC) != 0;
|
||||||
ioplug->pcm->mmap_rw = ioplug->mmap_rw;
|
ioplug->pcm->mmap_rw = ioplug->mmap_rw;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1634,6 +1634,7 @@ int snd_pcm_ladspa_open(snd_pcm_t **pcmp, const char *name,
|
||||||
pcm->private_data = ladspa;
|
pcm->private_data = ladspa;
|
||||||
pcm->poll_fd = slave->poll_fd;
|
pcm->poll_fd = slave->poll_fd;
|
||||||
pcm->poll_events = slave->poll_events;
|
pcm->poll_events = slave->poll_events;
|
||||||
|
pcm->monotonic = slave->monotonic;
|
||||||
snd_pcm_set_hw_ptr(pcm, &ladspa->plug.hw_ptr, -1, 0);
|
snd_pcm_set_hw_ptr(pcm, &ladspa->plug.hw_ptr, -1, 0);
|
||||||
snd_pcm_set_appl_ptr(pcm, &ladspa->plug.appl_ptr, -1, 0);
|
snd_pcm_set_appl_ptr(pcm, &ladspa->plug.appl_ptr, -1, 0);
|
||||||
*pcmp = pcm;
|
*pcmp = pcm;
|
||||||
|
|
|
||||||
|
|
@ -409,6 +409,7 @@ int snd_pcm_lfloat_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sfo
|
||||||
pcm->private_data = lfloat;
|
pcm->private_data = lfloat;
|
||||||
pcm->poll_fd = slave->poll_fd;
|
pcm->poll_fd = slave->poll_fd;
|
||||||
pcm->poll_events = slave->poll_events;
|
pcm->poll_events = slave->poll_events;
|
||||||
|
pcm->monotonic = slave->monotonic;
|
||||||
snd_pcm_set_hw_ptr(pcm, &lfloat->plug.hw_ptr, -1, 0);
|
snd_pcm_set_hw_ptr(pcm, &lfloat->plug.hw_ptr, -1, 0);
|
||||||
snd_pcm_set_appl_ptr(pcm, &lfloat->plug.appl_ptr, -1, 0);
|
snd_pcm_set_appl_ptr(pcm, &lfloat->plug.appl_ptr, -1, 0);
|
||||||
*pcmp = pcm;
|
*pcmp = pcm;
|
||||||
|
|
|
||||||
|
|
@ -466,6 +466,7 @@ int snd_pcm_linear_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sfo
|
||||||
pcm->private_data = linear;
|
pcm->private_data = linear;
|
||||||
pcm->poll_fd = slave->poll_fd;
|
pcm->poll_fd = slave->poll_fd;
|
||||||
pcm->poll_events = slave->poll_events;
|
pcm->poll_events = slave->poll_events;
|
||||||
|
pcm->monotonic = slave->monotonic;
|
||||||
snd_pcm_set_hw_ptr(pcm, &linear->plug.hw_ptr, -1, 0);
|
snd_pcm_set_hw_ptr(pcm, &linear->plug.hw_ptr, -1, 0);
|
||||||
snd_pcm_set_appl_ptr(pcm, &linear->plug.appl_ptr, -1, 0);
|
snd_pcm_set_appl_ptr(pcm, &linear->plug.appl_ptr, -1, 0);
|
||||||
*pcmp = pcm;
|
*pcmp = pcm;
|
||||||
|
|
|
||||||
|
|
@ -177,7 +177,8 @@ struct _snd_pcm {
|
||||||
int poll_fd_count;
|
int poll_fd_count;
|
||||||
int poll_fd;
|
int poll_fd;
|
||||||
unsigned short poll_events;
|
unsigned short poll_events;
|
||||||
int setup;
|
int setup: 1,
|
||||||
|
monotonic: 1;
|
||||||
snd_pcm_access_t access; /* access mode */
|
snd_pcm_access_t access; /* access mode */
|
||||||
snd_pcm_format_t format; /* SND_PCM_FORMAT_* */
|
snd_pcm_format_t format; /* SND_PCM_FORMAT_* */
|
||||||
snd_pcm_subformat_t subformat; /* subformat */
|
snd_pcm_subformat_t subformat; /* subformat */
|
||||||
|
|
@ -940,11 +941,15 @@ typedef union snd_tmp_double {
|
||||||
} snd_tmp_double_t;
|
} snd_tmp_double_t;
|
||||||
|
|
||||||
/* get the current timestamp */
|
/* get the current timestamp */
|
||||||
static inline void gettimestamp(snd_htimestamp_t *tstamp)
|
static inline void gettimestamp(snd_htimestamp_t *tstamp, int monotonic)
|
||||||
{
|
{
|
||||||
struct timeval tv;
|
if (monotonic) {
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, tstamp);
|
||||||
|
} else {
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
gettimeofday(&tv, 0);
|
gettimeofday(&tv, 0);
|
||||||
tstamp->tv_sec = tv.tv_sec;
|
tstamp->tv_sec = tv.tv_sec;
|
||||||
tstamp->tv_nsec = tv.tv_usec * 1000L;
|
tstamp->tv_nsec = tv.tv_usec * 1000L;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -581,6 +581,7 @@ int snd_pcm_meter_open(snd_pcm_t **pcmp, const char *name, unsigned int frequenc
|
||||||
pcm->private_data = meter;
|
pcm->private_data = meter;
|
||||||
pcm->poll_fd = slave->poll_fd;
|
pcm->poll_fd = slave->poll_fd;
|
||||||
pcm->poll_events = slave->poll_events;
|
pcm->poll_events = slave->poll_events;
|
||||||
|
pcm->monotonic = slave->monotonic;
|
||||||
snd_pcm_link_hw_ptr(pcm, slave);
|
snd_pcm_link_hw_ptr(pcm, slave);
|
||||||
snd_pcm_link_appl_ptr(pcm, slave);
|
snd_pcm_link_appl_ptr(pcm, slave);
|
||||||
*pcmp = pcm;
|
*pcmp = pcm;
|
||||||
|
|
|
||||||
|
|
@ -399,6 +399,7 @@ static int snd_pcm_mmap_emul_open(snd_pcm_t **pcmp, const char *name,
|
||||||
pcm->private_data = map;
|
pcm->private_data = map;
|
||||||
pcm->poll_fd = slave->poll_fd;
|
pcm->poll_fd = slave->poll_fd;
|
||||||
pcm->poll_events = slave->poll_events;
|
pcm->poll_events = slave->poll_events;
|
||||||
|
pcm->monotonic = slave->monotonic;
|
||||||
snd_pcm_set_hw_ptr(pcm, &map->hw_ptr, -1, 0);
|
snd_pcm_set_hw_ptr(pcm, &map->hw_ptr, -1, 0);
|
||||||
snd_pcm_set_appl_ptr(pcm, &map->appl_ptr, -1, 0);
|
snd_pcm_set_appl_ptr(pcm, &map->appl_ptr, -1, 0);
|
||||||
*pcmp = pcm;
|
*pcmp = pcm;
|
||||||
|
|
|
||||||
|
|
@ -465,6 +465,7 @@ int snd_pcm_mulaw_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sfor
|
||||||
pcm->private_data = mulaw;
|
pcm->private_data = mulaw;
|
||||||
pcm->poll_fd = slave->poll_fd;
|
pcm->poll_fd = slave->poll_fd;
|
||||||
pcm->poll_events = slave->poll_events;
|
pcm->poll_events = slave->poll_events;
|
||||||
|
pcm->monotonic = slave->monotonic;
|
||||||
snd_pcm_set_hw_ptr(pcm, &mulaw->plug.hw_ptr, -1, 0);
|
snd_pcm_set_hw_ptr(pcm, &mulaw->plug.hw_ptr, -1, 0);
|
||||||
snd_pcm_set_appl_ptr(pcm, &mulaw->plug.appl_ptr, -1, 0);
|
snd_pcm_set_appl_ptr(pcm, &mulaw->plug.appl_ptr, -1, 0);
|
||||||
*pcmp = pcm;
|
*pcmp = pcm;
|
||||||
|
|
|
||||||
|
|
@ -887,6 +887,7 @@ int snd_pcm_multi_open(snd_pcm_t **pcmp, const char *name,
|
||||||
pcm->private_data = multi;
|
pcm->private_data = multi;
|
||||||
pcm->poll_fd = multi->slaves[master_slave].pcm->poll_fd;
|
pcm->poll_fd = multi->slaves[master_slave].pcm->poll_fd;
|
||||||
pcm->poll_events = multi->slaves[master_slave].pcm->poll_events;
|
pcm->poll_events = multi->slaves[master_slave].pcm->poll_events;
|
||||||
|
pcm->monotonic = multi->slaves[master_slave].pcm->monotonic;
|
||||||
snd_pcm_link_hw_ptr(pcm, multi->slaves[master_slave].pcm);
|
snd_pcm_link_hw_ptr(pcm, multi->slaves[master_slave].pcm);
|
||||||
snd_pcm_link_appl_ptr(pcm, multi->slaves[master_slave].pcm);
|
snd_pcm_link_appl_ptr(pcm, multi->slaves[master_slave].pcm);
|
||||||
*pcmp = pcm;
|
*pcmp = pcm;
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ static int snd_pcm_null_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
|
||||||
memset(status, 0, sizeof(*status));
|
memset(status, 0, sizeof(*status));
|
||||||
status->state = null->state;
|
status->state = null->state;
|
||||||
status->trigger_tstamp = null->trigger_tstamp;
|
status->trigger_tstamp = null->trigger_tstamp;
|
||||||
gettimestamp(&status->tstamp);
|
gettimestamp(&status->tstamp, pcm->monotonic);
|
||||||
status->avail = pcm->buffer_size;
|
status->avail = pcm->buffer_size;
|
||||||
status->avail_max = status->avail;
|
status->avail_max = status->avail;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -1054,6 +1054,7 @@ int snd_pcm_plug_open(snd_pcm_t **pcmp,
|
||||||
pcm->poll_fd = slave->poll_fd;
|
pcm->poll_fd = slave->poll_fd;
|
||||||
pcm->poll_events = slave->poll_events;
|
pcm->poll_events = slave->poll_events;
|
||||||
pcm->mmap_shadow = 1;
|
pcm->mmap_shadow = 1;
|
||||||
|
pcm->monotonic = slave->monotonic;
|
||||||
snd_pcm_link_hw_ptr(pcm, slave);
|
snd_pcm_link_hw_ptr(pcm, slave);
|
||||||
snd_pcm_link_appl_ptr(pcm, slave);
|
snd_pcm_link_appl_ptr(pcm, slave);
|
||||||
*pcmp = pcm;
|
*pcmp = pcm;
|
||||||
|
|
|
||||||
|
|
@ -1093,7 +1093,7 @@ static int snd_pcm_rate_start(snd_pcm_t *pcm)
|
||||||
if (snd_pcm_state(rate->gen.slave) != SND_PCM_STATE_PREPARED)
|
if (snd_pcm_state(rate->gen.slave) != SND_PCM_STATE_PREPARED)
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
|
|
||||||
gettimestamp(&rate->trigger_tstamp);
|
gettimestamp(&rate->trigger_tstamp, pcm->monotonic);
|
||||||
|
|
||||||
avail = snd_pcm_mmap_playback_hw_avail(rate->gen.slave);
|
avail = snd_pcm_mmap_playback_hw_avail(rate->gen.slave);
|
||||||
if (avail == 0) {
|
if (avail == 0) {
|
||||||
|
|
@ -1366,6 +1366,7 @@ int snd_pcm_rate_open(snd_pcm_t **pcmp, const char *name,
|
||||||
pcm->poll_fd = slave->poll_fd;
|
pcm->poll_fd = slave->poll_fd;
|
||||||
pcm->poll_events = slave->poll_events;
|
pcm->poll_events = slave->poll_events;
|
||||||
pcm->mmap_rw = 1;
|
pcm->mmap_rw = 1;
|
||||||
|
pcm->monotonic = slave->monotonic;
|
||||||
snd_pcm_set_hw_ptr(pcm, &rate->hw_ptr, -1, 0);
|
snd_pcm_set_hw_ptr(pcm, &rate->hw_ptr, -1, 0);
|
||||||
snd_pcm_set_appl_ptr(pcm, &rate->appl_ptr, -1, 0);
|
snd_pcm_set_appl_ptr(pcm, &rate->appl_ptr, -1, 0);
|
||||||
*pcmp = pcm;
|
*pcmp = pcm;
|
||||||
|
|
|
||||||
|
|
@ -886,6 +886,7 @@ int snd_pcm_route_open(snd_pcm_t **pcmp, const char *name,
|
||||||
pcm->private_data = route;
|
pcm->private_data = route;
|
||||||
pcm->poll_fd = slave->poll_fd;
|
pcm->poll_fd = slave->poll_fd;
|
||||||
pcm->poll_events = slave->poll_events;
|
pcm->poll_events = slave->poll_events;
|
||||||
|
pcm->monotonic = slave->monotonic;
|
||||||
snd_pcm_set_hw_ptr(pcm, &route->plug.hw_ptr, -1, 0);
|
snd_pcm_set_hw_ptr(pcm, &route->plug.hw_ptr, -1, 0);
|
||||||
snd_pcm_set_appl_ptr(pcm, &route->plug.appl_ptr, -1, 0);
|
snd_pcm_set_appl_ptr(pcm, &route->plug.appl_ptr, -1, 0);
|
||||||
err = route_load_ttable(&route->params, pcm->stream, tt_ssize, ttable, tt_cused, tt_sused);
|
err = route_load_ttable(&route->params, pcm->stream, tt_ssize, ttable, tt_cused, tt_sused);
|
||||||
|
|
|
||||||
|
|
@ -962,7 +962,7 @@ static int snd_pcm_share_start(snd_pcm_t *pcm)
|
||||||
}
|
}
|
||||||
slave->running_count++;
|
slave->running_count++;
|
||||||
_snd_pcm_share_update(pcm);
|
_snd_pcm_share_update(pcm);
|
||||||
gettimestamp(&share->trigger_tstamp);
|
gettimestamp(&share->trigger_tstamp, pcm->monotonic);
|
||||||
_end:
|
_end:
|
||||||
Pthread_mutex_unlock(&slave->mutex);
|
Pthread_mutex_unlock(&slave->mutex);
|
||||||
return err;
|
return err;
|
||||||
|
|
@ -1095,7 +1095,7 @@ static void _snd_pcm_share_stop(snd_pcm_t *pcm, snd_pcm_state_t state)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
gettimestamp(&share->trigger_tstamp);
|
gettimestamp(&share->trigger_tstamp, pcm->monotonic);
|
||||||
if (pcm->stream == SND_PCM_STREAM_CAPTURE) {
|
if (pcm->stream == SND_PCM_STREAM_CAPTURE) {
|
||||||
snd_pcm_areas_copy(pcm->stopped_areas, 0,
|
snd_pcm_areas_copy(pcm->stopped_areas, 0,
|
||||||
pcm->running_areas, 0,
|
pcm->running_areas, 0,
|
||||||
|
|
@ -1492,6 +1492,7 @@ int snd_pcm_share_open(snd_pcm_t **pcmp, const char *name, const char *sname,
|
||||||
pcm->private_data = share;
|
pcm->private_data = share;
|
||||||
pcm->poll_fd = share->client_socket;
|
pcm->poll_fd = share->client_socket;
|
||||||
pcm->poll_events = stream == SND_PCM_STREAM_PLAYBACK ? POLLOUT : POLLIN;
|
pcm->poll_events = stream == SND_PCM_STREAM_PLAYBACK ? POLLOUT : POLLIN;
|
||||||
|
pcm->monotonic = pcm->monotonic;
|
||||||
snd_pcm_set_hw_ptr(pcm, &share->hw_ptr, -1, 0);
|
snd_pcm_set_hw_ptr(pcm, &share->hw_ptr, -1, 0);
|
||||||
snd_pcm_set_appl_ptr(pcm, &share->appl_ptr, -1, 0);
|
snd_pcm_set_appl_ptr(pcm, &share->appl_ptr, -1, 0);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -814,6 +814,7 @@ int snd_pcm_softvol_open(snd_pcm_t **pcmp, const char *name,
|
||||||
* an extra buffer.
|
* an extra buffer.
|
||||||
*/
|
*/
|
||||||
pcm->mmap_shadow = 1;
|
pcm->mmap_shadow = 1;
|
||||||
|
pcm->monotonic = slave->monotonic;
|
||||||
snd_pcm_set_hw_ptr(pcm, &svol->plug.hw_ptr, -1, 0);
|
snd_pcm_set_hw_ptr(pcm, &svol->plug.hw_ptr, -1, 0);
|
||||||
snd_pcm_set_appl_ptr(pcm, &svol->plug.appl_ptr, -1, 0);
|
snd_pcm_set_appl_ptr(pcm, &svol->plug.appl_ptr, -1, 0);
|
||||||
*pcmp = pcm;
|
*pcmp = pcm;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue