From a701fe3bba0e6c16224d2cd8e41ba65998a073b8 Mon Sep 17 00:00:00 2001
From: yanmorin <yanmorin>
Date: Sat, 29 Oct 2005 17:48:23 +0000
Subject: [PATCH] Don't close sflphone when portaudio failed to load Remove
 enable_audio variable (non-protected) in SipCall

---
 src/audio/audiolayer.cpp | 60 ++++++++++++++++++++++++---------
 src/audio/audiolayer.h   | 23 +++++++------
 src/audio/audiortp.cpp   | 13 +++-----
 src/managerimpl.cpp      | 72 +++++++++++++++++++---------------------
 src/sipcall.cpp          | 11 +++---
 src/sipcall.h            |  1 -
 src/sipvoiplink.cpp      | 29 ++++++++--------
 7 files changed, 112 insertions(+), 97 deletions(-)

diff --git a/src/audio/audiolayer.cpp b/src/audio/audiolayer.cpp
index 2e9650a560..d370b52982 100644
--- a/src/audio/audiolayer.cpp
+++ b/src/audio/audiolayer.cpp
@@ -33,10 +33,9 @@ AudioLayer::AudioLayer()
   , _mainSndRingBuffer(SIZEBUF)
   , _micRingBuffer(SIZEBUF)
   , _stream(NULL)
+  , _errorMessage("")
 {
-  _debugInit("   portaudio initialization...");
   portaudio::System::initialize();
-  _debugInit("   portaudio end initialization.");
   NBCHARFORTWOINT16 = sizeof(int16)/sizeof(unsigned char) * CHANNELS;
 }
 
