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