will want to match this parameter to the framesPerBuffer parameter used
when opening the stream.
- @return On success PaNoError will be returned,
- or paOutputUnderflowed if additional output data was inserted after the
- previous call and before this call.
+ @return On success PaNoError will be returned, or paOutputUnderflowed if
+ additional output data was inserted after the previous call and before this
+ call.
*/
PaError Pa_WriteStream( PaStream* stream,
const void *buffer,
stream->state = STOPPING;
VDBUG( ("Waiting for BLIO.\n") );
- paErr = waitUntilBlioWriteBufferIsEmpty( &stream->blio, stream->sampleRate );
+ paErr = waitUntilBlioWriteBufferIsEmpty( &stream->blio, stream->sampleRate, stream->outputFramesPerBuffer );
VDBUG( ( "waitUntilBlioWriteBufferIsEmpty returned %d\n", paErr ) );
return FinishStoppingStream( stream );
/*
* Wait until the data in the buffer has finished playing.
*/
-PaError waitUntilBlioWriteBufferIsEmpty( PaMacBlio *blio, double sampleRate )
+PaError waitUntilBlioWriteBufferIsEmpty( PaMacBlio *blio, double sampleRate,
+ size_t framesPerBuffer )
{
PaError result = paNoError;
if( blio->outputRingBuffer.buffer ) {
- int timeout = 5; // don't wait forever
- ring_buffer_size_t framesInBuffer = PaUtil_GetRingBufferReadAvailable( &blio->outputRingBuffer );
- while( framesInBuffer > 0 && timeout-- > 0 ) {
- long msecEstimated = 1 + (long)( 1000.0 * framesInBuffer / sampleRate);
- VDBUG(( "waitUntilBlioWriteBufferIsFlushed: framesInBuffer = %d, msecEstimated = %ld\n", framesInBuffer, msecEstimated ));
- Pa_Sleep( msecEstimated );
- framesInBuffer = PaUtil_GetRingBufferReadAvailable( &blio->outputRingBuffer );
+ ring_buffer_size_t framesLeft = PaUtil_GetRingBufferReadAvailable( &blio->outputRingBuffer );
+
+ /* Calculate when we should give up waiting. To be safe wait for two extra periods. */
+ PaTime now = PaUtil_GetTime();
+ PaTime startTime = now;
+ PaTime timeoutTime = startTime + (framesLeft + (2 * framesPerBuffer)) / sampleRate;
+
+ long msecPerBuffer = 1 + (long)( 1000.0 * framesPerBuffer / sampleRate);
+ while( framesLeft > 0 && now < timeoutTime ) {
+ VDBUG(( "waitUntilBlioWriteBufferIsFlushed: framesLeft = %d, framesPerBuffer = %ld\n",
+ framesLeft, framesPerBuffer ));
+ Pa_Sleep( msecPerBuffer );
+ framesLeft = PaUtil_GetRingBufferReadAvailable( &blio->outputRingBuffer );
+ now = PaUtil_GetTime();
}
- if( framesInBuffer > 0 )
+
+ if( framesLeft > 0 )
{
+ VDBUG(( "waitUntilBlioWriteBufferIsFlushed: TIMED OUT - framesLeft = %d\n", framesLeft ));
result = paTimedOut;
}
}
return result;
}
-
signed long GetStreamReadAvailable( PaStream* stream )
{
PaMacBlio *blio = & ((PaMacCoreStream*)stream) -> blio;
#include "portaudio.h"
#define SAMPLE_RATE (44100)
-#define FRAMES_PER_BUFFER (4096)
+#define FRAMES_PER_BUFFER (2048)
static float s_buffer[FRAMES_PER_BUFFER][2]; /* stereo output buffer */
PaTime time;
for (int i = 0; i < 20; i++)
{
+ /* ILLEGAL unsynchronised call to PA, see comment above */
time = Pa_GetStreamTime( stream );
printf("Stream time = %f\n", time);
fflush(stdout);
- Pa_Sleep(100);
+ usleep(100 * 1000);
}
printf("Call Pa_StopStream()\n");
fflush(stdout);