Commit 0de37a5c authored by Guillaume Carmel-Archambault's avatar Guillaume Carmel-Archambault
parents e5e0793c 636fd386
......@@ -30,40 +30,21 @@
AudioFile::AudioFile()
: AudioLoop()
{
// could vary later...
// could vary later ...
_start = false;
using std::cout;
using std::cerr;
void* codec = dlopen( CODECS_DIR "/libcodec_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 _codec;
}
// load file in mono format
bool
AudioFile::loadFile(const std::string& filename, unsigned int sampleRate=8000)
AudioFile::loadFile(const std::string& filename, AudioCodec* codec , unsigned int sampleRate=8000)
{
_codec = codec;
// if the filename was already load, with the same samplerate
// we do nothing
if (_filename == filename && _sampleRate == sampleRate) {
......@@ -106,7 +87,7 @@ AudioFile::loadFile(const std::string& filename, unsigned int sampleRate=8000)
// expandedsize is the number of bytes, not the number of int
// expandedsize should be exactly two time more, else failed
int16 monoBuffer[length];
unsigned int expandedsize = _ulaw->codecDecode (monoBuffer, (unsigned char *) fileBuffer, length);
unsigned int expandedsize = _codec->codecDecode (monoBuffer, (unsigned char *) fileBuffer, length);
if (expandedsize != length*2) {
_debug("Audio file error on loading audio file!");
return false;
......
......@@ -25,6 +25,7 @@
#include "audioloop.h"
#include "codecs/audiocodec.h"
#include "codecDescriptor.h"
/**
@author Yan Morin <yan.morin@savoirfairelinux.com>
......@@ -35,14 +36,14 @@ public:
AudioFile();
~AudioFile();
bool loadFile(const std::string& filename, unsigned int sampleRate/*=8000*/);
bool loadFile(const std::string& filename, AudioCodec *codec , unsigned int sampleRate/*=8000*/);
void start() { _start = true; }
void stop() { _start = false; }
bool isStarted() { return _start; }
private:
std::string _filename;
AudioCodec* _ulaw;
AudioCodec* _codec;
bool _start;
};
......
......@@ -43,6 +43,8 @@ public:
void reset() { _pos = 0; }
unsigned int getMonoSize() { return _size; }
unsigned int getSize() { return _size; }
protected:
SFLDataFormat* _buffer;
......
This diff is collapsed.
......@@ -122,23 +122,22 @@ class AudioRtpRTX : public ost::Thread, public ost::TimerPort {
int downSampleData(int, int);
/** Pointer on function to handle codecs **/
void* handle_codec;
//void* handle_codec;
AudioCodec* _audiocodec;
CodecDescriptor _codecDesc;
/**
* Load dynamically a codec (.so library)
* @param payload The payload of the codec you want to load
* @return AudioCodec* A pointer on a audio codec object
*/
void loadCodec(int payload);
//void loadCodec(int payload);
/**
* Destroy and close dynamically a codec (.so library)
* @param audiocodec The audio codec you want to unload
*/
void unloadCodec(void);
//void unloadCodec(void);
};
///////////////////////////////////////////////////////////////////////////////
......
......@@ -26,44 +26,79 @@
CodecDescriptor::CodecDescriptor()
{
init();
//#ifdef HAVE_SPEEX
//init();
//#ifdef HAVE_SPEEX
//_codecMap[PAYLOAD_CODEC_SPEEX] = new CodecSpeex(PAYLOAD_CODEC_SPEEX); // TODO: this is a variable payload!
//#endif
//#endif
}
void
CodecDescriptor::~CodecDescriptor()
{
}
void
CodecDescriptor::deleteHandlePointer( void )
{
_debug("Destroy codecs handles\n");
int i;
for( i = 0 ; i < _CodecInMemory.size() ; i++)
{
unloadCodec( _CodecInMemory[i] );
}
}
void
CodecDescriptor::init()
{
// init list of all codecs supported codecs
_codecMap[PAYLOAD_CODEC_ULAW] = "PCMU";
_codecMap[PAYLOAD_CODEC_GSM] = "GSM";
_codecMap[PAYLOAD_CODEC_ALAW] = "PCMA";
//_codecMap[PAYLOAD_CODEC_ILBC_20] = "iLBC";
_codecMap[PAYLOAD_CODEC_SPEEX_8000] = "speex";;
_debug("Scanning %s to find audio codecs....\n", CODECS_DIR);
std::vector<AudioCodec*> CodecDynamicList = scanCodecDirectory();
_nbCodecs = CodecDynamicList.size();
if( _nbCodecs <= 0 ){
_debug("Error - No codecs available in directory %s\n", CODECS_DIR);
exit(0);
}
int i;
for( i = 0 ; i < _nbCodecs ; i++ ) {
_CodecsMap[(CodecType)CodecDynamicList[i]->getPayload()] = CodecDynamicList[i];
}
}
void
void
CodecDescriptor::setDefaultOrder()
{
_codecOrder.clear();
_codecOrder.push_back(PAYLOAD_CODEC_ULAW);
_codecOrder.push_back(PAYLOAD_CODEC_ALAW);
_codecOrder.push_back(PAYLOAD_CODEC_GSM);
CodecsMap::iterator iter = _CodecsMap.begin();
while( iter != _CodecsMap.end())
{
_codecOrder.push_back(iter->first);
iter->second->setState( true );
}
}
std::string&
std::string
CodecDescriptor::getCodecName(CodecType payload)
{
CodecMap::iterator iter = _codecMap.find(payload);
if (iter!=_codecMap.end()) {
std::string resNull = "";
CodecsMap::iterator iter = _CodecsMap.find(payload);
if (iter!=_CodecsMap.end()) {
return (iter->second->getCodecName());
}
return resNull;
}
AudioCodec*
CodecDescriptor::getCodec(CodecType payload)
{
CodecsMap::iterator iter = _CodecsMap.find(payload);
if (iter!=_CodecsMap.end()) {
return (iter->second);
}
//return std::string("");
return NULL;
}
bool
bool
CodecDescriptor::isActive(CodecType payload)
{
int i;
......@@ -75,94 +110,67 @@ CodecDescriptor::isActive(CodecType payload)
return false;
}
void
void
CodecDescriptor::removeCodec(CodecType payload)
{
CodecMap::iterator iter = _codecMap.begin();
while(iter!=_codecMap.end()) {
if (iter->first == payload) {
_debug("Codec %s removed from the list", getCodecName(payload).data());
_codecMap.erase(iter);
break;
}
if (iter->first == payload) {
_debug("Codec %s removed from the list", getCodecName(payload).data());
_codecMap.erase(iter);
break;
}
iter++;
}
}
void
void
CodecDescriptor::addCodec(CodecType payload)
{
}
double
double
CodecDescriptor::getBitRate(CodecType payload)
{
switch(payload){
case PAYLOAD_CODEC_ULAW:
return 64;
case PAYLOAD_CODEC_ALAW:
return 64;
case PAYLOAD_CODEC_GSM:
return 13.3;
case PAYLOAD_CODEC_ILBC_20:
return 15.2;
case PAYLOAD_CODEC_ILBC_30:
return 13.3;
}
return 0.0;
CodecsMap::iterator iter = _CodecsMap.find(payload);
if (iter!=_CodecsMap.end())
return (iter->second->getBitRate());
else
return 0.0;
}
double
double
CodecDescriptor::getBandwidthPerCall(CodecType payload)
{
switch(payload){
case PAYLOAD_CODEC_ULAW:
return 80;
case PAYLOAD_CODEC_ALAW:
return 80;
case PAYLOAD_CODEC_GSM:
return 28.6;
case PAYLOAD_CODEC_ILBC_20:
return 30.8;
}
return 0.0;
CodecsMap::iterator iter = _CodecsMap.find(payload);
if (iter!=_CodecsMap.end())
return (iter->second->getBandwidth());
else
return 0.0;
}
int
int
CodecDescriptor::getSampleRate(CodecType payload)
{
switch(payload){
case PAYLOAD_CODEC_ULAW:
printf("PAYLOAD = %i\n", payload);
return 8000;
case PAYLOAD_CODEC_ALAW:
printf("PAYLOAD = %i\n", payload);
return 8000;
case PAYLOAD_CODEC_GSM:
printf("PAYLOAD = %i\n", payload);
return 8000;
case PAYLOAD_CODEC_ILBC_20:
printf("PAYLOAD = %i\n", payload);
return 8000;
case PAYLOAD_CODEC_SPEEX_8000:
printf("PAYLOAD = %i\n", payload);
return 8000;
case PAYLOAD_CODEC_SPEEX_16000:
printf("PAYLOAD = %i\n", payload);
return 16000;
case PAYLOAD_CODEC_SPEEX_32000:
printf("PAYLOAD = %i\n", payload);
return 32000;
default:
return -1;
}
return -1;
CodecsMap::iterator iter = _CodecsMap.find(payload);
if (iter!=_CodecsMap.end())
return (iter->second->getClockRate());
else
return 0;
}
int
CodecDescriptor::getChannel(CodecType payload)
{
CodecsMap::iterator iter = _CodecsMap.find(payload);
if (iter!=_CodecsMap.end())
return (iter->second->getChannel());
else
return 0;
}
void
void
CodecDescriptor::saveActiveCodecs(const std::vector<std::string>& list)
{
_codecOrder.clear();
......@@ -171,12 +179,103 @@ CodecDescriptor::saveActiveCodecs(const std::vector<std::string>& list)
int i=0;
int payload;
size_t size = list.size();
while(i<size)
while( i < size )
{
payload = std::atoi(list[i].data());
_codecOrder.push_back((CodecType)payload);
_CodecsMap.find((CodecType)payload)->second->setState( true );
i++;
}
}
std::vector<AudioCodec*>
CodecDescriptor::scanCodecDirectory( void )
{
std::vector<AudioCodec*> codecs;
std::string tmp;
std::string codecDir = CODECS_DIR;
codecDir.append("/");
std::string current = ".";
std::string previous = "..";
DIR *dir = opendir( codecDir.c_str() );
AudioCodec* audioCodec;
if( dir ){
dirent *dirStruct;
while( dirStruct = readdir( dir )) {
tmp = dirStruct -> d_name ;
if( tmp == current || tmp == previous){}
else{
if( seemsValid( tmp ) )
{
_debug("Codec : %s\n", tmp.c_str());
audioCodec = loadCodec( codecDir.append(tmp) );
codecs.push_back( audioCodec );
codecDir = CODECS_DIR;
codecDir.append("/");
}
}
}
}
closedir( dir );
return codecs;
}
AudioCodec*
CodecDescriptor::loadCodec( std::string path )
{
//_debug("Load path %s\n", path.c_str());
CodecHandlePointer p;
using std::cerr;
void * codecHandle = dlopen( path.c_str() , RTLD_LAZY );
if( !codecHandle )
cerr << dlerror() << '\n';
dlerror();
create_t* createCodec = (create_t*)dlsym( codecHandle , "create" );
if( dlerror() )
cerr << dlerror() << '\n';
AudioCodec* a = createCodec();
p = CodecHandlePointer( a, codecHandle );
_CodecInMemory.push_back(p);
return a;
}
void
CodecDescriptor::unloadCodec( CodecHandlePointer p )
{
// _debug("Unload codec %s\n", p.first->getCodecName().c_str());
using std::cerr;
int i;
destroy_t* destroyCodec = (destroy_t*)dlsym( p.second , "destroy");
if(dlerror())
cerr << dlerror() << '\n';
destroyCodec(p.first);
dlclose(p.second);
}
AudioCodec*
CodecDescriptor::getFirstCodecAvailable( void )
{
CodecsMap::iterator iter = _CodecsMap.begin();
if( iter != _CodecsMap.end())
return iter->second;
else
return NULL;
}
bool
CodecDescriptor::seemsValid( std::string lib)
{
// The name of the shared library seems valid <==> it looks like libcodec_xxx.so
// We check this
std::string begin = "libcodec_";
std::string end = ".so";
if(lib.substr(0, begin.length()) == begin)
if(lib.substr(lib.length() - end.length() , end.length() ) == end)
return true;
else
return false;
else
return false;
}
......@@ -26,8 +26,12 @@
#include <string>
#include <map>
#include <vector>
// To read directories content
#include <dirent.h>
#include "../global.h"
#include "codecs/audiocodec.h"
typedef enum {
// http://www.iana.org/assignments/rtp-parameters
// http://www.gnu.org/software/ccrtp/doc/refman/html/formats_8h.html#a0
......@@ -57,23 +61,38 @@ typedef std::map<CodecType, std::string> CodecMap;
/* The struct to reflect the order the user wants to use the codecs */
typedef std::vector<CodecType> CodecOrder;
typedef std::pair<AudioCodec* , void*> CodecHandlePointer;
typedef std::map<CodecType , AudioCodec*> CodecsMap;
class CodecDescriptor {
public:
/**
* Initialize all codec
*/
CodecDescriptor();
~CodecDescriptor() {};
~CodecDescriptor();
/*
* Accessor to data structures
*/
CodecMap& getCodecMap() { return _codecMap; }
CodecsMap& getCodecsMap() { return _CodecsMap; }
CodecOrder& getActiveCodecs() { return _codecOrder; }
/**
* Get codec with is associated payload
* @param payload the payload associated with the payload
* Get codec name by its payload
* @param payload the payload looked for
* same as getPayload()
* @return the name of the codec
*/
std::string& getCodecName(CodecType payload);
std::string getCodecName(CodecType payload);
/*
* Get the codec object associated with the payload
* @param payload The payload looked for
* @return AudioCodec* A pointer on a AudioCodec object
*/
AudioCodec* getCodec( CodecType payload );
/**
* Initialiaze the map with all the supported codecs, even those inactive
......@@ -129,15 +148,87 @@ public:
*/
int getSampleRate(CodecType payload);
/*
* Get the number of channels
* @param payload The payload of the codec
* @return int Number of channels
*/
int getChannel(CodecType payload);
/**
* Set the order of codecs by their payload
* @param list The ordered list sent by DBus
*/
void saveActiveCodecs(const std::vector<std::string>& list);
void saveActiveCodecs(const std::vector<std::string>& list);
std::string getDescription( std::string );
/*
* Get the number of codecs loaded in dynamic memory
*/
int getCodecsNumber( void ) { return _nbCodecs; }
/*
* Unreferences the codecs loaded in memory
*/
void deleteHandlePointer( void );
/*
* Get the first element of the CodecsMap struct.
* i.e the one with the lowest payload
* @return AudioCodec The pointer on the codec object
*/
AudioCodec* getFirstCodecAvailable( void );
private:
/*
* Scan the installation directory ( --prefix configure option )
* And load the dynamic library
* @return std::vector<AudioCodec*> The list of the codec object successfully loaded in memory
*/
std::vector<AudioCodec *> scanCodecDirectory( void );
/*
* Load a codec
* @param std::string The path of the shared ( dynamic ) library.
* @return AudioCodec* the pointer of the object loaded.
*/
AudioCodec* loadCodec( std::string );
/*
* Unload a codec
* @param CodecHandlePointer The map containing the pointer on the object and the pointer on the handle function
*/
void unloadCodec( CodecHandlePointer );
bool seemsValid( std::string );
/*
* Map the payload of a codec and its name
*/
CodecMap _codecMap;
/*
* Map the payload of a codec and the object associated
*/
CodecsMap _CodecsMap;
/*
* Vector containing the order of the codecs
*/
CodecOrder _codecOrder;
/*
* Number of codecs loaded
*/
int _nbCodecs;
/*
* Vector containing pairs
* Pair between pointer on function handle and pointer on audiocodec object
*/
std::vector< CodecHandlePointer > _CodecInMemory;
};
#endif // __CODEC_DESCRIPTOR_H__
......@@ -33,8 +33,8 @@ libcodec_ilbc_so_LDFLAGS = -shared ilbc/*.o -lc
SUBDIRS = ilbc
install-exec-local: install-libcodec_ulaw_so install-libcodec_alaw_so $(INSTALL_GSM_RULE) $(INSTALL_SPEEX_RULE) install-libcodec_ilbc_so
uninstall-local: uninstall-libcodec_ulaw_so uninstall-libcodec_alaw_so uninstall-libcodec_gsm_so uninstall-libcodec_speex_so uninstall-libcodec_ilbc_so
install-exec-local: install-libcodec_ulaw_so install-libcodec_alaw_so $(INSTALL_GSM_RULE) $(INSTALL_SPEEX_RULE)
uninstall-local: uninstall-libcodec_ulaw_so uninstall-libcodec_alaw_so uninstall-libcodec_gsm_so uninstall-libcodec_speex_so
install-libcodec_ulaw_so: libcodec_ulaw.so
mkdir -p $(sflcodecdir)
......@@ -45,8 +45,8 @@ install-libcodec_gsm_so: libcodec_gsm.so
$(INSTALL_PROGRAM) libcodec_gsm.so $(sflcodecdir)
install-libcodec_speex_so: libcodec_speex.so
$(INSTALL_PROGRAM) libcodec_speex.so $(sflcodecdir)
install-libcodec_ilbc_so: libcodec_ilbc.so
$(INSTALL_PROGRAM) libcodec_ilbc.so $(sflcodecdir)
#install-libcodec_ilbc_so: libcodec_ilbc.so
# $(INSTALL_PROGRAM) libcodec_ilbc.so $(sflcodecdir)