1

I'm working with the example recording program that's available here on the portaudio website. And I'm confused about how the frame index is being incremented

Given that the buffer size is 512 frames, and the sample rate is set to 44100Hz, you would assume that the program works through the buffer, returns the callback, and increases the frame index by 512 roughly every 11.6 ms. In main(), I have the program outputting the current frame index every 12ms (as opposed to every 1000ms like in the example, but the rest of my code is identical to theirs), and I assumed that it would increment by 512 with each line of output, but that's not the case. This is a chunk of the output:

index at 12 ms = 0
index at 24 ms = 0
index at 36 ms = 1024
index at 48 ms = 1024
index at 60 ms = 2048
index at 72 ms = 2048
index at 84 ms = 2048
index at 96 ms = 3072
index at 108 ms = 3072
index at 120 ms = 3072
index at 132 ms = 4096
index at 144 ms = 4096
index at 156 ms = 4096
index at 168 ms = 5120
index at 180 ms = 5120
index at 192 ms = 5120
index at 204 ms = 6144
index at 216 ms = 7680

As you can see, this is incrementing in a strange fashion. The index stays at 0 until 36ms, where it then jumps up to 1024, and then the index suddenly increases from 1024 to 2048 at 60ms. The way the index increases is not the way one would it expect it to, and it's also inconsistent. You'll notice that the index takes 24ms to increment from 1024 to 2048, and then 36ms to increment from 2048 to 3072, but then only 12ms to later increment from 6144 to 7680.

My question is, what is happening here and what can I do to get the output happening at a more consistent rate? Is it something to do with the ALSA audio buffer size perhaps?

  • 1
    Perhaps your measurement clock has more granularity than you expect. – Weather Vane Oct 27 '16 at 20:18
  • Apparently, you're attempting to asynchronously sample the callback state from `main`. You'd be better off storing the frame index and timestamp in an array (in the callback itself). Then you can print that information from `main`. – user3386109 Oct 27 '16 at 20:27
  • What do you mean by "frame index"? Where is this number coming from? – Ross Bencina Oct 28 '16 at 12:26

1 Answers1

1

The PortAudio callback buffer size is not necessarily the host buffer size. The relationship between the two is complex, because not all host APIs support all buffer sizes, but PortAudio will "adapt" to support your requested callback buffer size.

PortAudio computes the host buffer size using an algorithm that incorporates multiple constraints including: the user buffer size, the requested latency, supported host buffer sizes, and heuristics.

For example, if you request a very small callback buffer size, but a large latency, it is likely that PortAudio will use a larger host buffer size, and you may observe bursty callbacks. That looks like what's happening for you: 1024 frame host buffer size, but 512 frame PA callback buffer size.

There is more information in my answer here: Time between callback calls?

what can I do to get the output happening at a more consistent rate?

Request a smaller latency in the appropriate parameters to Pa_OpenStream().

For some PortAudio host APIs there is also a host-API specific mechanism to force the host buffer size. I'm not sure whether ALSA provides that option.

Alternatively, you can use the paFramesPerBufferUnspecified option, which should result in more regular callbacks at whatever buffer size PortAudio and ALSA negotiate based on your requested latency.

Note that there might be some ALSA-specific or device-specific reason why you're getting 1024 frame host buffers. But I'd try the above first.

Community
  • 1
  • 1
Ross Bencina
  • 3,822
  • 1
  • 19
  • 33