]> Repos - portaudio/commitdiff
pa_mac_core_blocking: Fix timeout.
authorPhil Burk <philburk@mobileer.com>
Wed, 21 Sep 2016 22:46:30 +0000 (15:46 -0700)
committerPhil Burk <philburk@mobileer.com>
Wed, 21 Sep 2016 22:46:30 +0000 (15:46 -0700)
Change alignment of comment.

include/portaudio.h
src/hostapi/coreaudio/pa_mac_core.c
src/hostapi/coreaudio/pa_mac_core_blocking.c
src/hostapi/coreaudio/pa_mac_core_blocking.h
test/patest_write_stop_hang_illegal.c

index 42e4d6d6472d7451beb4a7e722e93791ddd2154e..e3b991472952fae9723fcf3e19dd97108992004a 100644 (file)
@@ -1149,9 +1149,9 @@ PaError Pa_ReadStream( PaStream* stream,
  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,
index 896ee64621a82d2a11d8b01830be3841ce892152..beb6bae0a48daf15b279f234525bc13247c219ea 100644 (file)
@@ -2790,7 +2790,7 @@ static PaError StopStream( PaStream *s )
     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 );
index 959b765e00320610f16a1724f193b7e8f090c665..149d82c9cad6065fd6146b7bf09ed2a0a4cb389c 100644 (file)
@@ -587,27 +587,36 @@ PaError WriteStream( PaStream* 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;
index 8a9707b832347c568b5cf5d1a3dd850eee091c04..c994f0903aeb0d0ccec5042e7e4b1e5322cf8a13 100644 (file)
@@ -128,6 +128,7 @@ int BlioCallback(
         PaStreamCallbackFlags statusFlags,
         void *userData );
 
-PaError waitUntilBlioWriteBufferIsEmpty( PaMacBlio *blio, double sampleRate );
+PaError waitUntilBlioWriteBufferIsEmpty( PaMacBlio *blio, double sampleRate,
+                                        size_t framesPerBuffer );
 
 #endif /*PA_MAC_CORE_BLOCKING_H_*/
index 35f73a09fd73e4a20981fca2d5f640be86332c35..71e17de4e1d70b1027177e6030a48cd6f9b9eb8e 100644 (file)
@@ -50,7 +50,7 @@
 #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 */
 
@@ -75,10 +75,11 @@ void *stop_thread_proc(void *arg)
     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);