On Fri, 19.06.09 01:23, Fons Adriaensen (fons(a)kokkinizita.net) wrote:
On Fri, Jun 19, 2009 at 12:33:24AM +0200, Lennart Poettering wrote:
This is basically what happens. However in PA we
are much more dynamic
than JACK generally is. JACK clients generally just have a single
stream of PCM data which is passed between the RT and the non-RT
threads. However, PA is not as simple as that. We have streams coming
and going all the time, our control data changes. That's why we need
to change our internal pipeline and other shared meta data often while
streaming. In JACK the answer to pipeline changes is considering them
something that doesn't normally happen and when it happens then
drop-outs are fine. That doesn't really work for PA. If we'd drop out
each time someone triggeres a stupid event sound to be played then uh,
that would make people very unhappy. So, in PA that line is blurred
and we do change our pipeline while streaming, which means
communication between the control and the RT threads needs to go
beyond simple passing of PCM data. We need to be able to make changes
to the control stuff too. And some of that we do in asynchronous
fashion, by asynchronously triggering something in the RT loop to be
executed when the RT loop thinks it's a good time and verified that a
bit of is timeslace is available.
What I don't understand is this:
- You wait, e.g. using frames_since_cycle_start(), until near the
end of the current period, then give up if nothing wants your
attention.
No. I don't "wait" and not for the end of the current period. All I do
is set a maximum limit to how much non-IO work I do in the RT loop per
iteration.
Uh, I actually admit that the pseudocode I posted in
http://lists.linuxaudio.org/pipermail/linux-audio-dev/2009-June/023380.html
is completely broken. Sorry for the confusion. The one I was describing down on
http://lists.linuxaudio.org/pipermail/linux-audio-dev/2009-June/023370.html
was correct.
So, another try:
<snip>
for (;;) {
n = jack_client_wait()
process(n);
jack_cycle_signal();
while (jack_frames_since_cycle_start() < threshold) {
if (no_private_events_to_process())
break;
process_one_of_my_private_events();
}
}
</snip>
The early exit in the inner loop when there's nothing to do (which is
the usual case) is the key point here, I guess.
Sorry for the confusion.
Lennart
--
Lennart Poettering Red Hat, Inc.
lennart [at] poettering [dot] net
http://0pointer.net/lennart/ GnuPG 0x1A015CC4