Proposed Enhancements to PortAudio API

004 - Allow Callbacks to Accept Variable Number of Frames per Buffer

Enhancement Proposals Index, PortAudio Home Page

Updated: October 18, 2002

Status

This proposal sufficiently defined to be implemented. This proposal has been implemented in the v19-devel branch.

Background

Some host APIs (such as ASIO) prefer, or even require, a specific number of frames to be handled by their processing callback function and do not allow the client total flexibility in specifying this value. Some applications prefer or require a specific number of samples to be passed to the processing callback for a variety of reasons including the use of optimizations which depend on fixed-sized processing vectors. A more complete discussion of why a PortAudio client might want to request a fixed number of frames per callback was discussed on a mailing list thread begining with this message: http://techweb.rfa.org/pipermail/portaudio/2002-June/000868.html

In cases where both the host API and the PortAudio client require specific buffer sizes, and those buffer sizes are not the same, some system for adapting between host API callback and PortAudio callback will be required. When the buffer sizes are not related by an integer factor, the adaption will involve extra memory movement which will incur a performance penalty. Currently there is no way to avoid this penalty as the API requires the client to choose a fixed callback buffer size even if it really doesn't care about the buffer size. Some algorithms can easily work with any number or frames per callback, such as the one in "pa_tests/pa_fuzz.c". Such algorithms could avoid the performance penalty if they were able to indicate that they could handle any number of frames per callback.

Proposal

Pa_OpenStream() should be able to accept a special value (0) for framesPerBuffer which indicates that the number of frames passed to the callback should be chosen based on other constraints such as those resulting from requested latency values and buffer size constraints dictated by the host API.

A note will be placed in the documentation stating:

With some host APIs, the use of non-zero framesPerBuffer for a callback stream may introduce an additional layer of buffering which could introduce additional latency. It is strongly recommended that a non-zero framesPerBuffer value only be used when your algorithm requires a fixed number of frames per callback. In such cases PortAudio guaratees to introduce the theoretical minimum additional latency.

To make the code more obvious, a special constant will be defined:

#define paFramesPerBufferUnspecified (0)

Discussion

It was originally proposed that the following function could be provided to retrieve the actual number of samples which would be passed to each callback:

int Pa_GetStreamFramesPerBuffer( PaStream* stream );

However it was concluded that it would be more flexible to allow the number of frames passed to the callback to vary from one call to the next. Some APIs (JACK?) were identified which made no guarantees about the number of frames per buffer, and some implementations can provide different buffer sizes for each callback under certain circumstances (consider circular buffer wraparound in DirectSound for example.)

The name paVariableFramesPerBuffer was considered as an alternative to paFramesPerBufferUnspecified, however it was deemed to make it unclear whether PortAudio or the client determined the buffer size variation.

Impact Analysis

This proposal will not effect existing client code, since all clients will currently specify a non-zero framesPerBuffer parameter. Clients whose code can operate with a flexible number of framesPerBuffer may benefit from improved efficiency in some cases simply by specifying paFramesPerBufferUnspecified.