Skip to content
Snippets Groups Projects
Commit 93fc9bd9 authored by Emmanuel Milou's avatar Emmanuel Milou
Browse files

Dynamic loading of audio codecs

Note: Manually copy the .so library in /usr/lib , then ldconfig
parent 1319d055
No related branches found
No related tags found
No related merge requests found
Showing with 282 additions and 159 deletions
......@@ -12,9 +12,9 @@ SPEEX_FLAG=
SPEEX_LIB=
endif
libaudio_la_SOURCES = audiofile.cpp g711.cpp tonelist.cpp \
libaudio_la_SOURCES = audiofile.cpp tonelist.cpp \
audiortp.cpp dtmf.cpp tone.cpp audiolayer.cpp audiodevice.cpp dtmfgenerator.cpp gsmcodec.cpp \
tonegenerator.cpp ulaw.cpp codecDescriptor.cpp \
tonegenerator.cpp codecDescriptor.cpp \
audioloop.cpp ringbuffer.cpp $(SPEEX_SOURCES_CPP)
AM_CXXFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/libs $(libccext2_CFLAGS) $(libdbuscpp_CFLAGS) $(libccrtp1_CFLAGS) $(USER_INCLUDES)
......@@ -22,8 +22,8 @@ AM_CXXFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/libs $(libccext2_CFLAGS) $
libaudio_la_CPPFLAGS = $(SPEEX_FLAG)
noinst_HEADERS = audioloop.h common.h ringbuffer.h audiofile.h g711.h \
noinst_HEADERS = audioloop.h common.h ringbuffer.h audiofile.h \
tonelist.h audiortp.h audiocodec.h audiolayer.h audiodevice.h \
dtmfgenerator.h gsmcodec.h tonegenerator.h ulaw.h \
dtmfgenerator.h gsmcodec.h tonegenerator.h \
codecDescriptor.h dtmf.h tone.h \
CodecSpeex.h
......@@ -76,10 +76,6 @@ virtual int codecEncode (unsigned char *dst, short *src, unsigned int size)
return size;
}
virtual void test()
{
printf("MON OSTIE ALAW!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
}
uint8 ALawEncode (int16 pcm16)
{
......@@ -124,11 +120,11 @@ uint8 ALawEncode (int16 pcm16)
};
// the class factories
extern "C" AudioCodec* create_alaw() {
extern "C" AudioCodec* create() {
return new Alaw();
}
extern "C" void destroy_alaw(AudioCodec* a) {
extern "C" void destroy(AudioCodec* a) {
delete a;
}
......@@ -3,6 +3,7 @@
#include <string>
#include <iostream>
#include <dlfcn.h>
class AudioCodec {
protected:
......@@ -41,7 +42,6 @@ public:
*/
virtual int codecDecode(short *, unsigned char *, unsigned int) = 0;
virtual int codecEncode(unsigned char *, short *, unsigned int) = 0;
virtual void test()=0;
/** Returns description for GUI usage */
std::string getDescription() { return _description; }
......@@ -53,6 +53,7 @@ public:
unsigned int getChannel() { return _channel; }
bool isActive() { return _active; }
void setActive(bool active) { _active = active; }
};
......
......@@ -25,20 +25,40 @@
#include <fstream>
#include <math.h>
#include <samplerate.h>
#include <dlfcn.h>
AudioFile::AudioFile()
: AudioLoop()
{
// could vary later...
_ulaw = new Ulaw(PAYLOAD_CODEC_ULAW);
//_ulaw = new Ulaw(PAYLOAD_CODEC_ULAW);
_start = false;
using std::cout;
using std::cerr;
void* codec = dlopen("codec_ulaw.so", RTLD_LAZY);
if(!codec){
cerr<<"cannot load library: "<< dlerror() <<'\n';
}
dlerror();
create_t* create_codec = (create_t*)dlsym(codec, "create");
const char* dlsym_error = dlerror();
if(dlsym_error){
cerr << "Cannot load symbol create: " << dlsym_error << '\n';
}
destroy_t* destroy_codec = (destroy_t*) dlsym(codec, "destroy");
dlsym_error = dlerror();
if(dlsym_error){
cerr << "Cannot load symbol destroy" << dlsym_error << '\n';
}
_ulaw = create_codec();
}
AudioFile::~AudioFile()
{
delete _ulaw;
delete _ulaw;
}
// load file in mono format
......@@ -82,6 +102,7 @@ AudioFile::loadFile(const std::string& filename, unsigned int sampleRate=8000)
file.read (fileBuffer,length);
file.close();
// Decode file.ul
// expandedsize is the number of bytes, not the number of int
// expandedsize should be exactly two time more, else failed
......@@ -145,7 +166,7 @@ AudioFile::loadFile(const std::string& filename, unsigned int sampleRate=8000)
_buffer = bufferTmp; // just send the buffer pointer;
bufferTmp = 0;
}
return true;
}
......@@ -24,7 +24,7 @@
#define __AUDIOFILE_H__
#include "audioloop.h"
#include "ulaw.h"
#include "audiocodec.h"
/**
@author Yan Morin <yan.morin@savoirfairelinux.com>
......@@ -42,7 +42,7 @@ public:
private:
std::string _filename;
Ulaw* _ulaw;
AudioCodec* _ulaw;
bool _start;
};
......
......@@ -107,8 +107,10 @@ AudioRtpRTX::AudioRtpRTX (SIPCall *sipcall, bool sym)
_sym = sym;
// AudioRtpRTX should be close if we change sample rate
_codecSampleRate = _ca->getAudioCodec()->getClockRate();
//_codecSampleRate = _ca->getAudioCodec()->getClockRate();
_codecSampleRate = 8000;
// TODO: Change bind address according to user settings.
// TODO: this should be the local ip not the external (router) IP
std::string localipConfig = _ca->getLocalIp(); // _ca->getLocalIp();
......@@ -212,15 +214,19 @@ AudioRtpRTX::initAudioRtpSession (void)
return;
}
AudioCodec* audiocodec = _ca->getAudioCodec();
//AudioCodec* audiocodec = _ca->getAudioCodec();
CodecType audiocodec = _ca->getAudioCodec();
bool payloadIsSet = false;
if (audiocodec) {
if (audiocodec->hasDynamicPayload()) {
payloadIsSet = _sessionRecv->setPayloadFormat(ost::DynamicPayloadFormat((ost::PayloadType) audiocodec->getPayload(), audiocodec->getClockRate()));
} else {
payloadIsSet= _sessionRecv->setPayloadFormat(ost::StaticPayloadFormat((ost::StaticPayloadType) audiocodec->getPayload()));
payloadIsSet = _sessionSend->setPayloadFormat(ost::StaticPayloadFormat((ost::StaticPayloadType) audiocodec->getPayload()));
}
/*if (audiocodec->hasDynamicPayload()) {
//payloadIsSet = _sessionRecv->setPayloadFormat(ost::DynamicPayloadFormat((ost::PayloadType) audiocodec->getPayload(), audiocodec->getClockRate()));
payloadIsSet = _sessionRecv->setPayloadFormat(ost::DynamicPayloadFormat((ost::PayloadType) audiocodec, 8000));
} else {*/
//payloadIsSet= _sessionRecv->setPayloadFormat(ost::StaticPayloadFormat((ost::StaticPayloadType) audiocodec->getPayload()));
//payloadIsSet = _sessionSend->setPayloadFormat(ost::StaticPayloadFormat((ost::StaticPayloadType) audiocodec->getPayload()));
payloadIsSet= _sessionRecv->setPayloadFormat(ost::StaticPayloadFormat((ost::StaticPayloadType) audiocodec));
payloadIsSet = _sessionSend->setPayloadFormat(ost::StaticPayloadFormat((ost::StaticPayloadType) audiocodec));
//}
}
_sessionSend->setMark(true);
} else {
......@@ -231,14 +237,16 @@ AudioRtpRTX::initAudioRtpSession (void)
return;
}
AudioCodec* audiocodec = _ca->getAudioCodec();
//AudioCodec* audiocodec = _ca->getAudioCodec();
CodecType audiocodec = _ca->getAudioCodec();
bool payloadIsSet = false;
if (audiocodec) {
if (audiocodec->hasDynamicPayload()) {
/*if (audiocodec->hasDynamicPayload()) {
payloadIsSet = _session->setPayloadFormat(ost::DynamicPayloadFormat((ost::PayloadType) audiocodec->getPayload(), audiocodec->getClockRate()));
} else {
payloadIsSet = _session->setPayloadFormat(ost::StaticPayloadFormat((ost::StaticPayloadType) audiocodec->getPayload()));
}
} else {*/
//payloadIsSet = _session->setPayloadFormat(ost::StaticPayloadFormat((ost::StaticPayloadType) audiocodec->getPayload()));
payloadIsSet = _session->setPayloadFormat(ost::StaticPayloadFormat((ost::StaticPayloadType) audiocodec));
//}
}
}
} catch(...) {
......@@ -246,35 +254,51 @@ AudioRtpRTX::initAudioRtpSession (void)
throw;
}
}
void
AudioRtpRTX::sendSessionFromMic(int timestamp)
AudioCodec*
AudioRtpRTX::loadCodec(int payload)
{
using std::cout;
using std::cerr;
void* codec = dlopen("codec_alaw.so", RTLD_LAZY);
if(!codec){
cerr<<"cannot load library: "<< dlerror() <<'\n';
}
using std::cerr;
void* codec;
//reset errors
dlerror();
switch(payload){
case 0:
codec = dlopen("codec_ulaw.so", RTLD_LAZY);
break;
case 3:
codec = dlopen("codec_gsm.so", RTLD_LAZY);
break;
case 8:
codec = dlopen("codec_alaw.so", RTLD_LAZY);
break;
}
if(!codec){
cerr<<"cannot load library: "<< dlerror() <<'\n';
}
dlerror();
create_t* create_codec = (create_t*)dlsym(codec, "create");
const char* dlsym_error = dlerror();
if(dlsym_error){
cerr << "Cannot load symbol create: " << dlsym_error << '\n';
}
destroy_t* destroy_codec = (destroy_t*) dlsym(codec, "destroy");
dlsym_error = dlerror();
if(dlsym_error){
cerr << "Cannot load symbol destroy" << dlsym_error << '\n';
}
return create_codec();
//load the symbols
create_t* create_codec = (create_t*)dlsym(codec, "create_alaw");
const char* dlsym_error = dlerror();
if(dlsym_error){
cerr << "Cannot load symbol create: " << dlsym_error << '\n';
}
destroy_t* destroy_codec = (destroy_t*) dlsym(codec, "destroy_alaw");
dlsym_error = dlerror();
if(dlsym_error){
cerr << "Cannot load symbol destroy" << dlsym_error << '\n';
}
int pl = 0;
AudioCodec* audiocodec = create_codec();
audiocodec->test();
void
AudioRtpRTX::sendSessionFromMic(int timestamp)
{
AudioCodec* audiocodec = loadCodec(_ca->getAudioCodec());
// STEP:
// 1. get data from mic
......@@ -289,7 +313,6 @@ try {
AudioLayer* audiolayer = Manager::instance().getAudioDriver();
if (!audiolayer) { _debug(" !ARTP: No audiolayer available for mic\n"); return; }
//AudioCodec* audiocodec = _ca->getAudioCodec();
//AudioCodec* audiocodec = _ca->getAudioCodec();
if (!audiocodec) { _debug(" !ARTP: No audiocodec available for mic\n"); return; }
......@@ -338,8 +361,8 @@ try {
}
destroy_codec(audiocodec);
dlclose(codec);
//destroy_codec(audiocodec);
//dlclose(codec);
}
......@@ -369,7 +392,7 @@ try {
unsigned char* data = (unsigned char*)adu->getData(); // data in char
unsigned int size = adu->getSize(); // size in char
using std::cout;
/*using std::cout;
using std::cerr;
void* codec = dlopen("codec_alaw.so", RTLD_LAZY);
if(!codec){
......@@ -380,21 +403,20 @@ if(!codec){
dlerror();
//load the symbols
create_t* create_codec = (create_t*)dlsym(codec, "create_alaw");
create_t* create_codec = (create_t*)dlsym(codec, "create");
const char* dlsym_error = dlerror();
if(dlsym_error){
cerr << "Cannot load symbol create: " << dlsym_error << '\n';
}
destroy_t* destroy_codec = (destroy_t*) dlsym(codec, "destroy_alaw");
destroy_t* destroy_codec = (destroy_t*) dlsym(codec, "destroy");
dlsym_error = dlerror();
if(dlsym_error){
cerr << "Cannot load symbol destroy" << dlsym_error << '\n';
}
int pl = 0;
AudioCodec* audiocodec = create_codec();
//audiocodec1->test();
*/
AudioCodec* audiocodec = loadCodec(payload);
// Decode data with relevant codec
//AudioCodec* audiocodec = _ca->getCodecMap().getCodec((CodecType)payload);
_codecSampleRate = audiocodec->getClockRate();
......@@ -446,8 +468,8 @@ AudioCodec* audiocodec = create_codec();
}
delete adu; adu = NULL;
destroy_codec(audiocodec);
dlclose(codec);
//destroy_codec(audiocodec);
//dlclose(codec);
} catch(...) {
_debugException("! ARTP: receiving failed");
throw;
......
......@@ -119,6 +119,9 @@ class AudioRtpRTX : public ost::Thread, public ost::TimerPort {
* @return int The number of samples after the operation
*/
int downSampleData(int, int);
AudioCodec* loadCodec(int payload);
};
///////////////////////////////////////////////////////////////////////////////
......
......@@ -23,63 +23,63 @@
#include "audiocodec.h"
#include "gsmcodec.h"
//#include "alaw.h"
#include "ulaw.h"
#include "codecDescriptor.h"
#ifdef HAVE_SPEEX
/*#ifdef HAVE_SPEEX
#include "CodecSpeex.h"
#endif
#endif*/
CodecDescriptorMap::CodecDescriptorMap()
CodecDescriptor::CodecDescriptor()
{
//_codecMap[PAYLOAD_CODEC_ALAW] = new Alaw();
_codecMap[PAYLOAD_CODEC_ALAW] = new Ulaw();
_codecMap[PAYLOAD_CODEC_ULAW] = new Ulaw();
_codecMap[PAYLOAD_CODEC_GSM] = new Gsm();
// Default codecs
_codecMap[PAYLOAD_CODEC_ALAW] = "PCMA";
_codecMap[PAYLOAD_CODEC_ULAW] = "PCMU";
_codecMap[PAYLOAD_CODEC_GSM] = "GSM";
#ifdef HAVE_SPEEX
_codecMap[PAYLOAD_CODEC_SPEEX] = new CodecSpeex(PAYLOAD_CODEC_SPEEX); // TODO: this is a variable payload!
//_codecMap[PAYLOAD_CODEC_SPEEX] = new CodecSpeex(PAYLOAD_CODEC_SPEEX); // TODO: this is a variable payload!
#endif
// theses one are not implemented yet..
// _codecMap[PAYLOAD_CODEC_ILBC] = Ilbc();
// _codecMap[PAYLOAD_CODEC_SPEEX] = Speex();
}
AudioCodec*
CodecDescriptorMap::getCodec(CodecType payload)
std::string&
CodecDescriptor::getCodecName(CodecType payload)
{
CodecMap::iterator iter = _codecMap.find(payload);
if (iter!=_codecMap.end()) {
return (iter->second);
}
return NULL;
//return ;
}
void
CodecDescriptorMap::setActive(const std::string& codecDescription)
bool
CodecDescriptor::setActive(CodecType payload)
{
CodecMap::iterator iter = _codecMap.begin();
while(iter!=_codecMap.end()) {
if (iter->second!=0) {
if (iter->second->getDescription() == codecDescription) {
iter->second->setActive(true);
break;
if (iter->first == payload) {
// codec is already in the map --> nothing to do
_debug("Codec with payload %i already in the map\n", payload);
//break;
return true;
}
}
iter++;
}
///TODO: add the codec in the activ codecs list
return false;
}
void
CodecDescriptorMap::setInactive(const std::string& codecDescription)
CodecDescriptor::setInactive(CodecType payload)
{
CodecMap::iterator iter = _codecMap.begin();
while(iter!=_codecMap.end()) {
if (iter->second!=0) {
if (iter->second->getDescription() == codecDescription) {
iter->second->setActive(false);
if (iter->first == payload) {
///TODO : erase the codec from the list ()
//iter->second->setActive(false);
break;
}
}
iter++;
}
......
......@@ -2,6 +2,7 @@
* Copyright (C) 2004-2005 Savoir-Faire Linux inc.
* Author: Yan Morin <yan.morin@savoirfairelinux.com>
* Author: Laurielle Lea <laurielle.lea@savoirfairelinux.com>
* Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -25,6 +26,7 @@
#include <string>
#include <map>
#include "../global.h"
typedef enum {
// http://www.iana.org/assignments/rtp-parameters
// http://www.gnu.org/software/ccrtp/doc/refman/html/formats_8h.html#a0
......@@ -45,33 +47,36 @@ typedef enum {
} CodecType;
#include "audiocodec.h"
typedef std::map<CodecType, AudioCodec*> CodecMap;
class CodecDescriptorMap {
/* A codec is identified by its payload. A payload is associated with a name. */
typedef std::map<CodecType, std::string> CodecMap;
class CodecDescriptor {
public:
/**
* Initialize all codec
*/
CodecDescriptorMap();
~CodecDescriptorMap() {};
CodecMap getMap() { return _codecMap; }
CodecDescriptor();
~CodecDescriptor() {};
CodecMap& getCodecMap() { return _codecMap; }
/**
* Get codec with is associated payload
* @param payload the payload associated with the payload
* same as getPayload()
* @return the address of the codec or 0
* @return the name of the codec
*/
AudioCodec* getCodec(CodecType payload);
std::string& getCodecName(CodecType payload);
/**
* Get codec with is associated payload
* Put a codec active, with it's codec's _description
* Put a codec active, with its codec's _description
* O(n) if not found where n is the number of element
* @param codecDescription is the same as with getCodec(number)->getDescription()
*/
void setActive(const std::string& codecDescription);
void setInactive(const std::string& codecDescription);
//void setActive(const std::string& codecName);
bool setActive(CodecType payload);
//void setInactive(const std::string& codecName);
void setInactive(CodecType payload);
private:
CodecMap _codecMap;
};
......
No preview for this file type
No preview for this file type
No preview for this file type
......@@ -63,10 +63,6 @@ virtual int codecEncode (unsigned char *dst, short *src, unsigned int size)
return 33;
}
virtual void test()
{
printf("MOn OSTIE GSM!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
}
private:
gsm _decode_gsmhandle;
......@@ -75,10 +71,10 @@ private:
};
// the class factories
extern "C" AudioCodec* create_gsm() {
extern "C" AudioCodec* create() {
return new Gsm();
}
extern "C" void destroy_gsm(AudioCodec* a) {
extern "C" void destroy(AudioCodec* a) {
delete a;
}
......@@ -12,9 +12,6 @@ public:
_channel = 1;
}
virtual void test(){
printf("MON OSTIE !!!!!!!!!!!!!!!!!!!!!!!!!! ULAW\n");
}
virtual int codecDecode (short *dst, unsigned char *src, unsigned int size) {
int16* end = dst+size;
......@@ -91,10 +88,10 @@ public:
};
// the class factories
extern "C" AudioCodec* create_ulaw() {
extern "C" AudioCodec* create() {
return new Ulaw();
}
extern "C" void destroy_ulaw(AudioCodec* a) {
extern "C" void destroy(AudioCodec* a) {
delete a;
}
......@@ -25,7 +25,7 @@ Call::Call(const CallID& id, Call::CallType type) : _id(id), _type(type),
{
_connectionState = Call::Disconnected;
_callState = Call::Inactive;
_audioCodec = 0;
//_audioCodec = 0;
_localAudioPort = 0;
_localExternalAudioPort = 0;
_remoteAudioPort = 0;
......@@ -65,7 +65,7 @@ Call::getState()
return _callState;
}
CodecDescriptorMap&
CodecDescriptor&
Call::getCodecMap()
{
return _codecMap;
......@@ -99,7 +99,7 @@ Call::getRemoteIp()
return _remoteIPAddress;
}
AudioCodec*
CodecType
Call::getAudioCodec()
{
ost::MutexLock m(_callMutex);
......
......@@ -121,8 +121,8 @@ public:
// AUDIO
/** Set internal codec Map: initialization only, not protected */
void setCodecMap(const CodecDescriptorMap& map) { _codecMap = map; }
CodecDescriptorMap& getCodecMap();
void setCodecMap(const CodecDescriptor& map) { _codecMap = map; }
CodecDescriptor& getCodecMap();
/** Set my IP [not protected] */
void setLocalIp(const std::string& ip) { _localIPAddress = ip; }
......@@ -149,7 +149,7 @@ public:
const std::string& getRemoteIp();
/** Return audio codec [mutex protected] */
AudioCodec* getAudioCodec();
CodecType getAudioCodec();
......@@ -164,13 +164,14 @@ protected:
void setRemoteAudioPort(unsigned int port) { _remoteAudioPort = port; }
/** Set the audio codec used. [not protected] */
void setAudioCodec(AudioCodec* audioCodec) { _audioCodec = audioCodec; }
void setAudioCodec(CodecType audioCodec) { _audioCodec = audioCodec; }
/** Codec Map */
CodecDescriptorMap _codecMap;
CodecDescriptor _codecMap;
/** Codec pointer */
AudioCodec* _audioCodec;
//AudioCodec* _audioCodec;
CodecType _audioCodec;
bool _audioStarted;
......
......@@ -72,4 +72,14 @@ typedef short int16;
#define CHANNELS 2
#define SIZEBUF 1024*1024
// Codecs payloads, as defined in RFC3551
// http://www.iana.org/assignments/rtp-parameters
// http://www.gnu.org/software/ccrtp/doc/refman/html/formats_8h.html#a0
/*#define PAYLOAD_CODEC_ULAW 0 // PCMU 8000
#define PAYLOAD_CODEC_ALAW 8 // PCMA 8000
#define PAYLOAD_CODEC_GSM 3 // GSM 8000
// http://www.ietf.org/rfc/rfc3952.txt
#define PAYLOAD_CODEC_ILBC 97*/
#endif // __GLOBAL_H__
......@@ -36,7 +36,7 @@ IAXCall::setFormat(int format)
_format = format;
switch(format) {
case AST_FORMAT_ULAW:
/*case AST_FORMAT_ULAW:
setAudioCodec(_codecMap.getCodec(PAYLOAD_CODEC_ULAW)); break;
case AST_FORMAT_GSM:
setAudioCodec(_codecMap.getCodec(PAYLOAD_CODEC_GSM)); break;
......@@ -45,9 +45,19 @@ IAXCall::setFormat(int format)
case AST_FORMAT_ILBC:
setAudioCodec(_codecMap.getCodec(PAYLOAD_CODEC_ILBC)); break;
case AST_FORMAT_SPEEX:
setAudioCodec(_codecMap.getCodec(PAYLOAD_CODEC_SPEEX)); break;
setAudioCodec(_codecMap.getCodec(PAYLOAD_CODEC_SPEEX)); break;*/
case AST_FORMAT_ULAW:
setAudioCodec(PAYLOAD_CODEC_ULAW); break;
case AST_FORMAT_GSM:
setAudioCodec(PAYLOAD_CODEC_GSM); break;
case AST_FORMAT_ALAW:
setAudioCodec(PAYLOAD_CODEC_ALAW); break;
case AST_FORMAT_ILBC:
setAudioCodec(PAYLOAD_CODEC_ILBC); break;
case AST_FORMAT_SPEEX:
setAudioCodec(PAYLOAD_CODEC_SPEEX); break;
default:
setAudioCodec(NULL);
setAudioCodec((CodecType) -1);
break;
}
}
......@@ -56,7 +66,7 @@ IAXCall::setFormat(int format)
int
IAXCall::getSupportedFormat()
{
CodecMap map = getCodecMap().getMap();
CodecMap map = getCodecMap().getCodecMap();
int format = 0;
CodecMap::iterator iter = map.begin();
......@@ -84,7 +94,7 @@ IAXCall::getSupportedFormat()
int
IAXCall::getFirstMatchingFormat(int needles)
{
CodecMap map = getCodecMap().getMap();
CodecMap map = getCodecMap().getCodecMap();
int format = 0;
CodecMap::iterator iter = map.begin();
......
......@@ -29,6 +29,7 @@
#include <samplerate.h>
#include <iax/iax-client.h>
#include <math.h>
#include <dlfcn.h>
#define IAX_BLOCKING 1
......@@ -231,9 +232,36 @@ IAXVoIPLink::getEvent()
void
IAXVoIPLink::sendAudioFromMic(void)
{
IAXCall* currentCall = getIAXCall(Manager::instance().getCurrentCallId());
AudioCodec* audiocodec = NULL;
//CodecType audiocodec = (CodecType) -1;
using std::cout;
using std::cerr;
void* codec = dlopen("codec_alaw.so", RTLD_LAZY);
if(!codec){
cerr<<"cannot load library: "<< dlerror() <<'\n';
}
//reset errors
dlerror();
//load the symbols
create_t* create_codec = (create_t*)dlsym(codec, "create");
const char* dlsym_error = dlerror();
if(dlsym_error){
cerr << "Cannot load symbol create: " << dlsym_error << '\n';
}
destroy_t* destroy_codec = (destroy_t*) dlsym(codec, "destroy");
dlsym_error = dlerror();
if(dlsym_error){
cerr << "Cannot load symbol destroy" << dlsym_error << '\n';
}
AudioCodec* audiocodec = create_codec();
if (!currentCall) {
// Let's mind our own business.
return;
......@@ -249,7 +277,7 @@ IAXVoIPLink::sendAudioFromMic(void)
return;
}
audiocodec = currentCall->getAudioCodec();
//audiocodec = currentCall->getAudioCodec();
if (!audiocodec) {
// Audio codec still not determined.
......@@ -285,6 +313,7 @@ IAXVoIPLink::sendAudioFromMic(void)
// Audio ici est PARFAIT
int16* toIAX = NULL;
//if (audiolayer->getSampleRate() != audiocodec->getClockRate() && nbSample) {
if (audiolayer->getSampleRate() != audiocodec->getClockRate() && nbSample) {
SRC_DATA src_data;
#ifdef DATAFORMAT_IS_FLOAT
......@@ -302,7 +331,7 @@ IAXVoIPLink::sendAudioFromMic(void)
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_data.end_of_input = 0;
src_process(_src_state_mic, &src_data);
......@@ -328,17 +357,17 @@ IAXVoIPLink::sendAudioFromMic(void)
// 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
//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("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.
......@@ -365,6 +394,9 @@ IAXVoIPLink::sendAudioFromMic(void)
}
_mutexIAX.leaveMutex();
}
destroy_codec(audiocodec);
dlclose(codec);
}
......@@ -746,7 +778,7 @@ IAXVoIPLink::iaxHandleCallEvent(iax_event* event, IAXCall* call)
/* Handle audio event, VOICE packet received */
void
IAXVoIPLink::iaxHandleVoiceEvent(iax_event* event, IAXCall* call)
{
{
// If we receive datalen == 0, some things of the jitter buffer in libiax2/iax.c
// were triggered
if (!event->datalen) {
......@@ -755,15 +787,37 @@ IAXVoIPLink::iaxHandleVoiceEvent(iax_event* event, IAXCall* call)
return;
}
using std::cout;
using std::cerr;
void* codec = dlopen("codec_alaw.so", RTLD_LAZY);
if(!codec){
cerr<<"cannot load library: "<< dlerror() <<'\n';
}
//reset errors
dlerror();
create_t* create_codec = (create_t*)dlsym(codec, "create");
const char* dlsym_error = dlerror();
if(dlsym_error){
cerr << "Cannot load symbol create: " << dlsym_error << '\n';
}
destroy_t* destroy_codec = (destroy_t*) dlsym(codec, "destroy");
dlsym_error = dlerror();
if(dlsym_error){
cerr << "Cannot load symbol destroy" << dlsym_error << '\n';
}
AudioCodec* audiocodec;
if (audiolayer) {
AudioCodec* audiocodec = call->getAudioCodec();
//AudioCodec* audiocodec = call->getAudioCodec();
audiocodec = create_codec();
// On-the-fly codec changing (normally, when we receive a full packet)
// as per http://tools.ietf.org/id/draft-guy-iax-03.txt
// - subclass holds the voiceformat property.
if (event->subclass && event->subclass != call->getFormat()) {
call->setFormat(event->subclass);
audiocodec = call->getAudioCodec();
//audiocodec = call->getAudioCodec();
}
//_debug("Receive: len=%d, format=%d, _receiveDataDecoded=%p\n", event->datalen, call->getFormat(), _receiveDataDecoded);
......@@ -798,7 +852,7 @@ IAXVoIPLink::iaxHandleVoiceEvent(iax_event* event, IAXCall* call)
src_data.input_frames = nbSample;
src_data.output_frames = (int) floor(factord * nbSample);
src_data.src_ratio = factord;
src_data.end_of_input = 0; /* More data will come */
src_data.end_of_input = 0;
src_short_to_float_array(_receiveDataDecoded, _floatBuffer8000, nbSample);
// samplerate convert, go!
......@@ -826,6 +880,10 @@ IAXVoIPLink::iaxHandleVoiceEvent(iax_event* event, IAXCall* call)
} else {
_debug("IAX: incoming audio, but no sound card open");
}
destroy_codec(audiocodec);
dlclose(codec);
}
......
......@@ -1090,9 +1090,9 @@ ManagerImpl::initAudioCodec (void)
//_codecDescriptorMap.setActive(getConfigString("Audio", "Codecs.codec1"));
//_codecDescriptorMap.setActive(getConfigString("Audio", "Codec.codec2"));
//_codecDescriptorMap.setActive(getConfigString("Audio", "Codec.codec3"));
_codecDescriptorMap.setActive("G711a");
_codecDescriptorMap.setActive("G711u");
_codecDescriptorMap.setActive("GSM");
//_codecDescriptorMap.setActive("G711a");
//_codecDescriptorMap.setActive("G711u");
//_codecDescriptorMap.setActive("GSM");
}
void
......@@ -1106,11 +1106,11 @@ ManagerImpl::setPreferedCodec(const ::DBus::String& codec_name)
tmp = list[0];
list[0] = list[i];
list[i] = tmp;
_codecDescriptorMap.setActive(list[0]);
//_codecDescriptorMap.setActive(list[0]);
//_codecDescriptorMap.setInactive(list[1]);
//_codecDescriptorMap.setInactive(list[2]);
_codecDescriptorMap.setActive(list[1]);
_codecDescriptorMap.setActive(list[2]);
//_codecDescriptorMap.setActive(list[1]);
//_codecDescriptorMap.setActive(list[2]);
setConfig("Audio", "Codecs.codec1", list[0]);
setConfig("Audio", "Codecs.codec2", list[1]);
setConfig("Audio", "Codecs.codec3", list[2]);
......@@ -1127,8 +1127,8 @@ ManagerImpl::getDefaultCodecList( void )
{
std::vector< std::string > v;
std::string desc=DFT_CODEC1;
std::string rate=""+clockRate(desc);
printf("%s\n",rate.c_str());
//std::string rate=""+clockRate(desc);
//printf("%s\n",rate.c_str());
v.push_back(DFT_CODEC1); // G711u
v.push_back(DFT_CODEC2); // G711a
v.push_back(DFT_CODEC3); // GSM
......@@ -1137,18 +1137,19 @@ ManagerImpl::getDefaultCodecList( void )
unsigned int
ManagerImpl::clockRate(std::string& name)
{
CodecMap codecs = _codecDescriptorMap.getMap();
{/*
CodecMap codecs = _codecDescriptorMap.getCodecMap();
CodecMap::iterator iter = codecs.begin();
while(iter!=codecs.end())
{
if(iter->second!=NULL)
{
if(iter->second->getDescription() == name)
return iter->second->getClockRate();
}
iter++;
if(iter->second == name)
//return iter->second->getClockRate();
return 1;
}
iter++;
}*/
return -1;
}
......@@ -1483,19 +1484,20 @@ ManagerImpl::setConfig(const std::string& section, const std::string& name, int
bool
ManagerImpl::getConfigList(const std::string& sequenceId, const std::string& name)
{
/*
bool returnValue = false;
TokenList tk;
if (name == "codecdescriptor") {
CodecMap map = _codecDescriptorMap.getMap();
CodecMap map = _codecDescriptorMap.getCodecMap();
CodecMap::iterator iter = map.begin();
while( iter != map.end() ) {
tk.clear();
std::ostringstream strType;
strType << iter->first;
tk.push_back(strType.str());
if (iter->second) {
tk.push_back(iter->second->getDescription());
if (iter->second != -1) {
tk.push_back(iter->second);
} else {
tk.push_back(strType.str());
}
......@@ -1528,7 +1530,8 @@ ManagerImpl::getConfigList(const std::string& sequenceId, const std::string& nam
} else if (name == "countrytones") {
returnValue = getCountryTones(sequenceId);
}
return returnValue;
return returnValue;*/
return true;
}
//THREAD=Main
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment