Update of /cvsroot/alsa/alsa-kernel/core
In directory sc8-pr-cvs1:/tmp/cvs-serv15955/core

Modified Files:
        pcm_native.c timer.c 
Log Message:
Improved timer event notification for slave timer instances,
added SND_TIMER_EVENT_M* definitions.


Index: pcm_native.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/core/pcm_native.c,v
retrieving revision 1.48
retrieving revision 1.49
diff -u -r1.48 -r1.49
--- pcm_native.c        28 Feb 2003 16:59:54 -0000      1.48
+++ pcm_native.c        1 Mar 2003 18:56:35 -0000       1.49
@@ -30,6 +30,7 @@
 #include <sound/info.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
+#include <sound/timer.h>
 #include <sound/minors.h>
 
 /*
@@ -585,7 +586,7 @@
        return 0;
 }
 
-static void snd_pcm_trigger_time(snd_pcm_substream_t *substream)
+static void snd_pcm_trigger_tstamp(snd_pcm_substream_t *substream)
 {
        snd_pcm_runtime_t *runtime = substream->runtime;
        if (runtime->trigger_master == NULL)
@@ -593,7 +594,7 @@
        if (runtime->trigger_master == substream) {
                snd_timestamp_now(&runtime->trigger_tstamp, runtime->tstamp_timespec);
        } else {
-               snd_pcm_trigger_time(runtime->trigger_master);
+               snd_pcm_trigger_tstamp(runtime->trigger_master);
                runtime->trigger_tstamp = 
runtime->trigger_master->runtime->trigger_tstamp;
        }
        runtime->trigger_master = NULL;
@@ -668,13 +669,15 @@
 static inline void snd_pcm_post_start(snd_pcm_substream_t *substream, int state)
 {
        snd_pcm_runtime_t *runtime = substream->runtime;
-       snd_pcm_trigger_time(substream);
+       snd_pcm_trigger_tstamp(substream);
        runtime->status->state = SNDRV_PCM_STATE_RUNNING;
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
            runtime->silence_size > 0)
                snd_pcm_playback_silence(substream, ULONG_MAX);
        if (runtime->sleep_min)
                snd_pcm_tick_prepare(substream);
+       if (substream->timer)
+               snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MSTART, 
&runtime->trigger_tstamp);
 }
 
 /**
@@ -703,7 +706,9 @@
 static inline void snd_pcm_post_stop(snd_pcm_substream_t *substream, int state)
 {
        snd_pcm_runtime_t *runtime = substream->runtime;
-       snd_pcm_trigger_time(substream);
+       snd_pcm_trigger_tstamp(substream);
+       if (substream->timer)
+               snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MSTOP, 
&runtime->trigger_tstamp);
        runtime->status->state = state;
        snd_pcm_tick_set(substream, 0);
        wake_up(&runtime->sleep);
@@ -741,15 +746,19 @@
 static inline void snd_pcm_post_pause(snd_pcm_substream_t *substream, int push)
 {
        snd_pcm_runtime_t *runtime = substream->runtime;
-       snd_pcm_trigger_time(substream);
+       snd_pcm_trigger_tstamp(substream);
        if (push) {
                runtime->status->state = SNDRV_PCM_STATE_PAUSED;
+               if (substream->timer)
+                       snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MPAUSE, 
&runtime->trigger_tstamp);
                snd_pcm_tick_set(substream, 0);
                wake_up(&runtime->sleep);
        } else {
                runtime->status->state = SNDRV_PCM_STATE_RUNNING;
                if (runtime->sleep_min)
                        snd_pcm_tick_prepare(substream);
+               if (substream->timer)
+                       snd_timer_notify(substream->timer, 
SNDRV_TIMER_EVENT_MCONTINUE, &runtime->trigger_tstamp);
        }
 }
 
@@ -782,7 +791,9 @@
 static inline void snd_pcm_post_suspend(snd_pcm_substream_t *substream, int state)
 {
        snd_pcm_runtime_t *runtime = substream->runtime;
-       snd_pcm_trigger_time(substream);
+       snd_pcm_trigger_tstamp(substream);
+       if (substream->timer)
+               snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MPAUSE, 
&runtime->trigger_tstamp);
        runtime->status->state = SNDRV_PCM_STATE_SUSPENDED;
        snd_pcm_tick_set(substream, 0);
        wake_up(&runtime->sleep);
@@ -847,7 +858,9 @@
 static inline void snd_pcm_post_resume(snd_pcm_substream_t *substream, int state)
 {
        snd_pcm_runtime_t *runtime = substream->runtime;
-       snd_pcm_trigger_time(substream);
+       snd_pcm_trigger_tstamp(substream);
+       if (substream->timer)
+               snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MCONTINUE, 
&runtime->trigger_tstamp);
        runtime->status->state = runtime->status->suspended_state;
        if (runtime->sleep_min)
                snd_pcm_tick_prepare(substream);

Index: timer.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/core/timer.c,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -r1.28 -r1.29
--- timer.c     1 Mar 2003 14:50:36 -0000       1.28
+++ timer.c     1 Mar 2003 18:56:35 -0000       1.29
@@ -281,7 +281,7 @@
        return timeri;
 }
 
-static int _snd_timer_stop(snd_timer_instance_t * timeri, int keep_flag);
+static int _snd_timer_stop(snd_timer_instance_t * timeri, int keep_flag, enum 
sndrv_timer_event event);
 
 /*
  * close a timer instance
@@ -310,7 +310,7 @@
                list_for_each_safe(p, n, &timeri->slave_list_head) {
                        slave = (snd_timer_instance_t *)list_entry(p, 
snd_timer_instance_t, open_list);
                        spin_lock_irq(&slave_active_lock);
-                       _snd_timer_stop(slave, 1);
+                       _snd_timer_stop(slave, 1, SNDRV_TIMER_EVENT_RESOLUTION);
                        list_del(p);
                        list_add_tail(p, &snd_timer_slave_list);
                        slave->master = NULL;
@@ -343,6 +343,35 @@
        return 0;
 }
 
+static void snd_timer_notify1(snd_timer_instance_t *ti, enum sndrv_timer_event event)
+{
+       snd_timer_t *timer;
+       unsigned long flags;
+       unsigned long resolution = 0;
+       snd_timer_instance_t *ts;
+       struct list_head *n;
+       struct timespec tstamp;
+
+       snd_timestamp_now(&tstamp, 1);
+       snd_assert(event >= SNDRV_TIMER_EVENT_START && event <= 
SNDRV_TIMER_EVENT_PAUSE, return);
+       if (event == SNDRV_TIMER_EVENT_START || event == SNDRV_TIMER_EVENT_CONTINUE)
+               resolution = snd_timer_resolution(ti);
+       if (ti->ccallback)
+               ti->ccallback(ti, SNDRV_TIMER_EVENT_START, &tstamp, resolution);
+       if (ti->flags & SNDRV_TIMER_IFLG_SLAVE)
+               return;
+       timer = ti->timer;
+       if (timer == NULL)
+               return;
+       spin_lock_irqsave(&timer->lock, flags);
+       list_for_each(n, &ti->slave_active_head) {
+               ts = (snd_timer_instance_t *)list_entry(n, snd_timer_instance_t, 
active_list);
+               if (ts->ccallback)
+                       ts->ccallback(ti, event + 100, &tstamp, resolution);
+       }
+       spin_unlock_irqrestore(&timer->lock, flags);
+}
+
 static int snd_timer_start1(snd_timer_t *timer, snd_timer_instance_t *timeri, 
unsigned long sticks)
 {
        list_del(&timeri->active_list);
@@ -385,8 +414,7 @@
                return -EINVAL;
        if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) {
                result = snd_timer_start_slave(timeri);
-               if (timeri->ccallback)
-                       timeri->ccallback(timeri, SNDRV_TIMER_EVENT_START, 
snd_timer_resolution(timeri));
+               snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_START);
                return result;
        }
        timer = timeri->timer;
@@ -397,12 +425,11 @@
        timeri->pticks = 0;
        result = snd_timer_start1(timer, timeri, ticks);
        spin_unlock_irqrestore(&timer->lock, flags);
-       if (timeri->ccallback)
-               timeri->ccallback(timeri, SNDRV_TIMER_EVENT_START, 
snd_timer_resolution(timeri));
+       snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_START);
        return result;
 }
 
-static int _snd_timer_stop(snd_timer_instance_t * timeri, int keep_flag)
+static int _snd_timer_stop(snd_timer_instance_t * timeri, int keep_flag, enum 
sndrv_timer_event event)
 {
        snd_timer_t *timer;
        unsigned long flags;
@@ -437,8 +464,8 @@
        if (!keep_flag)
                timeri->flags &= ~(SNDRV_TIMER_IFLG_RUNNING|SNDRV_TIMER_IFLG_START);
        spin_unlock_irqrestore(&timer->lock, flags);
-       if (timeri->ccallback)
-               timeri->ccallback(timeri, SNDRV_TIMER_EVENT_STOP, 0);
+       if (event != SNDRV_TIMER_EVENT_RESOLUTION)
+               snd_timer_notify1(timeri, event);
        return 0;
 }
 
@@ -453,7 +480,7 @@
        unsigned long flags;
        int err;
 
-       err = _snd_timer_stop(timeri, 0);
+       err = _snd_timer_stop(timeri, 0, SNDRV_TIMER_EVENT_STOP);
        if (err < 0)
                return err;
        timer = timeri->timer;
@@ -486,8 +513,7 @@
        timeri->pticks = 0;
        result = snd_timer_start1(timer, timeri, timer->sticks);
        spin_unlock_irqrestore(&timer->lock, flags);
-       if (timeri->ccallback)
-               timeri->ccallback(timeri, SNDRV_TIMER_EVENT_CONTINUE, 
snd_timer_resolution(timeri));
+       snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_CONTINUE);
        return result;
 }
 
@@ -496,7 +522,7 @@
  */
 int snd_timer_pause(snd_timer_instance_t * timeri)
 {
-       return _snd_timer_stop(timeri, 0);
+       return _snd_timer_stop(timeri, 0, SNDRV_TIMER_EVENT_PAUSE);
 }
 
 /*
@@ -806,6 +832,35 @@
        return snd_timer_unregister(timer);
 }
 
+void snd_timer_notify(snd_timer_t *timer, enum sndrv_timer_event event, struct 
timespec *tstamp)
+{
+       unsigned long flags;
+       unsigned long resolution = 0;
+       snd_timer_instance_t *ti, *ts;
+       struct list_head *p, *n;
+
+       snd_runtime_check(timer->hw.flags & SNDRV_TIMER_HW_SLAVE, return);      
+       snd_assert(event >= SNDRV_TIMER_EVENT_MSTART && event <= 
SNDRV_TIMER_EVENT_MPAUSE, return);
+       spin_lock_irqsave(&timer->lock, flags);
+       if (event == SNDRV_TIMER_EVENT_MSTART || event == SNDRV_TIMER_EVENT_MCONTINUE) 
{
+               if (timer->hw.c_resolution)
+                       resolution = timer->hw.c_resolution(timer);
+               else
+                       resolution = timer->hw.resolution;
+       }
+       list_for_each(p, &timer->active_list_head) {
+               ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, 
active_list);
+               if (ti->ccallback)
+                       ti->ccallback(ti, event, tstamp, resolution);
+               list_for_each(n, &ti->slave_active_head) {
+                       ts = (snd_timer_instance_t *)list_entry(n, 
snd_timer_instance_t, active_list);
+                       if (ts->ccallback)
+                               ts->ccallback(ts, event, tstamp, resolution);
+               }
+       }
+       spin_unlock_irqrestore(&timer->lock, flags);
+}
+
 /*
  * exported functions for global timers
  */
@@ -1008,15 +1063,14 @@
 
 static void snd_timer_user_ccallback(snd_timer_instance_t *timeri,
                                     enum sndrv_timer_event event,
+                                    struct timespec *tstamp,
                                     unsigned long resolution)
 {
        snd_timer_user_t *tu = snd_magic_cast(snd_timer_user_t, timeri->callback_data, 
return);
        snd_timer_tread_t r1;
-       struct timespec tstamp;
 
-       snd_timestamp_now(&tstamp, 1);
        r1.event = event;
-       r1.tstamp = tstamp;
+       r1.tstamp = *tstamp;
        r1.val = resolution;
        spin_lock(&tu->qlock);
        snd_timer_user_append_to_tqueue(tu, &r1);
@@ -1602,6 +1656,7 @@
 EXPORT_SYMBOL(snd_timer_continue);
 EXPORT_SYMBOL(snd_timer_pause);
 EXPORT_SYMBOL(snd_timer_new);
+EXPORT_SYMBOL(snd_timer_notify);
 EXPORT_SYMBOL(snd_timer_global_new);
 EXPORT_SYMBOL(snd_timer_global_free);
 EXPORT_SYMBOL(snd_timer_global_register);



-------------------------------------------------------
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