[pulseaudio-discuss] PA and OS X

Daniel Mack daniel at caiaq.de
Sun Jul 19 12:26:40 PDT 2009


On Sun, Jul 19, 2009 at 07:55:20PM +0300, Tanu Kaskinen wrote:
> la, 2009-07-18 kello 14:05 +0200, Daniel Mack kirjoitti:
> > I've put some pieces together now and what I got is
> > 
> > - a kernel module that loads and unloads fine and offers a virtual
> >   stereo soundcard which can be selected by any CoreAudio application.
> 
> So this provides the interface for native Mac apps to connect to
> pulseaudio. Naming these things would probably be useful. I think "the
> kernel module" and "the kernel module's CoreAudio interface" might be
> appropriate names for this.

It's the kext. That describes it best, I'd say.

> > - a user space interface to share the ring buffers with application so
> >   that audio can be transported in and out.
> 
> What's this again? Is this "the other side" of the kernel module that
> provides the interface that will be used by the component that will
> communicate with the pulseaudio server using libpulse? Could this be
> called "the kernel module's user space interface"?

No, that's actually part of the kext, it's just a part that is not
mandatory for such a kernel module. Hence I noted it seperately. The
correct term for that part is 'IOUserClient'.

> > - a skeleton for an
> >   application that connects to that interface and maps the shared memory
> >   buffers.
> 
> And this is the beginnings of the previously mentioned component that
> uses libpulse? Maybe "the bridge" could be the name for this?

Yes, 'bridge' sounds good. This binary will probably have some other
duties eventually, though. Let's see. Things that come in mind are
supervising the pulseaudio daemon (stopping/starting/reconfiguring it
...). But that's something to be done much later.

> > 2. The CoreAudio backend needs a clock for the internal ring buffer
> > motor. There are two different possible aproaches. Either the audio
> > driver clocks itself using a timer and then is the clock master to the
> > user space. Or the user space appliction obtains the clock from PA and
> > clocks the kernel module. I'm sure there is a clearly preferred way to
> > go for PA, but I'm uncertain which one that is. And how is that handled
> > for both directions?
> 
> Sinks and sources provide the clocks in PA. That means the original
> clock source is in most cases the sound card. The clients (in this case
> the bridge) register callbacks that are called when the server wants
> more data (playback) or when there is some data available to read
> (record). Did this clear things at all? Hopefully the CoreAudio API
> matches this model so you don't need to resort to any complicated tricks

No, that's fine.

I was just considering an example like the following:

 - a client provides a stream recorded from an audio input which has its
   own clock
 - this stream is sent to the 'bridge' (let's say, over the network) for
   playback (which means it is provided as a virtual record stream to
   CoreAudio applications).
 - if the 'kext' would now be able to take any amount of audio material
   and hence sync to the original clock, that would be good.
 - if the 'kext' clocks itself, there would be some resampling needed in
   the middle. Which is not as good.

That whole model does of course not work in case the original data is
not served by a soundcard but - let's say - from a file. In that case,
having a clock supplied at the sink whould be mandatory.

Can you follow? ;)

So what I mean is: there could/should be a flag for each stream
identifing whether there is a clock supplied on it already. We could
then take that into account for the kernel module and switch the
clocking direction if necessary. But I don't know PA, so I can't say if
such scenarious are things that have been thought of at all.

> - so if CoreAudio applications communicate with the kernel module using
> callbacks, the calls can be hopefully be just propagated from the bridge
> to the kernel module and from there to the application.

Yes, more or less. It's not as easy though, because CoreAudio has a mix
buffer inbetween to serve different applications with different buffer
sizes. Hence, the kext is likely to be served with overlapping buffers,
especially when new clients connect. So there must be some abstraction
that breaks things up into chunks we send to the bridge. That will need
some consideration.

> If you haven't done so yet, read the libpulse documentation at
> http://0pointer.de/lennart/projects/pulseaudio/doxygen/ (from the front
> page go to the Asynchronous API section).

Jep, I clicked thru that a little but was missing some principle
information about the basics. But maybe I wasn't reading it patiently
enough ;)

Daniel




More information about the pulseaudio-discuss mailing list