On Wed, 27 Nov 2002, James Courtier-Dutton wrote:

> Paul Davis wrote:
> 
> >  
> >
> >>>the APIs that are used to write almost all audio software code in 
> >>>production these days all use a callback model. 
> >>>      
> >>>
> >>Sorry for questioning this statement. Of course we all don't have any statisti
> >>cal data but
> >>you miss what I see as the majority of applications that use audio devices:
> >>
> >>1) games
> >>2) media players
> >>3) GUI sounds (i.e. accessibility)
> >>    
> >>
> >
> >this is a fair point. i apologize. i have my head so far inside the
> >"audio software for musicians" box that i tend to fail to see such
> >applications :)
> >
> >however, the very fact that the applications developers of such
> >programs really don't know much (if anything) about audio programming,
> >and probably don't want to know much about it either, suggests that an
> >API like ALSA which exposes the full HAL is probably a mistake. again,
> >i consider PortAudio a vastly preferable solution.
> >
> >  
> >
> I would like to point out that a "callback" api would work just as well 
> as an open/write/close api for
> 
> 1) games
> 2) media players
> 3) GUI sounds (i.e. accessibility)
> 
> I have to agree with Paul on the fact that a "callback" approach is really the ONLY 
>real option.
> Here is my reasoning: -
> 1) My perspective is from "(2) Media players" and not "Pro-Audio"
> 2) Sound Hardware tends to have very small buffers.
> 3) For nice sounding audio, these buffers should never run dry. I.E. No XRUNs.
> 4) A open/write/close api will never ever be able to guarantee no XRUNs, as it has 
>no control on when it will get scheduling time to do the next write.
> 5) With a "callback" approach, the kernel would be notified by the sound hardware 
>that it was ready for new samples, the kernel could then adjust the scheduler, so 
>that the "callback" function was called ASAP.
> The "callback" function then only has to decide which samples to give. If the 
>"callback" function could receive a "delay" value from the sound hardware at each 
>callback, a media player would then have all the information it needed to do full 
>audio/video sync.

Sorry, it's not as easy as you've described. It's not possible to invoke
any user code from the kernel code directly. There is a scheduler which is
informed that a task has been woken up. It depends on scheduler when the
task is really invoked. It's quite same as for the r/w model where the
application is notified over poll that something occured.

> 6) I don't need "sample sync", but I do NEED "callback" based api to provide me with 
>"no XRUNs".

I don't think that there is some difference. If the scheduler don't give 
you enough time, the audio stream is somehow broken on all architectures.

> Summary: - 
> The only way to cure XRUN problems is with a "callback" based api.
> All application that currently use open/write/close apis, can just as easily use a 
>"callback" api.

Let's go and see the implementation:

The callback model is good for perfect sync between applications. It can 
do (and does) chaining of more sources, arbitrating (removing invalid 
sources) and so on. It is simply something "over" the audio HAL. If it 
really helps, it's a different point.

The discussed difference (a few months ago) was in a count of the task 
context switches.

With jack, you have these context switches (daemon and two applications 
mixed together) for one period of samples (* means a context switch):

jackd -*> app1 -*> app2 -*> jackd -> soundcard

With r/w model and a sample mixing server implemented in the user space, 
you can get this for one period of samples:

mserver -> soundcard
        -*(ring buffer does not contain enough samples)> app1
        -*(ring buffer does not contain enough samples)> app2

In real real-time setup, there will be two periods (thus app1 and app2) 
will be woken up all times. So, in real world the context switches are for 
one period of samples:

mserver -*> app1 -*> app2   or
mserver -*> app2 -*> app1

Note: mserver implementation uses same assumptions as jack (or any other
callback model). The ring buffers are shared between app and mserver and
the period of samples is a constant. The playback / capture pointers are
incrementing by the period size steps. Thus there is no need to commit 
result directly back to the mserver. mserver will be woken up by the 
kernel scheduler when next poll() event occurs (on next period boundary).

Ok, it's only simple example, that there are more solutions than Paul 
suggests. I fully agree, that the callback model is suitable for the 
perfect synchronization among more applications. Also, imagine that
mserver is not using a soundcard as output device, but jackd. So, 
applications using r/w can use benefits of jackd (of course, there will be 
one more period of samples buffered, but who will care when the start is 
synchronized?).

In my brain, there is also totaly different solution with the zero context 
switching overhead - sharing the soundcard DMA buffer among more 
applications. There is only one problem: snd_pcm_rewind() implementation 
cannot be perfect, because of wrapping added sample values (we lose 
information which cannot be recovered). The question is, if it's a fatal 
problem.

Let's discuss these things. Hopefully, I'll get some time to implement at 
least the mserver functionality.

                                                Jaroslav

-----
Jaroslav Kysela <[EMAIL PROTECTED]>
Linux Kernel Sound Maintainer
ALSA Project, SuSE Labs



-------------------------------------------------------
This SF.net email is sponsored by: Get the new Palm Tungsten T 
handheld. Power & Color in a compact size! 
http://ads.sourceforge.net/cgi-bin/redirect.pl?palm0002en
_______________________________________________
Alsa-devel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/alsa-devel

Reply via email to