diff --git a/src/audio/audiolayer.cpp b/src/audio/audiolayer.cpp index 2e9650a5602f52995aee6fd9995251088df86dcb..d370b529821766b72f12ba3848d5b6a67d53ad1a 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 3c0cdab7592940fe816c13a1b8a5f432ed933a72..8349d9e6558f456e4e96c30aa1b98c7a31c3d313 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 6a65a1ffe278db2be00046a72ee0d1131a028574..7eeac7441d29a7a2b9e126919808d0feac9ce553 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 bebae80cab25f33a6252f942d4657d1f7bc8140e..baec39cc25130a0b71309906d1281a4a22693cba 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 c6eb8e8744e0a8915316cac82f794fc88eedc581..644657793f56c5c4f9eda890efe9ceb985b5a30b 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 87f2e6fd84bff1c8d0484c70a2b9fccdf8e8ecbf..bbeea534a273cd28cf3abdc38afb8a291ab63274 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 d68d0b5debf8910937f204db96d6106f15b68f63..25e53f2f5203720234d03a731b22762fa5027a10 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);