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 @@
#include "iaxcall.h"
#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()
{
_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 @@
#include "call.h"
#include <iax/iax-client.h>
#include <iax/frame.h>
/**
* IAXCall are IAX implementation of a normal Call
......@@ -33,7 +34,7 @@ public:
~IAXCall();
/** Get the session pointer or 0 */
/** Get the session pointer or NULL */
struct iax_session* getSession() { return _session; }
/** Set the session pointer
......@@ -41,12 +42,49 @@ public:
*/
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; }
/**
* 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:
// each call is associate to a session
/** Each call is associated with an iax_session */
struct iax_session* _session;
/**
* Format currently in use in the conversation,
* sent in each outgoing voice packet.
*/
int _format;
};
......
This diff is collapsed.
......@@ -22,6 +22,7 @@
#include "voiplink.h"
#include <iax/iax-client.h>
#include "global.h"
#include <samplerate.h>
class EventThread;
......@@ -49,6 +50,15 @@ public:
void terminate (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);
Call* newOutgoingCall(const CallID& id, const std::string& toUrl);
......@@ -101,26 +111,45 @@ private:
*/
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
* @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;
/** registration session : 0 if not register */
struct iax_session* _regSession;
/** IAX Host */
std::string _host;
/** IAX User */
std::string _user;
/** IAX Password */
std::string _pass;
/** IAX full name */
std::string _fullName;
ost::Mutex _mutexIAX;
// extra pointer / not dynamic yet
AudioCodec* audiocodec;
AudioLayer* audiolayer;
/** When we receive data, we decode it inside this buffer */
......@@ -140,6 +169,15 @@ private:
/** Buffer for 8000hz samples for mic conversion */
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 */
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