From 93fc9bd99172cb248ee5ca8a7fc93776e8967f97 Mon Sep 17 00:00:00 2001
From: Emmanuel Milou
 <emmanuel.milou@savoirfairelinux.comemmanuel.milou@savoirfairelinux.com>
Date: Thu, 24 Jan 2008 09:25:21 -0500
Subject: [PATCH] Dynamic loading of audio codecs

Note: Manually copy the .so library in /usr/lib , then ldconfig
---
 src/audio/Makefile.am         |   8 +--
 src/audio/alaw.cpp            |   8 +--
 src/audio/audiocodec.h        |   3 +-
 src/audio/audiofile.cpp       |  29 +++++++--
 src/audio/audiofile.h         |   4 +-
 src/audio/audiortp.cpp        | 118 ++++++++++++++++++++--------------
 src/audio/audiortp.h          |   3 +
 src/audio/codecDescriptor.cpp |  50 +++++++-------
 src/audio/codecDescriptor.h   |  27 ++++----
 src/audio/codec_alaw.so       | Bin 11881 -> 11538 bytes
 src/audio/codec_gsm.so        | Bin 12024 -> 11685 bytes
 src/audio/codec_ulaw.so       | Bin 11857 -> 11522 bytes
 src/audio/gsmcodec.cpp        |   8 +--
 src/audio/ulaw.cpp            |   7 +-
 src/call.cpp                  |   6 +-
 src/call.h                    |  13 ++--
 src/global.h                  |  10 +++
 src/iaxcall.cpp               |  20 ++++--
 src/iaxvoiplink.cpp           |  88 ++++++++++++++++++++-----
 src/managerimpl.cpp           |  39 +++++------
 src/managerimpl.h             |   4 +-
 src/sipcall.cpp               |  32 +++++----
 src/sipvoiplink.cpp           |  16 ++---
 23 files changed, 311 insertions(+), 182 deletions(-)

diff --git a/src/audio/Makefile.am b/src/audio/Makefile.am
index 04c7127315..73333764de 100644
--- a/src/audio/Makefile.am
+++ b/src/audio/Makefile.am
@@ -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
diff --git a/src/audio/alaw.cpp b/src/audio/alaw.cpp
index 52d8177a54..cb9c810824 100644
--- a/src/audio/alaw.cpp
+++ b/src/audio/alaw.cpp
@@ -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;
 }
 
diff --git a/src/audio/audiocodec.h b/src/audio/audiocodec.h
index cf0b636e56..399e9416df 100644
--- a/src/audio/audiocodec.h
+++ b/src/audio/audiocodec.h
@@ -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; }
+  
 
 };
 
diff --git a/src/audio/audiofile.cpp b/src/audio/audiofile.cpp
index bae4379c42..d96dc3852e 100644
--- a/src/audio/audiofile.cpp
+++ b/src/audio/audiofile.cpp
@@ -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;
 }
 
diff --git a/src/audio/audiofile.h b/src/audio/audiofile.h
index 25773ad62e..e476fe98ff 100644
--- a/src/audio/audiofile.h
+++ b/src/audio/audiofile.h
@@ -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;
 };
 
diff --git a/src/audio/audiortp.cpp b/src/audio/audiortp.cpp
index 920741d37b..f91414d530 100644
--- a/src/audio/audiortp.cpp
+++ b/src/audio/audiortp.cpp
@@ -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;
diff --git a/src/audio/audiortp.h b/src/audio/audiortp.h
index 2444be5676..09dda4c205 100644
--- a/src/audio/audiortp.h
+++ b/src/audio/audiortp.h
@@ -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);
 };
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/src/audio/codecDescriptor.cpp b/src/audio/codecDescriptor.cpp
index e9a0e0db85..92cf39c6aa 100644
--- a/src/audio/codecDescriptor.cpp
+++ b/src/audio/codecDescriptor.cpp
@@ -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++;
   }
 	
diff --git a/src/audio/codecDescriptor.h b/src/audio/codecDescriptor.h
index e001862adb..193ea88933 100644
--- a/src/audio/codecDescriptor.h
+++ b/src/audio/codecDescriptor.h
@@ -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;
 };
diff --git a/src/audio/codec_alaw.so b/src/audio/codec_alaw.so
index 4fd5503da3ba915f1a67fac93488c80142c776cc..48ed19010a3b631d572d2630789887954b97ad86 100755
GIT binary patch
delta 4519
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

delta 4827
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
TBL^|ZtE#e+x{-2C*-QTe<B*zI

diff --git a/src/audio/codec_gsm.so b/src/audio/codec_gsm.so
index 832e6ddff6b8903494b819f128231876b48fa17d..fe907692027f6e0dae596df4e0d5afac6d6b7422 100755
GIT binary patch
delta 4583
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

