This patch adds async support to pulse and jack plugins. I tested only jack plugin, so far. The pulse might be buggy due to possible races.
Anyway, as you can see, the implementation is pretty simple for a plugin with a parallel thread like jack or pulse. For other cases like oss plugin, it might be more difficult.
Takashi
--- diff -r 0833aa56dbe2 jack/pcm_jack.c --- a/jack/pcm_jack.c Tue May 13 13:16:06 2008 +0200 +++ b/jack/pcm_jack.c Tue May 20 13:07:57 2008 +0200 @@ -48,6 +48,8 @@
jack_port_t **ports; jack_client_t *client; + + int call_async; } snd_pcm_jack_t;
static void snd_pcm_jack_free(snd_pcm_jack_t *jack) @@ -90,6 +92,18 @@ *revents = pfds[0].revents; return 0; } + +#if SND_PCM_IOPLUG_VERSION >= 0x010002 +static int snd_pcm_jack_async(snd_pcm_ioplug_t *io, int sig, pid_t pid) +{ + snd_pcm_jack_t *jack = io->private_data; + if (sig < 0) + jack->call_async = 0; + else + jack->call_async = 1; + return 0; +} +#endif
static snd_pcm_sframes_t snd_pcm_jack_pointer(snd_pcm_ioplug_t *io) { @@ -145,6 +159,11 @@
write(jack->fd, buf, 1); /* for polling */
+#if SND_PCM_IOPLUG_VERSION >= 0x010002 + /* call async handlers if needed */ + if (jack->call_async) + snd_pcm_ioplug_call_async_handlers(io); +#endif return 0; }
@@ -238,6 +257,9 @@ .pointer = snd_pcm_jack_pointer, .prepare = snd_pcm_jack_prepare, .poll_revents = snd_pcm_jack_poll_revents, +#if SND_PCM_IOPLUG_VERSION >= 0x010002 + .async = snd_pcm_jack_async, +#endif };
#define ARRAY_SIZE(ary) (sizeof(ary)/sizeof(ary[0])) @@ -372,6 +394,9 @@ jack->io.poll_fd = fd[1]; jack->io.poll_events = POLLIN; jack->io.mmap_rw = 1; +#if SND_PCM_IOPLUG_VERSION >= 0x010002 + jack->io.no_signal_async = 1; +#endif
err = snd_pcm_ioplug_create(&jack->io, name, stream, mode); if (err < 0) { diff -r 0833aa56dbe2 pulse/pcm_pulse.c --- a/pulse/pcm_pulse.c Tue May 13 13:16:06 2008 +0200 +++ b/pulse/pcm_pulse.c Tue May 20 13:07:57 2008 +0200 @@ -45,6 +45,8 @@ pa_sample_spec ss; unsigned int frame_size; pa_buffer_attr buffer_attr; + + int call_async; } snd_pcm_pulse_t;
static void update_ptr(snd_pcm_pulse_t *pcm) @@ -365,6 +367,11 @@ assert(pcm->p);
pulse_poll_activate(pcm->p); + +#if SND_PCM_IOPLUG_VERSION >= 0x010002 + if (pcm->call_async) + snd_pcm_ioplug_call_async_handlers(&pcm->io); +#endif }
static void stream_underrun_cb(pa_stream *p, void *userdata) { @@ -446,6 +453,18 @@
return err; } + +#if SND_PCM_IOPLUG_VERSION >= 0x010002 +static int pulse_pcm_async(snd_pcm_ioplug_t *io, int sig, pid_t pid) +{ + snd_pcm_pulse_t *pcm = io->private_data; + if (sig < 0) + pcm->call_async = 0; + else + pcm->call_async = 1; + return 0; +} +#endif
static int pulse_prepare(snd_pcm_ioplug_t *io) { @@ -620,6 +639,9 @@ .prepare = pulse_prepare, .hw_params = pulse_hw_params, .close = pulse_close, +#if SND_PCM_IOPLUG_VERSION >= 0x010002 + .async = pulse_pcm_async, +#endif };
@@ -635,6 +657,9 @@ .prepare = pulse_prepare, .hw_params = pulse_hw_params, .close = pulse_close, +#if SND_PCM_IOPLUG_VERSION >= 0x010002 + .async = pulse_pcm_async, +#endif };
@@ -746,6 +771,9 @@ pcm->io.poll_fd = -1; pcm->io.poll_events = 0; pcm->io.mmap_rw = 0; +#if SND_PCM_IOPLUG_VERSION >= 0x010002 + pcm->io.no_signal_async = 1; +#endif pcm->io.callback = stream == SND_PCM_STREAM_PLAYBACK ? &pulse_playback_callback : &pulse_capture_callback; pcm->io.private_data = pcm;