Timestamp update (struct timeval -> struct timespec).

This commit is contained in:
Jaroslav Kysela 2003-02-28 17:23:28 +00:00
parent 8bb29f007d
commit cf9e518d51
15 changed files with 91 additions and 36 deletions

View File

@ -114,6 +114,11 @@ int snd_async_handler_get_fd(snd_async_handler_t *handler);
int snd_async_handler_get_signo(snd_async_handler_t *handler);
void *snd_async_handler_get_callback_private(snd_async_handler_t *handler);
/** Timestamp */
typedef struct timeval snd_timestamp_t;
/** Hi-res timestamp */
typedef struct timespec snd_htimestamp_t;
/** \} */
#ifdef __cplusplus

View File

@ -288,8 +288,6 @@ typedef enum _snd_pcm_tstamp {
typedef unsigned long snd_pcm_uframes_t;
/** Signed frames quantity */
typedef long snd_pcm_sframes_t;
/** Timestamp */
typedef struct timeval snd_timestamp_t;
/** Non blocking mode (flag for open mode) \hideinitializer */
#define SND_PCM_NONBLOCK 0x0001

View File

@ -135,7 +135,7 @@ size_t snd_rawmidi_status_sizeof(void);
int snd_rawmidi_status_malloc(snd_rawmidi_status_t **ptr);
void snd_rawmidi_status_free(snd_rawmidi_status_t *obj);
void snd_rawmidi_status_copy(snd_rawmidi_status_t *dst, const snd_rawmidi_status_t *src);
void snd_rawmidi_status_get_tstamp(const snd_rawmidi_status_t *obj, snd_timestamp_t *ptr);
void snd_rawmidi_status_get_tstamp(const snd_rawmidi_status_t *obj, snd_htimestamp_t *ptr);
size_t snd_rawmidi_status_get_avail(const snd_rawmidi_status_t *obj);
size_t snd_rawmidi_status_get_xruns(const snd_rawmidi_status_t *obj);
int snd_rawmidi_status(snd_rawmidi_t *rmidi, snd_rawmidi_status_t * status);

View File

@ -1,6 +1,6 @@
/*
* Advanced Linux Sound Architecture - ALSA - Driver
* Copyright (c) 1994-2000 by Jaroslav Kysela <perex@suse.cz>,
* Copyright (c) 1994-2003 by Jaroslav Kysela <perex@suse.cz>,
* Abramo Bagnara <abramo@alsa-project.org>
*
*
@ -93,7 +93,7 @@ struct sndrv_aes_iec958 {
* *
****************************************************************************/
#define SNDRV_HWDEP_VERSION SNDRV_PROTOCOL_VERSION(1, 0, 0)
#define SNDRV_HWDEP_VERSION SNDRV_PROTOCOL_VERSION(1, 0, 1)
enum sndrv_hwdep_iface {
SNDRV_HWDEP_IFACE_OPL2 = 0,
@ -150,7 +150,7 @@ enum {
* *
*****************************************************************************/
#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 3)
#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 5)
typedef unsigned long sndrv_pcm_uframes_t;
typedef long sndrv_pcm_sframes_t;
@ -398,8 +398,8 @@ struct sndrv_pcm_channel_info {
struct sndrv_pcm_status {
enum sndrv_pcm_state state; /* stream state */
struct timeval trigger_tstamp; /* time when stream was started/stopped/paused */
struct timeval tstamp; /* reference timestamp */
struct timespec trigger_tstamp; /* time when stream was started/stopped/paused */
struct timespec tstamp; /* reference timestamp */
sndrv_pcm_uframes_t appl_ptr; /* appl ptr */
sndrv_pcm_uframes_t hw_ptr; /* hw ptr */
sndrv_pcm_sframes_t delay; /* current delay in frames */
@ -414,7 +414,7 @@ struct sndrv_pcm_mmap_status {
enum sndrv_pcm_state state; /* RO: state - SNDRV_PCM_STATE_XXXX */
int pad1; /* Needed for 64 bit alignment */
sndrv_pcm_uframes_t hw_ptr; /* RO: hw ptr (0...boundary-1) */
struct timeval tstamp; /* Timestamp */
struct timespec tstamp; /* Timestamp */
enum sndrv_pcm_state suspended_state; /* RO: suspended stream state */
};
@ -438,6 +438,7 @@ struct sndrv_xfern {
enum {
SNDRV_PCM_IOCTL_PVERSION = _IOR('A', 0x00, int),
SNDRV_PCM_IOCTL_INFO = _IOR('A', 0x01, struct sndrv_pcm_info),
SNDRV_PCM_IOCTL_TSTAMP = _IOW('A', 0x02, int),
SNDRV_PCM_IOCTL_HW_REFINE = _IOWR('A', 0x10, struct sndrv_pcm_hw_params),
SNDRV_PCM_IOCTL_HW_PARAMS = _IOWR('A', 0x11, struct sndrv_pcm_hw_params),
SNDRV_PCM_IOCTL_HW_FREE = _IO('A', 0x12),
@ -455,6 +456,7 @@ enum {
SNDRV_PCM_IOCTL_REWIND = _IOW('A', 0x46, sndrv_pcm_uframes_t),
SNDRV_PCM_IOCTL_RESUME = _IO('A', 0x47),
SNDRV_PCM_IOCTL_XRUN = _IO('A', 0x48),
SNDRV_PCM_IOCTL_FORWARD = _IOW('A', 0x49, sndrv_pcm_uframes_t),
SNDRV_PCM_IOCTL_WRITEI_FRAMES = _IOW('A', 0x50, struct sndrv_xferi),
SNDRV_PCM_IOCTL_READI_FRAMES = _IOR('A', 0x51, struct sndrv_xferi),
SNDRV_PCM_IOCTL_WRITEN_FRAMES = _IOW('A', 0x52, struct sndrv_xfern),
@ -512,7 +514,7 @@ struct sndrv_rawmidi_params {
struct sndrv_rawmidi_status {
enum sndrv_rawmidi_stream stream;
struct timeval tstamp; /* Timestamp */
struct timespec tstamp; /* Timestamp */
size_t avail; /* available bytes */
size_t xruns; /* count of overruns since last status (in bytes) */
unsigned char reserved[16]; /* reserved for future use */
@ -531,7 +533,7 @@ enum {
* Timer section - /dev/snd/timer
*/
#define SNDRV_TIMER_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 0)
#define SNDRV_TIMER_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 1)
enum sndrv_timer_class {
SNDRV_TIMER_CLASS_NONE = -1,
@ -591,8 +593,8 @@ struct sndrv_timer_params {
};
struct sndrv_timer_status {
struct timeval tstamp; /* Timestamp */
unsigned int resolution; /* current resolution */
struct timespec tstamp; /* Timestamp - last update */
unsigned int resolution; /* current resolution in ns */
unsigned int lost; /* counter of master tick lost */
unsigned int overrun; /* count of read queue overruns */
unsigned int queue; /* used queue size */
@ -602,6 +604,7 @@ struct sndrv_timer_status {
enum {
SNDRV_TIMER_IOCTL_PVERSION = _IOR('T', 0x00, int),
SNDRV_TIMER_IOCTL_NEXT_DEVICE = _IOWR('T', 0x01, struct sndrv_timer_id),
SNDRV_TIMER_IOCTL_TREAD = _IOW('T', 0x02, int),
SNDRV_TIMER_IOCTL_SELECT = _IOW('T', 0x10, struct sndrv_timer_select),
SNDRV_TIMER_IOCTL_INFO = _IOR('T', 0x11, struct sndrv_timer_info),
SNDRV_TIMER_IOCTL_PARAMS = _IOW('T', 0x12, struct sndrv_timer_params),
@ -616,13 +619,27 @@ struct sndrv_timer_read {
unsigned int ticks;
};
enum sndrv_timer_event {
SNDRV_TIMER_EVENT_RESOLUTION = 0, /* val = resolution in ns */
SNDRV_TIMER_EVENT_TICK, /* val = ticks */
SNDRV_TIMER_EVENT_START, /* val = resolution in ns */
SNDRV_TIMER_EVENT_STOP, /* val = 0 */
SNDRV_TIMER_EVENT_CONTINUE /* val = resolution in ns */
};
struct sndrv_timer_tread {
enum sndrv_timer_event event;
struct timespec tstamp;
unsigned int val;
};
/****************************************************************************
* *
* Section for driver control interface - /dev/snd/control? *
* *
****************************************************************************/
#define SNDRV_CTL_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 0)
#define SNDRV_CTL_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 1)
struct sndrv_ctl_card_info {
int card; /* card number */
@ -663,6 +680,7 @@ enum sndrv_ctl_elem_iface {
#define SNDRV_CTL_ELEM_ACCESS_WRITE (1<<1)
#define SNDRV_CTL_ELEM_ACCESS_READWRITE (SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE)
#define SNDRV_CTL_ELEM_ACCESS_VOLATILE (1<<2) /* control value may be changed without a notification */
#define SNDRV_CTL_ELEM_ACCESS_TIMESTAMP (1<<2) /* when was control changed */
#define SNDRV_CTL_ELEM_ACCESS_INACTIVE (1<<8) /* control does actually nothing, but may be updated */
#define SNDRV_CTL_ELEM_ACCESS_LOCK (1<<9) /* write lock */
#define SNDRV_CTL_ELEM_ACCESS_OWNER (1<<10) /* write lock owner */
@ -743,7 +761,8 @@ struct sndrv_ctl_elem_value {
} bytes;
struct sndrv_aes_iec958 iec958;
} value; /* RO */
unsigned char reserved[128];
struct timespec timestamp;
unsigned char reserved[128-sizeof(struct timespec)];
};
enum {

View File

@ -171,7 +171,7 @@ int snd_timer_status_malloc(snd_timer_status_t **ptr);
void snd_timer_status_free(snd_timer_status_t *obj);
void snd_timer_status_copy(snd_timer_status_t *dst, const snd_timer_status_t *src);
struct timeval snd_timer_status_get_timestamp(snd_timer_status_t * status);
snd_htimestamp_t snd_timer_status_get_timestamp(snd_timer_status_t * status);
long snd_timer_status_get_resolution(snd_timer_status_t * status);
long snd_timer_status_get_lost(snd_timer_status_t * status);
long snd_timer_status_get_overrun(snd_timer_status_t * status);

View File

@ -5,7 +5,7 @@
<confdir:pcm/front.conf>
EMU10K1.pcm.front.0 {
@args [ CARD ]
@args [ CARD ]
@args.CARD {
type string
}

View File

@ -13,7 +13,7 @@ libpcm_la_SOURCES = atomic.c mask.c interval.c \
pcm_rate.c pcm_plug.c pcm_misc.c pcm_mmap.c pcm_multi.c \
pcm_shm.c pcm_file.c pcm_null.c pcm_share.c \
pcm_meter.c pcm_hooks.c pcm_lfloat.c pcm_ladspa.c \
pcm_dmix.c pcm_symbols.c $(JACK_PLUGIN)
pcm_dmix.c $(JACK_PLUGIN) pcm_symbols.c
noinst_HEADERS = pcm_local.h pcm_plugin.h mask.h mask_inline.h \
interval.h interval_inline.h plugin_ops.h ladspa.h

View File

@ -1585,9 +1585,9 @@ int snd_pcm_status_dump(snd_pcm_status_t *status, snd_output_t *out)
assert(status);
snd_output_printf(out, "state : %s\n", snd_pcm_state_name((snd_pcm_state_t) status->state));
snd_output_printf(out, "trigger_time: %ld.%06ld\n",
status->trigger_tstamp.tv_sec, status->trigger_tstamp.tv_usec);
status->trigger_tstamp.tv_sec, status->trigger_tstamp.tv_nsec);
snd_output_printf(out, "tstamp : %ld.%06ld\n",
status->tstamp.tv_sec, status->tstamp.tv_usec);
status->tstamp.tv_sec, status->tstamp.tv_nsec);
snd_output_printf(out, "delay : %ld\n", (long)status->delay);
snd_output_printf(out, "avail : %ld\n", (long)status->avail);
snd_output_printf(out, "avail_max : %ld\n", (long)status->avail_max);
@ -5538,7 +5538,8 @@ snd_pcm_state_t snd_pcm_status_get_state(const snd_pcm_status_t *obj)
void snd_pcm_status_get_trigger_tstamp(const snd_pcm_status_t *obj, snd_timestamp_t *ptr)
{
assert(obj && ptr);
*ptr = obj->trigger_tstamp;
ptr->tv_sec = obj->trigger_tstamp.tv_sec;
ptr->tv_usec = obj->trigger_tstamp.tv_nsec / 1000L;
}
/**
@ -5548,7 +5549,8 @@ void snd_pcm_status_get_trigger_tstamp(const snd_pcm_status_t *obj, snd_timestam
void snd_pcm_status_get_tstamp(const snd_pcm_status_t *obj, snd_timestamp_t *ptr)
{
assert(obj && ptr);
*ptr = obj->tstamp;
ptr->tv_sec = obj->tstamp.tv_sec;
ptr->tv_usec = obj->tstamp.tv_nsec / 1000L;
}
/**

View File

@ -66,6 +66,7 @@ const char *_snd_module_pcm_dmix = "";
*/
int snd_timer_async(snd_timer_t *timer, int sig, pid_t pid);
struct timespec snd_pcm_hw_fast_tstamp(snd_pcm_t *pcm);
typedef void (mix_areas1_t)(unsigned int size,
volatile signed short *dst, signed short *src,
@ -117,7 +118,7 @@ typedef struct {
snd_pcm_uframes_t slave_appl_ptr;
snd_pcm_uframes_t slave_hw_ptr;
snd_pcm_state_t state;
snd_timestamp_t trigger_tstamp;
snd_htimestamp_t trigger_tstamp;
int server, client;
int comm_fd; /* communication file descriptor (socket) */
int hw_fd; /* hardware file descriptor */
@ -748,7 +749,10 @@ static int snd_pcm_dmix_sync_ptr(snd_pcm_t *pcm)
if (pcm->stop_threshold >= pcm->boundary) /* don't care */
return 0;
if ((avail = snd_pcm_mmap_playback_avail(pcm)) >= pcm->stop_threshold) {
gettimeofday(&dmix->trigger_tstamp, 0);
struct timeval tv;
gettimeofday(&tv, 0);
dmix->trigger_tstamp.tv_sec = tv.tv_sec;
dmix->trigger_tstamp.tv_nsec = tv.tv_usec * 1000L;
dmix->state = SND_PCM_STATE_XRUN;
dmix->avail_max = avail;
return -EPIPE;
@ -936,7 +940,7 @@ static int snd_pcm_dmix_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
memset(status, 0, sizeof(*status));
status->state = dmix->state;
status->trigger_tstamp = dmix->trigger_tstamp;
gettimeofday(&status->tstamp, 0);
status->tstamp = snd_pcm_hw_fast_tstamp(dmix->spcm);
status->avail = snd_pcm_mmap_playback_avail(pcm);
status->avail_max = status->avail > dmix->avail_max ? status->avail : dmix->avail_max;
dmix->avail_max = 0;
@ -1013,6 +1017,7 @@ static int snd_pcm_dmix_start(snd_pcm_t *pcm)
{
snd_pcm_dmix_t *dmix = pcm->private_data;
snd_pcm_sframes_t avail;
struct timeval tv;
int err;
if (dmix->state != SND_PCM_STATE_PREPARED)
@ -1028,7 +1033,9 @@ static int snd_pcm_dmix_start(snd_pcm_t *pcm)
if (avail > (snd_pcm_sframes_t)pcm->buffer_size)
avail = pcm->buffer_size;
snd_pcm_dmix_sync_area(pcm, avail);
gettimeofday(&dmix->trigger_tstamp, 0);
gettimeofday(&tv, 0);
dmix->trigger_tstamp.tv_sec = tv.tv_sec;
dmix->trigger_tstamp.tv_nsec = tv.tv_usec * 1000L;
return 0;
}

View File

@ -112,9 +112,17 @@ typedef struct {
hw->appl_ptr = hw->mmap_control->appl_ptr; } while (0)
#define FAST_PCM_STATE(hw) \
((enum sndrv_pcm_state) (hw)->mmap_status->state)
#define FAST_PCM_TSTAMP(hw) \
((hw)->mmap_status->tstamp)
#endif /* DOC_HIDDEN */
struct timespec snd_pcm_hw_fast_tstamp(snd_pcm_t *pcm)
{
snd_pcm_hw_t *hw = pcm->private_data;
return FAST_PCM_TSTAMP(hw);
}
static int snd_pcm_hw_nonblock(snd_pcm_t *pcm, int nonblock)
{
long flags;

View File

@ -51,7 +51,7 @@ typedef enum _jack_format {
typedef struct {
int fd;
int activated; /* jack is activated? */
snd_timestamp_t trigger_tstamp;
snd_htimestamp_t trigger_tstamp;
snd_pcm_uframes_t avail_max;
snd_pcm_state_t state;
snd_pcm_uframes_t appl_ptr;
@ -162,7 +162,7 @@ static int snd_pcm_jack_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
memset(status, 0, sizeof(*status));
status->state = jack->state;
status->trigger_tstamp = jack->trigger_tstamp;
gettimeofday(&status->tstamp, 0);
// gettimeofday(&status->tstamp, 0);
status->avail = pcm->buffer_size;
status->avail_max = jack->avail_max;
return 0;
@ -255,7 +255,10 @@ snd_pcm_jack_process_cb (jack_nframes_t nframes, snd_pcm_t *pcm)
if (pcm->stop_threshold < pcm->boundary) {
samples = snd_pcm_mmap_avail(pcm);
if (samples >= pcm->stop_threshold) {
gettimeofday(&jack->trigger_tstamp, 0);
struct timeval tv;
gettimeofday(&tv, 0);
jack->trigger_tstamp.tv_sec = tv.tv_sec;
jack->trigger_tstamp.tv_nsec = tv.tv_usec * 1000L;
jack->state = SND_PCM_STATE_XRUN;
jack->avail_max = samples;
}
@ -319,6 +322,7 @@ static int snd_pcm_jack_start(snd_pcm_t *pcm)
{
snd_pcm_jack_t *jack = pcm->private_data;
unsigned int i;
struct timeval tv;
assert(jack->state == SND_PCM_STATE_PREPARED);
@ -374,6 +378,9 @@ static int snd_pcm_jack_start(snd_pcm_t *pcm)
}
}
gettimeofday(&tv, 0);
jack->trigger_tstamp.tv_sec = tv.tv_sec;
jack->trigger_tstamp.tv_nsec = tv.tv_usec * 1000L;
jack->state = SND_PCM_STATE_RUNNING;
return 0;

View File

@ -39,7 +39,7 @@ const char *_snd_module_pcm_null = "";
#ifndef DOC_HIDDEN
typedef struct {
snd_timestamp_t trigger_tstamp;
snd_htimestamp_t trigger_tstamp;
snd_pcm_state_t state;
snd_pcm_uframes_t appl_ptr;
snd_pcm_uframes_t hw_ptr;
@ -85,10 +85,13 @@ static int snd_pcm_null_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t * in
static int snd_pcm_null_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
{
snd_pcm_null_t *null = pcm->private_data;
struct timeval tv;
memset(status, 0, sizeof(*status));
status->state = null->state;
status->trigger_tstamp = null->trigger_tstamp;
gettimeofday(&status->tstamp, 0);
gettimeofday(&tv, 0);
status->tstamp.tv_sec = tv.tv_sec;
status->tstamp.tv_nsec = tv.tv_usec * 1000L;
status->avail = pcm->buffer_size;
status->avail_max = status->avail;
return 0;

View File

@ -106,7 +106,7 @@ typedef struct {
unsigned int channels;
unsigned int *slave_channels;
int drain_silenced;
struct timeval trigger_tstamp;
snd_htimestamp_t trigger_tstamp;
snd_pcm_state_t state;
snd_pcm_uframes_t hw_ptr;
snd_pcm_uframes_t appl_ptr;
@ -890,6 +890,7 @@ static int snd_pcm_share_start(snd_pcm_t *pcm)
snd_pcm_share_t *share = pcm->private_data;
snd_pcm_share_slave_t *slave = share->slave;
snd_pcm_t *spcm = slave->pcm;
struct timeval tv;
int err = 0;
if (share->state != SND_PCM_STATE_PREPARED)
return -EBADFD;
@ -945,7 +946,9 @@ static int snd_pcm_share_start(snd_pcm_t *pcm)
}
slave->running_count++;
_snd_pcm_share_update(pcm);
gettimeofday(&share->trigger_tstamp, 0);
gettimeofday(&tv, 0);
share->trigger_tstamp.tv_sec = tv.tv_sec;
share->trigger_tstamp.tv_nsec = tv.tv_usec * 1000L;
_end:
Pthread_mutex_unlock(&slave->mutex);
return err;
@ -1072,13 +1075,16 @@ static void _snd_pcm_share_stop(snd_pcm_t *pcm, snd_pcm_state_t state)
{
snd_pcm_share_t *share = pcm->private_data;
snd_pcm_share_slave_t *slave = share->slave;
struct timeval tv;
#if 0
if (!pcm->mmap_channels) {
/* PCM closing already begun in the main thread */
return;
}
#endif
gettimeofday(&share->trigger_tstamp, 0);
gettimeofday(&tv, 0);
share->trigger_tstamp.tv_sec = tv.tv_sec;
share->trigger_tstamp.tv_nsec = tv.tv_usec * 1000L;
if (pcm->stream == SND_PCM_STREAM_CAPTURE) {
snd_pcm_areas_copy(pcm->stopped_areas, 0,
pcm->running_areas, 0,

View File

@ -893,7 +893,7 @@ void snd_rawmidi_status_copy(snd_rawmidi_status_t *dst, const snd_rawmidi_status
* \param status pointer to a snd_rawmidi_status_t structure
* \param tstamp returned timestamp value
*/
void snd_rawmidi_status_get_tstamp(const snd_rawmidi_status_t *status, snd_timestamp_t *tstamp)
void snd_rawmidi_status_get_tstamp(const snd_rawmidi_status_t *status, snd_htimestamp_t *tstamp)
{
assert(status && tstamp);
*tstamp = status->tstamp;

View File

@ -687,7 +687,7 @@ void snd_timer_status_copy(snd_timer_status_t *dst, const snd_timer_status_t *sr
* \param status pointer to #snd_timer_status_t structure
* \return timestamp
*/
struct timeval snd_timer_status_get_timestamp(snd_timer_status_t * status)
snd_htimestamp_t snd_timer_status_get_timestamp(snd_timer_status_t * status)
{
assert(status);
return status->tstamp;