Subject: Re: [linux-audio-dev] Still I cannot understand why...
From: Paul Davis (pbd_AT_Op.Net)
Date: Sat Dec 15 2001 - 23:55:07 EET
>> ALSA poll interface is (necessarily) a bit complex. but it would still
>> be a huge step to have applications move to this model rather than the
>> block-on-read/write one that so many do these days.
>
>Or is it? I think the read/write interface suits well for implementing
>wait()-then-operate(). With a blocking read() application says, "wait
>until next hw-interrupt, then copy data to my buffer area". With write(),
>"wait until next hw-interrupt, copy data from my buffer area". So it's
>just as good as using poll/select.
well, there are 2 problems.
1) it actually means that they work in the wrong order:
generate data
wait until there is space (i.e. next h/w interrupt)
copy data from my buffer area
admittedly, in the long haul, this just means they are 1 cycle or
"period" to use the ALSA phrase (actually, not quite: this is
determined by avail_min in ALSA) behind (or ahead). but its
conceptually wrong - their code is being driven by the work their
program has done rather than the work that the graph needs
them to do. maybe this is nitpicking, but it seems like an
important mental switch.
with X apps, you don't think of it as:
do a bunch of stuff
wait till the X server is ready to receive the data
deliver info+requests to the server
but rather
wait for next event
process event (possibly sending requests + info back to server)
i have a feeling that this is important. its important because
it means that there is no guarantee that the program will have
data ready when it is supposed to. even if it could meet the RT
timelines, it may be doing something else when the interrupt
comes in. it could still get its data delivered in time
to meet the h/w constraint, but not to satisfy the graph.
2) the second problem is that the read/write interface doesn't
restrict people to working in chunks of audio that match the
period/cycle/avail_min numbers. this then leads to them both having
worse latency, with all that implies.
again, to go back to the X model: you really don't think in X about
read/write to the server, even though at a fundamental level, that
is what is going on. the same is true for Win32 and other
GUIs. instead, you sense yourself driven by events delivered by the
GUI, and you process them as they arrive rather than trying to
"read ahead", because there is no way to do that (i know X has an
event queue with XPeekEvent, but thats not really what i mean
here).
if programs really did this:
set avail_min = period_size
while (read (handle, input, period_size)) {
... compute output ...
write (handle, output, period_size);
}
then i agree that to all effects and purposes this is really
equivalent to the poll-driven callback-centered system. but in reality
we have:
1) pure playback programs:
while (!eof) {
read (file, data, chunksize);
... possibly massage data ...
write (handle, data, chunksize);
}
2) pure capture programs:
while (!some_condition) {
read (handle, data, chunksize);
... possibly massage data ...
write (file, data, chunksize);
}
Neither of these designs is appropriate as far as i can see for a
synchronous execution system. This points to the final problem with
the read/write API: it encourages mono-threading. this works for a
number of simple programs, but in an low latency RT graph, it will
almost invariably break.
>The biggest difference is probably the ability to wait on multiple device
>handles, but if we have a syncronously working system, waiting on one
>device is enough (--> blocking call on other devices will never actually
>block unless an error has occured). And from reading your recent messages
>on alsa-devel about the trident driver, polling on multiple handles
>doesn't seem completely carefree either. ;)
its a total ugly mess. but it works now in the JACK code. tim goetze
is doing something very similar in his code too. but its silly to have
lots of programs (mostly those doing full duplex) duplicating all this
complexity, i think. it can go in a library (alsa-lib) or in a server
(e.g. jack).
>Hmm, could gstreamer be used as the lower-priority frontend server? Does
>it support dynamic client registration?
gstreamer is entirely and 100% about internal streaming. its a toolkit
to build streams within an application, nothing more (or less). there
is no "gstreamer" program as such.
--p
This archive was generated by hypermail 2b28 : Sat Dec 15 2001 - 23:51:09 EET