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
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
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);
/*
* 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>
*
*
* *
****************************************************************************/
-#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,
* *
*****************************************************************************/
-#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;
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 */
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 */
};
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),
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),
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 */
* 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,
};
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 */
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),
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 */
#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 */
} bytes;
struct sndrv_aes_iec958 iec958;
} value; /* RO */
- unsigned char reserved[128];
+ struct timespec timestamp;
+ unsigned char reserved[128-sizeof(struct timespec)];
};
enum {
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);
<confdir:pcm/front.conf>
EMU10K1.pcm.front.0 {
- @args [ CARD ]
+ @args [ CARD ]
@args.CARD {
type string
}
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
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);
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;
}
/**
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;
}
/**
*/
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,
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 */
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;
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;
{
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)
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;
}
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;
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;
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;
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;
}
{
snd_pcm_jack_t *jack = pcm->private_data;
unsigned int i;
+ struct timeval tv;
assert(jack->state == SND_PCM_STATE_PREPARED);
}
}
+ 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;
#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;
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;
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;
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;
}
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;
{
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,
* \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;
* \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;