literal 12024
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
bi+0n>_dmR9O3zQXBb>*hY*eQ-xtRV3apidu

diff --git a/src/audio/codec_ulaw.so b/src/audio/codec_ulaw.so
index 0c7c40fc05cb5c467620b498603ade019cc00da3..441893d69d3a397b1c6b914b13afc7905502ebf2 100755
GIT binary patch
delta 4527
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
AiU0rr

delta 4734
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

diff --git a/src/audio/gsmcodec.cpp b/src/audio/gsmcodec.cpp
index 1556185632..fbc924feb9 100644
--- a/src/audio/gsmcodec.cpp
+++ b/src/audio/gsmcodec.cpp
@@ -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;
 }
diff --git a/src/audio/ulaw.cpp b/src/audio/ulaw.cpp
index b99416a57f..fd1c58370f 100644
--- a/src/audio/ulaw.cpp
+++ b/src/audio/ulaw.cpp
@@ -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;
 }
diff --git a/src/call.cpp b/src/call.cpp
index b19a198ded..36428177aa 100644
--- a/src/call.cpp
+++ b/src/call.cpp
@@ -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);  
diff --git a/src/call.h b/src/call.h
index 7794be6815..a01fe6173c 100644
--- a/src/call.h
+++ b/src/call.h
@@ -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;
 
diff --git a/src/global.h b/src/global.h
index 06a3206afe..0f13cf1c46 100644
--- a/src/global.h
+++ b/src/global.h
@@ -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__
diff --git a/src/iaxcall.cpp b/src/iaxcall.cpp
index 314f57a351..a2c07838f5 100644
--- a/src/iaxcall.cpp
+++ b/src/iaxcall.cpp
@@ -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();
diff --git a/src/iaxvoiplink.cpp b/src/iaxvoiplink.cpp
index 2996b75038..fa77f7ce95 100644
--- a/src/iaxvoiplink.cpp
+++ b/src/iaxvoiplink.cpp
@@ -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);
+
+
 }
 
 
diff --git a/src/managerimpl.cpp b/src/managerimpl.cpp
index b16891dc9b..7887e499db 100644
--- a/src/managerimpl.cpp
+++ b/src/managerimpl.cpp
@@ -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
diff --git a/src/managerimpl.h b/src/managerimpl.h
index cfdac255d8..38d25a22c8 100644
--- a/src/managerimpl.h
+++ b/src/managerimpl.h
@@ -110,7 +110,7 @@ public:
   /**
    * Get a descriptor map of codec available
    */
-  CodecDescriptorMap& getCodecDescriptorMap(void) {return _codecDescriptorMap;}
+  CodecDescriptor& getCodecDescriptorMap(void) {return _codecDescriptorMap;}
 
   /**
    * Functions which occur with a user's action
@@ -513,7 +513,7 @@ private:
   DTMF* _dtmfKey;
 
   // map of codec (for configlist request)
-  CodecDescriptorMap _codecDescriptorMap;
+  CodecDescriptor _codecDescriptorMap;
 
   /////////////////////
   // Protected by Mutex
diff --git a/src/sipcall.cpp b/src/sipcall.cpp
index 37f2b84d4e..3bbb6f361d 100644
--- a/src/sipcall.cpp
+++ b/src/sipcall.cpp
@@ -76,6 +76,7 @@ SIPCall::SIPCallInvite(eXosip_event_t *event)
   }
 
   if (!setAudioCodecFromSDP(remote_med, event->tid)) {
+    _debug("SIP Failure: unable to set audio codecs from the remote SDP\n");
     sdp_message_free (remote_sdp);
     return false;
   }
@@ -90,7 +91,6 @@ SIPCall::SIPCallInvite(eXosip_event_t *event)
       _debug("< Sending Answer 415 : unsupported media type\n");
       eXosip_call_send_answer (event->tid, 415, NULL);
     } else {
-
       sdp_message_t *local_sdp = eXosip_get_sdp_info(answer);
       sdp_media_t *local_med = NULL;
       if (local_sdp != NULL) {
@@ -283,11 +283,12 @@ SIPCall::SIPCallAnsweredWithoutHold(eXosip_event_t* event)
 #else
   char *tmp = (char*) osip_list_get (&(remote_med->m_payloads), 0);
 #endif
-  setAudioCodec(0);
+  setAudioCodec((CodecType)-1);
   if (tmp != NULL) {
     int payload = atoi (tmp);
     _debug("            Remote Payload: %d\n", payload);
-    setAudioCodec(_codecMap.getCodec((CodecType)payload)); // codec builder for the mic
+    //setAudioCodec(_codecMap.getCodecName((CodecType)payload)); // codec builder for the mic
+    setAudioCodec((CodecType)payload); // codec builder for the mic
   }
 
 /*
@@ -352,17 +353,21 @@ SIPCall::sdp_complete_message(sdp_message_t * remote_sdp, osip_message_t * msg)
       remote_med_m_payloads = &(remote_med->m_payloads);
       #endif
 
-      while (!osip_list_eol(remote_med_m_payloads, iPayload)) {
+      while (!osip_list_eol(remote_med_m_payloads, iPayload) && iPayload < 2) {
         tmp = (char *)osip_list_get(remote_med_m_payloads, iPayload);
         if (tmp!=NULL) {
           int payload = atoi(tmp);
-          AudioCodec* audiocodec = _codecMap.getCodec((CodecType)payload);
-          if (audiocodec != NULL && audiocodec->isActive()) {
+	  _debug("remote payload = %s\n", tmp);
+          CodecType audiocodec = (CodecType)payload;
+          //if (audiocodec != NULL && audiocodec->isActive()) {
+          if (audiocodec != (CodecType)-1 && _codecMap.setActive(audiocodec))  { //TODO: check if the remote payload matches with one of the codec map
             listCodec << payload << " ";
-            listRtpMap << "a=rtpmap:" << payload << " " << audiocodec->getCodecName() << "/" << audiocodec->getClockRate();
-            if ( audiocodec->getChannel() != 1) {
+            //listRtpMap << "a=rtpmap:" << payload << " " << audiocodec->getCodecName() << "/" << audiocodec->getClockRate();
+            listRtpMap << "a=rtpmap:" << payload << " " << _codecMap.getCodecName(audiocodec) << "/" << 8000;
+        // TODO: manage a way to get the channel infos    
+	/*if ( audiocodec->getChannel() != 1) {
               listRtpMap << "/" << audiocodec->getChannel();
-            }
+            }*/
             listRtpMap << "\r\n";
           }
         }