@@ -61,7 +60,7 @@ void
 AudioLayer::listDevices()
 {
   ost::MutexLock guard(_mutex);
-  portaudio::System::DeviceIterator pos = portaudio::System::instance().devicesBegin();
+  portaudio::System::DeviceIterator pos =  portaudio::System::instance().devicesBegin();
   while(pos != portaudio::System::instance().devicesEnd()) {
     _debug("AudioLayer: Device (%d) %s\n", pos->index(), pos->name());
     pos++;
@@ -72,8 +71,8 @@ AudioLayer::listDevices()
 void
 AudioLayer::openDevice (int index) 
 {
-  ost::MutexLock guard(_mutex);
   closeStream();
+
   // Set up the parameters required to open a (Callback)Stream:
   portaudio::DirectionSpecificStreamParameters 
     outParams(portaudio::System::instance().deviceByIndex(index), 
@@ -93,6 +92,7 @@ AudioLayer::openDevice (int index)
 					   SAMPLING_RATE, FRAME_PER_BUFFER /*paFramesPerBufferUnspecified*/, paNoFlag /*paPrimeOutputBuffersUsingStreamCallback | paNeverDropInput*/);
 		  
   // Create (and open) a new Stream, using the AudioLayer::audioCallback
+  ost::MutexLock guard(_mutex);
   _stream = new portaudio::MemFunCallbackStream<AudioLayer>(params, 
 							    *this, 
 							    &AudioLayer::audioCallback);
@@ -128,7 +128,9 @@ AudioLayer::stopStream(void)
 void
 AudioLayer::sleep(int msec) 
 {
-  portaudio::System::instance().sleep(msec);
+  if (_stream) {
+    portaudio::System::instance().sleep(msec);
+  }
 }
 
 bool
@@ -143,16 +145,19 @@ AudioLayer::isStreamActive (void)
   }
 }
 
-void
+int 
 AudioLayer::putMain(void* buffer, int toCopy)
 {
   ost::MutexLock guard(_mutex);
-  int a = _mainSndRingBuffer.AvailForPut();
-  if ( a >= toCopy ) {
-    _mainSndRingBuffer.Put(buffer, toCopy);
-  } else {
-    _mainSndRingBuffer.Put(buffer, a);
+  if (_stream) {
+    int a = _mainSndRingBuffer.AvailForPut();
+    if ( a >= toCopy ) {
+      return _mainSndRingBuffer.Put(buffer, toCopy);
+    } else {
+      return _mainSndRingBuffer.Put(buffer, a);
+    }
   }
+  return 0;
 }
 
 void
@@ -162,14 +167,37 @@ AudioLayer::flushMain()
   _mainSndRingBuffer.flush();
 }
 
-void
+int
 AudioLayer::putUrgent(void* buffer, int toCopy)
 {
-  int a = _urgentRingBuffer.AvailForPut();
-  if ( a >= toCopy ) {
-    _urgentRingBuffer.Put(buffer, toCopy);
+  if (_stream) {
+    int a = _urgentRingBuffer.AvailForPut();
+    if ( a >= toCopy ) {
+      return _urgentRingBuffer.Put(buffer, toCopy);
+    } else {
+      return _urgentRingBuffer.Put(buffer, a);
+    }
+  }
+  return 0;
+}
+
+int
+AudioLayer::canGetMic()
+{
+  if (_stream) {
+    return _micRingBuffer.AvailForGet();
+  } else {
+    return 0;
+  }
+}
+
+int 
+AudioLayer::getMic(void *buffer, int toCopy)
+{
+  if(_stream) {
+    return _micRingBuffer.Get(buffer, toCopy, 100);
   } else {
-    _urgentRingBuffer.Put(buffer, a);
+    return 0;
   }
 }
 
diff --git a/src/audio/audiolayer.h b/src/audio/audiolayer.h
index 3c0cdab759..8349d9e655 100644
--- a/src/audio/audiolayer.h
+++ b/src/audio/audiolayer.h
@@ -52,23 +52,26 @@ public:
 	bool    isStreamStopped	        (void);
 
   void flushMain();
-  void putMain(void* buffer, int toCopy);
-  void putUrgent(void* buffer, int toCopy);
+  int putMain(void* buffer, int toCopy);
+  int putUrgent(void* buffer, int toCopy);
+  int canGetMic();
+  int getMic(void *, int);
   void flushMic();
 
-	int audioCallback (const void *, void *, unsigned long,
-			   const PaStreamCallbackTimeInfo*, PaStreamCallbackFlags);
+  int audioCallback (const void *, void *, unsigned long,
+        const PaStreamCallbackTimeInfo*, PaStreamCallbackFlags);
 
-	inline RingBuffer &urgentRingBuffer(void) { return _urgentRingBuffer; }
-	inline RingBuffer &micRingBuffer(void) { return _micRingBuffer; }
+  void setErrorMessage(const std::string& error) { _errorMessage = error; }
+  std::string getErrorMessage() { return _errorMessage; }
 
 private:
-	void	closeStream	(void);
-	RingBuffer _urgentRingBuffer;
-	RingBuffer _mainSndRingBuffer;
-	RingBuffer _micRingBuffer;
+  void	closeStream	(void);
+  RingBuffer _urgentRingBuffer;
+  RingBuffer _mainSndRingBuffer;
+  RingBuffer _micRingBuffer;
 
 	portaudio::MemFunCallbackStream<AudioLayer> *_stream;
+  std::string _errorMessage;
 //	portaudio::AutoSystem autoSys;
   ost::Mutex _mutex;
   int NBCHARFORTWOINT16;
diff --git a/src/audio/audiortp.cpp b/src/audio/audiortp.cpp
index 6a65a1ffe2..7eeac7441d 100644
--- a/src/audio/audiortp.cpp
+++ b/src/audio/audiortp.cpp
@@ -48,7 +48,6 @@ AudioRtp::~AudioRtp (void) {
 int 
 AudioRtp::createNewSession (SipCall *ca) {
   // Start RTP Send/Receive threads
-  ca->enable_audio = 1;
   _symmetric = Manager::instance().getConfigInt(SIGNALISATION,SYMMETRIC) ? true : false;
   _RTXThread = new AudioRtpRTX (ca, Manager::instance().getAudioDriver(), _symmetric);
 
@@ -169,7 +168,7 @@ AudioRtpRTX::initAudioRtpSession (void)
 void
 AudioRtpRTX::sendSessionFromMic (unsigned char* data_to_send, int16* data_from_mic_stereo, int16* data_from_mic_mono, int timestamp)
 {
-  int availBytesFromMic = Manager::instance().getAudioDriver()->micRingBuffer().AvailForGet();
+  int availBytesFromMic = Manager::instance().getAudioDriver()->canGetMic();
   int maxBytesToGet = RTP_FRAMES2SEND * 2 * 2; // * channels * int16/byte
   int bytesAvail;
 
@@ -181,7 +180,7 @@ AudioRtpRTX::sendSessionFromMic (unsigned char* data_to_send, int16* data_from_m
   }
 
   // Get bytes from micRingBuffer to data_from_mic
-  Manager::instance().getAudioDriver()->micRingBuffer().Get(data_from_mic_stereo, bytesAvail, 100);
+  Manager::instance().getAudioDriver()->getMic(data_from_mic_stereo, bytesAvail);
   // control volume and stereo->mono
   // the j is in int16 RTP_FRAMES2SEND
   // data_from_mic_mono = 0 to RTP_FRAME2SEND [in int16]
@@ -225,7 +224,6 @@ AudioRtpRTX::receiveSessionForSpkr (int16* data_for_speakers_stereo, int16* data
     adu = _session->getData(_session->getFirstTimestamp());
   }
   if (adu == NULL) {
-    //Manager::instance().getAudioDriver()->flushMain();
     return;
   }
 
@@ -256,8 +254,6 @@ AudioRtpRTX::receiveSessionForSpkr (int16* data_for_speakers_stereo, int16* data
   // Set decoded data to sound device
   // expandedSize is in mono/bytes, since we double in stereo, we send two time more
   Manager::instance().getAudioDriver()->putMain(data_for_speakers_stereo, expandedSize*2);
-  //}
-	
   Manager::instance().getAudioDriver()->startStream();
 
 	// Notify (with a beep) an incoming call when there is already a call 
@@ -309,7 +305,7 @@ AudioRtpRTX::run (void) {
   TimerPort::setTimer(frameSize);
 
   audiolayer->flushMic();
-	while (!testCancel() && _ca != NULL && _ca->enable_audio != -1) {
+	while (!testCancel() && _ca != NULL) {
 		////////////////////////////
 		// Send session
 		////////////////////////////
@@ -325,14 +321,13 @@ AudioRtpRTX::run (void) {
 		Thread::sleep(TimerPort::getTimer());
 		TimerPort::incTimer(frameSize); // 'frameSize' ms
 	}
+  audiolayer->stopStream();
 
 	delete [] data_for_speakers_stereo; data_for_speakers_stereo = 0;
   delete [] data_for_speakers_recv;   data_for_speakers_recv   = 0;
 	delete [] char_to_send;          char_to_send          = 0;
 	delete [] data_from_mic_mono;    data_from_mic_mono    = 0;
 	delete [] data_from_mic_stereo;  data_from_mic_stereo  = 0;
-
-  audiolayer->stopStream();
 }
 
 
diff --git a/src/managerimpl.cpp b/src/managerimpl.cpp
index bebae80cab..baec39cc25 100644
--- a/src/managerimpl.cpp
+++ b/src/managerimpl.cpp
@@ -128,26 +128,19 @@ ManagerImpl::init()
   try {
     selectAudioDriver();
   }
-  catch (const portaudio::PaException &e)
-    {
-      displayError(e.paErrorText());
-      throw e;
-    }
-  catch (const portaudio::PaCppException &e)
-    {
-      displayError(e.what());
-      throw e;
-    }
-  catch (const std::runtime_error &e)
-    {
-      displayError(e.what());
-      throw e;
-    }
-  catch (...)
-    {
-      displayError("An unknown exception occured.");
+  catch (const portaudio::PaException &e) {
+      getAudioDriver()->setErrorMessage(e.paErrorText());
+  }
+  catch (const portaudio::PaCppException &e) {
+      getAudioDriver()->setErrorMessage(e.what());
+  }
+  catch (const std::runtime_error &e) {
+      getAudioDriver()->setErrorMessage(e.what());
+  }
+  catch (...) {
+      displayError("An unknown exception occured while selecting audio driver.");
       throw;
-    }
+  }
   initAudioCodec();
 
   _debugInit("Adding new VoIP Link");
@@ -584,11 +577,7 @@ ManagerImpl::playDtmf(char code)
     // put the size in bytes...
     // so size * CHANNELS * 2 (bytes for the int16)
     int nbInt16InChar = sizeof(int16)/sizeof(char);
-    int toSend = audiolayer->urgentRingBuffer().AvailForPut();
-    if (toSend > (size * CHANNELS * nbInt16InChar)) {
-      toSend = size * CHANNELS * nbInt16InChar;
-    }
-    audiolayer->urgentRingBuffer().Put(buf_ctrl_vol, toSend);
+    audiolayer->putUrgent(buf_ctrl_vol, size * CHANNELS * nbInt16InChar);
 
     // We activate the stream if it's not active yet.
     if (!audiolayer->isStreamActive()) {
@@ -1509,24 +1498,31 @@ ManagerImpl::getConfigList(const std::string& sequenceId, const std::string& nam
 bool 
 ManagerImpl::getAudioDeviceList(const std::string& sequenceId) 
 {
-  TokenList tk;
-  portaudio::System& sys = portaudio::System::instance();
+  bool returnValue = false;
+  try {
+    // TODO: test when there is an error on initializing...
+    TokenList tk;
+    portaudio::System& sys = portaudio::System::instance();
 
-  const char *hostApiName;
-  const char *deviceName;
+    const char *hostApiName;
+    const char *deviceName;
 
-  for (int index = 0; index < sys.deviceCount(); index++ ) {
-    portaudio::Device& device = sys.deviceByIndex(index);
-    hostApiName = device.hostApi().name();
-    deviceName  = device.name();
+    for (int index = 0; index < sys.deviceCount(); index++ ) {
+      portaudio::Device& device = sys.deviceByIndex(index);
+      hostApiName = device.hostApi().name();
+      deviceName  = device.name();
 
-    tk.clear();
-    std::ostringstream str; str << index; tk.push_back(str.str());
-    tk.push_back(deviceName);
-    tk.push_back(std::string(hostApiName));
-    _gui->sendMessage("100", sequenceId, tk);
+      tk.clear();
+      std::ostringstream str; str << index; tk.push_back(str.str());
+      tk.push_back(deviceName);
+      tk.push_back(std::string(hostApiName));
+      _gui->sendMessage("100", sequenceId, tk);
+    }
+    returnValue = true;
+  } catch (...) {
+    returnValue = false;
   }
-  return true;
+  return returnValue;
 }
 
 bool
diff --git a/src/sipcall.cpp b/src/sipcall.cpp
index c6eb8e8744..644657793f 100644
--- a/src/sipcall.cpp
+++ b/src/sipcall.cpp
@@ -44,7 +44,6 @@ SipCall::SipCall (CALLID id, CodecDescriptorVector* cdv) : _localIp("127.0.0.1")
   alloc(); // char* allocation
   _cdv = cdv;
   _audiocodec = NULL;
-  enable_audio = false;
 
   _local_audio_port = 0;
   _remote_sdp_audio_port = 0;
@@ -262,7 +261,6 @@ SipCall::newIncomingCall (eXosip_event_t *event) {
       eXosip_call_send_answer (_tid, 415, NULL);
       _debug("< Sending Answer 415\n");
     } else {
-      enable_audio = false;
 
       sdp_message_t *local_sdp = eXosip_get_sdp_info(answer);
       sdp_media_t *local_med = NULL;
@@ -397,18 +395,17 @@ SipCall::answeredCall(eXosip_event_t *event) {
 void
 SipCall::answeredCall_without_hold (eXosip_event_t *event) 
 {
-  if (enable_audio == true && event->response != NULL) {
+  if (event->response == NULL ) { return; }
+
+  if (_cid!=0) {
     sdp_message_t *sdp = eXosip_get_sdp_info (event->response);
     if (sdp != NULL) {
         /* audio is started and session has just been modified */
-      enable_audio = false;
       sdp_message_free (sdp);
     }
   }
 
-  if (enable_audio == false && 
-      event->request  != NULL && 
-      event->response != NULL) {   /* audio is started */ 
+  if (event->request != NULL) {   /* audio is started */ 
 
     sdp_message_t *local_sdp = eXosip_get_sdp_info (event->request);
     sdp_message_t *remote_sdp = eXosip_get_sdp_info (event->response);
diff --git a/src/sipcall.h b/src/sipcall.h
index 87f2e6fd84..bbeea534a2 100644
--- a/src/sipcall.h
+++ b/src/sipcall.h
@@ -44,7 +44,6 @@ public:
 	~SipCall (void);
 
   int payload;
-  bool enable_audio; /* true = started, false = stopped */
 	
 	/*
 	 * Store information about incoming call and negociate payload
diff --git a/src/sipvoiplink.cpp b/src/sipvoiplink.cpp
index d68d0b5deb..25e53f2f52 100644
--- a/src/sipvoiplink.cpp
+++ b/src/sipvoiplink.cpp
@@ -402,7 +402,6 @@ SipVoIPLink::hangup (CALLID id)
   eXosip_unlock();
 
   // Release RTP channels
-  sipcall->enable_audio = false;
   _audiortp.closeRtpSession();
 
   deleteSipCall(id);
@@ -482,15 +481,14 @@ SipVoIPLink::onhold (CALLID id)
     osip_message_set_content_type (invite, "application/sdp");
   }
   
-  eXosip_lock ();
   // Send request
   _audiortp.closeRtpSession();
 
+  eXosip_lock ();
   i = eXosip_call_send_request (did, invite);
   eXosip_unlock ();
   
   // Disable audio
-  sipcall->enable_audio = false;
   return i;
 }
 
@@ -682,7 +680,18 @@ SipVoIPLink::getEvent (void)
     // proceeding call...
     break;
 
-    // The peer-user answers
+  case EXOSIP_CALL_RINGING: // 9 peer call is ringing
+    id = findCallIdInitial(event);
+    _debug("Call is ringing [id = %d, cid = %d, did = %d]\n", id, event->cid, event->did);
+    if (id != 0) {
+      getSipCall(id)->ringingCall(event);
+      Manager::instance().peerRingingCall(id);
+    } else {
+      returnValue = -1;
+    }
+    break;
+
+  // The peer-user answers
   case EXOSIP_CALL_ANSWERED: // 10
   {
     id = findCallIdInitial(event);
@@ -717,17 +726,6 @@ SipVoIPLink::getEvent (void)
       returnValue = -1;
     }
   }
-  case EXOSIP_CALL_RINGING: //peer call is ringing
-    id = findCallIdInitial(event);
-    _debug("Call is ringing [id = %d, cid = %d, did = %d]\n", id, event->cid, event->did);
-    if (id != 0) {
-      getSipCall(id)->ringingCall(event);
-      Manager::instance().peerRingingCall(id);
-    } else {
-      returnValue = -1;
-    }
-    break;
-
   case EXOSIP_CALL_REDIRECTED:
     break;
 
@@ -748,7 +746,6 @@ SipVoIPLink::getEvent (void)
     if (id != 0) {
       if (Manager::instance().callCanBeClosed(id)) {
          sipcall = getSipCall(id);
-         if ( sipcall != NULL ) { sipcall->enable_audio = false; }
          _audiortp.closeRtpSession();
       }
       Manager::instance().peerHungupCall(id);
-- 
GitLab