Hi Guys

Coming in very late on this but just wanted to add my two cents...

Roger Dannenberg wrote:
> I'm not totally sure about the proper way to get audio output time from
> PortAudio

The intended way is using:

timeInfo->outputBufferDacTime

> and we recently upgraded Audacity to use a more experimental
> version of PortAudio because an earlier version we had been using did
> not have audio output time implemented as well. I don't know what
> systems and API's support accurate audio output time.

With CoreAudio, the system provides information which can be (relatively) 
easily mapped to timeInfo->outputBufferDacTime. Sometime last year I made 
some changes to PA that make this work better on OSX than the previous 
implementation.

On Windows there are in-general no specific APIs to get accurate time 
information. DS has a buffer position API but it is known to be extremely 
unreliable.

In most cases PA does something like:

timeInfo->outputBufferDacTime = callbackInvocationTime + 
knownBufferingLatency;

This is, of course, an approximation to this:

timeInfo->outputBufferDacTime = idealCallbackInvocationTime + allLatency;

callbackInvocationTime = idealCallbackInvocationTime + 
osSignallingAndSchedulingJitter;

and

allLatency = knownBufferingLatency + unknownBufferingLatency + dacLatency;

So the accuracy of timeInfo->outputBufferDacTime is dependent on two things:

1. OS scheduling jitter in callbackInvocationTime

2. Availability of accurate knownBufferingLatency information.

Note that if the OS has a mixer (like Windows kmixer) it may perform 
internal "buffer size adaption" and that makes the 
osSignallingAndSchedulingJitter even more complex since it may include 
periodic buffer adaption delay offset too.


In my experience, best-cast accuracy of callbackInvocationTime is about 
400us on OSX, and somewhat higher on Windows (800us?). When using 
DirectSound or or WMMW, or some ASIO drivers (eg ASIO4ALL) jitter can be 
much higher if the driver or kmixer is doing buffer adaption. For example 
I've seen ~15ms callback delay variation with ASIO4ALL even with a 5ms 
buffer.


It is possible to significantly reduce (1) using by filtering callback 
invocation times using PLL/DLL techniques and/or other types of clock 
recovery. That's what I do in AudioMulch, and this gives me subsample 
accurate clock even with large amounts of callback jitter.

ASIO and CoreAudio drivers can return knownBufferingLatency information 
which makes (2) relatively accurate. For WMME and DirectSound 
knownBufferingLatency currently only includes latency introduced by PA and 
WMME/DirectSound buffers (in fact with DS right now I think we only use PA 
buffering latencies, if any).

Note that the next major milestone (V19-M1) is the "latency milestone" and I 
plan to clean up a number of open tickets relating to this stuff.

I've also been considering implementing some low level telemetry tools so we 
can inspect scheduling jitter and latencies in PA. I've recently done this 
in a network audio streaming project and have already coded analysis and 
visualisation tools using NumPy.


> Long ago, we wrote
> some code for winmm, which transfers samples to devices through a list
> of buffers. The timing of buffers was full of jitter, so we had some
> complicated smoothing software (maybe Kalman filters) to estimate the
> sample output times. It worked pretty well, but illustrates how hard the
> problem can be with "mainstream" audio APIs.

Agreed, with many APIs it is non-trivial.

JACK uses a digital PLL for clock recovery:
http://www.kokkinizita.net/papers/usingdll.pdf
(that link seems broken but if you google for "Using a DLL to filter time" 
you can use Google Quick-View to read it).

I think there are better ways to do it.

I've considered building clock recovery into PortAudio to filter the 
callback timestamps. I have an algorithm that I believe performs better than 
the second order filter used by JACK, but I need to do some more work to 
prove it.

Conclusion: at the moment you can't rely on raw PortAudio timestamps being 
super-accurate for MIDI scheduling on all platforms. Like many things in PA 
this is simply a case of PortAudio providing support that is no better than 
that provided by the underlying host APIs. On the other hand, on OSX at 
least, I think you will get sufficient accuracy for the timestamps to be 
usable without further filtering.

Cheers

Ross.








_______________________________________________
media_api mailing list
[email protected]
http://lists.create.ucsb.edu/mailman/listinfo/media_api

Reply via email to