Hi John,
First up, I tried to reproduce the problem you describe with ASIO4ALL
and could not.
My first guess is that there is a problem with the suggested latency
parameters that Jack is passing to Pa_OpenStream(). I recommend setting
them to 0 when using the ASIO host API. That will force the lowest
practical latency, which is recent versions of PA/ASIO will correspond
to the framesPerBuffer parameter to Pa_OpenStream().
Post by John EmmasPost by Ross BencinaThroughout your email you talk about modifying the buffer size,
however there is no direct way to modify the ASIO buffer size
programatically. Therefore I'm unsure about what you are talking
about. Can you please be more specific about this.
Actually, that's quite interesting because I can see two functions in
PortAudio that seem to suggest otherwise:-
ASIOCreateBuffers() - and, SelectHostBufferSize()
What I meant was that the PortAudio API provides Jack with no direct way
of specifying the host buffer size. The framesPerBuffer parameter to
Pa_OpenStream() is not directly used as the host buffer size.
Post by John EmmasHowever, I've already established with Stephane that neither of them
gets called by Jack. The only time Jack requests a specific buffer
size is when it first calls Pa_OpenStream(). From what I can tell,
Pa_OpenStream() requests the buffer sizes it would like
As I tried to explain, the buffer size passed to Pa_OpenStream() does
not map directly to the host buffer size you receive. The mapping logic
is in SelectHostBufferSize and as you can see, there is a long comment
there documenting the algorithm used.
SelectHostBufferSizeForSpecifiedUserFramesPerBuffer() should be being
used in this case.
Post by John Emmas- but they
aren't necessarily the sizes that it subsequently gets - and therein
lies the problem.... Is there any way to tell what buffer sizes
actually got allocated?
As I said in my later email, this is a function of the client buffer
size (Pa_OpenStream() framesPerBuffer parameter) and the suggested
latency parameters.
Post by John EmmasI assume there must be but I can't find a
PortAudio call that will return that information.
It's a low level detail. Pretty much every host API has a different
buffering model so PortAudio abstracts this. The algorithms involved are
documented here:
https://www.assembla.com/spaces/portaudio/wiki/BufferingLatencyAndTimingImplementationGuidelines
My guess is that the latency parameters to Pa_OpenStream that Jack is
using are higher than framesPerBuffer * (1.0 / sampleRate)
Post by John EmmasPost by Ross Bencina- does Jack limit the audio buffer size to only those sizes that
the ASIO driver is reporting as available?
- are you sure that you are selecting a buffer size that is
reported as supported by the driver?
As far as we know, we're selecting valid buffer sizes - but the
situation is complicated by having Asio4All in the equation (see
below).
I recommend instrumenting the code to print the result of
SelectHostBufferSize() and see whether this matches what the driver is
reporting. I would also be good to find out what
targetBufferingLatencyFrames is since this is the main variable (aside
from userFramesPerBuffer) that would be used.
Post by John EmmasPost by Ross BencinaCan you be specific about what hardware you're using? aside from
ASIO4ALL (which seems to me to often report bogus values) I have
not found that "most" drivers report these values.
The drivers I have seen only allow you to select a specific buffer
size and therefore the client application has absolutely no choice
but to use that buffer size (ie preferred = min = max)
Right, here's where it gets complicated. I first discovered this
problem when using Asio4All. Nobody else had ever reported it so I
assumed it must be some quirk of Asio4All. Knowing that Asio4All
isn't really a true ASIO driver I dismissed the problem as a one-off.
However, one of our customers is using an Audiophile 2496 interface
from M-Audio (which we're led to believe is a genuine ASIO device).
He's using the current M-Audio driver and he's reporting exactly the
same problem (buffer sizes get set correctly at 44.1K but not at any
other sample rate).
Both cases (Asio4All and M-Audio) provide a small 'control panel'
applet that let's you see the current buffer setting. Both applets
indicate that the requested size is only set correctly at 44.1K. Our
customer is able to access his Audiophile 2496 I/O using other DAWs
but they don't exhibit this problem.
Post by Ross BencinaAre you sure that the buffer size is available as a supported
driver buffer size?
We're reasonably sure. Both applets allow a user to select various
sizes (usually in powers of 2) from 64 samples up to about 2048
samples).
The ASIO API reports the buffer size using 4 parameters:
min, preferred, max, bufferGranularity
You can read about these in the ASIO API documentation.
How a control panel applet might provide a single parameter that maps to
all of these is indeterminate.
I've seen some drivers do this:
min = preferred = max
In the case of ASIO4ALL it looks like the slider in the applet is
setting the "preferred" value only. PortAudio will ignore the ASIO
preferred size if you specify a framesPerBuffer parameter to Pa_OpenStream()
Post by John EmmasPost by Ross BencinaWhat do you mean by "request"? And how do you know what you
"actually get"?
Mixbus allows the user to request a buffer size based on the minimum
and maximum values returned by PaAsio_GetAvaialableLatencyValues().
You havn't said how you request it. Is it passed as the framesPerBuffer
parameter to Pa_OpenStream? You also need to request a latency using
inputParameters->suggestedLatency and
outputParameters->suggestedLatency. These combined with framesPerBuffer
determine the host buffer size.
Post by John EmmasAt 48KHz the user might select (say) 256 samples - but if he opens
the small applet he can see that the size actually allocated was 512
samples.
For what it's worth, I don't see that behavior with ASIO4ALL here at the
moment although I have seen some weird stuff in the past.
Post by John EmmasPost by Ross BencinaThere is not really any such thing as "ASIO" that could be blamed.
ASIO is just a driver interface specification. Every driver is
potentially different.
And bear in mind that we have many other people using ASIO who
haven't reported this problem at all. That's why we need to find out
if it's a general problem or if it's a quirk of these two particular
drivers. However, the fact that our customer doesn't get the same
problem when he uses other DAWs (with the same driver) suggests that
the problem must be with Mixbus, PortAudio or Jack.
Post by Ross BencinaPost by John Emmasit kinda looks like PortAudio might be the culprit.
That's possible, however there is no code in PA that would make the
sample rate and the buffer size interact.
Please can you provide a simple test case that isolates the issue?
Perhaps Stephane might be able to do that? Jack can be operated from
a command line and hopefully I've given enough information to
reproduce the problem. Even if you don't have any ASIO hardware
available, the problem is very obvious, even with Asio4All. Thanks
for all your help so far Ross.
One more thing that might be helpful.... I've noticed a preprocessor
directive called PA_LOG_API_CALLS. If defined at compile time, this
will output the requested buffer sizes when Pa_OpenStream() gets
called. I've asked Stephane to produce a build with PA_LOG_API_CALLS
defined so we can check whether the requested sizes are indeed
correct.
That's a good idea. I'd be most interested to see what latency
parameters are being passed to Pa_OpenStream().
Post by John EmmasOne question though - where does the log output go? To a
file or to the console?
By default to the console. It is possible to replace the default logging
function (to write to a file for example) by calling
PaUtil_SetDebugPrintFunction().
Ross.