diff --git a/src/audio/alsalayer.cpp b/src/audio/alsalayer.cpp index 5409c855963e18002f45ebb8ab787a98afef0f83..3ddb66a845e3a05ac1dbeed0a829a47433d63b79 100644 --- a/src/audio/alsalayer.cpp +++ b/src/audio/alsalayer.cpp @@ -54,15 +54,25 @@ AlsaLayer::~AlsaLayer (void) AlsaLayer::closeLayer() { _debugAlsa("Close ALSA streams\n"); - - if (_audioThread) - { - _debug("Try to stop audio thread\n"); - delete _audioThread; _audioThread=NULL; + + try { + /* Stop the audio thread first */ + if (_audioThread) + { + delete _audioThread; _audioThread=NULL; + } } - + catch(...) { + _debugException("! ARTP Exception: when stopping audiortp\n"); + throw; + } + + /* Then close the audio devices */ closeCaptureStream(); closePlaybackStream(); + + _CaptureHandle = 0; + _PlaybackHandle = 0; } bool @@ -106,6 +116,7 @@ AlsaLayer::startStream(void) prepareCaptureStream (); startCaptureStream (); startPlaybackStream (); + } void @@ -116,38 +127,36 @@ AlsaLayer::stopStream(void) //stopPlaybackStream (); /* Flush the ring buffers */ - flushUrgent(); - flushMain(); + flushUrgent (); + flushMain (); + flushMic (); } int AlsaLayer::canGetMic() { - int avail; - - if (! _CaptureHandle ) - return 0; - - avail = snd_pcm_avail_update( _CaptureHandle ); - - if( avail == -EPIPE ){ - stop_capture (); - return 0; - } + if(_CaptureHandle) + return _micRingBuffer.AvailForGet(); else - return ((avail < 0)? 0:avail); + return 0; } int AlsaLayer::getMic(void *buffer, int toCopy) { - int res = 0 ; - if( _CaptureHandle ) - { - res = read( buffer, toCopy ); - adjustVolume( buffer , toCopy , SFL_PCM_CAPTURE ); - } - return res ; + if( _CaptureHandle ){ + return _micRingBuffer.Get(buffer, toCopy,100); + } + else + return 0; +} + +bool AlsaLayer::isCaptureActive(void) { + ost::MutexLock guard( _mutex ); + if( _CaptureHandle ) + return (snd_pcm_state( _CaptureHandle) == SND_PCM_STATE_RUNNING ? true : false); + else + return false; } ////////////////////////////////////////////////////////////////////////////////////////////// @@ -175,6 +184,7 @@ void AlsaLayer::closeCaptureStream (void) void AlsaLayer::startCaptureStream (void) { if(_CaptureHandle){ + _debug("Start the capture\n"); snd_pcm_start (_CaptureHandle); start_capture(); } @@ -183,6 +193,7 @@ void AlsaLayer::startCaptureStream (void) void AlsaLayer::prepareCaptureStream (void) { if (is_capture_open() ) { + _debug("Prepare the capture\n"); if(snd_pcm_prepare (_CaptureHandle) < 0) _debug("Error preparing the device\n"); prepare_capture (); } @@ -360,7 +371,7 @@ AlsaLayer::open_device(std::string pcm_p, std::string pcm_c, int flag) close_capture (); return false; } - if(!alsa_set_params( _CaptureHandle, 0, 8000 /*getSampleRate()*/ )){ + if(!alsa_set_params( _CaptureHandle, 0, 8000 )){ _debug("capture failed\n"); snd_pcm_close( _CaptureHandle ); close_capture (); @@ -368,12 +379,16 @@ AlsaLayer::open_device(std::string pcm_p, std::string pcm_c, int flag) } open_capture (); - - startCaptureStream (); + prepare_capture (); } /* Start the secondary audio thread for callbacks */ - _audioThread->start(); + try { + _audioThread->start(); + } + catch(...){ + _debug("Fail to start audio thread\n"); + } return true; } @@ -382,8 +397,6 @@ AlsaLayer::open_device(std::string pcm_p, std::string pcm_c, int flag) int AlsaLayer::write(void* buffer, int length) { - - if (_trigger_request == true) { _trigger_request = false; @@ -417,13 +430,12 @@ AlsaLayer::write(void* buffer, int length) int AlsaLayer::read( void* buffer, int toCopy) { - ost::MutexLock lock( _mutex ); + //ost::MutexLock lock( _mutex ); int samples; if(snd_pcm_state( _CaptureHandle ) == SND_PCM_STATE_XRUN) { - _debug("xrun caught before start\n"); prepareCaptureStream (); startCaptureStream (); } @@ -437,12 +449,16 @@ AlsaLayer::read( void* buffer, int toCopy) case -EIO: _debugAlsa(" XRUN capture ignored (%s)\n", snd_strerror(samples)); handle_xrun_capture(); - samples = snd_pcm_readi( _CaptureHandle, buffer, frames); - if (samples<0) samples=0; + //samples = snd_pcm_readi( _CaptureHandle, buffer, frames); + //if (samples<0) samples=0; + break; + case EPERM: + _debugAlsa(" Capture EPERM (%s)\n", snd_strerror(samples)); + prepareCaptureStream (); + startCaptureStream (); break; default: - //_debugAlsa ("Error when capturing data ***********************************************: %s\n", snd_strerror(samples)); - stopCaptureStream(); + _debugAlsa("%s\n", snd_strerror(samples)); break; } return 0; @@ -599,11 +615,12 @@ AlsaLayer::soundCardGetIndex( std::string description ) void AlsaLayer::audioCallback (void) { - int toGet, toPut, urgentAvail, normalAvail, micAvailPut, maxBytes; + int toGet, toPut, urgentAvail, normalAvail, micAvailAlsa, micAvailPut, maxBytes; unsigned short spkrVolume, micVolume; AudioLoop *tone; SFLDataFormat *out; + SFLDataFormat *in; spkrVolume = _manager->getSpkrVolume(); micVolume = _manager->getMicVolume(); @@ -650,13 +667,21 @@ void AlsaLayer::audioCallback (void) } // Additionally handle the mic's audio stream - //micAvailPut = _micRingBuffer.AvailForPut(); - //toPut = (micAvailPut <= (int)(framesPerBufferAlsa * sizeof(SFLDataFormat))) ? micAvailPut : framesPerBufferAlsa * sizeof(SFLDataFormat); - //_debug("AL: Nb sample: %d char, [0]=%f [1]=%f [2]=%f\n", toPut, in[0], in[1], in[2]); - //_micRingBuffer.Put(in, toPut, micVolume); + //if(is_capture_running()){ + micAvailAlsa = snd_pcm_avail_update(_CaptureHandle); + if(micAvailAlsa > 0) { + micAvailPut = _micRingBuffer.AvailForPut(); + toPut = (micAvailAlsa <= micAvailPut) ? micAvailAlsa : micAvailPut; + in = (SFLDataFormat*)malloc(toPut * sizeof(SFLDataFormat)); + toPut = read (in, toPut); + if (in != 0) + { + _micRingBuffer.Put(in, toPut, 100); + } + free(in); in=0; + } } - void* AlsaLayer::adjustVolume( void* buffer , int len, int stream ) { int vol, i, size; diff --git a/src/audio/alsalayer.h b/src/audio/alsalayer.h index 875e0cc14124b19963b50e7fbc947e9ba3e7ad65..1a392f691e0534eeff24ce80b20c2b8bc5c6768a 100644 --- a/src/audio/alsalayer.h +++ b/src/audio/alsalayer.h @@ -139,7 +139,7 @@ class AlsaLayer : public AudioLayer { void audioCallback (void); - bool isCaptureActive (void) { return is_capture_running (); } + bool isCaptureActive (void); private: diff --git a/src/audio/audiortp.cpp b/src/audio/audiortp.cpp index ed25feec437a4373e2dc787453a348e3e9bb510a..56dc7174d9e6acd7229f3682dc6efd68e51538f4 100644 --- a/src/audio/audiortp.cpp +++ b/src/audio/audiortp.cpp @@ -89,8 +89,8 @@ AudioRtp::closeRtpSession () { _debugException("! ARTP Exception: when stopping audiortp\n"); throw; } - //AudioLayer* audiolayer = Manager::instance().getAudioDriver(); - //audiolayer->stopStream(); + AudioLayer* audiolayer = Manager::instance().getAudioDriver(); + audiolayer->stopStream(); } //////////////////////////////////////////////////////////////////////////////// @@ -240,7 +240,7 @@ AudioRtpRTX::sendSessionFromMic(int timestamp) // 2. convert it to int16 - good sample, good rate // 3. encode it // 4. send it - try { + //try { timestamp += time->getSecond(); if (_ca==0) { _debug(" !ARTP: No call associated (mic)\n"); return; } // no call, so we do nothing @@ -279,10 +279,10 @@ AudioRtpRTX::sendSessionFromMic(int timestamp) } else { _session->putData(timestamp, micDataEncoded, compSize); } - } catch(...) { + /*} catch(...) { _debugException("! ARTP: sending failed"); throw; - } + }*/ } void @@ -291,7 +291,7 @@ AudioRtpRTX::receiveSessionForSpkr (int& countTime) if (_ca == 0) { return; } - try { + //try { AudioLayer* audiolayer = Manager::instance().getAudioDriver(); if (!audiolayer) { return; } @@ -357,11 +357,10 @@ AudioRtpRTX::receiveSessionForSpkr (int& countTime) countTime += time->getSecond(); } delete adu; adu = NULL; - } catch(...) { - _debugException("! ARTP: receiving failed"); - throw; - } - + //} catch(...) { + //_debugException("! ARTP: receiving failed"); + //throw; + //} } @@ -388,7 +387,7 @@ AudioRtpRTX::run () { initBuffers(); int step; - try { + //try { // Init the session initAudioRtpSession(); step = (int) (_layerFrameSize * _codecSampleRate / 1000); @@ -425,15 +424,16 @@ AudioRtpRTX::run () { } //_debug("stop stream for audiortp loop\n"); audiolayer->stopStream(); - } catch(std::exception &e) { - _start.post(); - _debug("! ARTP: Stop %s\n", e.what()); - throw; - } catch(...) { - _start.post(); - _debugException("* ARTP Action: Stop"); - throw; - } + _debug("- ARTP Action: Stop\n"); + //} catch(std::exception &e) { + //_start.post(); + //_debug("! ARTP: Stop %s\n", e.what()); + //throw; + //} catch(...) { + //_start.post(); + //_debugException("* ARTP Action: Stop"); + //throw; + //} } diff --git a/src/iaxvoiplink.cpp b/src/iaxvoiplink.cpp index f085ea1544981952c128c736071261fca0d7ceed..bb7d060895507de250eb10054c742b15e51c565a 100644 --- a/src/iaxvoiplink.cpp +++ b/src/iaxvoiplink.cpp @@ -248,7 +248,7 @@ IAXVoIPLink::sendAudioFromMic(void) // Audio codec still not determined. if (audiolayer) { // To keep latency low.. - //audiolayer->flushMic(); + audiolayer->flushMic(); } return; } @@ -412,8 +412,8 @@ IAXVoIPLink::answer(const CallID& id) call->setState(Call::Active); call->setConnectionState(Call::Connected); // Start audio + audiolayer->flushMic(); audiolayer->startStream(); - //audiolayer->flushMic(); return true; } @@ -621,7 +621,7 @@ IAXVoIPLink::iaxHandleCallEvent(iax_event* event, IAXCall* call) } Manager::instance().peerAnsweredCall(id); - //audiolayer->flushMic(); + audiolayer->flushMic(); audiolayer->startStream(); // start audio here? } else { @@ -637,8 +637,8 @@ IAXVoIPLink::iaxHandleCallEvent(iax_event* event, IAXCall* call) break; case IAX_EVENT_VOICE: - if (!audiolayer->isCaptureActive ()) - audiolayer->startStream (); + //if (!audiolayer->isCaptureActive ()) + // audiolayer->startStream (); iaxHandleVoiceEvent(event, call); break; diff --git a/src/sipvoiplink.cpp b/src/sipvoiplink.cpp index 52e31d4350cfa41b5eb63a6f8f2f427fe69659fb..527876d6aefc78099b2366c37cfc4cf4f09623f9 100644 --- a/src/sipvoiplink.cpp +++ b/src/sipvoiplink.cpp @@ -522,7 +522,7 @@ SIPVoIPLink::onhold(const CallID& id) call->setState(Call::Hold); _debug("* SIP Info: Stopping AudioRTP for onhold action\n"); //_mutexSIP.enterMutex(); - _audiortp->closeRtpSession(); + _audiortp->closeRtpSession(); //_mutexSIP.leaveMutex(); local_sdp = call->getLocalSDPSession();