Update of /cvsroot/alsa/alsa-kernel/core
In directory sc8-pr-cvs1:/tmp/cvs-serv3838/core
Modified Files:
pcm.c pcm_lib.c pcm_native.c timer.c
Log Message:
Updated timestamps - use 'struct timespec' now.
Enhanced timer read API (events + timestamps).
Index: pcm.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/core/pcm.c,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -r1.25 -r1.26
--- pcm.c 28 Feb 2003 14:29:18 -0000 1.25
+++ pcm.c 28 Feb 2003 16:59:53 -0000 1.26
@@ -386,10 +386,10 @@
return;
}
snd_iprintf(buffer, "state: %s\n", snd_pcm_state_name(status.state));
- snd_iprintf(buffer, "trigger_time: %ld.%06ld\n",
- status.trigger_tstamp.tv_sec, status.trigger_tstamp.tv_usec);
- snd_iprintf(buffer, "tstamp : %ld.%06ld\n",
- status.tstamp.tv_sec, status.tstamp.tv_usec);
+ snd_iprintf(buffer, "trigger_time: %ld.%09ld\n",
+ status.trigger_tstamp.tv_sec, status.trigger_tstamp.tv_nsec);
+ snd_iprintf(buffer, "tstamp : %ld.%09ld\n",
+ status.tstamp.tv_sec, status.tstamp.tv_nsec);
snd_iprintf(buffer, "delay : %ld\n", status.delay);
snd_iprintf(buffer, "avail : %ld\n", status.avail);
snd_iprintf(buffer, "avail_max : %ld\n", status.avail_max);
Index: pcm_lib.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/core/pcm_lib.c,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -r1.32 -r1.33
--- pcm_lib.c 28 Feb 2003 14:29:19 -0000 1.32
+++ pcm_lib.c 28 Feb 2003 16:59:53 -0000 1.33
@@ -137,7 +137,7 @@
old_hw_ptr = runtime->status->hw_ptr;
pos = substream->ops->pointer(substream);
if (runtime->tstamp_mode & SNDRV_PCM_TSTAMP_MMAP)
- snd_timestamp_now((snd_timestamp_t*)&runtime->status->tstamp);
+ snd_timestamp_now((snd_timestamp_t*)&runtime->status->tstamp,
runtime->tstamp_timespec);
#ifdef CONFIG_SND_DEBUG
if (pos >= runtime->buffer_size) {
snd_printk(KERN_ERR "BUG: stream = %i, pos = 0x%lx, buffer size =
0x%lx, period size = 0x%lx\n", substream->stream, pos, runtime->buffer_size,
runtime->period_size);
@@ -198,7 +198,7 @@
old_hw_ptr = runtime->status->hw_ptr;
pos = substream->ops->pointer(substream);
if (runtime->tstamp_mode & SNDRV_PCM_TSTAMP_MMAP)
- snd_timestamp_now((snd_timestamp_t*)&runtime->status->tstamp);
+ snd_timestamp_now((snd_timestamp_t*)&runtime->status->tstamp,
runtime->tstamp_timespec);
#ifdef CONFIG_SND_DEBUG
if (pos >= runtime->buffer_size) {
snd_printk(KERN_ERR "BUG: stream = %i, pos = 0x%lx, buffer size =
0x%lx, period size = 0x%lx\n", substream->stream, pos, runtime->buffer_size,
runtime->period_size);
Index: pcm_native.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/core/pcm_native.c,v
retrieving revision 1.47
retrieving revision 1.48
diff -u -r1.47 -r1.48
--- pcm_native.c 28 Feb 2003 14:13:53 -0000 1.47
+++ pcm_native.c 28 Feb 2003 16:59:54 -0000 1.48
@@ -514,9 +514,9 @@
if (runtime->tstamp_mode & SNDRV_PCM_TSTAMP_MMAP)
status->tstamp = runtime->status->tstamp;
else
- snd_timestamp_now(&status->tstamp);
+ snd_timestamp_now(&status->tstamp, runtime->tstamp_timespec);
} else
- snd_timestamp_now(&status->tstamp);
+ snd_timestamp_now(&status->tstamp, runtime->tstamp_timespec);
status->appl_ptr = runtime->control->appl_ptr;
status->hw_ptr = runtime->status->hw_ptr;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
@@ -591,7 +591,7 @@
if (runtime->trigger_master == NULL)
return;
if (runtime->trigger_master == substream) {
- snd_timestamp_now(&runtime->trigger_tstamp);
+ snd_timestamp_now(&runtime->trigger_tstamp, runtime->tstamp_timespec);
} else {
snd_pcm_trigger_time(runtime->trigger_master);
runtime->trigger_tstamp =
runtime->trigger_master->runtime->trigger_tstamp;
@@ -2165,6 +2165,14 @@
return put_user(SNDRV_PCM_VERSION, (int *)arg) ? -EFAULT : 0;
case SNDRV_PCM_IOCTL_INFO:
return snd_pcm_info_user(substream, (snd_pcm_info_t *) arg);
+ case SNDRV_PCM_IOCTL_TSTAMP:
+ {
+ int xarg;
+ if (get_user(xarg, (int *) arg))
+ return -EFAULT;
+ substream->runtime->tstamp_timespec = xarg ? 1 : 0;
+ return 0;
+ }
case SNDRV_PCM_IOCTL_HW_REFINE:
return snd_pcm_hw_refine_user(substream, (snd_pcm_hw_params_t *) arg);
case SNDRV_PCM_IOCTL_HW_PARAMS:
Index: timer.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/core/timer.c,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -r1.25 -r1.26
--- timer.c 11 Feb 2003 17:55:28 -0000 1.25
+++ timer.c 28 Feb 2003 16:59:54 -0000 1.26
@@ -51,6 +51,7 @@
typedef struct {
snd_timer_instance_t *timeri;
+ int tread; /* enhanced read with timestamps and events */
unsigned long ticks;
unsigned long overrun;
int qhead;
@@ -58,7 +59,9 @@
int qused;
int queue_size;
snd_timer_read_t *queue;
+ snd_timer_tread_t *tqueue;
spinlock_t qlock;
+ unsigned long last_resolution;
wait_queue_head_t qchange_sleep;
struct fasync_struct *fasync;
} snd_timer_user_t;
@@ -938,9 +941,17 @@
{
snd_timer_user_t *tu = snd_magic_cast(snd_timer_user_t, timeri->callback_data,
return);
snd_timer_read_t *r;
- int _wake = 0;
+ int prev;
spin_lock(&tu->qlock);
+ if (tu->queue_size > 0) {
+ prev = tu->qtail == 0 ? tu->queue_size - 1 : tu->qtail - 1;
+ r = &tu->queue[prev];
+ if (r->resolution == resolution) {
+ r->ticks += ticks;
+ goto __wake;
+ }
+ }
if (tu->qused >= tu->queue_size) {
tu->overrun++;
} else {
@@ -949,15 +960,60 @@
r->resolution = resolution;
r->ticks = ticks;
tu->qused++;
- _wake++;
}
+ __wake:
spin_unlock(&tu->qlock);
- if (_wake) {
- kill_fasync(&tu->fasync, SIGIO, POLL_IN);
- wake_up(&tu->qchange_sleep);
+ kill_fasync(&tu->fasync, SIGIO, POLL_IN);
+ wake_up(&tu->qchange_sleep);
+}
+
+static void snd_timer_user_append_to_tqueue(snd_timer_user_t *tu, snd_timer_tread_t
*tread)
+{
+ if (tu->qused >= tu->queue_size) {
+ tu->overrun++;
+ } else {
+ memcpy(&tu->queue[tu->qtail++], tread, sizeof(*tread));
+ tu->qused++;
}
}
+static void snd_timer_user_tinterrupt(snd_timer_instance_t *timeri,
+ unsigned long resolution,
+ unsigned long ticks)
+{
+ snd_timer_user_t *tu = snd_magic_cast(snd_timer_user_t, timeri->callback_data,
return);
+ snd_timer_tread_t *r, r1;
+ struct timespec tstamp;
+ int prev;
+
+ snd_timestamp_now(&tstamp, 1);
+ spin_lock(&tu->qlock);
+ if (tu->last_resolution != resolution) {
+ r1.event = SNDRV_TIMER_EVENT_RESOLUTION;
+ r1.tstamp = tstamp;
+ r1.val = resolution;
+ snd_timer_user_append_to_tqueue(tu, &r1);
+ tu->last_resolution = resolution;
+ }
+ if (tu->queue_size > 0) {
+ prev = tu->qtail == 0 ? tu->queue_size - 1 : tu->qtail - 1;
+ r = &tu->tqueue[prev];
+ if (r->event == SNDRV_TIMER_EVENT_TICK) {
+ r->tstamp = tstamp;
+ r->val += ticks;
+ goto __wake;
+ }
+ }
+ r1.event = SNDRV_TIMER_EVENT_TICK;
+ r1.tstamp = tstamp;
+ r1.val = ticks;
+ snd_timer_user_append_to_tqueue(tu, &r1);
+ __wake:
+ spin_unlock(&tu->qlock);
+ kill_fasync(&tu->fasync, SIGIO, POLL_IN);
+ wake_up(&tu->qchange_sleep);
+}
+
static int snd_timer_user_open(struct inode *inode, struct file *file)
{
snd_timer_user_t *tu;
@@ -1120,8 +1176,23 @@
tselect.id.dev_sclass = SNDRV_TIMER_SCLASS_APPLICATION;
if ((tu->timeri = snd_timer_open(str, &tselect.id, current->pid)) == NULL)
return -ENODEV;
+
+ if (tu->tread) {
+ tu->tqueue = (snd_timer_tread_t *)kmalloc(tu->queue_size *
sizeof(snd_timer_tread_t), GFP_KERNEL);
+ if (tu->tqueue == NULL) {
+ snd_timer_close(tu->timeri);
+ return -ENOMEM;
+ }
+ } else {
+ tu->queue = (snd_timer_read_t *)kmalloc(tu->queue_size *
sizeof(snd_timer_read_t), GFP_KERNEL);
+ if (tu->queue == NULL) {
+ snd_timer_close(tu->timeri);
+ return -ENOMEM;
+ }
+ }
+
tu->timeri->flags |= SNDRV_TIMER_IFLG_FAST;
- tu->timeri->callback = snd_timer_user_interrupt;
+ tu->timeri->callback = tu->tread ? snd_timer_user_tinterrupt :
snd_timer_user_interrupt;
tu->timeri->callback_data = (void *)tu;
return 0;
}
@@ -1229,6 +1300,7 @@
snd_assert(tu->timeri != NULL, return -ENXIO);
snd_timer_stop(tu->timeri);
tu->timeri->lost = 0;
+ tu->last_resolution = 0;
return (err = snd_timer_start(tu->timeri, tu->ticks)) < 0 ? err : 0;
}
@@ -1264,6 +1336,17 @@
return put_user(SNDRV_TIMER_VERSION, (int *)arg) ? -EFAULT : 0;
case SNDRV_TIMER_IOCTL_NEXT_DEVICE:
return snd_timer_user_next_device((snd_timer_id_t *)arg);
+ case SNDRV_TIMER_IOCTL_TREAD:
+ {
+ int xarg;
+
+ if (tu->timeri) /* too late */
+ return -EBUSY;
+ if (get_user(xarg, (int *) arg))
+ return -EFAULT;
+ tu->tread = xarg ? 1 : 0;
+ return 0;
+ }
case SNDRV_TIMER_IOCTL_SELECT:
return snd_timer_user_tselect(file, (snd_timer_select_t *)arg);
case SNDRV_TIMER_IOCTL_INFO:
@@ -1297,12 +1380,13 @@
static ssize_t snd_timer_user_read(struct file *file, char *buffer, size_t count,
loff_t *offset)
{
snd_timer_user_t *tu;
- long result = 0;
+ long result = 0, unit;
int err = 0;
tu = snd_magic_cast(snd_timer_user_t, file->private_data, return -ENXIO);
+ unit = tu->tread ? sizeof(snd_timer_tread_t) : sizeof(snd_timer_read_t);
spin_lock_irq(&tu->qlock);
- while (count - result >= sizeof(snd_timer_read_t)) {
+ while (count - result >= unit) {
while (!tu->qused) {
wait_queue_t wait;
@@ -1331,15 +1415,22 @@
if (err < 0)
break;
- if (copy_to_user(buffer, &tu->queue[tu->qhead++],
sizeof(snd_timer_read_t))) {
- err = -EFAULT;
- break;
+ if (tu->tread) {
+ if (copy_to_user(buffer, &tu->tqueue[tu->qhead++],
sizeof(snd_timer_tread_t))) {
+ err = -EFAULT;
+ break;
+ }
+ } else {
+ if (copy_to_user(buffer, &tu->queue[tu->qhead++],
sizeof(snd_timer_read_t))) {
+ err = -EFAULT;
+ break;
+ }
}
tu->qhead %= tu->queue_size;
- result += sizeof(snd_timer_read_t);
- buffer += sizeof(snd_timer_read_t);
+ result += unit;
+ buffer += unit;
spin_lock_irq(&tu->qlock);
tu->qused--;
-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
Alsa-cvslog mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/alsa-cvslog