From 8f65d6cb2bb93795bde923274a4ede0156390de2 Mon Sep 17 00:00:00 2001
From: rossb Updated: May 14, 2002 Updated: May 16, 2002 This document describes modifications to the PortAudio API currently being considered by the developer community. It is intended to capture the current state of discussions. The authors are the various members of the PortAudio community and are too numerous to mention. Please refer to the mailing list archives to see who said what. We are still at the design stage with all of these proposals - if you think something is missing, could be improved, or would just like to comment please do so on the PortAudio mailing list. The proposals above which are marked with a * are under construction, those marked with |C| are essentially complete but require community approval or comment before they are considered complete. The remaining proposals are essentially complete and will be implemented as-is unless significant objections are raised. For streams providing input, the inputBuffer parameter will always point to a valid memory location containing framesPerBuffer frames of sample data in the requested format. The inputBuffer parameter will be NULL for output only streams. Similarly, the outputBuffer parameter will be NULL for input only streams, otherwise it will point to a valid memory location containing framesPerBuffer frames of sample data. A new parameter will be added to the PortAudioCallback Function that gives the status of the data as bit flags. These bits may be set in the statusFlags parameter. New rules will govern when the PortAudioCallback is called: New rules will govern when the PortAudioCallback is called: At a minimum this call would need to return values indicating whether the requested format(s) are supported natively, or will undergo conversion by PortAudio. The result could be a set of flags indicating: There also needs to be a method for accommodating host-API-specific return flags. A related issue is the need to improve the interface available to determine default latency parameters. The most recent proposal is documented below, however there is still some debate as to whether this is satisfactory. See this thread: http://techweb.rfa.org/pipermail/portaudio/2001-October/000196.html The numBuffers parameter to Pa_OpenStream() could be removed, and replaced by two new parameters inputLatencySamples and outputLatencySamples. These parameters allow clients to fine-tune latency in a portable manner. PortAudio implementations should make every reasonable to select buffer sizes based on these parameters, but for various reasons they may choose the closest viable buffer size and latency instead. In such cases PortAudio implementations should round-up (ie always provide equal or higher latency than requested.) The numBuffers parameter to Pa_OpenStream() could be removed, and replaced by two new parameters inputLatencyFrames and outputLatencyFrames. These parameters allow clients to fine-tune latency in a portable manner. PortAudio implementations should select buffer sizes based on these parameters, if this is not possible they may choose the closest viable buffer size and latency instead. In such cases the PortAudio implementations should round-up (ie always provide equal or higher latency than requested.) The special latency value of 0 indicates that the implementation should use the default latency values, this will produce the same behavior as passing 0 for numBuffers in existing PortAudio implementations. Clients may retrieve recommended safe latency settings using the following two functions: Currently, when numBuffers>0, Pa_OpenStream will constrain the actual numBuffers so that the latency is within a valid range determined by the host API, or an environment variables such as PA_MIN_LATENCY_MSEC. Propose changing the behavior so that the requested value is honored as much as possible. This will allow the user to override the minimum if they know their system can handle it. This might be used, for example on patched Linux kernels In addition to the portable latency setting mechanism just described, implementations may use the inputDriverInfo and outputDriverInfo Pa_OpenStream() parameters to provide host API specific latency setting mechanisms which directly reflect the underlying buffer passing scheme. For example, the MME driverInfo structure would provide a way to directly set the bufferSize and numberOfBuffers parameters for input and output. When driverInfo structures are passed to Pa_OpenStream(), using 0 values for their API specific latency settings should cause PortAudio to use Pa_OpenStream()'s latencySamples parameters. In cases where Host API specific latency parameters may be limited to certain allowable ranges (buffer sizes in ASIO for example) a method for querying these limits should be provided. This will consist of host-API specific query functions declared in a host-api specific header file. These header files will also contain the declaration of the host API specific driverInfo structure. The following two functions have been proposed to retrieve the estimated input and output latency of a stream. Both return the estimated latency in ms. The Pa_GetMinNumBuffers( int framesPerBuffer, double sampleRate ); function will be removed, as it's functionality is fulfilled by the get recommended latency functions. This proposal provides both a high level mechanism for portable latency tuning, and suggests method for providing a host-API specific latency tuning interface. The provision of both default latency settings (via 0 valued latencySamples parameters) and query functions for recommended latency settings provide the needed flexibility for simple, and portable applications. It is not clear whether a 0 latencySamples parameter produces the same latency as returned by Pa_GetRecommendedHighLatencySamples() or whether there is a separate default latency value, in which case there should also be a Pa_GetDefaultLatencySamples() function.Introduction
Proposal
typedef int (PortAudioCallback)(
- void *inputBuffer, void *outputBuffer,
- unsigned long framesPerBuffer,
- PaTimestamp outTime,
- unsigned long statusFlags,
- void *userData );
-
-These bits may be set in the statusFlags parameter.
-#define paInputUnderflow (1<<0) /* Input data is all zeros because no real data is available. */
+
+typedef int (PortAudioCallback)(
+ void *inputBuffer, void *outputBuffer,
+ unsigned long framesPerBuffer,
+ PaTimestamp outTime,
+ unsigned long statusFlags,
+ void *userData );
+
+#define paInputUnderflow (1<<0) /* Input data is all zeros because no real data is available. */
#define paInputOverflow (1<<1) /* Input data was discarded by PortAudio */
-#define paOutputUnderflow (1<<2) /* Output data was inserted by PortAudio because the callback is using too much CPU */
-#define paOutputOverflow (1<<3) /* Output data will be ignored because no room is available. */
-
-
-
Proposal
- int Pa_GetRecommendedLowLatencySamples( PaDeviceID deviceID ); /* For interactive performance. */
- int Pa_GetRecommendedHighLatencySamples( PaDeviceID deviceID ); /* For playing sound files. */
+ int Pa_GetRecommendedLowLatencyFrames( PaDeviceID deviceID ); /* For interactive performance. */
+ int Pa_GetRecommendedHighLatencyFrames( PaDeviceID deviceID ); /* For playing sound files. */
/* the following would operate directly on streams */
+
+
+/* the following would operate directly on streams */
double Pa_StreamInputLatency( PortAudioStream *stream );
-double Pa_StreamOutputLatency(PortAudioStream *stream );
+double Pa_StreamOutputLatency(PortAudioStream *stream );
+Discussion
To make the code more obvious, this constant could be used:
-#define paFramesPerBufferUnspecified (0)
+#define paFramesPerBufferUnspecified (0)
In order to find out what value the implementation chose, and also to help the application determine the actual latency, the following calls could be added:
-int Pa_GetFramesPerBuffer( PortAudioStream* stream );
+int Pa_GetFramesPerBuffer( PortAudioStream* stream );
int Pa_GetNumOutputBuffers( PortAudioStream* stream );
int Pa_GetNumInputBuffers( PortAudioStream* stream );
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.
____________
This proposal is sufficiently well defined to be implemented. No objections have been raised.
http://techweb.rfa.org/pipermail/portaudio/2001-October/000210.html
+http://techweb.rfa.org/pipermail/portaudio/2001-October/000210.html
Some native APIs use non-interleaved buffers, particularly those that support N>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 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.
Memory allocation should probably be handled with platform specific functions such as Win32 GlobalAlloc() rather than using malloc()
This proposal only effects PortAudio implementors. Increasing the utility of shared code will improve the quality of all PortAudio implementations in terms of speed, size, and robustness. It should also reduce the effort involved in porting PortAudio to a new host API.
-____________