Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
savoirfairelinux
jami-daemon
Commits
fb081475
Commit
fb081475
authored
Sep 07, 2007
by
Pierre-Luc Beaudoin
Browse files
Merge commit 'origin/master' into dbus
Conflicts: .gitignore src/Makefile.am src/managerimpl.cpp
parents
96868436
4be69b42
Changes
114
Hide whitespace changes
Inline
Side-by-side
src/eventthread.cpp
View file @
fb081475
...
...
@@ -19,7 +19,7 @@
*/
#include
"eventthread.h"
#include
"vo
IPL
ink.h"
#include
"vo
ipl
ink.h"
EventThread
::
EventThread
(
VoIPLink
*
link
)
:
Thread
()
{
...
...
src/iaxaccount.cpp
View file @
fb081475
...
...
@@ -17,12 +17,14 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include
"iaxaccount.h"
#include
"account.h"
#include
"iaxvoiplink.h"
#include
"manager.h"
#define IAX_HOST "IAX.host"
#define IAX_USER "IAX.user"
#define IAX_PASS "IAX.pass"
#define IAX_FULL_NAME "IAX.fullName"
#define IAX_HOST "IAX.host"
#define IAX_USER "IAX.user"
#define IAX_PASS "IAX.pass"
IAXAccount
::
IAXAccount
(
const
AccountID
&
accountID
)
:
Account
(
accountID
)
...
...
@@ -50,9 +52,10 @@ IAXAccount::registerAccount()
{
if
(
_link
&&
!
_registered
)
{
init
();
unregisterAccount
();
//
unregisterAccount();
No need to unregister first.
IAXVoIPLink
*
tmplink
=
dynamic_cast
<
IAXVoIPLink
*>
(
_link
);
if
(
tmplink
)
{
// Stuff needed for IAX registration
tmplink
->
setHost
(
Manager
::
instance
().
getConfigString
(
_accountID
,
IAX_HOST
));
tmplink
->
setUser
(
Manager
::
instance
().
getConfigString
(
_accountID
,
IAX_USER
));
tmplink
->
setPass
(
Manager
::
instance
().
getConfigString
(
_accountID
,
IAX_PASS
));
...
...
@@ -99,12 +102,13 @@ IAXAccount::initConfig(Conf::ConfigTree& config)
std
::
string
section
(
_accountID
);
std
::
string
type_str
(
"string"
);
std
::
string
type_int
(
"int"
);
// Account generic
Account
::
initConfig
(
config
);
// IAX specific
config
.
addConfigTreeItem
(
section
,
Conf
::
ConfigTreeItem
(
CONFIG_ACCOUNT_TYPE
,
"IAX"
,
type_str
));
config
.
addConfigTreeItem
(
section
,
Conf
::
ConfigTreeItem
(
CONFIG_ACCOUNT_ENABLE
,
"1"
,
type_int
));
config
.
addConfigTreeItem
(
section
,
Conf
::
ConfigTreeItem
(
CONFIG_ACCOUNT_AUTO_REGISTER
,
"1"
,
type_int
));
config
.
addConfigTreeItem
(
section
,
Conf
::
ConfigTreeItem
(
CONFIG_ACCOUNT_ALIAS
,
_
(
"My account"
),
type_str
));
config
.
addConfigTreeItem
(
section
,
Conf
::
ConfigTreeItem
(
IAX_FULL_NAME
,
""
,
type_str
));
config
.
addConfigTreeItem
(
section
,
Conf
::
ConfigTreeItem
(
IAX_HOST
,
""
,
type_str
));
config
.
addConfigTreeItem
(
section
,
Conf
::
ConfigTreeItem
(
IAX_USER
,
""
,
type_str
));
config
.
addConfigTreeItem
(
section
,
Conf
::
ConfigTreeItem
(
IAX_PASS
,
""
,
type_str
));
...
...
@@ -113,6 +117,9 @@ IAXAccount::initConfig(Conf::ConfigTree& config)
void
IAXAccount
::
loadConfig
()
{
_shouldInitOnStart
=
Manager
::
instance
().
getConfigInt
(
_accountID
,
CONFIG_ACCOUNT_ENABLE
)
?
true
:
false
;
_shouldRegisterOnStart
=
Manager
::
instance
().
getConfigInt
(
_accountID
,
CONFIG_ACCOUNT_AUTO_REGISTER
)
?
true
:
false
;
// Account generic
Account
::
loadConfig
();
// IAX specific
//none
}
src/iaxcall.cpp
View file @
fb081475
...
...
@@ -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
;
}
src/iaxcall.h
View file @
fb081475
...
...
@@ -20,7 +20,8 @@
#define IAXCALL_H
#include
"call.h"
#include
<iax-client.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,51 @@ 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 for the voice codec used
*
* Bitmask for codecs defined in iax/frame.h
*/
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:
/
/ e
ach call is associate
to a
session
/
** E
ach call is associate
d with an iax_
session
*/
struct
iax_session
*
_session
;
/**
* Format currently in use in the conversation,
* sent in each outgoing voice packet.
*/
int
_format
;
};
...
...
src/iaxvoiplink.cpp
View file @
fb081475
...
...
@@ -26,6 +26,17 @@
#include
"audio/audiolayer.h"
#include
<samplerate.h>
#include
<iax/iax-client.h>
#include
<math.h>
/** @todo Remove the fstream and iostream stuff */
//#include <fstream> // fstream + iostream pour fstream debugging..
//#include <iostream> // removeable...
#define IAX_BLOCKING 1
#define IAX_NONBLOCKING 0
#define IAX_SUCCESS 0
#define IAX_FAILURE -1
...
...
@@ -34,44 +45,26 @@
// from IAXC : iaxclient.h
/* payload formats : WARNING: must match libiax values!!! */
/* Data formats for capabilities and frames alike */
#define IAX__FORMAT_G723_1 (1 << 0)
/* G.723.1 compression */
#define IAX__FORMAT_GSM (1 << 1)
/* GSM compression */
#define IAX__FORMAT_ULAW (1 << 2)
/* Raw mu-law data (G.711) */
#define IAX__FORMAT_ALAW (1 << 3)
/* Raw A-law data (G.711) */
#define IAX__FORMAT_G726 (1 << 4)
/* ADPCM, 32kbps */
#define IAX__FORMAT_ADPCM (1 << 5)
/* ADPCM IMA */
#define IAX__FORMAT_SLINEAR (1 << 6)
/* Raw 16-bit Signed Linear (8000 Hz) PCM */
#define IAX__FORMAT_LPC10 (1 << 7)
/* LPC10, 180 samples/frame */
#define IAX__FORMAT_G729A (1 << 8)
/* G.729a Audio */
#define IAX__FORMAT_SPEEX (1 << 9)
/* Speex Audio */
#define IAX__FORMAT_ILBC (1 << 10)
/* iLBC Audio */
#define IAX__FORMAT_MAX_AUDIO (1 << 15)
/* Maximum audio format */
#define IAX__FORMAT_JPEG (1 << 16)
/* JPEG Images */
#define IAX__FORMAT_PNG (1 << 17)
/* PNG Images */
#define IAX__FORMAT_H261 (1 << 18)
/* H.261 Video */
#define IAX__FORMAT_H263 (1 << 19)
/* H.263 Video */
#define IAX__FORMAT_H263_PLUS (1 << 20)
/* H.263+ Video */
#define IAX__FORMAT_MPEG4 (1 << 21)
/* MPEG4 Video */
#define IAX__FORMAT_H264 (1 << 23)
/* H264 Video */
#define IAX__FORMAT_THEORA (1 << 24)
/* Theora Video */
#define IAX__20S_8KHZ_MAX 320 // 320 samples
#define IAX__20S_48KHZ_MAX 1920 // 320*6 samples, 6 = 48000/8000
#define IAX__20S_8KHZ_MAX 160 // 320 //320 samples
#define IAX__20S_48KHZ_MAX 960 // 1920 // 320*6 samples = 1920, 6 = 48000/8000
#define CHK_VALID_CALL if (call == NULL) { _debug("IAX: Call doesn't exists\n"); \
return false; }
IAXVoIPLink
::
IAXVoIPLink
(
const
AccountID
&
accountID
)
:
VoIPLink
(
accountID
)
:
VoIPLink
(
accountID
)
// , _fstream("/tmp/audio.dat", std::ofstream::binary) /** @todo Remove this */
{
_evThread
=
new
EventThread
(
this
);
_regSession
=
0
;
_regSession
=
NULL
;
_nextRefreshStamp
=
0
;
// to get random number for RANDOM_PORT
srand
(
time
(
NULL
));
audiocodec
=
0
;
audiolayer
=
0
;
audiolayer
=
NULL
;
_receiveDataDecoded
=
new
int16
[
IAX__20S_48KHZ_MAX
];
_sendDataEncoded
=
new
unsigned
char
[
IAX__20S_8KHZ_MAX
];
...
...
@@ -81,24 +74,32 @@ IAXVoIPLink::IAXVoIPLink(const AccountID& accountID)
_floatBuffer8000
=
new
float32
[
IAX__20S_8KHZ_MAX
];
_floatBuffer48000
=
new
float32
[
IAX__20S_48KHZ_MAX
];
_intBuffer8000
=
new
int16
[
IAX__20S_8KHZ_MAX
];
// libsamplerate-related
_src_state_mic
=
src_new
(
SRC_SINC_BEST_QUALITY
,
1
,
&
_src_err
);
_src_state_spkr
=
src_new
(
SRC_SINC_BEST_QUALITY
,
1
,
&
_src_err
);
}
IAXVoIPLink
::~
IAXVoIPLink
()
{
delete
_evThread
;
_evThread
=
0
;
_regSession
=
0
;
// shall not delete it
delete
_evThread
;
_evThread
=
NULL
;
_regSession
=
NULL
;
// shall not delete it
terminate
();
audiocodec
=
0
;
audiolayer
=
0
;
delete
[]
_intBuffer8000
;
_intBuffer8000
=
0
;
delete
[]
_floatBuffer48000
;
_floatBuffer48000
=
0
;
delete
[]
_floatBuffer8000
;
_floatBuffer8000
=
0
;
delete
[]
_dataAudioLayer
;
_dataAudioLayer
=
0
;
audiolayer
=
NULL
;
delete
[]
_intBuffer8000
;
_intBuffer8000
=
NULL
;
delete
[]
_floatBuffer48000
;
_floatBuffer48000
=
NULL
;
delete
[]
_floatBuffer8000
;
_floatBuffer8000
=
NULL
;
delete
[]
_dataAudioLayer
;
_dataAudioLayer
=
NULL
;
delete
[]
_sendDataEncoded
;
_sendDataEncoded
=
NULL
;
delete
[]
_receiveDataDecoded
;
_receiveDataDecoded
=
NULL
;
delete
[]
_sendDataEncoded
;
_sendDataEncoded
=
0
;
delete
[]
_receiveDataDecoded
;
_receiveDataDecoded
=
0
;
// libsamplerate-related
_src_state_mic
=
src_delete
(
_src_state_mic
);
_src_state_spkr
=
src_delete
(
_src_state_spkr
);
}
bool
...
...
@@ -128,8 +129,6 @@ IAXVoIPLink::init()
_evThread
->
start
();
// audio stuff, not dynamic yet
audiocodec
=
Manager
::
instance
().
getCodecDescriptorMap
().
getCodec
((
CodecType
)
0
);
audiolayer
=
Manager
::
instance
().
getAudioDriver
();
break
;
}
...
...
@@ -162,8 +161,8 @@ IAXVoIPLink::terminateIAXCall()
_mutexIAX
.
enterMutex
();
iax_hangup
(
call
->
getSession
(),
"Dumped Call"
);
_mutexIAX
.
leaveMutex
();
call
->
setSession
(
0
);
delete
call
;
call
=
0
;
call
->
setSession
(
NULL
);
delete
call
;
call
=
NULL
;
}
iter
++
;
}
...
...
@@ -173,118 +172,279 @@ IAXVoIPLink::terminateIAXCall()
void
IAXVoIPLink
::
getEvent
()
{
// mutex here
IAXCall
*
call
=
NULL
;
// lock iax_ stuff..
_mutexIAX
.
enterMutex
();
iax_event
*
event
=
NULL
;
while
(
(
event
=
iax_get_event
(
IAX_NONBLOCKING
))
!=
NULL
)
{
// If we received an 'ACK', libiax2 tells apps to ignore them.
if
(
event
->
etype
==
IAX_EVENT_NULL
)
{
continue
;
}
//_debug ("Receive IAX Event: %d (0x%x)\n", event->etype, event->etype);
iax_event
*
event
=
0
;
IAXCall
*
call
=
0
;
while
(
(
event
=
iax_get_event
(
0
))
!=
0
)
{
//_debug ("Receive IAX Event: %d\n", event->etype);
call
=
iaxFindCallBySession
(
event
->
session
);
if
(
call
!=
0
)
{
if
(
call
)
{
// We know that call, deal with it
iaxHandleCallEvent
(
event
,
call
);
}
else
if
(
event
->
session
!=
0
&&
event
->
session
==
_regSession
)
{
// in iaxclient, there is many session handling, here, only one
}
else
if
(
event
->
session
&&
event
->
session
==
_regSession
)
{
// This is a registration session, deal with it
iaxHandleRegReply
(
event
);
}
else
{
switch
(
event
->
etype
)
{
case
IAX_EVENT_REGACK
:
case
IAX_EVENT_REGREJ
:
_debug
(
"Unknown IAX Registration Event
\n
"
);
break
;
}
else
{
// We've got an event before it's associated with any call
iaxHandlePrecallEvent
(
event
);
}
iax_event_free
(
event
);
}
_mutexIAX
.
leaveMutex
();
case
IAX_EVENT_REGREQ
:
_debug
(
"Registration by a peer, don't allow it
\n
"
);
break
;
case
IAX_EVENT_CONNECT
:
// new call
// New incoming call!
break
;
case
IAX_EVENT_TIMEOUT
:
// timeout for an unknown session
// Do the doodle-moodle to send audio from the microphone to the IAX channel.
sendAudioFromMic
();
break
;
default:
_debug
(
"Unknown event type: %d
\n
"
,
event
->
etype
);
}
// Refresh registration.
if
(
_nextRefreshStamp
&&
_nextRefreshStamp
-
2
<
time
(
NULL
))
{
setRegister
();
}
// thread wait 5 millisecond
_evThread
->
sleep
(
3
);
}
void
IAXVoIPLink
::
sendAudioFromMic
(
void
)
{
IAXCall
*
currentCall
=
getIAXCall
(
Manager
::
instance
().
getCurrentCallId
());
AudioCodec
*
audiocodec
=
NULL
;
if
(
!
currentCall
)
{
// Let's mind our own business.
return
;
}
// Just make sure the currentCall is in state to receive audio right now.
//_debug("Here we get: connectionState: %d state: %d \n",
// currentCall->getConnectionState(),
// currentCall->getState());
if
(
currentCall
->
getConnectionState
()
!=
Call
::
Connected
||
currentCall
->
getState
()
!=
Call
::
Active
)
{
return
;
}
audiocodec
=
currentCall
->
getAudioCodec
();
if
(
!
audiocodec
)
{
// Audio codec still not determined.
if
(
audiolayer
)
{
// To keep latency low..
audiolayer
->
flushMic
();
}
iax_event_free
(
event
)
;
return
;
}
// send sound here
if
(
_currentCall
!=
0
&&
audiolayer
!=
0
)
{
int
samples
=
audiolayer
->
canGetMic
();
if
(
samples
!=
0
)
{
int
datalen
=
audiolayer
->
getMic
(
_sendDataEncoded
,
samples
);
_debug
(
"iax_send_voice(%p, %d, ,%d, %d)
\n
"
,
_currentCall
->
getSession
(),
_currentCall
->
getFormat
(),
datalen
,
samples
);
//if ( iax_send_voice(_currentCall->getSession(), _currentCall->getFormat(), (char*)_sendDataEncoded, datalen, samples) == -1) {
// // error sending voice
//}
// Send sound here
if
(
audiolayer
)
{
// we have to get 20ms of data from the mic *20/1000 = /50
// rate/50 shall be lower than IAX__20S_48KHZ_MAX
int
maxBytesToGet
=
audiolayer
->
getSampleRate
()
/
50
*
sizeof
(
SFLDataFormat
);
// available bytes inside ringbuffer
int
availBytesFromMic
=
audiolayer
->
canGetMic
();
if
(
availBytesFromMic
<
maxBytesToGet
)
{
// We need packets full!
return
;
}
// take the lowest
int
bytesAvail
=
(
availBytesFromMic
<
maxBytesToGet
)
?
availBytesFromMic
:
maxBytesToGet
;
_debug
(
"available = %d, maxBytesToGet = %d
\n
"
,
availBytesFromMic
,
maxBytesToGet
);
// Get bytes from micRingBuffer to data_from_mic
int
nbSample
=
audiolayer
->
getMic
(
_dataAudioLayer
,
bytesAvail
)
/
sizeof
(
SFLDataFormat
);
// Audio ici est PARFAIT
int16
*
toIAX
=
NULL
;
if
(
audiolayer
->
getSampleRate
()
!=
audiocodec
->
getClockRate
()
&&
nbSample
)
{
SRC_DATA
src_data
;
#ifdef DATAFORMAT_IS_FLOAT
src_data
.
data_in
=
_dataAudioLayer
;
#else
src_short_to_float_array
(
_dataAudioLayer
,
_floatBuffer48000
,
nbSample
);
src_data
.
data_in
=
_floatBuffer48000
;
#endif
// Audio parfait à ce point.
double
factord
=
(
double
)
audiocodec
->
getClockRate
()
/
audiolayer
->
getSampleRate
();
src_data
.
src_ratio
=
factord
;
src_data
.
input_frames
=
nbSample
;
src_data
.
output_frames
=
(
int
)
floor
(
factord
*
nbSample
);
src_data
.
data_out
=
_floatBuffer8000
;
src_data
.
end_of_input
=
0
;
/* More data to come */
src_process
(
_src_state_mic
,
&
src_data
);
nbSample
=
src_data
.
output_frames_gen
;
// Bon, l'audio en float 8000 est laid mais yé consistant.
src_float_to_short_array
(
_floatBuffer8000
,
_intBuffer8000
,
nbSample
);
toIAX
=
_intBuffer8000
;
// Audio bon ici aussi..
}
else
{
#ifdef DATAFORMAT_IS_FLOAT
// convert _receiveDataDecoded to float inside _receiveData
src_float_to_short_array
(
_dataAudioLayer
,
_intBuffer8000
,
nbSample
);
toIAX
=
_intBuffer8000
;
//if (nbSample > IAX__20S_8KHZ_MAX) { _debug("Alert from mic, nbSample %d is bigger than expected %d\n", nbSample, IAX__20S_8KHZ_MAX); }
#else
toIAX
=
_dataAudioLayer
;
// int to int
#endif
}
// NOTE: L'audio ici est bon.
/*
// LE PROBLÈME est dans cette snippet de fonction:
// C'est une fonction destructrice ! On n'en veut pas!
if ( nbSample < (IAX__20S_8KHZ_MAX - 10) ) { // if only 10 is missing, it's ok
// fill end with 0...
_debug("begin: %p, nbSample: %d\n", toIAX, nbSample);
_debug("has to fill: %d chars at %p\n", (IAX__20S_8KHZ_MAX-nbSample)*sizeof(int16), toIAX + nbSample);
memset(toIAX + nbSample, 0, (IAX__20S_8KHZ_MAX-nbSample)*sizeof(int16));
nbSample = IAX__20S_8KHZ_MAX;
}
*/
//_debug("AR: Nb sample: %d int, [0]=%d [1]=%d [2]=%d\n", nbSample, toIAX[0], toIAX[1], toIAX[2]);
// NOTE: Le son dans toIAX (nbSamle*sizeof(int16)) est mauvais,
// s'il passe par le snippet précédent.
// DEBUG
//_fstream.write((char *) toIAX, nbSample*sizeof(int16));
//_fstream.flush();
// for the mono: range = 0 to IAX_FRAME2SEND * sizeof(int16)
int
compSize
=
audiocodec
->
codecEncode
(
_sendDataEncoded
,
toIAX
,
nbSample
*
sizeof
(
int16
));
// Send it out!
_mutexIAX
.
enterMutex
();
// Make sure the session and the call still exists.
if
(
currentCall
->
getSession
())
{
if
(
iax_send_voice
(
currentCall
->
getSession
(),
currentCall
->
getFormat
(),
(
unsigned
char
*
)
_sendDataEncoded
,
compSize
,
nbSample
)
==
-
1
)
{
_debug
(
"IAX: Error sending voice data.
\n
"
);
}
}
_mutexIAX
.
leaveMutex
();
}
}
// unlock mutex here
_mutexIAX
.
leaveMutex
();
//iaxRefreshRegistrations();
// thread wait 5 millisecond
_evThread
->
sleep
(
5
);
/*
void IAXVoIPLink::recvAudioForSpkr(void)
{
}
*/
IAXCall
*
IAXVoIPLink
::
getIAXCall
(
const
CallID
&
id
)
{
Call
*
call
=
getCall
(
id
);
if
(
call
)
{
return
dynamic_cast
<
IAXCall
*>
(
call
);
}
return
NULL
;
}
bool
IAXVoIPLink
::
setRegister
()
{
bool
result
=
false
;
if
(
_regSession
==
0
)
{