Commit a1f6c4ac authored by Alexandre Bourget's avatar Alexandre Bourget
Browse files

IAX: Dynamic codecs + Fixed samplerate conversion + Ability to receive calls

Added documentation.
parent 77751a2f
...@@ -20,13 +20,93 @@ ...@@ -20,13 +20,93 @@
#include "iaxcall.h" #include "iaxcall.h"
#include "global.h" // for _debug #include "global.h" // for _debug
IAXCall::IAXCall(const CallID& id, Call::CallType type) : Call(id, type), _session(0) IAXCall::IAXCall(const CallID& id, Call::CallType type) : Call(id, type), _session(NULL)
{ {
} }
IAXCall::~IAXCall() IAXCall::~IAXCall()
{ {
_session = 0; // just to be sure to don't have unknown pointer, do not delete it! _session = NULL; // just to be sure to don't have unknown pointer, do not delete it!
} }
void
IAXCall::setFormat(int format)
{
_format = format;
switch(format) {
case AST_FORMAT_ULAW:
setAudioCodec(_codecMap.getCodec(PAYLOAD_CODEC_ULAW)); break;
case AST_FORMAT_GSM:
setAudioCodec(_codecMap.getCodec(PAYLOAD_CODEC_GSM)); break;
case AST_FORMAT_ALAW:
setAudioCodec(_codecMap.getCodec(PAYLOAD_CODEC_ALAW)); break;
case AST_FORMAT_ILBC:
setAudioCodec(_codecMap.getCodec(PAYLOAD_CODEC_ILBC)); break;
case AST_FORMAT_SPEEX:
setAudioCodec(_codecMap.getCodec(PAYLOAD_CODEC_SPEEX)); break;
default:
setAudioCodec(NULL);
break;
}
}
int
IAXCall::getSupportedFormat()
{
CodecMap map = getCodecMap().getMap();
int format = 0;
CodecMap::iterator iter = map.begin();
while(iter != map.end()) {
switch(iter->first) {
case PAYLOAD_CODEC_ULAW:
format |= AST_FORMAT_ULAW; break;
case PAYLOAD_CODEC_GSM:
format |= AST_FORMAT_GSM; break;
case PAYLOAD_CODEC_ALAW:
format |= AST_FORMAT_ALAW; break;
case PAYLOAD_CODEC_ILBC:
format |= AST_FORMAT_ILBC; break;
case PAYLOAD_CODEC_SPEEX:
format |= AST_FORMAT_SPEEX; break;
default:
break;
}
iter++;
}
return format;
}
int
IAXCall::getFirstMatchingFormat(int needles)
{
CodecMap map = getCodecMap().getMap();
int format = 0;
CodecMap::iterator iter = map.begin();
while(iter != map.end()) {
switch(iter->first) {
case PAYLOAD_CODEC_ULAW:
format = AST_FORMAT_ULAW; break;
case PAYLOAD_CODEC_GSM:
format = AST_FORMAT_GSM; break;
case PAYLOAD_CODEC_ALAW:
format = AST_FORMAT_ALAW; break;
case PAYLOAD_CODEC_ILBC:
format = AST_FORMAT_ILBC; break;
case PAYLOAD_CODEC_SPEEX:
format = AST_FORMAT_SPEEX; break;
default:
break;
}
// Return the first that matches
if (format & needles)
return format;
iter++;
}
return 0;
}
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "call.h" #include "call.h"
#include <iax/iax-client.h> #include <iax/iax-client.h>
#include <iax/frame.h>
/** /**
* IAXCall are IAX implementation of a normal Call * IAXCall are IAX implementation of a normal Call
...@@ -33,7 +34,7 @@ public: ...@@ -33,7 +34,7 @@ public:
~IAXCall(); ~IAXCall();
/** Get the session pointer or 0 */ /** Get the session pointer or NULL */
struct iax_session* getSession() { return _session; } struct iax_session* getSession() { return _session; }
/** Set the session pointer /** Set the session pointer
...@@ -41,12 +42,49 @@ public: ...@@ -41,12 +42,49 @@ public:
*/ */
void setSession(struct iax_session* session) { _session = session; } void setSession(struct iax_session* session) { _session = session; }
void setFormat(int format) { _format = format; } /**
* Set format (one single bit
*
* This function sets the _audioCodec variable with the correct
* codec.
*/
void setFormat(int format);
/**
* Get format
*/
int getFormat() { return _format; } int getFormat() { return _format; }
/**
* Get the bitwise list of supported formats
*/
int getSupportedFormat();
/**
* Return a format (int) with the first matching codec selected.
*
* This considers the order of the appearance in the CodecMap,
* thus, the order of preference.
*
* NOTE: Everything returned is bound to the content of the local
* CodecMap, so it won't return format values that aren't valid
* in this call context.
*
* @param needles The format(s) (bitwise) you are looking for to match
* @return The matching format, thus 0 if none matches
*/
int getFirstMatchingFormat(int needles);
private: private:
// each call is associate to a session /** Each call is associated with an iax_session */
struct iax_session* _session; struct iax_session* _session;
/**
* Format currently in use in the conversation,
* sent in each outgoing voice packet.
*/
int _format; int _format;
}; };
......
This diff is collapsed.
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "voiplink.h" #include "voiplink.h"
#include <iax/iax-client.h> #include <iax/iax-client.h>
#include "global.h" #include "global.h"
#include <samplerate.h>
class EventThread; class EventThread;
...@@ -49,6 +50,15 @@ public: ...@@ -49,6 +50,15 @@ public:
void terminate (void); void terminate (void);
bool setRegister (void); bool setRegister (void);
/**
* Destroy registration session
*
* @todo Send an IAX_COMMAND_REGREL to force unregistration upstream.
* Urgency: low
*
* @return bool If we're registered upstream
*/
bool setUnregister (void); bool setUnregister (void);
Call* newOutgoingCall(const CallID& id, const std::string& toUrl); Call* newOutgoingCall(const CallID& id, const std::string& toUrl);
...@@ -101,26 +111,45 @@ private: ...@@ -101,26 +111,45 @@ private:
*/ */
void iaxHandleRegReply(iax_event* event); void iaxHandleRegReply(iax_event* event);
/**
* Handle IAX pre-call setup-related events
* @param event An iax_event pointer
*/
void iaxHandlePrecallEvent(iax_event* event);
/** /**
* Send an outgoing call invite to iax * Send an outgoing call invite to iax
* @param call An IAXCall pointer
*/
bool iaxOutgoingInvite(IAXCall* call);
/**
* Convert CodecMap to IAX format using IAX constants
* @return `format` ready to go into iax_* calls
*/ */
bool iaxOutgoingInvite(IAXCall* Call); int iaxCodecMapToFormat(IAXCall* call);
/** Threading object */
EventThread* _evThread; EventThread* _evThread;
/** registration session : 0 if not register */ /** registration session : 0 if not register */
struct iax_session* _regSession; struct iax_session* _regSession;
/** IAX Host */ /** IAX Host */
std::string _host; std::string _host;
/** IAX User */ /** IAX User */
std::string _user; std::string _user;
/** IAX Password */ /** IAX Password */
std::string _pass; std::string _pass;
/** IAX full name */
std::string _fullName;
ost::Mutex _mutexIAX; ost::Mutex _mutexIAX;
// extra pointer / not dynamic yet
AudioCodec* audiocodec;
AudioLayer* audiolayer; AudioLayer* audiolayer;
/** When we receive data, we decode it inside this buffer */ /** When we receive data, we decode it inside this buffer */
...@@ -140,6 +169,15 @@ private: ...@@ -140,6 +169,15 @@ private:
/** Buffer for 8000hz samples for mic conversion */ /** Buffer for 8000hz samples for mic conversion */
int16* _intBuffer8000; int16* _intBuffer8000;
/** libsamplerate converter for incoming voice */
SRC_STATE* _src_state_spkr;
/** libsamplerate converter for outgoing voice */
SRC_STATE* _src_state_mic;
/** libsamplerate error */
int _src_err;
/** Current IAX call pointer, used for sending, change when starting audio, switching */ /** Current IAX call pointer, used for sending, change when starting audio, switching */
IAXCall* _currentCall; IAXCall* _currentCall;
}; };
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment