[pulseaudio-discuss] PA and OS X

Daniel Mack daniel at caiaq.de
Mon Jul 20 03:41:05 PDT 2009


On Mon, Jul 20, 2009 at 02:22:44AM +0300, Tanu Kaskinen wrote:
> su, 2009-07-19 kello 21:26 +0200, Daniel Mack kirjoitti:
> > 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'.
> 
> I understood that it's part of the kext. But what's its role? (Yes, you
> explained it above, but I do not understand the explanation.) Is it the
> interface that the bridge uses to pass data to/from the kext?

Yes, exactly. This the high level API the Darwin kernel uses to
communicate with the user space.

> > I was just considering an example like the following:
> > 
> >  - a client provides a stream recorded from an audio input which has its
> >    own clock
> 
> I understand this so that the client (a CoreAudio application) records
> stuff from somewhere and simultaneously plays the recorded audio to the
> kext. Did I understand correctly?

No. The example is somewhat confusing, I must admit.

- A linux box plays something by looping the hardware input to the PA
  sink backend.
- It uses the local PA server for playback.
- The PA server in configured to send that audio over the network to a
  MacOSX box, is caught there by the 'bridge' and sent to the 'kext'.
- The kext offers that stream as virtual record source to CoreAudio
  applications which then do with it whatever they want.

A little clearer now? :)

That is all straight forward, just the question remains who's clocking
the system in this particular case.

> >  - 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.
> 
> This looks to me like the kext would offer CoreAudio applications a
> push-based playback api. The pulseaudio api is pull-based, as I
> explained in the previous mail. Does the kext possibly offer both push-
> and pull-based apis? Anyway, combining the push-based api with
> pulseaudio's pull-based api requires the kext to maintain a buffer from
> which the bridge reads when it wants to and to which the application
> writes when it wants to. If the application should be able to always
> push data without blocking (since it has its own clock), you need to do
> resampling here.

On the user space side, CoreAudio is pull-IO all the way. From the
kernel space though, everything is implemented with shared memory and
some tricks to sync the read and write heads. In particular, a driver
allocates a piece of memory for each stream to be used as ring buffer.
Whenever the driver sees the ring turning over, it calls a method to
take a timestamp which needs to be as precise as possible. The timestamp
information is taken as hint for CoreAudio's core for syncing to the
current sample position as close as possible.

So whenever there is new data available from the sound device (no matter
if it's a piece of hardware or virtual), data is written to the ring
buffer and the internal sample pointer is enhanced. That's it. So it
doesn't really match any of the classical pull or push APIs, it's merely
meant to be as easy as possible to use for read hardware drivers.

I'll have to find a way to adopt that model to what we need for our
virtual sources and sinks.


> > 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.
> 
> A PA sink always provides a clock. Well, some kind of a clock anyway - I
> think the file sink asks for more data as fast as it can write to the
> disk. (But I believe the file sink shouldn't be used for anything
> serious, and AFAIK in practice it isn't really used for anything
> non-serious either.)

Ok, that limits our possibilties a little then.

> > 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.
> 
> This "clock-at-both-ends" problem is probably very familiar to anyone
> who has been reading this list for a while :) It comes up whenever
> someone wants to hook a source directly to a sink. And pulseaudio
> doesn't have a good solution for that yet - the clock is always at the
> sink/source and nowhere else. I don't think this is going to change
> anytime soon, so you're pretty much out of luck. And resampling couldn't
> be avoided anyway, the only question is where it should be done at.

In the example above it could. But I'll postpone that that for now and
let the kext find its own velocity.

Thanks for your answers,
Daniel



More information about the pulseaudio-discuss mailing list