Proposed Enhancements to PortAudio API

016 - Use Structs for Pa_OpenStream() Parameters

Enhancement Proposals Index, PortAudio Home Page

Updated: October 24, 2002

Status

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

Background

The current version of Pa_OpenStream() has 16 parameters. This is a very large number of parameters for a C function to take. Code that calls Pa_OpenStream may be difficult to read, as it is difficult to identify which parameters are which.

Proposal

Define a new structure called PaStreamParameters:

typedef struct PaStreamParameters{
     PaDeviceIndex device;
     int channelCount;
     PaSampleFormat sampleFormat;
     PaTime suggestedLatency;
     void *hostApiSpecificStreamInfo;
}PaStreamParameters;

Replace existing input and output parameter fields in Pa_OpenStream() with pointers to PaStreamParameters structures.

 PaError  Pa_OpenStream (
   PaStream **stream,
   const PaStreamParameters *inputParameters,
   const PaStreamParameters *outputParameters,
   double sampleRate,
   unsigned long framesPerBuffer,
   PaStreamFlags streamFlags,
   PortAudioCallback *callback,
   void *userData);

The new Pa_IsFormatSupported() function defined here would also use pointers to PaStreamParameters structures:

PaError Pa_IsFormatSupported(
   const PaStreamParameters *inputParameters,
   const PaStreamParameters *outputParameters,
   double sampleRate );

When opening a half duplex stream with Pa_OpenStream(), or querying half duplex format capabilities with Pa_IsFormatSupported(), clients should pass NULL for the parameter structure covering the unused direction.

In cases where a PaStreamParameters pointer is supplied, its device field must NOT be set to paNoDevice, nor may its numChannels field be zero.

Discussion

Using structures to pack function parameters has the advantage of creating more readable code, because clients can assign values to these structures as follows. Incedentally, the ability to write the following code in C was one of the reasons Bjarne Stroustrup gave for not adding named parameters to C++.

PaStreamParameters inputParameters;
inputParameters.device = Pa_GetDefaultInputDevice();
inputParameters.channelCount = 2;
inputParameters.sampleFormat = paFloat32;
inputParameters.suggestedlatency = Pa_GetDefaultLowInputLatency( inputParameters.device );
inputParameters.hostApiSpecificStreamInfo = NULL;

The new implementation (V19) of PortAudio provides support for all sample formats, so the value of PaStreamParameters::sampleFormat will not be relevant to Pa_IsFormatSupported(). Using the PaStreamParameters structure for Pa_IsFormatSupported() parameters is still considered to be worthwhile.

Originally the channelCount field was called numChannels in line with the old Pa_OpenStream parameters of the same name. However it was discovered that this field was the only one in the whole api that used an abbreviation, so it was changed to channelCount for consistency. Other abbreviations currently used are Info and Ptr, neither of these are field names. Further more, Info is a very common abbreviation (over 113 million appearances in google). There is an enumeration called PaErrorNum, but we are considering eliding this with PaError or renaming it PaErrorCode.

Impact Analysis

This proposal will require clients that use Pa_OpenStream() to rewrite their parameter passing code.