diff --git a/src/audio/audiolayer.cpp b/src/audio/audiolayer.cpp index c5ba9570e5289fe37b6b150be333ea1264199bc3..b179db8002f26f7d6fff5c19b5911b7199e40828 100644 --- a/src/audio/audiolayer.cpp +++ b/src/audio/audiolayer.cpp @@ -28,11 +28,11 @@ #include "../global.h" #include "../manager.h" -AudioLayer::AudioLayer () +AudioLayer::AudioLayer(ManagerImpl& manager) : _urgentRingBuffer(SIZEBUF) , _mainSndRingBuffer(SIZEBUF) , _micRingBuffer(SIZEBUF) - , _stream(NULL) + , _stream(NULL), _manager(manager) { portaudio::System::initialize(); listDevices(); @@ -98,7 +98,7 @@ void AudioLayer::startStream(void) { ost::MutexLock guard(_mutex); - if (Manager::instance().isDriverLoaded()) { + if (_manager.isDriverLoaded()) { if (_stream && !_stream->isActive()) { _debug("Thread: start audiolayer stream\n"); _stream->start(); @@ -110,10 +110,11 @@ void AudioLayer::stopStream(void) { ost::MutexLock guard(_mutex); - if (Manager::instance().isDriverLoaded()) { + if (_manager.isDriverLoaded()) { if (_stream && !_stream->isStopped()) { _debug("Thread: stop audiolayer stream\n"); _stream->stop(); + _mainSndRingBuffer.flush(); } } } @@ -142,6 +143,14 @@ AudioLayer::putMain(void* buffer, int toCopy) ost::MutexLock guard(_mutex); _mainSndRingBuffer.Put(buffer, toCopy); } + +void +AudioLayer::flushMain() +{ + ost::MutexLock guard(_mutex); + _mainSndRingBuffer.flush(); +} + void AudioLayer::putUrgent(void* buffer, int toCopy) { @@ -165,13 +174,14 @@ AudioLayer::audioCallback (const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags) { - (void) timeInfo; - (void) statusFlags; + + (void) timeInfo; + (void) statusFlags; int16 *in = (int16 *) inputBuffer; int16 *out = (int16 *) outputBuffer; int toGet, toPut, urgentAvail, normalAvail, micAvailPut; - + urgentAvail = _urgentRingBuffer.AvailForGet(); if (urgentAvail > 0) { // Urgent data (dtmf, incoming call signal) come first. @@ -180,11 +190,10 @@ AudioLayer::audioCallback (const void *inputBuffer, void *outputBuffer, } else { toGet = framesPerBuffer; } - _urgentRingBuffer.Get(out, SAMPLES_SIZE(toGet)); + _urgentRingBuffer.Get(out, SAMPLES_SIZE(toGet), _manager.getSpkrVolume()); // Consume the regular one as well (same amount of bytes) _mainSndRingBuffer.Discard(SAMPLES_SIZE(toGet)); - } else { // If nothing urgent, play the regular sound samples @@ -194,19 +203,18 @@ AudioLayer::audioCallback (const void *inputBuffer, void *outputBuffer, //_debug("%d vs %d : %d\t", normalAvail, (int)framesPerBuffer, toGet); if (toGet) { - _mainSndRingBuffer.Get(out, SAMPLES_SIZE(toGet)); + _mainSndRingBuffer.Get(out, SAMPLES_SIZE(toGet), _manager.getSpkrVolume()); } else { toGet = SAMPLES_SIZE(framesPerBuffer); _mainSndRingBuffer.PutZero(toGet); - _mainSndRingBuffer.Get(out, toGet); + _mainSndRingBuffer.Get(out, toGet, 0); } } // Additionally handle the mike's audio stream micAvailPut = _micRingBuffer.AvailForPut(); - toPut = (micAvailPut <= (int)framesPerBuffer) ? micAvailPut : - framesPerBuffer; - _micRingBuffer.Put(in, SAMPLES_SIZE(toPut)); + toPut = (micAvailPut <= (int)framesPerBuffer) ? micAvailPut : framesPerBuffer; + _micRingBuffer.Put(in, SAMPLES_SIZE(toPut), _manager.getMicVolume()); return paContinue; } diff --git a/src/audio/audiolayer.h b/src/audio/audiolayer.h index 69a0d4db36fd64adeda82491c324e156a1e74452..9ed53488a7cbbbd7f06ee88155ea572dbf2962c7 100644 --- a/src/audio/audiolayer.h +++ b/src/audio/audiolayer.h @@ -29,6 +29,7 @@ #include "../global.h" #include "ringbuffer.h" #include <cc++/thread.h> +#include "../manager.h" #define FRAME_PER_BUFFER 160 #define MIC_CHANNELS 2 // 1=mono 2=stereo @@ -38,10 +39,9 @@ class RingBuffer; - class AudioLayer { public: - AudioLayer(); + AudioLayer(ManagerImpl& manager); ~AudioLayer (void); void listDevices(); @@ -52,6 +52,7 @@ public: bool isStreamActive (void); bool isStreamStopped (void); + void flushMain(); void putMain(void* buffer, int toCopy); void putUrgent(void* buffer, int toCopy); @@ -59,7 +60,6 @@ public: const PaStreamCallbackTimeInfo*, PaStreamCallbackFlags); inline RingBuffer &urgentRingBuffer(void) { return _urgentRingBuffer; } - inline RingBuffer &mainSndRingBuffer(void) { return _mainSndRingBuffer; } inline RingBuffer &micRingBuffer(void) { return _micRingBuffer; } private: @@ -71,6 +71,7 @@ private: portaudio::MemFunCallbackStream<AudioLayer> *_stream; portaudio::AutoSystem autoSys; ost::Mutex _mutex; + ManagerImpl& _manager; }; #endif // _AUDIO_LAYER_H_ diff --git a/src/audio/audiortp.cpp b/src/audio/audiortp.cpp index 03e1e7607afdbe9a2d17a960f5190c623574ab74..55f7f3bc270fe99e1785c438abae58ec1d224f01 100644 --- a/src/audio/audiortp.cpp +++ b/src/audio/audiortp.cpp @@ -29,7 +29,6 @@ #include "audiocodec.h" #include "audiortp.h" #include "audiolayer.h" -#include "codecDescriptor.h" #include "ringbuffer.h" #include "../user_cfg.h" #include "../sipcall.h" @@ -73,29 +72,16 @@ AudioRtp::createNewSession (SipCall *ca) { void -AudioRtp::closeRtpSession (SipCall *ca) { - // This will make RTP threads finish. - if (ca) { - if (ca->enable_audio > 0) { - ca->enable_audio = -1; - - if (_RTXThread != NULL) { - _debug("Thread: stop AudioRTP for sipcall: %d\n", ca->getId()); - delete _RTXThread; _RTXThread = NULL; - } - } - } else { - _debug("Thread: stop AudioRTP for no sipcall\n"); - delete _RTXThread; _RTXThread = NULL; - } +AudioRtp::closeRtpSession () { + // This will make RTP threads finish. + delete _RTXThread; _RTXThread = NULL; } //////////////////////////////////////////////////////////////////////////////// // AudioRtpRTX Class // //////////////////////////////////////////////////////////////////////////////// -AudioRtpRTX::AudioRtpRTX (SipCall *sipcall, - AudioLayer* driver, - bool sym) { +AudioRtpRTX::AudioRtpRTX (SipCall *sipcall, AudioLayer* driver, + bool sym) : _codecBuilder(0) { time = new ost::Time(); _ca = sipcall; _sym = sym; @@ -123,6 +109,7 @@ AudioRtpRTX::~AudioRtpRTX () { } catch (...) { _debug("AudioRtpRTX: try to terminate, but catch an exception...\n"); } + _ca = NULL; _debug("Thread: AudioRtpRTX stop session\n"); if (!_sym) { delete _sessionRecv; _sessionRecv = NULL; @@ -189,7 +176,8 @@ AudioRtpRTX::initAudioRtpSession (void) } void -AudioRtpRTX::sendSessionFromMic (unsigned char* data_to_send, int16* data_from_mic, int16* data_from_mic_tmp, int timestamp, int micVolume) +// AudioRtpRTX::sendSessionFromMic (unsigned char* data_to_send, int16* data_from_mic, int16* data_from_mic_tmp, int timestamp, int micVolume) +AudioRtpRTX::sendSessionFromMic (unsigned char* data_to_send, int16* data_from_mic, int16* data_from_mic_tmp, int timestamp) { int k; int compSize; @@ -204,34 +192,34 @@ 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, - SAMPLES_SIZE(bytesAvail)); + Manager::instance().getAudioDriver()->micRingBuffer().Get(data_from_mic, SAMPLES_SIZE(bytesAvail), 0); // control volume and stereo->mono for (int j = 0; j < RTP_FRAMES2SEND; j++) { - k = j*2; - data_from_mic_tmp[j] = (int16)(0.5f*(data_from_mic[k] + - data_from_mic[k+1]) * - micVolume/100); + k = j<<1; + data_from_mic_tmp[j] = (int16)(0.5f*(data_from_mic[k] + data_from_mic[k+1])); + //micVolume/100); } - // Encode acquired audio sample - compSize = _ca->getAudioCodec()->codecEncode (data_to_send, - data_from_mic_tmp, - RTP_FRAMES2SEND*2); - // Send encoded audio sample over the network - if (!_sym) { - _sessionSend->putData(timestamp, data_to_send, compSize); - } else { - _session->putData(timestamp, data_to_send, compSize); - } - + if ( _ca != NULL ) { + // Encode acquired audio sample + AudioCodec* ac = _ca->getAudioCodec(); + if ( ac != NULL ) { + compSize = ac->codecEncode (data_to_send, data_from_mic_tmp, RTP_FRAMES2SEND*2); + // Send encoded audio sample over the network + if (!_sym) { + _sessionSend->putData(timestamp, data_to_send, compSize); + } else { + _session->putData(timestamp, data_to_send, compSize); + } + } + } } void AudioRtpRTX::receiveSessionForSpkr (int16* data_for_speakers, - int16* data_for_speakers_tmp, int spkrVolume, int& countTime) +// int16* data_for_speakers_tmp, int spkrVolume, int& countTime) + int16* data_for_speakers_tmp, int& countTime) { - int expandedSize; int k; const ost::AppDataUnit* adu = NULL; @@ -242,31 +230,33 @@ AudioRtpRTX::receiveSessionForSpkr (int16* data_for_speakers, adu = _session->getData(_session->getFirstTimestamp()); } if (adu == NULL) { -// Manager::instance().getAudioDriver()->mainSndRingBuffer().flush(); -// Manager::instance().getAudioDriver()->stopStream(); + Manager::instance().getAudioDriver()->flushMain(); return; } - // Decode data with relevant codec - CodecDescriptor* cd = new CodecDescriptor (adu->getType()); - - AudioCodec* ac = cd->alloc(adu->getType(), ""); + int payload = adu->getType(); + unsigned char* data = (unsigned char*)adu->getData(); + unsigned int size = adu->getSize(); - expandedSize = ac->codecDecode (data_for_speakers, - (unsigned char*) adu->getData(), - adu->getSize()); - - // control volume for speakers and mono->stereo - for (int j = 0; j < expandedSize; j++) { - k = j*2; - data_for_speakers_tmp[k] = data_for_speakers_tmp[k+1]= - data_for_speakers[j] * spkrVolume/100; + // Decode data with relevant codec + int expandedSize = 0; + AudioCodec* ac = _codecBuilder.alloc(payload, ""); + if (ac != NULL) { + expandedSize = ac->codecDecode (data_for_speakers, data, size); } + ac = NULL; + + // control volume for speakers and mono->stereo + for (int j = 0; j < expandedSize; j++) { + k = j<<1; // fast multiply by two + data_for_speakers_tmp[k] = data_for_speakers_tmp[k+1] = data_for_speakers[j]; + // * spkrVolume/100; + } - // If the current call is the call which is answered - // Set decoded data to sound device - Manager::instance().getAudioDriver()->putMain(data_for_speakers_tmp, SAMPLES_SIZE(RTP_FRAMES2SEND)); - //} + // If the current call is the call which is answered + // Set decoded data to sound device + Manager::instance().getAudioDriver()->putMain(data_for_speakers_tmp, SAMPLES_SIZE(RTP_FRAMES2SEND)); + //} // Notify (with a beep) an incoming call when there is already a call countTime += time->getSecond(); @@ -279,15 +269,13 @@ AudioRtpRTX::receiveSessionForSpkr (int16* data_for_speakers, Manager::instance().getAudioDriver()->startStream(); - delete ac; ac = NULL; - delete cd; cd = NULL; delete adu; adu = NULL; } void AudioRtpRTX::run (void) { - int micVolume; - int spkrVolume; +// int micVolume; +// int spkrVolume; unsigned char *data_to_send; int16 *data_from_mic; int16 *data_from_mic_tmp; @@ -314,7 +302,6 @@ AudioRtpRTX::run (void) { // flush stream: ManagerImpl& manager = Manager::instance(); AudioLayer *audiolayer = manager.getAudioDriver(); - audiolayer->mainSndRingBuffer().flush(); audiolayer->urgentRingBuffer().flush(); // start running the packet queue scheduler. @@ -326,23 +313,23 @@ AudioRtpRTX::run (void) { _session->startRunning(); } - while (!testCancel() && _ca->enable_audio != -1) { - micVolume = manager.getMicVolume(); - spkrVolume = manager.getSpkrVolume(); + while (!testCancel() && _ca != NULL && _ca->enable_audio != -1) { + //micVolume = manager.getMicVolume(); + //spkrVolume = manager.getSpkrVolume(); //////////////////////////// // Send session //////////////////////////// - sendSessionFromMic(data_to_send, data_from_mic, data_from_mic_tmp, - timestamp, micVolume); + //sendSessionFromMic(data_to_send, data_from_mic, data_from_mic_tmp, timestamp, micVolume); + sendSessionFromMic(data_to_send, data_from_mic, data_from_mic_tmp, timestamp); timestamp += RTP_FRAMES2SEND; //////////////////////////// // Recv session //////////////////////////// - receiveSessionForSpkr(data_for_speakers, data_for_speakers_tmp, - spkrVolume, countTime); + //receiveSessionForSpkr(data_for_speakers, data_for_speakers_tmp, spkrVolume, countTime); + receiveSessionForSpkr(data_for_speakers, data_for_speakers_tmp, countTime); // Let's wait for the next transmit cycle Thread::sleep(TimerPort::getTimer()); @@ -356,8 +343,6 @@ AudioRtpRTX::run (void) { delete [] data_from_mic; data_from_mic = 0; audiolayer->stopStream(); - audiolayer->mainSndRingBuffer().flush(); - //audiolayer->urgentRingBuffer().flush(); } diff --git a/src/audio/audiortp.h b/src/audio/audiortp.h index 273136cdd6ae72ed4e0297f79bf7492632c6e1c5..716296f5eb1b9a8be0f1c649d91bb1f62c683559 100644 --- a/src/audio/audiortp.h +++ b/src/audio/audiortp.h @@ -25,6 +25,7 @@ #include <ccrtp/rtp.h> #include <cc++/numbers.h> +#include "codecDescriptor.h" #define RTP_FRAMES2SEND 160 @@ -52,9 +53,14 @@ private: ost::SymmetricRTPSession *_session; bool _sym; + // build codec... + CodecDescriptor _codecBuilder; + void initAudioRtpSession (void); - void sendSessionFromMic (unsigned char*, int16*, int16*, int, int); - void receiveSessionForSpkr (int16*, int16*, int, int&); +// void sendSessionFromMic (unsigned char*, int16*, int16*, int, int); + void sendSessionFromMic (unsigned char*, int16*, int16*, int); +// void receiveSessionForSpkr (int16*, int16*, int, int&); + void receiveSessionForSpkr (int16*, int16*, int&); }; /////////////////////////////////////////////////////////////////////////////// @@ -66,7 +72,7 @@ public: ~AudioRtp(); int createNewSession (SipCall *); - void closeRtpSession (SipCall *); + void closeRtpSession (); private: AudioRtpRTX* _RTXThread; diff --git a/src/audio/codecDescriptor.cpp b/src/audio/codecDescriptor.cpp index 7c64f397a793ca191011af361b13e62ec35efd5e..9e5feae22bb35eebff797bf9934da20a62119a47 100644 --- a/src/audio/codecDescriptor.cpp +++ b/src/audio/codecDescriptor.cpp @@ -46,36 +46,63 @@ CodecDescriptor::CodecDescriptor (int payload) { _payload = payload; _codecName = rtpmapPayload(_payload); + initCache(); } CodecDescriptor::CodecDescriptor (const std::string& name) { _codecName = name; _payload = matchPayloadCodec(name); + initCache(); } CodecDescriptor::CodecDescriptor (int payload, const std::string& name) { _payload = payload; _codecName = name; + initCache(); } -CodecDescriptor::~CodecDescriptor (void) +void CodecDescriptor::initCache() { + _ac1 = NULL; + _ac2 = NULL; + _ac3 = NULL; +} + + +CodecDescriptor::~CodecDescriptor (void) +{ + delete _ac1; + delete _ac2; + delete _ac3; } AudioCodec* CodecDescriptor::alloc (int payload, const std::string& name) { + // _ac1, _ac2 and _ac3 are caching... switch(payload) { case PAYLOAD_CODEC_ULAW: - return new Ulaw(payload, name); + if ( _ac1 == NULL ) { + _ac1 = new Ulaw(payload, name); + //return new Ulaw(payload, name); + } + return _ac1; break; case PAYLOAD_CODEC_ALAW: - return new Alaw(payload, name); + if ( _ac2 == NULL ) { + _ac2 = new Alaw(payload, name); + //return new Alaw(payload, name); + } + return _ac2; break; case PAYLOAD_CODEC_GSM: - return new Gsm(payload, name); + if ( _ac3 == NULL ) { + _ac3 = new Gsm(payload, name); + //return new Gsm(payload, name); + } + return _ac3; break; default: return NULL; diff --git a/src/audio/codecDescriptor.h b/src/audio/codecDescriptor.h index 4ca94aea42402656a83343789ac7829d654ead1b..db8e6a96dd3710f3f667bea7c891ecde70815d51 100644 --- a/src/audio/codecDescriptor.h +++ b/src/audio/codecDescriptor.h @@ -77,8 +77,13 @@ public: std::string rtpmapPayload (int); private: + void initCache(); int _payload; std::string _codecName; + + AudioCodec* _ac1; + AudioCodec* _ac2; + AudioCodec* _ac3; }; #endif // __CODEC_DESCRIPTOR_H__ diff --git a/src/audio/gsmcodec.cpp b/src/audio/gsmcodec.cpp index 36767d1c410c18f8e7fb6bd99c8ad1273e20481b..60d54eda887faf917524db2bd74780476aaec9ae 100644 --- a/src/audio/gsmcodec.cpp +++ b/src/audio/gsmcodec.cpp @@ -36,7 +36,6 @@ Gsm::~Gsm (void) { gsm_destroy(_decode_gsmhandle); gsm_destroy(_encode_gsmhandle); - } int diff --git a/src/audio/ringbuffer.cpp b/src/audio/ringbuffer.cpp index 54168f31dce3783f25e9ced2738a75f4d596a225..c7825b35ff7271c41cd16b63f0f18960b5859d17 100644 --- a/src/audio/ringbuffer.cpp +++ b/src/audio/ringbuffer.cpp @@ -50,10 +50,8 @@ RingBuffer::~RingBuffer() { void RingBuffer::flush (void) { - mMutex.enterMutex(); mStart = 0; mEnd = 0; - mMutex.leaveMutex(); } int @@ -78,19 +76,19 @@ RingBuffer::PutZero(int toZero) } // This one puts some data inside the ring buffer. +// Change the volume if it's not 0 int -RingBuffer::Put(void* buffer, int toCopy) { +RingBuffer::Put(void* buffer, int toCopy, unsigned short volume) { samplePtr src; int block; int copied; int pos; int len = Len(); - mMutex.enterMutex(); if (toCopy > (mBufferSize-4) - len) toCopy = (mBufferSize-4) - len; - src = (samplePtr) buffer; + src = (samplePtr) buffer; copied = 0; pos = mEnd; @@ -98,9 +96,15 @@ RingBuffer::Put(void* buffer, int toCopy) { while(toCopy) { block = toCopy; if (block > mBufferSize - pos) // from current pos. to end of buffer - block = mBufferSize - pos; + block = mBufferSize - pos; // put the data inside the buffer. + if (volume) { + int16* src16 = (int16*)src; + int int16len = (block >> 1); + for (int i=0; i< int16len; i++) { src16[i] = src16[i] * volume / 100; } + } + // bcopy(src, dest, len) bcopy (src, mBuffer + pos, block); src += block; @@ -110,7 +114,6 @@ RingBuffer::Put(void* buffer, int toCopy) { } mEnd = pos; - mMutex.leaveMutex(); // How many items copied. return copied; @@ -128,13 +131,14 @@ RingBuffer::AvailForGet() const { // Get will move 'toCopy' bytes from the internal FIFO to 'buffer' int -RingBuffer::Get(void *buffer, int toCopy) { +RingBuffer::Get(void *buffer, int toCopy, unsigned short volume) { samplePtr dest; int block; int copied; int len = Len(); - - mMutex.enterMutex(); + int int16len; + int16* start; + if (toCopy > len) toCopy = len; @@ -146,14 +150,17 @@ RingBuffer::Get(void *buffer, int toCopy) { if (block > (mBufferSize - mStart)) block = mBufferSize - mStart; - bcopy (mBuffer + mStart, dest, block); + start = (int16*)(mBuffer + mStart); + int16len = (block >> 1); + for (int i=0; i<int16len; i++) { start[i] = start[i] * volume / 100; } + // bcopy(src, dest, len) + bcopy (start, dest, block); dest += block; mStart = (mStart + block) % mBufferSize; toCopy -= block; copied += block; } - mMutex.leaveMutex(); return copied; } @@ -169,10 +176,3 @@ RingBuffer::Discard(int toDiscard) { return toDiscard; } - -/* -T -RingBuffer::getNextItem (void) { - return (T) 0; -} -*/ diff --git a/src/audio/ringbuffer.h b/src/audio/ringbuffer.h index c18f82b08f614608ecc41018bee594c44ae0bfeb..9e1ef6bef4177f45a0f92e7ef5e9d59982fcc411 100644 --- a/src/audio/ringbuffer.h +++ b/src/audio/ringbuffer.h @@ -42,14 +42,14 @@ class RingBuffer { // For the writer only: // int AvailForPut (void) const; - int Put (void*, int); + int Put (void*, int, unsigned short = 0); void PutZero(int); // // For the reader only: // int AvailForGet (void) const; - int Get (void *, int); + int Get (void *, int, unsigned short); int Discard(int); int Len() const; @@ -57,7 +57,6 @@ class RingBuffer { private: // T getNextSample(void); - ost::Mutex mMutex; int mStart; int mEnd; int mBufferSize; diff --git a/src/audio/tonegenerator.cpp b/src/audio/tonegenerator.cpp index c7b1488e4a2833b6e139fb3bb837941d4154d8ff..7a430f38179c90e1ec9f3355a75af7a76ff5061c 100644 --- a/src/audio/tonegenerator.cpp +++ b/src/audio/tonegenerator.cpp @@ -56,7 +56,7 @@ ToneThread::~ToneThread (void) { void ToneThread::run (void) { int k; - int spkrVolume; + //int spkrVolume; bool started = false; // How long do 'size' samples play ? @@ -64,14 +64,16 @@ ToneThread::run (void) { unsigned int pause = (size * 1000) / SAMPLING_RATE - 100; ManagerImpl& manager = Manager::instance(); - manager.getAudioDriver()->mainSndRingBuffer().flush(); + manager.getAudioDriver()->flushMain(); while (!testCancel()) { // Create a new stereo buffer with the volume adjusted - spkrVolume = manager.getSpkrVolume(); + //spkrVolume = manager.getSpkrVolume(); for (int j = 0; j < size; j++) { - k = j*2; // channels is 2 (global.h) - buf_ctrl_vol[k] = buf_ctrl_vol[k+1] = buffer[j] * spkrVolume/100; + k = j<<1; // channels is 2 (global.h) + // split in two + buf_ctrl_vol[k] = buf_ctrl_vol[k+1] = buffer[j]; + // * spkrVolume/100; } // Push the tone to the audio FIFO diff --git a/src/call.cpp b/src/call.cpp index 3804e160d325db2c497c8c13d0f714c192bc4dfc..e1b74afc2c8419b589d48bf72f831590fdf37e51 100644 --- a/src/call.cpp +++ b/src/call.cpp @@ -185,7 +185,7 @@ Call::isAnswered (void) bool Call::isNotAnswered (void) { - return (_state == Error || _state == NotExist ) ? true : false; + return (_state == Error || _state == NotExist || _state == Busy) ? true : false; } bool diff --git a/src/gui/server/tcpstreampool.h b/src/gui/server/tcpstreampool.h index 46f8e90af0d61e9389f48879652d0c59d8fe3d98..6bec3bd783f1fec6ae55c9071bbace7356084457 100644 --- a/src/gui/server/tcpstreampool.h +++ b/src/gui/server/tcpstreampool.h @@ -43,6 +43,7 @@ public: { setCancel(cancelDeferred); } + TCPStreamPool::~TCPStreamPool() {terminate();} void run(); void send(const std::string& response); diff --git a/src/managerimpl.cpp b/src/managerimpl.cpp index 3656c65cd71578dbea9ab7958fb76a9a4764d098..7716a8e8e894de15f0ec1c75899867e0351087dc 100644 --- a/src/managerimpl.cpp +++ b/src/managerimpl.cpp @@ -336,7 +336,7 @@ ManagerImpl::onHoldCall (CALLID id) if (call == NULL) { return -1; } - if ( call->getState() == Call::OnHold) { + if ( call->getState() == Call::OnHold || call->isNotAnswered()) { return 1; } return call->onHold(); @@ -349,6 +349,7 @@ ManagerImpl::onHoldCall (CALLID id) int ManagerImpl::offHoldCall (CALLID id) { + stopTone(); ost::MutexLock m(_mutex); Call* call = getCall(id); if (call == NULL) { @@ -480,6 +481,7 @@ ManagerImpl::sendDtmf (CALLID id, char code) int returnValue = false; switch (sendType) { case 0: // SIP INFO + playDtmf(code); _voIPLinkVector.at(DFT_VOIP_LINK)->carryingDTMFdigits(id, code); returnValue = true; break; @@ -509,7 +511,8 @@ ManagerImpl::playDtmf(char code) _key.startTone(code); if ( _key.generateDTMF(_buf, SAMPLING_RATE) ) { - int k, spkrVolume; + int k; + //int spkrVolume; int16* buf_ctrl_vol; // Determine dtmf pulse length @@ -517,12 +520,13 @@ ManagerImpl::playDtmf(char code) int size = pulselen * (OCTETS /1000); buf_ctrl_vol = new int16[size*CHANNELS]; - spkrVolume = getSpkrVolume(); + //spkrVolume = getSpkrVolume(); // Control volume and format mono->stereo for (int j = 0; j < size; j++) { - k = j*2; - buf_ctrl_vol[k] = buf_ctrl_vol[k+1] = _buf[j] * spkrVolume/100; + k = j<<1; // fast multiply by two + buf_ctrl_vol[k] = buf_ctrl_vol[k+1] = _buf[j]; + // * spkrVolume/100; } AudioLayer *audiolayer = getAudioDriver(); @@ -815,7 +819,6 @@ ManagerImpl::stopTone() { _tone->stopTone(); } _toneMutex.leaveMutex(); - getAudioDriver()->mainSndRingBuffer().flush(); getAudioDriver()->stopStream(); } } @@ -899,16 +902,18 @@ ManagerImpl::notificationIncomingCall (void) { int16* buf_ctrl_vol; int16* buffer = new int16[SAMPLING_RATE]; int size = SAMPLES_SIZE(FRAME_PER_BUFFER);//SAMPLING_RATE/2; - int k, spkrVolume; + int k; + //int spkrVolume; _tone->generateSin(440, 0, buffer); // Volume Control buf_ctrl_vol = new int16[size*CHANNELS]; - spkrVolume = getSpkrVolume(); + // spkrVolume = getSpkrVolume(); for (int j = 0; j < size; j++) { - k = j*2; - buf_ctrl_vol[k] = buf_ctrl_vol[k+1] = buffer[j] * spkrVolume/100; + k = j<<1; // fast multiply by two + buf_ctrl_vol[k] = buf_ctrl_vol[k+1] = buffer[j]; + // * spkrVolume/100; } getAudioDriver()->putUrgent(buf_ctrl_vol, SAMPLES_SIZE(FRAME_PER_BUFFER)); @@ -1083,7 +1088,7 @@ ManagerImpl::selectAudioDriver (void) { #if defined(AUDIO_PORTAUDIO) try { - _audiodriverPA = new AudioLayer(); + _audiodriverPA = new AudioLayer(*this); _audiodriverPA->openDevice(getConfigInt(AUDIO, DRIVER_NAME)); } catch(...) { throw; diff --git a/src/managerimpl.h b/src/managerimpl.h index 3a631a9b24e7cf824e9869af74085817dddba93d..cc5050bbf1b7d0fa52007c37c26d1e02591f97e5 100644 --- a/src/managerimpl.h +++ b/src/managerimpl.h @@ -222,13 +222,27 @@ name); void getStunInfo (StunAddress4& stunSvrAddr); bool useStun (void); - /* - * Inline functions to manage volume control - */ - inline int getSpkrVolume (void) { ost::MutexLock m(_mutex); return _spkr_volume; } - inline void setSpkrVolume (int spkr_vol) { ost::MutexLock m(_mutex); _spkr_volume = spkr_vol; } - inline int getMicVolume (void) { ost::MutexLock m(_mutex); return _mic_volume; } - inline void setMicVolume (int mic_vol) { ost::MutexLock m(_mutex); _mic_volume = _mic_volume_before_mute = mic_vol; } + /* + * Inline functions to manage volume control + * Read by main thread and AudioLayer thread + * Write by main thread only + */ + unsigned short getSpkrVolume(void) { + //ost::MutexLock m(_mutex); + return _spkr_volume; + } + void setSpkrVolume(unsigned short spkr_vol) { + //ost::MutexLock m(_mutex); + _spkr_volume = spkr_vol; + } + unsigned short getMicVolume(void) { + //ost::MutexLock m(_mutex); + return _mic_volume; + } + void setMicVolume(unsigned short mic_vol) { + //ost::MutexLock m(_mutex); + _mic_volume = _mic_volume_before_mute = mic_vol; + } bool hasLoadedSetup() { return _setupLoaded; } @@ -378,10 +392,10 @@ private: unsigned int _nCodecs; - // To handle volume control - int _spkr_volume; - int _mic_volume; - int _mic_volume_before_mute; + // To handle volume control + short _spkr_volume; + short _mic_volume; + short _mic_volume_before_mute; // To handle firewall int _firewallPort; diff --git a/src/sipcall.cpp b/src/sipcall.cpp index 2028c1481fb2a02a3445ba30b1cda76e87ee30f0..02ce78d86b61823d1dd78e30dc7a7a35e278d71b 100644 --- a/src/sipcall.cpp +++ b/src/sipcall.cpp @@ -44,7 +44,7 @@ SipCall::SipCall (CALLID id, CodecDescriptorVector* cdv) : _localIp("127.0.0.1") alloc(); // char* allocation _cdv = cdv; _audiocodec = NULL; - enable_audio = -1; + enable_audio = false; _state = 0; _local_audio_port = 0; @@ -57,7 +57,8 @@ SipCall::SipCall (CALLID id, CodecDescriptorVector* cdv) : _localIp("127.0.0.1") SipCall::~SipCall (void) { dealloc(); - delete _audiocodec; _audiocodec = NULL; + //delete _audiocodec; don't delete it, the Manager will do it... + _audiocodec = NULL; } void @@ -142,7 +143,8 @@ void SipCall::setAudioCodec (AudioCodec* ac) { // it use a new! - delete _audiocodec; _audiocodec = ac; + // delete _audiocodec; + _audiocodec = ac; } // newIncomingCall is called when the IP-Phone user receives a new call. @@ -253,10 +255,10 @@ SipCall::newIncomingCall (eXosip_event_t *event) { eXosip_call_send_answer (_tid, 415, NULL); } else { /* start sending audio */ - if (enable_audio > 0) { - enable_audio = -1; + if (enable_audio == true) { + enable_audio = false; } - if (enable_audio != 1) /* audio is started */ { + if (enable_audio == false) /* audio is started */ { sdp_message_t *local_sdp; local_sdp = eXosip_get_sdp_info (answer); if (remote_sdp != NULL && local_sdp != NULL) { @@ -284,12 +286,12 @@ SipCall::newIncomingCall (eXosip_event_t *event) { && local_med != NULL) { tmp = (char *) osip_list_get (local_med->m_payloads, 0); } - if (tmp != NULL) { - payload = atoi (tmp); - _debug("SipCall::newIncomingCall: For incoming payload = %d\n", payload); - setAudioCodec(_cdv->at(0)->alloc(payload, "")); - } - if (tmp != NULL + if (tmp != NULL) { + payload = atoi (tmp); + _debug("SipCall::newIncomingCall: For incoming payload = %d\n", payload); + setAudioCodec(_cdv->at(0)->alloc(payload, "")); // codec builder for the mic + } + if (tmp != NULL && audio_port > 0 && _remote_sdp_audio_port > 0 && _remote_sdp_audio_ip[0] != '\0') { @@ -353,64 +355,6 @@ SipCall::ringingCall (eXosip_event_t *event) { osip_free (tmp); } } -/* - sdp_message_t *remote_sdp; - sdp_message_t *local_sdp; - - local_sdp = eXosip_get_sdp_info (event->request); - remote_sdp = eXosip_get_sdp_info (event->response); - if (remote_sdp == NULL) { - _debug("SipCall::ringingCall: No remote SDP body found for call\n"); - // TODO: remote_sdp = retreive from ack above - } - if (local_sdp == NULL) { - _debug("SipCall::ringingCall: SDP body was probably in the ACK (TODO)\n"); - } - if (remote_sdp != NULL && local_sdp != NULL) { - sdp_connection_t *conn; - sdp_media_t *local_med; - sdp_media_t *remote_med; - char *tmp = NULL; - int audio_port = 0; - - conn = eXosip_get_audio_connection (remote_sdp); - if (conn != NULL && conn->c_addr != NULL) { - snprintf (_remote_sdp_audio_ip, 49, "%s", conn->c_addr); - } - remote_med = eXosip_get_audio_media (remote_sdp); - if (remote_med != NULL && remote_med->m_port != NULL) { - _remote_sdp_audio_port = atoi (remote_med->m_port); - } - local_med = eXosip_get_audio_media (local_sdp); - if (local_med != NULL && local_med->m_port != NULL) { - audio_port = atoi (local_med->m_port); - } - if (_remote_sdp_audio_port > 0 && _remote_sdp_audio_ip[0] != '\0' - && remote_med != NULL) { - tmp = (char *) osip_list_get (remote_med->m_payloads, 0); - } - if (tmp != NULL) { - ca->payload = atoi (tmp); - } - if (tmp != NULL - && audio_port > 0 - && _remote_sdp_audio_port > 0 - && _remote_sdp_audio_ip[0] != '\0') { - // search if stream is sendonly or recvonly - _remote_sendrecv = - sdp_analyse_attribute (remote_sdp, remote_med); - _local_sendrecv = sdp_analyse_attribute (local_sdp, local_med); - if (_local_sendrecv == _SENDRECV) { - if (_remote_sendrecv == _SENDONLY) - _local_sendrecv = _RECVONLY; - else if (_remote_sendrecv == _RECVONLY) - _local_sendrecv = _SENDONLY; - } - } - } - sdp_message_free (local_sdp); - sdp_message_free (remote_sdp); -*/ this->_state = event->type;; return 0; } @@ -420,74 +364,6 @@ SipCall::receivedAck (eXosip_event_t *event) { _cid = event->cid; _did = event->did; -/* - if (event->ack != NULL) { - sdp_message_t *remote_sdp; - remote_sdp = eXosip_get_sdp_info (event->ack); - if (remote_sdp != NULL) { - _debug("SipCall::receivedAck: SDP detected in ACK!\n"); - } else { - _debug("SipCall::receivedAck: no SDP detected in ACK!\n"); - } - } - - if (enable_audio != 1) { // audio is started - sdp_message_t *remote_sdp; - sdp_message_t *local_sdp; - - remote_sdp = eXosip_get_remote_sdp (_did); - local_sdp = eXosip_get_local_sdp (_did); - if (remote_sdp == NULL) { - _debug("SipCall::receivedAck: No remote SDP body found for call\n"); - } - if (remote_sdp != NULL && local_sdp != NULL) { - sdp_connection_t *conn; - sdp_media_t *local_med; - sdp_media_t *remote_med; - char *tmp = NULL; - int audio_port = 0; - - conn = eXosip_get_audio_connection (remote_sdp); - if (conn != NULL && conn->c_addr != NULL) { - snprintf (_remote_sdp_audio_ip, 49, "%s", conn->c_addr); - } - remote_med = eXosip_get_audio_media (remote_sdp); - if (remote_med != NULL && remote_med->m_port != NULL) { - _remote_sdp_audio_port = atoi (remote_med->m_port); - } - local_med = eXosip_get_audio_media (local_sdp); - if (local_med != NULL && local_med->m_port != NULL) { - audio_port = atoi (local_med->m_port); - } - - if (_remote_sdp_audio_port > 0 - && _remote_sdp_audio_ip[0] != '\0' && local_med != NULL) { - tmp = (char *) osip_list_get (local_med->m_payloads, 0); - } - if (tmp != NULL) { - ca->payload = atoi (tmp); - } - if (tmp != NULL - && audio_port > 0 - && _remote_sdp_audio_port > 0 - && _remote_sdp_audio_ip[0] != '\0') { - - // search if stream is sendonly or recvonly - _remote_sendrecv = - sdp_analyse_attribute (remote_sdp, remote_med); - _local_sendrecv = sdp_analyse_attribute (local_sdp, local_med); - if (_local_sendrecv == _SENDRECV) { - if (_remote_sendrecv == _SENDONLY) - _local_sendrecv = _RECVONLY; - else if (_remote_sendrecv == _RECVONLY) - _local_sendrecv = _SENDONLY; - } - } - } - sdp_message_free (local_sdp); - sdp_message_free (remote_sdp); - } -*/ _state = event->type; return 0; } @@ -557,16 +433,16 @@ SipCall::answeredCall(eXosip_event_t *event) { void SipCall::answeredCall_without_hold (eXosip_event_t *event) { - if (enable_audio == 1 && event->response != NULL) { + if (enable_audio == true && event->response != NULL) { sdp_message_t *sdp = eXosip_get_sdp_info (event->response); if (sdp != NULL) { /* audio is started and session has just been modified */ - enable_audio = -1; + enable_audio = false; sdp_message_free (sdp); } } - if (enable_audio != 1 && + if (enable_audio == false && event->request != NULL && event->response != NULL) { /* audio is started */ diff --git a/src/sipcall.h b/src/sipcall.h index 18cb3864ae54fbde343acc1ec2f2bf92089a903a..95626bc9636b5dfd5c0d8d666229247f599028b8 100644 --- a/src/sipcall.h +++ b/src/sipcall.h @@ -44,7 +44,7 @@ public: ~SipCall (void); int payload; - int enable_audio; /* 1 started, -1 stopped */ + 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 e187dea7728c22e32c9e7b1a3164317fba070bab..b74a707a4ace39f86bee46d20828ce55a599b60d 100644 --- a/src/sipvoiplink.cpp +++ b/src/sipvoiplink.cpp @@ -379,11 +379,16 @@ SipVoIPLink::answer (CALLID id) return i; } + +/** + * @return > 0 is good, -1 is bad + */ int SipVoIPLink::hangup (CALLID id) { int i = 0; SipCall* sipcall = getSipCall(id); + if (sipcall == NULL) { return -1; } _debug("Hang up call [id = %d, cid = %d, did = %d]\n", id, sipcall->getCid(), sipcall->getDid()); // Release SIP stack. @@ -392,7 +397,8 @@ SipVoIPLink::hangup (CALLID id) eXosip_unlock(); // Release RTP channels - _audiortp.closeRtpSession(sipcall); + sipcall->enable_audio = false; + _audiortp.closeRtpSession(); deleteSipCall(id); return i; @@ -413,6 +419,9 @@ SipVoIPLink::cancel (CALLID id) return i; } +/* + * @return -1 = sipcall not present + */ int SipVoIPLink::onhold (CALLID id) { @@ -422,12 +431,15 @@ SipVoIPLink::onhold (CALLID id) sdp_message_t *local_sdp = NULL; - did = getSipCall(id)->getDid(); - + SipCall *sipcall = getSipCall(id); + if ( sipcall == NULL ) { return -1; } + + did = sipcall->getDid(); + eXosip_lock (); local_sdp = eXosip_get_local_sdp (did); eXosip_unlock (); - + if (local_sdp == NULL) { return -1; } @@ -445,7 +457,7 @@ SipVoIPLink::onhold (CALLID id) /* add sdp body */ { char *tmp = NULL; - + i = sdp_hold_call (local_sdp); if (i != 0) { sdp_message_free (local_sdp); @@ -471,7 +483,8 @@ SipVoIPLink::onhold (CALLID id) eXosip_unlock (); // Disable audio - _audiortp.closeRtpSession(getSipCall(id)); + sipcall->enable_audio = false; + _audiortp.closeRtpSession(); return i; } @@ -740,7 +753,9 @@ SipVoIPLink::getEvent (void) _debug("Call is closed [id = %d, cid = %d, did = %d]\n", id, event->cid, event->did); if (id != 0) { if (Manager::instance().callCanBeClosed(id)) { - _audiortp.closeRtpSession(getSipCall(id)); + SipCall* sipcall = getSipCall(id); + if ( sipcall != NULL ) { sipcall->enable_audio = false; } + _audiortp.closeRtpSession(); } Manager::instance().peerHungupCall(id); deleteSipCall(id); @@ -1005,7 +1020,7 @@ SipVoIPLink::endSipCalls() eXosip_unlock(); // Release RTP channels - _audiortp.closeRtpSession(*iter); + _audiortp.closeRtpSession(); delete *iter; *iter = NULL; } iter++;