[Portaudio] Reported latency
rossb-lists at audiomulch.com
Mon Dec 7 20:20:14 EST 2015
I'll try to answer from inline below...
> PS. I’m on CoreAudio, Mac OS X 10.10
That's useful. Each host API has to implement their own timing
mechanisms. You should definitely test against all of your targets.
On 8/12/2015 9:48 AM, Erik Ronström wrote:
> Hi List,
> (Apologies if this has been asked before, but I haven’t yet found an
> answer by searching the web)
> I want to synchronize recorded audio with the track that was played
> back during recording. As far as I understand, this means offsetting
> the recorded audio by (inputLatency + outputLatency). The problem is
> that I cannot make sense of the latency values that PortAudio
Roughly speaking yes.
> There seems to be four latency values of interest here: the suggested
> latency (set by PaStreamParameters), the ”actual” latency (as
> reported by PaStreamInfo), the difference between inputBufferAdcTime
> and outputBufferDacTime in PaStreamCallback, and finally, the
> ”real-world” actual latency.
The PaStreamParameters are just requests/suggestions.
(In theory) the PaStreamInfo latencies are as close as PA is able to
statically report (which varies in accuracy) based on allocated buffers
and any additional info provided by the native API (often not much).
inputBufferAdcTime and outputBufferDacTime are functions of the current
buffer fill levels, and the time at which buffers were captured. It
stands to reason that these calculations could be more accurate, but
also suggests that in your case there might be an error in the
calculation of the PaStreamInfo input latency with the particular host
API that you are testing.
> To get the ”real-world” latency I recorded the backtrack playing from
> the computer speaker directly into the internal microphone, and
> looked at the audio file. I did this several times, and there is no
> measurable difference between the offsets of the different
> These are the values of one test (input/output, rounded to ms):
> Suggested Latency: 0.010 / 0.010 ”Actual” Latency (PaStreamInfo):
> 0.059 / 0.020 Diff ADC/DAC: 0.035 ”Real-world”: 0.044
> And another: Suggested Latency: 0.040 / 0.040 ”Actual” Latency
> (PaStreamInfo): 0.233 / 0.061 Diff ADC/DAC: 0.110 ”Real-world”:
Are these observations with different hardware? To clarify: Is the "Diff
ADC/DAC" derived from inputBufferAdcTime and outputBufferDacTime?
> I’m certainly not an expert on these matters, but to me the values
> reported by PaStreamInfo looks weird – the input latency cannot
> possibly be 59 ms when the recorded ”echo” starts 44 ms into the
True. It's possible that there is a bug either in the buffer phase
handling or in the calculation of the latency. This code is different
for each host API.
In the case of PA/CoreAudio this is further complicated by the fact that
there are two full-duplex code paths depending on whether the input and
output are on the same CoreAudio device, or on two separate devices (the
latter case also applies to drivers that expose their audio as two
separate sub-devices). In the latter case, PA/CoreAudio introduces an
extra ring-buffer to adapt the two half-duplex streams into a single
stream. This code path is likely to be used if one of your inputs is the
To reduce the number of moving parts, are you able to test your code
with a full-duplex device (e.g. a pro audio interface)? Or else, create
a full-duplex aggregate device and test that. This should present a
single full-duplex device to PortAudio.
> Furthermore, I would have expected some sort of match between
> the PaStreamInfo latency values and the ADC/DAC diff. Here, I can see
> no obvious relation between them.
One guess is that it could be that there is a power-of-two buffer being
allocated and you have stepped over a size boundary.
> The ADC/DAC diff seems to be closest to the real-world values, and in
> the first example,
That would make sense to me. inputBufferAdcTime and outputBufferDacTime
are calculated from all available information including buffer fill
levels, whereas the static PaStreamInfo latencies don't take this into
account (and may also be mis-calculated in this case).
> I could have just accepted the 9 ms diff for the
> unknown latency which lays outside of the knowledge of PortAudio. But
> in that case, it wouldn’t have increased so much in the second
> example, I would rather have expected a constant addition.
Yes, I agree that behavior is mysterious.
> How is this supposed to be done? Is it even possible to have the
> system roundtrip latency automatically calculated? (But even if the
> answer is no, the values reported by PaStreamInfo still don’t make
> any sense IMO!)
In theory there are two options: (1) PaStreamInfo or (2)
inputBufferAdcTime and outputBufferDacTime. For your case I'd use
To move forward with this I'll need answers to the questions above.
Also, for your use-case would it be reasonable to require users to use a
synchronised full-duplex device, or do you absolutely need time
alignment from two arbitrary devices (like internal mic)?
> Best regards Erik
> PS. I’m on CoreAudio, Mac OS X 10.10
More information about the Portaudio