Proposed Enhancements to PortAudio API

006 - Non-Interleaved Buffers

Enhancement Proposals Index, PortAudio Home Page

Updated: July 23, 2002

Status

This proposal is sufficiently well defined to be implemented. It has been implemented in the v19-devel common infrastructure, implementations do not need to do anthing special to support this proposal.

Background

http://techweb.rfa.org/pipermail/portaudio/2001-October/000210.html

Some native APIs use non-interleaved buffers, particularly those that support more than 2 channels. Additionally, many client applications use non-interleaved buffers internally. In order to avoid adding unnecessary overhead, PortAudio should support both interleaved and non-interleaved buffers on all platforms.

The current (V18) PortAudio/ASIO implementation works as follows : ASIO native buffers are non-interleaved and the de-interleaving, format conversion and copying the data into PortAudio interleaved buffers is done in one loop. But if PortAudio supported non-interleaved buffers then we could use efficient vector operations even for native buffer <==> port audio buffers transfers.

Proposal

A new sample format could be defined:

#define paNonInterleaved ((PaSampleFormat) (1<<31))

This could be used as a modifier flag to the buffer format fields of Pa_OpenStream(). When present, this flag would indicate that non-interleaved buffers would be passed to the callback. When not present, interleaved buffers would be used as is currently always the case. For example, the following code would open an interleaved stream:

Pa_OpenStream(&stream,
    paNoDevice,
    0,
    paFloat32
    NULL,
    Pa_GetDefaultOutputDevice(),
    2,
    paFloat32,
    NULL,
    SAMPLE_RATE,
    FRAMES_PER_BUFFER,
    0,
    paClipOff,
    patestCallback,
    &data );

And the following code would open a non-interleaved stream:

Pa_OpenStream(&stream,
    paNoDevice,
    0,
    paFloat32|paNonInterleaved,
    NULL,
    Pa_GetDefaultOutputDevice(),
    2,
    paFloat32|paNonInterleaved,
    NULL,
    SAMPLE_RATE,
    FRAMES_PER_BUFFER,
    0,
    paClipOff,
    patestCallback,
    &data );

In the user callback, the application would be passed a pointer to an array of buffers. The left and right buffers of a non-interleaved stream could be accessed as follows:

    float *left = ((float **) inputBuffer)[0];
    float *right = ((float **) inputBuffer)[1];

This new sample format could also be used to interrogate the host API to see if it supports interleaved or non-interleaved buffers. This would be achieved by reading the nativeSampleFormats field of the PaDeviceInfo structure.

Impact Analysis

This proposal extends the functionality of PortAudio without any impact on existing client code. It will require new conversion functions and all existing PortAudio implementations will have to be modified to reference these new conversion functions.