File Info

Rev. 2af31d809b5b1a7920472fdfb1645186830ac141
Size 4,653 bytes
Time 2021-12-12 23:10:44
Author simphone
Log Message

simphone 0.8.2

Content

diff -urb portaudio/src/hostapi/alsa/pa_linux_alsa.c portaudio/src/hostapi/alsa/pa_linux_alsa.c
--- portaudio/src/hostapi/alsa/pa_linux_alsa.c
+++ portaudio/src/hostapi/alsa/pa_linux_alsa.c
@@ -1991,6 +1991,11 @@
         alternateAccessMode = SND_PCM_ACCESS_MMAP_NONINTERLEAVED;
 
         /* test if MMAP supported */
+#if 1
+        /* simphone patch: allow disabling mmap for testing and bug fixing */
+
+        if( !getenv( "PA_ALSA_NO_MMAP" ) || !atoi( getenv( "PA_ALSA_NO_MMAP" ) ) )
+#endif
         self->canMmap = alsa_snd_pcm_hw_params_test_access( pcm, hwParams, accessMode ) >= 0 ||
                         alsa_snd_pcm_hw_params_test_access( pcm, hwParams, alternateAccessMode ) >= 0;
 
@@ -2009,6 +2014,11 @@
         alternateAccessMode = SND_PCM_ACCESS_MMAP_INTERLEAVED;
 
         /* test if MMAP supported */
+#if 1
+        /* simphone patch: allow disabling mmap for testing and bug fixing */
+
+        if( !getenv( "PA_ALSA_NO_MMAP" ) || !atoi( getenv( "PA_ALSA_NO_MMAP" ) ) )
+#endif
         self->canMmap = alsa_snd_pcm_hw_params_test_access( pcm, hwParams, accessMode ) >= 0 ||
                         alsa_snd_pcm_hw_params_test_access( pcm, hwParams, alternateAccessMode ) >= 0;
 
@@ -3311,7 +3321,16 @@
         }
     }
 
+#if 0
+    /* if we got here, we should attempt recovery even if neither stream is in xrun state.
+       that's particularly the case when xrun was set without receiving -EPIPE (PaAlsaStream_WaitForFrames).
+       in any case it is more important to recover reliably than to do it fast (snd_pcm_recover).
+       this is always done if device is MMAPed and there is no reason to do it faster for the slower case.
+
+       simphone patch: always restart Alsa. */
+
     if( restartAlsa )
+#endif
     {
         PA_DEBUG(( "%s: restarting Alsa to recover from XRUN\n", __FUNCTION__ ));
         PA_ENSURE( AlsaRestart( self ) );
@@ -3871,7 +3890,16 @@
                 Pa_Sleep( 1 ); /* avoid hot loop */
             }
             /* not else ! */
+#if 1
+            /* sleeping 2048 times for one millisecond does not always take only two seconds.
+               this is a very damaging blocking delay.
+
+               simphone patch: reduce the timeouts limit to 100. */
+
+            if( timeouts >= 100 )
+#else
             if( timeouts >= 2048 ) /* audio device not working, shall return error to notify waiters */
+#endif
             {
                 *framesAvail = 0; /* no frames available for processing */
                 xrun = 1; /* try recovering device */
@@ -4498,6 +4526,21 @@
             framesGot = PaUtil_CopyOutput( &stream->bufferProcessor, &userBuffer, framesGot );
             PA_ENSURE( PaAlsaStream_EndProcessing( stream, framesGot, &xrun ) );
             frames -= framesGot;
+
+#if 1
+            /* an xrun is sometimes returned by the hardware driver here when using plughw (pcm_rate).
+
+               simphone patch: recover and break out of the loop to exit the whole function.
+
+               the next call to WriteStream will return the error. ReadStream may need
+               a similar patch; this was not done as a ReadStream xrun was not produced. */
+
+            if( xrun )
+            {
+                PA_ENSURE( PaAlsaStream_HandleXrun( stream ) );
+                break;
+            }
+#endif
         }
 
         /* Start stream after one period of samples worth */
@@ -4530,6 +4573,21 @@
     int xrun;
 
     PA_ENSURE( PaAlsaStreamComponent_GetAvailableFrames( &stream->capture, &avail, &xrun ) );
+#if 1
+    /* an -EPIPE error (xrun) is lost (not returned) on an MMAPed device when using plughw (pcm_rate).
+
+       simphone patch: explicitly check for xrun state and then recover immediately. */
+
+    if( stream->capture.pcm )
+    {
+        snd_pcm_state_t state = alsa_snd_pcm_state( stream->capture.pcm );
+
+        if( state == SND_PCM_STATE_XRUN )
+        {
+            xrun = 1;
+        }
+    }
+#endif
     if( xrun )
     {
         PA_ENSURE( PaAlsaStream_HandleXrun( stream ) );
@@ -4552,6 +4610,21 @@
     int xrun;
 
     PA_ENSURE( PaAlsaStreamComponent_GetAvailableFrames( &stream->playback, &avail, &xrun ) );
+#if 1
+    /* an -EPIPE error (xrun) is lost (not returned) on an MMAPed device when using plughw (pcm_rate).
+
+       simphone patch: explicitly check for xrun state and then recover immediately. */
+
+    if( stream->playback.pcm )
+    {
+        snd_pcm_state_t state = alsa_snd_pcm_state( stream->playback.pcm );
+
+        if( state == SND_PCM_STATE_XRUN )
+        {
+            xrun = 1;
+        }
+    }
+#endif
     if( xrun )
     {
         snd_pcm_sframes_t savail;
Show on old repository browser