@@ -581,7 +586,7 @@ SIPCall::setAudioCodecFromSDP(sdp_media_t* remote_med, int tid)
     if (tmp != NULL ) {
       int payload = atoi(tmp);
       // stop if we find a correct codec
-      if (_codecMap.getCodec((CodecType)payload) != NULL){
+      if (_codecMap.setActive((CodecType)payload)){
           break;
       }
     }
@@ -589,13 +594,14 @@ SIPCall::setAudioCodecFromSDP(sdp_media_t* remote_med, int tid)
     pos++;
   }
 
-  setAudioCodec(0);
+  setAudioCodec((CodecType)-1);
   if (tmp != NULL) {
     int payload = atoi (tmp);
     _debug("            Payload: %d\n", payload);
-    setAudioCodec(_codecMap.getCodec((CodecType)payload)); // codec builder for the mic
+    setAudioCodec((CodecType)payload); // codec builder for the mic
+	_debug("SetAUDIOcodec!!\n");
   }
-  if (getAudioCodec() == 0) {
+  if (getAudioCodec() == (CodecType) -1) {
     _debug("SIPCall Failure: Unable to set codec\n");
     _debug("< Sending 415 Unsupported media type\n");
     eXosip_lock();
diff --git a/src/sipvoiplink.cpp b/src/sipvoiplink.cpp
index 168a2d0e8b..a23936925f 100644
--- a/src/sipvoiplink.cpp
+++ b/src/sipvoiplink.cpp
@@ -947,24 +947,24 @@ SIPVoIPLink::SIPStartCall(SIPCall* call, const std::string& subject)
   int nbChannel;
 
   // Set rtpmap according to the supported codec order
-  CodecMap map = call->getCodecMap().getMap();
+  CodecMap map = call->getCodecMap().getCodecMap();
+  //CodecMap map = Manager::instance().getCodecDescriptorMap();	
   CodecMap::iterator iter = map.begin();
 
   while(iter != map.end()) {
-    printf("codec = %s\n",iter->second->getCodecName().data());
-    if (iter->second!=0 && iter->second->isActive()) {
-    printf("codec = %s\n",iter->second->getCodecName().data());
-      payload = iter->first;
+    //if (iter->second!=0 && iter->second->isActive()) {
+      if(iter->first != -1){
+	payload = iter->first;
       // add each payload in the list of payload
       media_audio << payload << " ";
 
       rtpmap_attr << "a=rtpmap:" << payload << " " << 
-      iter->second->getCodecName().data() << "/" << iter->second->getClockRate();
+      iter->second.data() << "/" << 8000; //iter->second->getClockRate();
 
-      nbChannel = iter->second->getChannel();
+      /*nbChannel = iter->second->getChannel();
       if (nbChannel!=1) {
         rtpmap_attr << "/" << nbChannel;
-      }
+      }*/
       rtpmap_attr << "\r\n";
     }
     // go to next codec
-- 
GitLab