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

Reply via email to