From 5cf03fa3b36d1cc1cf427591e90821e5fd165ccd Mon Sep 17 00:00:00 2001
From: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
Date: Mon, 2 Feb 2009 15:14:12 -0500
Subject: [PATCH] Better handling of capture XRUNs

---
 src/audio/alsalayer.cpp | 27 +++++++++++++++------------
 src/audio/alsalayer.h   |  2 ++
 src/audio/audiolayer.h  |  1 +
 src/audio/pulselayer.h  |  2 ++
 src/iaxvoiplink.cpp     | 16 ++--------------
 5 files changed, 22 insertions(+), 26 deletions(-)

diff --git a/src/audio/alsalayer.cpp b/src/audio/alsalayer.cpp
index 24827d5249..5409c85596 100644
--- a/src/audio/alsalayer.cpp
+++ b/src/audio/alsalayer.cpp
@@ -124,16 +124,18 @@ AlsaLayer::stopStream(void)
 AlsaLayer::canGetMic()
 {
     int avail;
-    if ( _CaptureHandle ) {
-        avail = snd_pcm_avail_update( _CaptureHandle );
-        //printf("%d\n", avail ); 
-        if(avail > 0)
-            return avail;
-        else 
-            return 0;  
+    
+    if (! _CaptureHandle )
+        return 0;
+
+    avail = snd_pcm_avail_update( _CaptureHandle );
+    
+    if( avail == -EPIPE ){
+        stop_capture ();
+        return 0;
     }
     else
-        return 0;
+        return ((avail < 0)? 0:avail);
 }
 
     int 
@@ -421,6 +423,7 @@ AlsaLayer::read( void* buffer, int toCopy)
 
     if(snd_pcm_state( _CaptureHandle ) == SND_PCM_STATE_XRUN)
     {
+        _debug("xrun caught before start\n");
         prepareCaptureStream ();
         startCaptureStream ();
     }
@@ -432,7 +435,7 @@ AlsaLayer::read( void* buffer, int toCopy)
             case -EPIPE:
             case -ESTRPIPE:
             case -EIO:
-                //_debugAlsa(" XRUN capture ignored (%s)\n", snd_strerror(samples));
+                _debugAlsa(" XRUN capture ignored (%s)\n", snd_strerror(samples));
                 handle_xrun_capture();
                 samples = snd_pcm_readi( _CaptureHandle, buffer, frames);
                 if (samples<0)  samples=0;
@@ -458,9 +461,9 @@ AlsaLayer::handle_xrun_capture( void )
     int res = snd_pcm_status( _CaptureHandle, status );
     if( res <= 0){
         if(snd_pcm_status_get_state(status) == SND_PCM_STATE_XRUN ){
-            stop_capture ();
-            prepare_capture ();
-            start_capture ();
+            stopCaptureStream ();
+            prepareCaptureStream ();
+            startCaptureStream ();
         }
     }
     else
diff --git a/src/audio/alsalayer.h b/src/audio/alsalayer.h
index 8f7bdbc426..875e0cc141 100644
--- a/src/audio/alsalayer.h
+++ b/src/audio/alsalayer.h
@@ -139,6 +139,8 @@ class AlsaLayer : public AudioLayer {
 
     void audioCallback (void);
 
+    bool isCaptureActive (void) { return is_capture_running (); }
+
   private:
   
     // Copy Constructor
diff --git a/src/audio/audiolayer.h b/src/audio/audiolayer.h
index 35e7e92d7e..679738b68c 100644
--- a/src/audio/audiolayer.h
+++ b/src/audio/audiolayer.h
@@ -147,6 +147,7 @@ class AudioLayer {
          */
         void flushMic();
 
+        virtual bool isCaptureActive (void) = 0;
 
         /**
          * Write accessor to the error state
diff --git a/src/audio/pulselayer.h b/src/audio/pulselayer.h
index a4491476d1..bdb34085b6 100644
--- a/src/audio/pulselayer.h
+++ b/src/audio/pulselayer.h
@@ -76,6 +76,8 @@ class PulseLayer : public AudioLayer {
     static void stream_state_callback( pa_stream* s, void* user_data );	
     static void context_state_callback( pa_context* c, void* user_data );	
 
+    bool isCaptureActive (void){return true;}
+
     /**
      * UNUSED in pulseaudio layer
      */
diff --git a/src/iaxvoiplink.cpp b/src/iaxvoiplink.cpp
index 8fc1c5f308..f085ea1544 100644
--- a/src/iaxvoiplink.cpp
+++ b/src/iaxvoiplink.cpp
@@ -333,16 +333,6 @@ IAXVoIPLink::sendRegister(AccountID id)
     if (!_regSession) {
         _debug("Error when generating new session for register");
     } else {
-        // refresh
-        // last reg
-        //char host[_host.length()+1]; 
-        //strcpy(host, _host.c_str());
-        //char user[_user.length()+1];
-        //strcpy(user, _user.c_str());
-        //char pass[_pass.length()+1]; 
-        //strcpy(pass, _pass.c_str());
-        // iax_register doesn't use const char*
-
         _debug("IAX Sending registration to %s with user %s\n", account->getHostname().c_str() , account->getUsername().c_str() );
         int val = iax_register(_regSession, account->getHostname().data(), account->getUsername().data(), account->getPassword().data(), 120);
         _debug ("Return value: %d\n", val);
@@ -647,10 +637,8 @@ IAXVoIPLink::iaxHandleCallEvent(iax_event* event, IAXCall* call)
             break;
 
         case IAX_EVENT_VOICE:
-            //_debug("Should have a decent value!!!!!! = %i\n" , call -> getAudioCodec());
-            //TODO Check this method
-            //if( !audiolayer -> is_capture_running())
-                //audiolayer->startStream();
+            if (!audiolayer->isCaptureActive ())
+                audiolayer->startStream ();
             iaxHandleVoiceEvent(event, call);
             break;
 
-- 
GitLab