diff --git a/debian/Release b/debian/Release
index 7fb4d2cd9ab47a7db36db62a5fbbdea976a4655d..5bbfec2cc9ae328804760f3a3782a036edea9761 100644
--- a/debian/Release
+++ b/debian/Release
@@ -1,7 +1,7 @@
 Archive : unstable
-Version: 0.9
+Version: 0.9.1
 Component : universe
 Origin : SFLphone
 Label : sflphone
-Architecture : all
+Architecture : i386
 
diff --git a/debian/arch b/debian/arch
deleted file mode 100644
index 5a9a476a8b7b3a362fa7925b74bda4a771cba262..0000000000000000000000000000000000000000
--- a/debian/arch
+++ /dev/null
@@ -1 +0,0 @@
-i386
diff --git a/debian/autopackage.sh b/debian/autopackage.sh
index 4d6248ca2dd49d3256469f817de477754a8b04d8..b3cb825990fc7ea91066b8cab1ec5d60e7a745cb 100755
--- a/debian/autopackage.sh
+++ b/debian/autopackage.sh
@@ -42,7 +42,7 @@ cp $bindir/sflphoned $sfldir$bindir
 strip $sfldir$bindir/sflphoned
 cp $bindir/sflphone-gtk $sfldir$bindir
 strip $sfldir$bindir/sflphone-gtk
-ln -sf $sfldir$bindir/sflphone-gtk $sfldir$bindir/sflphone
+ln -sf $bindir/sflphone-gtk $sfldir$bindir/sflphone
 
 #/usr/lib
 mkdir -p $sfldir/usr/lib/sflphone/codecs
@@ -76,8 +76,10 @@ cp changelog.Debian.gz $sfldir$sharedir/doc/sflphone
 cp copyright $sfldir$sharedir/doc/sflphone
 cp TODO $sfldir$sharedir/doc/sflphone
 
-# DEBIAN files
 mkdir -p $debdir 
+cp debian-binary $sfldir
+cp postrm $debdir
+# DEBIAN files
 # Create control file
 control="$debdir/control"
 touch $control
@@ -99,4 +101,4 @@ fakeroot dpkg --build $sfldir ${sfldir}_$2.deb
 
 # Clean up the generated stuff
 echo "Clean up ... "
-#rm -rf $sfldir 
+rm -rf $sfldir 
diff --git a/debian/changelog b/debian/changelog
deleted file mode 100644
index b2b6d3bc6cbd494a5becc148f8774450befdb577..0000000000000000000000000000000000000000
--- a/debian/changelog
+++ /dev/null
@@ -1,70 +0,0 @@
-sflphone (0.9.1) unstable; urgency=low
-  * Add a search tool in the history
-  * Migrate some gtk_entry_new to sexy_icon_entry_new
-  * Bug fix (Ticket #78): The voicemail password isn't displayed anymore in
-    the history tab
-  * Add the SIP registration expire value in the user file.
-
- -- Emmanuel Milou <emmanuel.milou@savoirfairelinux.com> Thu, 22 May 2008 11:14:25 -0500
-
-sflphone (0.9.0) unstable; urgency=low
-  * Add history features
-    * Call date
-    * Call duration
-    * Mouse events in the history tab
-  * Smooth switch from the history tab to the calls tab
-  * Remove most of GTK-Critical warnings
-
- -- Emmanuel Milou <emmanuel.milou@savoirfairelinux.com> Wed, 13 May 2008 16:58:25 -0500
-
-sflphone (0.9-2008-06-06) unstable; urgency=low
-  * Audio bug correction: capture stopped after a few minutes of conversation
-  with USB Plantronics sound card
-
- -- Emmanuel Milou <emmanuel.milou@savoirfairelinux.com> Tue, 06 May 2008 16:58:25 -0500
-
-sflphone (0.9-2008-05-06) unstable; urgency=low
-  * Bug correction: account creation with the assistant
-  * GTK+ warnings removal
-  * libnotify warnings removal
-  * Remove aliasing on the SFLphone logo
-  
- -- Emmanuel Milou <emmanuel.milou@savoirfairelinux.com> Mon, 05 May 2008 16:58:25 -0500
-
-sflphone (0.9) unstable; urgency=low
-  * Clean dependencies ( removal of libboost )
-  * Several GTK improvement and updates
-    -account window
-    -configuration window
-  * Migrate from GtkCheckMenuItem to GtkImageMenuItem  
-  * ALSA standard I/O transfers: MMAP instead of R/W
-  * Fix speex audio quality
-  * IAX2 protocol
-    -Fix hold/unhold situation
-    -Add on hold music
-  * SIP protocol
-    -Ringtone on incoming call
-    -Fix transfer situation
-  * Add desktop notification ( libnotify )
-  * Improve the system tray icon behaviour
-  * Improve registration error handling
-  * Register/unregister from the account window takes effect without starting back SFLphone
-  * Compilation warnings removal
-  * Call history
-  * Add an account configuration wizard
-
- -- Emmanuel Milou <emmanuel.milou@savoirfairelinux.com> Wed, 30 Apr 2008 16:58:25 -0500
-
-
-
-sflphone (0.8.2 ) unstable; urgency=low
-
-  * Internationalization of the GTK GUI 
-      * English / French
-  * STUN support
-  * Slight modifications of the graphical interface ( tooltips, dialpad, ...)
-
-
- -- Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>  Fri, 21 Mar 2008 11:37:53 -0500
-
-
diff --git a/debian/control b/debian/control
index aa80a7f5a06dafd35c55efe11a5bb68577f51864..bf0d3fd666e70203a245c34ab00b4b6b6f0ee61b 100644
--- a/debian/control
+++ b/debian/control
@@ -2,18 +2,18 @@ Source: sflphone
 Maintainer: SavoirFaireLinux Inc <emmanuel.milou@savoirfairelinux.com>
 Section: gnome
 Priority: optional
-Standards-Version: 0.9
+Build-Depends: debhelper (>> 3.0.0)
+Standards-Version: 0.9.1
 
 Package: sflphone
-Architecture: i386
 Section: gnome
 Priority: optional
+Architecture: i386
 Essential: no
-Depends: libgcc1 , libsamplerate0 (>=0.1.2) , libdbus-glib-1-2 (>= 0.73), libexpat1 , libgtk2.0-0 , gnome-common , libc6 (>= 2.3.6-6) , libglib2.0-0 (>= 2.12.0) , libosip2-3, libexosip2-5, libcommoncpp2-1.5.3-0 , libccrtp1-1.5-1 , libiax0 , libgtkglext1
+Depends: libgcc1 , libsamplerate0 (>=0.1.2) , libdbus-glib-1-2 (>= 0.73), libexpat1 , libgtk2.0-0 , libc6 (>= 2.3.6-6) , libglib2.0-0 (>= 2.12.0) , libosip2-2, libexosip2-4, libcommoncpp2-1.6-0 , libccrtp1-1.6-0  , sflphone-iax2 , libgsm1 (>=1.0.10) , libspeex1 (>=1.1.12) , dbus-c++-1 (>=0.5.0) , libsexy2 (>=0.1.11)
 Homepage: http://www.sflphone.org
-Description: SFLphone - Answer the call
- SFLphone is meant to be a robust enterprise-class desktop phone. It is design with a hundred-calls-a-day receptionist in mind. It can work for you, too.
- .
+Description: SIP and IAX2 compatible softphone
+ SFLphone is meant to be a robust enterprise-class desktop phone.
  SFLphone is released under the GNU General Public License.
- .
- SFLphone is being developed by the global community, and maintained by Savoir-faire Linux, a Montreal, Quebec, Canada-based Linux consulting company.
+ SFLphone is being developed by the global community, and maintained by
+ Savoir-faire Linux, a Montreal, Quebec, Canada-based Linux consulting company.
diff --git a/debian/debian-binary b/debian/debian-binary
new file mode 100644
index 0000000000000000000000000000000000000000..cd5ac039d67e0bdadb17976e4ac39f0ffe6bb6e4
--- /dev/null
+++ b/debian/debian-binary
@@ -0,0 +1 @@
+2.0
diff --git a/debian/postrm b/debian/postrm
new file mode 100755
index 0000000000000000000000000000000000000000..56801250786e23c392e1598602ed8593b4c64ff5
--- /dev/null
+++ b/debian/postrm
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+# debian/postrm postremoval script for SFLphone
+
+if [ "$1" = "purge" ]
+then
+
+  # remove the user config file
+  rm -f $HOME/.sflphone/sflphonedrc
+
+fi
+
+exit 0
+
+## -------------------------------------------------
diff --git a/debian/rules b/debian/rules
index efde01dd03e95702fef9e90f0c6e0c0cfd5ed9bf..110e88d2256c17cad8b2f0c36a9cddc8b2c05a54 100755
--- a/debian/rules
+++ b/debian/rules
@@ -35,10 +35,12 @@ endif
 config.status: configure
 	dh_testdir
 	# Add here commands to configure the package.
-	autoreconf --install	
-	CFLAGS="$(CFLAGS)" CXX="$(CXX)" ./configure --prefix=/usr --with-debug
+#autoreconf --install	
+#CFLAGS="$(CFLAGS)" CXX="$(CXX)" ./configure --prefix=/usr --with-debu
+	./configure --prefix=/
+#gnome-autogen.sh --prefix=/usr --with-debug
 	cd sflphone-gtk
-	gnome-autogen.sh --prefix=/usr
+	./configure --prefix=/
 	
 
 #Architecture 
@@ -48,7 +50,8 @@ build-arch: build-arch-stamp
 build-arch-stamp:  config.status
 
 	# Add here commands to compile the arch part of the package.
-	#$(MAKE) 
+	$(MAKE) && (cd sflphone-gtk)
+	$(MAKE)
 	touch build-arch-stamp
 
 build-indep: build-indep-stamp
@@ -96,7 +99,7 @@ install-arch:
 
 	# Add here commands to install the arch part of the package into 
 	# debian/tmp.
-	$(MAKE) install DESTDIR=$(CURDIR)/debian/sflphoned
+	$(MAKE) install DESTDIR=$(CURDIR)/debian/sflphone/usr
 
 	dh_install -s
 # Must not depend on anything. This is to be called by
diff --git a/debian/sflphone.install b/debian/sflphone.install
new file mode 100644
index 0000000000000000000000000000000000000000..7e7915dafd83894ad61e23a94368b0baca82fa00
--- /dev/null
+++ b/debian/sflphone.install
@@ -0,0 +1,29 @@
+usr/bin
+usr/bin/sflphoned
+usr/bin/sflphone-gtk
+usr/bin/sflphone
+
+#/usr/lib
+usr/lib/sflphone/codecs
+usr/lib/sflphone/codecs/libcodec_*
+
+#/usr/share/applications
+usr/share/applications
+usr/share/applications/sflphone.desktop
+usr/share/dbus-1/services 
+usr/share/dbus-1/services/org.sflphone.SFLphone.service
+usr/share/pixmaps
+usr/share/pixmaps/sflphone.png
+
+usr/share/sflphone/*
+usr/share/sflphone/ringtones/* 
+
+usr/share/locale/fr/LC_MESSAGES
+usr/share/locale/fr/LC_MESSAGES/sflphone.mo
+usr/share/locale/es/LC_MESSAGES
+usr/share/locale/es/LC_MESSAGES/sflphone.mo
+
+changelog.Debian.gz 
+copyright 
+TODO 
+
diff --git a/sflphone-gtk/src/assistant.c b/sflphone-gtk/src/assistant.c
index e50d043c89c298d21a00b3480fc64f189c17d279..27c066cc6e4c8fd888af2ea69fd8a8a6a8c22be3 100644
--- a/sflphone-gtk/src/assistant.c
+++ b/sflphone-gtk/src/assistant.c
@@ -41,11 +41,13 @@ set_account_type( GtkWidget* widget , gpointer data )
 static void close_callback( void )
 {
   gtk_widget_destroy(wiz->assistant);
+  g_free(wiz); wiz = NULL;
 }
 
 static void cancel_callback( void )
 {
   gtk_widget_destroy(wiz->assistant);
+  g_free(wiz); wiz = NULL;
 }
 
   static void
@@ -98,6 +100,7 @@ enable_stun( GtkWidget* widget )
   void
 build_wizard( void )
 {
+if(!wiz){
   wiz = ( struct _wizard* )g_malloc( sizeof( struct _wizard));
   current = g_new0(account_t, 1);
   current->properties = g_hash_table_new(NULL, g_str_equal);
@@ -116,14 +119,14 @@ build_wizard( void )
   build_iax_account_configuration();
   build_registration_error();
   build_summary();
-
+  
   g_signal_connect(G_OBJECT(wiz->assistant), "close" , G_CALLBACK(close_callback), NULL);
   g_signal_connect(G_OBJECT(wiz->assistant), "cancel" , G_CALLBACK(cancel_callback), NULL);
 
   gtk_widget_show_all(wiz->assistant);
 
   gtk_assistant_update_buttons_state(GTK_ASSISTANT(wiz->assistant));
-
+	}
 }
 
   GtkWidget*
diff --git a/src/Makefile.am b/src/Makefile.am
index d5e84d57d0c0e921bbc8ca3b315efd894203168f..5915d0166af82089b66206bcbe3e8750b86c9cda 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -31,10 +31,10 @@ endif
 ALSAFLAG= -lasound
 PULSEAUDIO_LIBS=-lpulse
 
-SUBDIRS = audio config dbus $(ZEROCONFDIR)# contact memmanager video mixer
+SUBDIRS = audio config dbus $(ZEROCONFDIR) #contact memmanager video mixer
 
 sflphoned_SOURCES = eventthread.cpp 	main.cpp 	voiplink.cpp \
-		managerimpl.cpp	observer.cpp \
+		managerimpl.cpp	observer.cpp  samplerateconverter.cpp \
 		account.cpp sipaccount.cpp accountcreator.cpp \
                 sipvoiplink.cpp call.cpp sipcall.cpp \
 		$(IAXSOURCES)
@@ -61,7 +61,7 @@ libsflphone_la_SOURCES =
 
 noinst_LTLIBRARIES = libsflphone.la
 noinst_HEADERS = managerimpl.h manager.h global.h observer.h eventthread.h user_cfg.h \
-                 voiplink.h \
+                 voiplink.h  samplerateconverter.h \
 		 account.h sipaccount.h accountcreator.h \
                  sipvoiplink.h  call.h  sipcall.h \
 		 $(IAXHEADERS)
diff --git a/src/audio/audiortp.cpp b/src/audio/audiortp.cpp
index cb30737f116a1af7dc9242722248b747137f630c..641eb4f841a5ebfc05ea3fb7c06828ca6a36d4fa 100644
--- a/src/audio/audiortp.cpp
+++ b/src/audio/audiortp.cpp
@@ -38,7 +38,6 @@
 #include "ringbuffer.h"
 #include "../user_cfg.h"
 #include "../sipcall.h"
-#include <samplerate.h>
 
 ////////////////////////////////////////////////////////////////////////////////
 // AudioRtp                                                          
@@ -102,9 +101,6 @@ AudioRtpRTX::AudioRtpRTX (SIPCall *sipcall, bool sym)
   _ca = sipcall;
   _sym = sym;
   // AudioRtpRTX should be close if we change sample rate
-  //int IDcodec= _ca->getAudioCodec();
-  //_codecSampleRate = _ca->getAudioCodec()->getClockRate();
-  //_codecDesc = Manager::instance().getCodecDescriptorMap(); 
   // 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();
@@ -118,13 +114,6 @@ AudioRtpRTX::AudioRtpRTX (SIPCall *sipcall, bool sym)
     _sessionRecv = NULL;
     _sessionSend = NULL;
   }
-
-  // libsamplerate-related
-  // Set the converter type for the upsampling and the downsampling
-  // interpolator SRC_SINC_BEST_QUALITY
-  _src_state_mic  = src_new(SRC_SINC_BEST_QUALITY, 1, &_src_err);
-  _src_state_spkr = src_new(SRC_SINC_BEST_QUALITY, 1, &_src_err);
-
 }
 
 AudioRtpRTX::~AudioRtpRTX () {
@@ -145,39 +134,34 @@ AudioRtpRTX::~AudioRtpRTX () {
     delete _session;     _session = NULL;
   }
 
-  delete [] _intBufferDown; _intBufferDown = NULL;
-  delete [] _floatBufferUp; _floatBufferUp = NULL;
-  delete [] _floatBufferDown; _floatBufferDown = NULL;
-  delete [] _dataAudioLayer; _dataAudioLayer = NULL;
+  delete [] micData;  micData = NULL;
+  delete [] micDataConverted;  micDataConverted = NULL;
+  delete [] micDataEncoded;  micDataEncoded = NULL;
 
-  delete [] _sendDataEncoded; _sendDataEncoded = NULL;
-  delete [] _receiveDataDecoded; _receiveDataDecoded = NULL;
+  delete [] spkrDataDecoded; spkrDataDecoded = NULL;
+  delete [] spkrDataConverted; spkrDataConverted = NULL;
 
   delete time; time = NULL;
-
-  // libsamplerate-related
-  _src_state_mic  = src_delete(_src_state_mic);
-  _src_state_spkr = src_delete(_src_state_spkr);
 }
 
   void
 AudioRtpRTX::initBuffers()
 {
+  converter = new SamplerateConverter( _layerSampleRate , _layerFrameSize );
+
   int nbSamplesMax = (int) (_layerSampleRate * _layerFrameSize /1000);
-  _dataAudioLayer = new SFLDataFormat[nbSamplesMax];
-  _receiveDataDecoded = new int16[nbSamplesMax];
-  _floatBufferDown  = new float32[nbSamplesMax];
-  _floatBufferUp = new float32[nbSamplesMax];
-  _sendDataEncoded = new unsigned char[nbSamplesMax];
-  _intBufferDown = new int16[nbSamplesMax];
+
+  micData = new SFLDataFormat[nbSamplesMax];
+  micDataConverted = new SFLDataFormat[nbSamplesMax];
+  micDataEncoded = new unsigned char[nbSamplesMax];
+
+  spkrDataConverted = new SFLDataFormat[nbSamplesMax];
+  spkrDataDecoded = new SFLDataFormat[nbSamplesMax];
 }
 
   void
 AudioRtpRTX::initAudioRtpSession (void) 
 {
-
-
-
   try {
     if (_ca == 0) { return; }
     _audiocodec = Manager::instance().getCodecDescriptorMap().getCodec( _ca->getAudioCodec() );
@@ -254,7 +238,6 @@ AudioRtpRTX::sendSessionFromMic(int timestamp)
   //   3. encode it
   //   4. send it
   try {
-    int16* toSIP = NULL;
 
     timestamp += time->getSecond();
     if (_ca==0) { _debug(" !ARTP: No call associated (mic)\n"); return; } // no call, so we do nothing
@@ -267,50 +250,38 @@ AudioRtpRTX::sendSessionFromMic(int timestamp)
     int maxBytesToGet = _layerSampleRate * _layerFrameSize * sizeof(SFLDataFormat) / 1000;
     // available bytes inside ringbuffer
     int availBytesFromMic = audiolayer->canGetMic();
-    //printf("availBytesFromMic = %i \n", availBytesFromMic);
 
     // take the lowest
     int bytesAvail = (availBytesFromMic < maxBytesToGet) ? availBytesFromMic : maxBytesToGet;
-    //printf("max bytes to get: %i\n", bytesAvail);
     // Get bytes from micRingBuffer to data_from_mic
-    int nbSample = audiolayer->getMic(_dataAudioLayer, bytesAvail) / sizeof(SFLDataFormat);
+    //_debug("get data from mic\n");
+    int nbSample = audiolayer->getMic( micData , bytesAvail ) / sizeof(SFLDataFormat);
     int nb_sample_up = nbSample;
     int nbSamplesMax = _layerFrameSize * _audiocodec->getClockRate() / 1000;
 
+    //_debug("resample data\n");
     nbSample = reSampleData(_audiocodec->getClockRate(), nb_sample_up, DOWN_SAMPLING);	
 
-    toSIP = _intBufferDown;
-
     if ( nbSample < nbSamplesMax - 10 ) { // if only 10 is missing, it's ok
       // fill end with 0...
-      //_debug("begin: %p, nbSample: %d\n", toSIP, nbSample);
-      memset(toSIP + nbSample, 0, (nbSamplesMax-nbSample)*sizeof(int16));
+      memset( micDataConverted + nbSample, 0, (nbSamplesMax-nbSample)*sizeof(int16));
       nbSample = nbSamplesMax;
     }
-    // debug - dump sound in a file
-    //_debug("AR: Nb sample: %d int, [0]=%d [1]=%d [2]=%d\n", nbSample, toSIP[0], toSIP[1], toSIP[2]);
-    // for the mono: range = 0 to RTP_FRAME2SEND * sizeof(int16)
-    // codecEncode(char *dest, int16* src, size in bytes of the src)
-    int compSize = _audiocodec->codecEncode(_sendDataEncoded, toSIP, nbSample*sizeof(int16));
-    //printf("jusqu'ici tout vas bien\n");
-
+    int compSize = _audiocodec->codecEncode( micDataEncoded , micDataConverted , nbSample*sizeof(int16));
     // encode divise by two
     // Send encoded audio sample over the network
     if (compSize > nbSamplesMax) { _debug("! ARTP: %d should be %d\n", compSize, nbSamplesMax);}
     if (!_sym) {
-      _sessionSend->putData(timestamp, _sendDataEncoded, compSize);
+      _sessionSend->putData(timestamp, micDataEncoded, compSize);
     } else {
-      _session->putData(timestamp, _sendDataEncoded, compSize);
+      _session->putData(timestamp, micDataEncoded, compSize);
     }
-    toSIP = NULL;
   } catch(...) {
     _debugException("! ARTP: sending failed");
     throw;
   }
 }
 
-
-
   void
 AudioRtpRTX::receiveSessionForSpkr (int& countTime)
 {
@@ -334,54 +305,44 @@ AudioRtpRTX::receiveSessionForSpkr (int& countTime)
       return;
     }
 
-    int payload = adu->getType(); // codec type
-    unsigned char* data  = (unsigned char*)adu->getData(); // data in char
+    //int payload = adu->getType(); // codec type
+    unsigned char* spkrData  = (unsigned char*)adu->getData(); // data in char
     unsigned int size = adu->getSize(); // size in char
 
-
-    //_fstream.write((char*) data, size);
     // Decode data with relevant codec
-    int max = (int)(_codecSampleRate * _layerFrameSize / 1000);
+    unsigned int max = (unsigned int)(_codecSampleRate * _layerFrameSize / 1000);
 
     if ( size > max ) {
-      _debug("We have received from RTP a packet larger than expected: %s VS %s\n", size, max);
+      _debug("We have received from RTP a packet larger than expected: %d VS %d\n", size, max);
       _debug("The packet size has been cropped\n");
       size=max;
     }
 
-    //printf("size = %i\n", size);
-
     if (_audiocodec != NULL) {
 
-      int expandedSize = _audiocodec->codecDecode(_receiveDataDecoded, data, size);
-      //	printf("%i\n", expandedSize);
-      //_fstream.write((char*) _receiveDataDecoded, );
+      int expandedSize = _audiocodec->codecDecode( spkrDataDecoded , spkrData , size );
       //buffer _receiveDataDecoded ----> short int or int16, coded on 2 bytes
       int nbInt16 = expandedSize / sizeof(int16);
       //nbInt16 represents the number of samples we just decoded
       if (nbInt16 > max) {
-	_debug("We have decoded an RTP packet larger than expected: %s VS %s. Cropping.\n", nbInt16, max);
+	_debug("We have decoded an RTP packet larger than expected: %d VS %d. Cropping.\n", nbInt16, max);
 	nbInt16=max;
       }
-
-      SFLDataFormat* toAudioLayer;
       int nbSample = nbInt16;
 
       // Do sample rate conversion
       int nb_sample_down = nbSample;
       nbSample = reSampleData(_codecSampleRate , nb_sample_down, UP_SAMPLING);
 #ifdef DATAFORMAT_IS_FLOAT
-      toAudioLayer = _floatBufferUp;
 #else
-      toAudioLayer = _dataAudioLayer;
 #endif
 
       int layer = audiolayer->getLayerType();
       //_debug(" interface %i - ALSA = %i\n" , layer, ALSA);
       if( CHECK_INTERFACE( layer, ALSA ) )
-	audiolayer->playSamples(toAudioLayer, nbSample * sizeof(SFLDataFormat), true);
+	audiolayer->playSamples( spkrDataConverted, nbSample * sizeof(SFLDataFormat), true);
       else      
-	audiolayer->putMain( toAudioLayer, nbSample * sizeof(SFLDataFormat) );
+	audiolayer->putMain( spkrDataConverted, nbSample * sizeof(SFLDataFormat) );
       // Notify (with a beep) an incoming call when there is already a call 
       countTime += time->getSecond();
       if (Manager::instance().incomingCallWaiting() > 0) {
@@ -394,7 +355,6 @@ AudioRtpRTX::receiveSessionForSpkr (int& countTime)
     } else {
       countTime += time->getSecond();
     }
-
     delete adu; adu = NULL;
   } catch(...) {
     _debugException("! ARTP: receiving failed");
@@ -407,72 +367,21 @@ AudioRtpRTX::receiveSessionForSpkr (int& countTime)
   int 
 AudioRtpRTX::reSampleData(int sampleRate_codec, int nbSamples, int status)
 {
-  if(status==UP_SAMPLING)
-    return upSampleData(sampleRate_codec, nbSamples);
-  else if(status==DOWN_SAMPLING)
-    return downSampleData(sampleRate_codec, nbSamples);
-  else
-    return 0;
-}
-
-////////////////////////////////////////////////////////////////////
-//////////// RESAMPLING FUNCTIONS /////////////////////////////////
-//////////////////////////////////////////////////////////////////
-
-  int
-AudioRtpRTX::upSampleData(int sampleRate_codec, int nbSamples)
-{
-  double upsampleFactor = (double) _layerSampleRate / sampleRate_codec;
-  int nbSamplesMax = (int) (_layerSampleRate * _layerFrameSize /1000);
-  if( upsampleFactor != 1 )
-  {
-    SRC_DATA src_data;
-    src_data.data_in = _floatBufferDown;
-    src_data.data_out = _floatBufferUp;
-    src_data.input_frames = nbSamples;
-    src_data.output_frames = (int) floor(upsampleFactor * nbSamples);
-    src_data.src_ratio = upsampleFactor;
-    src_data.end_of_input = 0; // More data will come
-    src_short_to_float_array(_receiveDataDecoded, _floatBufferDown, nbSamples);
-    src_process(_src_state_spkr, &src_data);
-    nbSamples  = ( src_data.output_frames_gen > nbSamplesMax) ? nbSamplesMax : src_data.output_frames_gen;		
-    src_float_to_short_array(_floatBufferUp, _dataAudioLayer, nbSamples);
+  if(status==UP_SAMPLING){
+    return converter->upsampleData( spkrDataDecoded , spkrDataConverted , sampleRate_codec , _layerSampleRate , nbSamples );
   }
-
-  return nbSamples;
-}	
-
-  int
-AudioRtpRTX::downSampleData(int sampleRate_codec, int nbSamples)
-{
-  double downsampleFactor = (double) sampleRate_codec / _layerSampleRate;
-  int nbSamplesMax = (int) (sampleRate_codec * _layerFrameSize / 1000);
-  if ( downsampleFactor != 1)
-  {
-    SRC_DATA src_data;	
-    src_data.data_in = _floatBufferUp;
-    src_data.data_out = _floatBufferDown;
-    src_data.input_frames = nbSamples;
-    src_data.output_frames = (int) floor(downsampleFactor * nbSamples);
-    src_data.src_ratio = downsampleFactor;
-    src_data.end_of_input = 0; // More data will come
-    src_short_to_float_array(_dataAudioLayer, _floatBufferUp, nbSamples);
-    src_process(_src_state_mic, &src_data);
-    nbSamples  = ( src_data.output_frames_gen > nbSamplesMax) ? nbSamplesMax : src_data.output_frames_gen;
-    src_float_to_short_array(_floatBufferDown, _intBufferDown, nbSamples);
+  else if(status==DOWN_SAMPLING){
+    return converter->downsampleData( micData , micDataConverted , sampleRate_codec , _layerSampleRate , nbSamples );
   }
-  return nbSamples;
-
+  else
+    return 0;
 }
 
-//////////////////////// END RESAMPLING //////////////////////////////////////////////////////
-
 void
 AudioRtpRTX::run () {
   //mic, we receive from soundcard in stereo, and we send encoded
   //encoding before sending
   AudioLayer *audiolayer = Manager::instance().getAudioDriver();
-  //loadCodec(_ca->getAudioCodec());
   _layerFrameSize = audiolayer->getFrameSize(); // en ms
   _layerSampleRate = audiolayer->getSampleRate();	
   initBuffers();
@@ -496,7 +405,6 @@ AudioRtpRTX::run () {
     int countTime = 0; // for receive
     TimerPort::setTimer(_layerFrameSize);
 
-    //audiolayer->flushMic();
     audiolayer->startStream();
     _start.post();
     _debug("- ARTP Action: Start\n");
@@ -514,8 +422,6 @@ AudioRtpRTX::run () {
       Thread::sleep(TimerPort::getTimer());
       TimerPort::incTimer(_layerFrameSize); // 'frameSize' ms
     }
-    //_fstream.close();
-    //unloadCodec();
     //_debug("stop stream for audiortp loop\n");
     audiolayer->stopStream();
   } catch(std::exception &e) {
diff --git a/src/audio/audiortp.h b/src/audio/audiortp.h
index 0b735ac890414ed4a27b7556432d18111b0779d1..a0cb003bf35566a6251361edf0b0a3b5ef0a5ce5 100644
--- a/src/audio/audiortp.h
+++ b/src/audio/audiortp.h
@@ -28,8 +28,8 @@
 #include <ccrtp/rtp.h>
 #include <cc++/numbers.h>
 
-#include <samplerate.h>
 #include "../global.h"
+#include "../samplerateconverter.h"
 
 #define UP_SAMPLING 0
 #define DOWN_SAMPLING 1
@@ -83,33 +83,17 @@ class AudioRtpRTX : public ost::Thread, public ost::TimerPort {
     /** Is the session symmetric or not */
     bool _sym;
 
-    /** When we receive data, we decode it inside this buffer */
-    int16* _receiveDataDecoded;
+    /** Mic-data related buffers */
+    SFLDataFormat* micData;
+    SFLDataFormat* micDataConverted;
+    unsigned char* micDataEncoded;
 
-    /** Buffers used for send data from the mic */
-    unsigned char* _sendDataEncoded;
-    
-    /** Downsampled int16 buffer */
-    int16* _intBufferDown;
-
-    /** After that we send the data inside this buffer if there is a format conversion or rate conversion */
-    /** Also use for getting mic-ringbuffer data */
-    SFLDataFormat* _dataAudioLayer;
-
-    /** Downsampled float buffer */
-    float32* _floatBufferDown;
-
-    /** Upsampled float buffer */
-    float32* _floatBufferUp;
-
-    /** libsamplerate converter for incoming voice */
-    SRC_STATE*    _src_state_spkr;
+    /** Speaker-data related buffers */
+    SFLDataFormat* spkrDataDecoded;
+    SFLDataFormat* spkrDataConverted;
 
-    /** libsamplerate converter for outgoing voice */
-    SRC_STATE*    _src_state_mic;
-
-    /** libsamplerate error */
-    int _src_err;
+    /** Sample rate converter object */
+    SamplerateConverter* converter;
 
     /** Variables to process audio stream: sample rate for playing sound (typically 44100HZ) */
     int _layerSampleRate;  
@@ -154,22 +138,6 @@ class AudioRtpRTX : public ost::Thread, public ost::TimerPort {
      */ 
     int reSampleData(int sampleRate_codec, int nbSamples, int status);
     
-    /**
-     * Upsample the data from the clock rate of the codec to the sample rate of the layer
-     * @param sampleRate_codec	The sample rate of the codec selected to encode/decode the data
-     * @param nbSamples		Number of samples to process
-     * @return int The number of samples after process
-     */
-    int upSampleData(int sampleRate_codec, int nbSamples);
-    
-    /**
-     * Downsample the data from the sample rate of the layer to the clock rate of the codec
-     * @param sampleRate_codec	The sample rate of the codec selected to encode/decode the data
-     * @param nbSamples		Number of samples to process
-     * @return int The number of samples after process
-     */
-    int downSampleData(int sampleRate_codec, int nbSamples);
-
     /** The audio codec used during the session */
     AudioCodec* _audiocodec;	
 };
diff --git a/src/iaxvoiplink.cpp b/src/iaxvoiplink.cpp
index 1cc5a5d26404bfddf3848f6279e82961acc1e4c0..6b76c9c123dc6bcdfae3761b2cdb33facedd8b45 100644
--- a/src/iaxvoiplink.cpp
+++ b/src/iaxvoiplink.cpp
@@ -25,12 +25,10 @@
 #include "manager.h"
 #include "audio/audiolayer.h"
 
-#include <samplerate.h>
 //#include <iax/iax-client.h>
 #include <math.h>
 #include <dlfcn.h>
 
-
 #define IAX_BLOCKING    1
 #define IAX_NONBLOCKING 0
 
@@ -40,20 +38,12 @@
 #define RANDOM_IAX_PORT   rand() % 64000 + 1024
 
 #define MUSIC_ONHOLD true
-#define NO_MUSIC_ONHOLD	false
-
-// from IAXC : iaxclient.h
-
-#define IAX__20S_8KHZ_MAX   320 //320 samples, IAX packets can have more than 20ms.
-#define IAX__20S_48KHZ_MAX  1920 // 320*6 samples = 1920, 6 = 48000/8000 
 
 #define CHK_VALID_CALL   if (call == NULL) { _debug("IAX: Call doesn't exists\n"); \
-                                             return false; }
-
+  return false; }
 
-
-IAXVoIPLink::IAXVoIPLink(const AccountID& accountID)
-  : VoIPLink(accountID)
+  IAXVoIPLink::IAXVoIPLink(const AccountID& accountID)
+: VoIPLink(accountID)
 {
   _evThread = new EventThread(this);
   _regSession = NULL;
@@ -64,19 +54,16 @@ IAXVoIPLink::IAXVoIPLink(const AccountID& accountID)
 
   audiolayer = NULL;
 
-  _receiveDataDecoded = new int16[IAX__20S_48KHZ_MAX];
-  _sendDataEncoded   =  new unsigned char[IAX__20S_8KHZ_MAX];
+  converter = new SamplerateConverter();
 
-  // we estimate that the number of format after a conversion 8000->48000 is expanded to 6 times
-  _dataAudioLayer = new SFLDataFormat[IAX__20S_48KHZ_MAX];
-  _floatBuffer8000  = new float32[IAX__20S_8KHZ_MAX];
-  _floatBuffer48000 = new float32[IAX__20S_48KHZ_MAX];
-  _intBuffer8000  = new int16[IAX__20S_8KHZ_MAX];
+  int nbSamplesMax = (int) ( converter->getFrequence() * converter->getFramesize() / 1000 );
 
-  // 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);
+  micData = new SFLDataFormat[nbSamplesMax];
+  micDataConverted = new SFLDataFormat[nbSamplesMax];
+  micDataEncoded = new unsigned char[nbSamplesMax];
 
+  spkrDataConverted = new SFLDataFormat[nbSamplesMax];
+  spkrDataDecoded = new SFLDataFormat[nbSamplesMax];
 }
 
 
@@ -87,20 +74,16 @@ IAXVoIPLink::~IAXVoIPLink()
   terminate();
 
   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 [] micData;  micData = NULL;
+  delete [] micDataConverted;  micDataConverted = NULL;
+  delete [] micDataEncoded;  micDataEncoded = NULL;
 
-  // libsamplerate-related
-  _src_state_mic  = src_delete(_src_state_mic);
-  _src_state_spkr = src_delete(_src_state_spkr);
+  delete [] spkrDataDecoded; spkrDataDecoded = NULL;
+  delete [] spkrDataConverted; spkrDataConverted = NULL;
 }
 
-bool
+  bool
 IAXVoIPLink::init()
 {
   // If it was done, don't do it again, until we call terminate()
@@ -139,15 +122,14 @@ IAXVoIPLink::init()
   }
   if (port == IAX_FAILURE || nbTry==0) {
     _debug("Fail to initialize iax\n");
-    
+
     _initDone = false;
   }
-  
 
   return returnValue;
 }
 
-void
+  void
 IAXVoIPLink::terminate()
 {
   // If it was done, don't do it again, until we call init()
@@ -162,7 +144,7 @@ IAXVoIPLink::terminate()
   _initDone = false;
 }
 
-void
+  void
 IAXVoIPLink::terminateIAXCall()
 {
   std::string reason = "Dumped Call";
@@ -183,7 +165,7 @@ IAXVoIPLink::terminateIAXCall()
   _callMap.clear();
 }
 
-void
+  void
 IAXVoIPLink::getEvent() 
 {
   IAXCall* call = NULL;
@@ -214,7 +196,7 @@ IAXVoIPLink::getEvent()
       // We've got an event before it's associated with any call
       iaxHandlePrecallEvent(event);
     }
-    
+
     iax_event_free(event);
   }
   _mutexIAX.leaveMutex();
@@ -233,7 +215,7 @@ IAXVoIPLink::getEvent()
   _evThread->sleep(3);
 }
 
-void
+  void
 IAXVoIPLink::sendAudioFromMic(void)
 {
   IAXCall* currentCall = getIAXCall(Manager::instance().getCurrentCallId());
@@ -242,7 +224,7 @@ IAXVoIPLink::sendAudioFromMic(void)
     // Let's mind our own business.
     return;
   }
-  
+
   if( currentCall -> getAudioCodec() < 0 )
     return;
 
@@ -266,13 +248,13 @@ IAXVoIPLink::sendAudioFromMic(void)
     }
     return;
   }
-  
+
   // 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);
+    int maxBytesToGet = audiolayer->getSampleRate()* audiolayer->getFrameSize() / 1000 * sizeof(SFLDataFormat);
 
     // available bytes inside ringbuffer
     int availBytesFromMic = audiolayer->canGetMic();
@@ -285,59 +267,21 @@ IAXVoIPLink::sendAudioFromMic(void)
     // 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) {
-    if (audiolayer->getSampleRate() != ac ->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) ac->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; 
-      
-      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
-    }
+    int nbSample = audiolayer->getMic( micData, bytesAvail ) / sizeof(SFLDataFormat);
+
+    // resample
+    nbSample = converter->downsampleData( micData , micDataConverted , (int)ac ->getClockRate() ,  (int)audiolayer->getSampleRate() , nbSample );
 
     // for the mono: range = 0 to IAX_FRAME2SEND * sizeof(int16)
-    int compSize = ac->codecEncode(_sendDataEncoded, toIAX, nbSample*sizeof(int16));
+    int compSize = ac->codecEncode( micDataEncoded, micDataConverted , 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) {
+      if ( iax_send_voice(currentCall->getSession(), currentCall->getFormat(), micDataEncoded, compSize, nbSample) == -1) {
 	_debug("IAX: Error sending voice data.\n");
       }
     }
@@ -346,7 +290,7 @@ IAXVoIPLink::sendAudioFromMic(void)
 }
 
 
-IAXCall* 
+  IAXCall* 
 IAXVoIPLink::getIAXCall(const CallID& id) 
 {
   Call* call = getCall(id);
@@ -358,7 +302,7 @@ IAXVoIPLink::getIAXCall(const CallID& id)
 
 
 
-bool
+  bool
 IAXVoIPLink::sendRegister() 
 {
   bool result = false;
@@ -412,7 +356,7 @@ IAXVoIPLink::sendRegister()
 
 
 
-bool
+  bool
 IAXVoIPLink::sendUnregister()
 {
   _mutexIAX.enterMutex();
@@ -434,7 +378,7 @@ IAXVoIPLink::sendUnregister()
   return false;
 }
 
-Call* 
+  Call* 
 IAXVoIPLink::newOutgoingCall(const CallID& id, const std::string& toUrl)
 {
   IAXCall* call = new IAXCall(id, Call::Outgoing);
@@ -456,12 +400,12 @@ IAXVoIPLink::newOutgoingCall(const CallID& id, const std::string& toUrl)
 }
 
 
-bool 
+  bool 
 IAXVoIPLink::answer(const CallID& id)
 {
   IAXCall* call = getIAXCall(id);
   call->setCodecMap(Manager::instance().getCodecDescriptorMap());
-  
+
   CHK_VALID_CALL;
 
   _mutexIAX.enterMutex();
@@ -477,7 +421,7 @@ IAXVoIPLink::answer(const CallID& id)
   return true;
 }
 
-bool 
+  bool 
 IAXVoIPLink::hangup(const CallID& id)
 {
   IAXCall* call = getIAXCall(id);
@@ -495,7 +439,7 @@ IAXVoIPLink::hangup(const CallID& id)
   return true;	
 }
 
-bool 
+  bool 
 IAXVoIPLink::onhold(const CallID& id) 
 {
   IAXCall* call = getIAXCall(id);
@@ -503,7 +447,7 @@ IAXVoIPLink::onhold(const CallID& id)
   CHK_VALID_CALL;
 
   //if (call->getState() == Call::Hold) { _debug("Call is already on hold\n"); return false; }
-  
+
   _mutexIAX.enterMutex();
   iax_quelch_moh(call->getSession() , MUSIC_ONHOLD);
   _mutexIAX.leaveMutex();
@@ -512,7 +456,7 @@ IAXVoIPLink::onhold(const CallID& id)
   return true;
 }
 
-bool 
+  bool 
 IAXVoIPLink::offhold(const CallID& id)
 {
   IAXCall* call = getIAXCall(id);
@@ -528,7 +472,7 @@ IAXVoIPLink::offhold(const CallID& id)
   return true;
 }
 
-bool 
+  bool 
 IAXVoIPLink::transfer(const CallID& id, const std::string& to)
 {
   IAXCall* call = getIAXCall(id);
@@ -537,7 +481,7 @@ IAXVoIPLink::transfer(const CallID& id, const std::string& to)
 
   char callto[to.length()+1];
   strcpy(callto, to.c_str());
-  
+
   _mutexIAX.enterMutex();
   iax_transfer(call->getSession(), callto); 
   _mutexIAX.leaveMutex();
@@ -546,7 +490,7 @@ IAXVoIPLink::transfer(const CallID& id, const std::string& to)
   // removeCall(id);
 }
 
-bool 
+  bool 
 IAXVoIPLink::refuse(const CallID& id)
 {
   IAXCall* call = getIAXCall(id);
@@ -560,7 +504,7 @@ IAXVoIPLink::refuse(const CallID& id)
   removeCall(id);
 }
 
-bool
+  bool
 IAXVoIPLink::carryingDTMFdigits(const CallID& id, char code)
 {
   IAXCall* call = getIAXCall(id);
@@ -574,7 +518,7 @@ IAXVoIPLink::carryingDTMFdigits(const CallID& id, char code)
 
 
 
-bool
+  bool
 IAXVoIPLink::iaxOutgoingInvite(IAXCall* call) 
 {
   struct iax_session *newsession;
@@ -582,18 +526,18 @@ IAXVoIPLink::iaxOutgoingInvite(IAXCall* call)
 
   newsession = iax_session_new();
   if (!newsession) {
-     _debug("IAX Error: Can't make new session for a new call\n");
-     return false;
+    _debug("IAX Error: Can't make new session for a new call\n");
+    return false;
   }
   call->setSession(newsession);
   /* reset activity and ping "timers" */
   // iaxc_note_activity(callNo);
-  
+
   std::string strNum = _user + ":" + _pass + "@" + _host + "/" + call->getPeerNumber();  
 
   char user[_user.length()+1];
   strcpy(user, _user.c_str());
-  
+
   char num[strNum.length()+1];
   strcpy(num, strNum.c_str());
 
@@ -610,7 +554,7 @@ IAXVoIPLink::iaxOutgoingInvite(IAXCall* call)
 }
 
 
-IAXCall* 
+  IAXCall* 
 IAXVoIPLink::iaxFindCallBySession(struct iax_session* session) 
 {
   // access to callMap shoud use that
@@ -628,7 +572,7 @@ IAXVoIPLink::iaxFindCallBySession(struct iax_session* session)
   return NULL; // not found
 }
 
-void
+  void
 IAXVoIPLink::iaxHandleCallEvent(iax_event* event, IAXCall* call) 
 {
   // call should not be 0
@@ -636,192 +580,158 @@ IAXVoIPLink::iaxHandleCallEvent(iax_event* event, IAXCall* call)
   //
   CallID id = call->getCallId();
   int16* output = 0; // for audio output
-  
+
   switch(event->etype) {
-  case IAX_EVENT_HANGUP:
-    Manager::instance().peerHungupCall(id); 
-    if (Manager::instance().isCurrentCall(id)) {
-      audiolayer->stopStream();
-      // stop audio
-    }
-    removeCall(id);
-    break;
-    
-  case IAX_EVENT_REJECT:
-    //Manager::instance().peerHungupCall(id); 
-    if (Manager::instance().isCurrentCall(id)) {
-      // stop audio
-      audiolayer->stopStream();
-    }
-    call->setConnectionState(Call::Connected);
-    call->setState(Call::Error);
-    Manager::instance().callFailure(id);
-    removeCall(id);
-    break;
-
-  case IAX_EVENT_ACCEPT:
-    // Call accepted over there by the computer, not the user yet.
-    if (event->ies.format) {
-      call->setFormat(event->ies.format);
-    }
-    break;
-    
-  case IAX_EVENT_ANSWER:
-    if (call->getConnectionState() != Call::Connected){
+    case IAX_EVENT_HANGUP:
+      Manager::instance().peerHungupCall(id); 
+      if (Manager::instance().isCurrentCall(id)) {
+	audiolayer->stopStream();
+	// stop audio
+      }
+      removeCall(id);
+      break;
+
+    case IAX_EVENT_REJECT:
+      //Manager::instance().peerHungupCall(id); 
+      if (Manager::instance().isCurrentCall(id)) {
+	// stop audio
+	audiolayer->stopStream();
+      }
       call->setConnectionState(Call::Connected);
-      call->setState(Call::Active);
+      call->setState(Call::Error);
+      Manager::instance().callFailure(id);
+      removeCall(id);
+      break;
 
+    case IAX_EVENT_ACCEPT:
+      // Call accepted over there by the computer, not the user yet.
       if (event->ies.format) {
-	// Should not get here, should have been set in EVENT_ACCEPT
 	call->setFormat(event->ies.format);
       }
-      
-      Manager::instance().peerAnsweredCall(id);
-      //audiolayer->flushMic();
-      audiolayer->startStream();
-      // start audio here?
-    } else {
-      // deja connecté ?
-    }
-    break;
-    
-  case IAX_EVENT_BUSY:
-    call->setConnectionState(Call::Connected);
-    call->setState(Call::Busy);
-    Manager::instance().callBusy(id);
-    removeCall(id);
-    break;
-    
-  case IAX_EVENT_VOICE:
-    //_debug("Should have a decent value!!!!!! = %i\n" , call -> getAudioCodec());
-    if( !audiolayer -> isCaptureActive())
-      audiolayer->startStream();
-    iaxHandleVoiceEvent(event, call);
-    break;
-    
-  case IAX_EVENT_TEXT:
-    break;
-    
-  case IAX_EVENT_RINGA:
-    call->setConnectionState(Call::Ringing);
-    Manager::instance().peerRingingCall(call->getCallId());
-    break;
-    
-  case IAX_IE_MSGCOUNT:	
-   // _debug("messssssssssssssssssssssssssssssssssssssssssssssssages\n");
-    break;
-  case IAX_EVENT_PONG:
-    break;
-    
-  case IAX_EVENT_URL:
-    break;
-    
-    //    case IAX_EVENT_CNG: ??
-    //    break;
-    
-  case IAX_EVENT_TIMEOUT:
-    break;
-    
-  case IAX_EVENT_TRANSFER:
-    break;
-    
-  default:
-    _debug("Unknown event type (in call event): %d\n", event->etype);
-    
+      break;
+
+    case IAX_EVENT_ANSWER:
+      if (call->getConnectionState() != Call::Connected){
+	call->setConnectionState(Call::Connected);
+	call->setState(Call::Active);
+
+	if (event->ies.format) {
+	  // Should not get here, should have been set in EVENT_ACCEPT
+	  call->setFormat(event->ies.format);
+	}
+
+	Manager::instance().peerAnsweredCall(id);
+	//audiolayer->flushMic();
+	audiolayer->startStream();
+	// start audio here?
+      } else {
+	// deja connecté ?
+      }
+      break;
+
+    case IAX_EVENT_BUSY:
+      call->setConnectionState(Call::Connected);
+      call->setState(Call::Busy);
+      Manager::instance().callBusy(id);
+      removeCall(id);
+      break;
+
+    case IAX_EVENT_VOICE:
+      //_debug("Should have a decent value!!!!!! = %i\n" , call -> getAudioCodec());
+      //if( !audiolayer -> isCaptureActive())
+      //audiolayer->startStream();
+      iaxHandleVoiceEvent(event, call);
+      break;
+
+    case IAX_EVENT_TEXT:
+      break;
+
+    case IAX_EVENT_RINGA:
+      call->setConnectionState(Call::Ringing);
+      Manager::instance().peerRingingCall(call->getCallId());
+      break;
+
+    case IAX_IE_MSGCOUNT:	
+      break;
+    case IAX_EVENT_PONG:
+      break;
+
+    case IAX_EVENT_URL:
+      break;
+
+      //    case IAX_EVENT_CNG: ??
+      //    break;
+
+    case IAX_EVENT_TIMEOUT:
+      break;
+
+    case IAX_EVENT_TRANSFER:
+      break;
+
+    default:
+      _debug("Unknown event type (in call event): %d\n", event->etype);
+
   }
 }
 
 
 /* Handle audio event, VOICE packet received */
-void
+  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) {
-      // Skip this empty packet.
-      //_debug("IAX: Skipping empty jitter-buffer interpolated packet\n");
-      return;
+  // If we receive datalen == 0, some things of the jitter buffer in libiax2/iax.c
+  // were triggered
+  if (!event->datalen) {
+    // Skip this empty packet.
+    //_debug("IAX: Skipping empty jitter-buffer interpolated packet\n");
+    return;
+  }
+
+  if (audiolayer) {
+    // 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);
     }
+    //_debug("Receive: len=%d, format=%d, _receiveDataDecoded=%p\n", event->datalen, call->getFormat(), _receiveDataDecoded);
+    AudioCodec* ac = call->getCodecMap().getCodec( call -> getAudioCodec() );
 
-    if (audiolayer) {
-  //    _debug("codec = %i\n" , call->getFormat());
-   //   _debug("codec = %i\n" , _audiocodec->getPayload());
-      //_debug("codec = %s\n" , _audiocodec->getCodecName().c_str());
-      // 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);
-      }
-      //_debug("Receive: len=%d, format=%d, _receiveDataDecoded=%p\n", event->datalen, call->getFormat(), _receiveDataDecoded);
-      AudioCodec* ac = call->getCodecMap().getCodec( call -> getAudioCodec() );
+    unsigned char* data = (unsigned char*)event->data;
+    unsigned int size   = event->datalen;
 
-      unsigned char* data = (unsigned char*)event->data;
-      unsigned int size   = event->datalen;
+    // Decode data with relevant codec
+    int max = (int)( ac->getClockRate() * audiolayer->getFrameSize() / 1000 );
 
-      if (size > IAX__20S_8KHZ_MAX) {
-	_debug("The size %d is bigger than expected %d. Packet cropped. Ouch!\n", size, IAX__20S_8KHZ_MAX);
-	size = IAX__20S_8KHZ_MAX;
-      }
+    if (size > max) {
+      _debug("The size %d is bigger than expected %d. Packet cropped. Ouch!\n", size, max);
+      size = max;
+    }
 
-      int expandedSize = ac->codecDecode(_receiveDataDecoded, data, size);
-      int nbInt16      = expandedSize/sizeof(int16);
+    int expandedSize = ac->codecDecode( spkrDataDecoded , data , size );
+    int nbInt16      = expandedSize/sizeof(int16);
 
-      if (nbInt16 > IAX__20S_8KHZ_MAX) {
-	_debug("We have decoded an IAX VOICE packet larger than expected: %s VS %s. Cropping.\n", nbInt16, IAX__20S_8KHZ_MAX);
-	nbInt16 = IAX__20S_8KHZ_MAX;
-      }
-      
-      SFLDataFormat* toAudioLayer;
-      int nbSample = nbInt16;
-      int nbSampleMaxRate = nbInt16 * 6;
-      
-      if ( audiolayer->getSampleRate() != ac->getClockRate() && nbSample ) {
-	// Do sample rate conversion
-	double factord = (double) audiolayer->getSampleRate() / ac->getClockRate();
-	// SRC_DATA from samplerate.h
-	SRC_DATA src_data;
-	src_data.data_in = _floatBuffer8000;
-	src_data.data_out = _floatBuffer48000;
-	src_data.input_frames = nbSample;
-	src_data.output_frames = (int) floor(factord * nbSample);
-	src_data.src_ratio = factord;
-	src_data.end_of_input = 0;
-	src_short_to_float_array(_receiveDataDecoded, _floatBuffer8000, nbSample);
-
-	// samplerate convert, go!
-	src_process(_src_state_spkr, &src_data);
-	
-	nbSample = ( src_data.output_frames_gen > IAX__20S_48KHZ_MAX) ? IAX__20S_48KHZ_MAX : src_data.output_frames_gen;
-#ifdef DATAFORMAT_IS_FLOAT
-	toAudioLayer = _floatBuffer48000;
-#else
-	src_float_to_short_array(_floatBuffer48000, _dataAudioLayer, nbSample);
-	toAudioLayer = _dataAudioLayer;
-#endif
-  	
-      } else {
-	nbSample = nbInt16;
-#ifdef DATAFORMAT_IS_FLOAT
-	// convert _receiveDataDecoded to float inside _receiveData
-	src_short_to_float_array(_receiveDataDecoded, _floatBuffer8000, nbSample);
-	toAudioLayer = _floatBuffer8000;
-#else
-	toAudioLayer = _receiveDataDecoded; // int to int
-#endif
-      }
-      audiolayer->playSamples(toAudioLayer, nbSample * sizeof(SFLDataFormat), true);
-    } else {
-      _debug("IAX: incoming audio, but no sound card open");
+    if (nbInt16 > max) {
+      _debug("We have decoded an IAX VOICE packet larger than expected: %s VS %s. Cropping.\n", nbInt16, max);
+      nbInt16 = max;
     }
 
+    int nbSample = nbInt16;
+    // resample
+    nbInt16 = converter->upsampleData( spkrDataDecoded , spkrDataConverted , ac->getClockRate() , audiolayer->getSampleRate() , nbSample);
+
+    audiolayer->playSamples( spkrDataConverted , nbInt16 * sizeof(SFLDataFormat), true);
+
+  } else {
+    _debug("IAX: incoming audio, but no sound card open");
+  }
+
 }
 
 /**
  * Handle the registration process
  */
-void
+  void
 IAXVoIPLink::iaxHandleRegReply(iax_event* event) 
 {
   if (event->etype == IAX_EVENT_REGREJ) {
@@ -846,7 +756,7 @@ IAXVoIPLink::iaxHandleRegReply(iax_event* event)
   }
 }
 
-void
+  void
 IAXVoIPLink::iaxHandlePrecallEvent(iax_event* event)
 {
   IAXCall* call = NULL;
@@ -854,96 +764,96 @@ IAXVoIPLink::iaxHandlePrecallEvent(iax_event* event)
   std::string reason = "Error ringing user.";
 
   switch(event->etype) {
-  case IAX_EVENT_REGACK:
-  case IAX_EVENT_REGREJ:
-    _debug("IAX Registration Event in a pre-call setup\n");
-    break;
-    
-  case IAX_EVENT_REGREQ:
-    // Received when someone wants to register to us!?!
-    // Asterisk receives and answers to that, not us, we're a phone.
-    _debug("Registration by a peer, don't allow it\n");
-    break;
-    
-  case IAX_EVENT_CONNECT:
-    // We've got an incoming call! Yikes!
-    _debug("> IAX_EVENT_CONNECT (receive)\n");
-
-    id = Manager::instance().getNewCallID();
-
-
-    call = new IAXCall(id, Call::Incoming);
-
-    if (!call) {
-      _debug("! IAX Failure: unable to create an incoming call");
-      return;
-    }
+    case IAX_EVENT_REGACK:
+    case IAX_EVENT_REGREJ:
+      _debug("IAX Registration Event in a pre-call setup\n");
+      break;
 
-    // Setup the new IAXCall
-    // Associate the call to the session.
-    call->setSession(event->session);
+    case IAX_EVENT_REGREQ:
+      // Received when someone wants to register to us!?!
+      // Asterisk receives and answers to that, not us, we're a phone.
+      _debug("Registration by a peer, don't allow it\n");
+      break;
 
-    // setCallAudioLocal(call);
-    call->setCodecMap(Manager::instance().getCodecDescriptorMap());
-    call->setConnectionState(Call::Progressing);
+    case IAX_EVENT_CONNECT:
+      // We've got an incoming call! Yikes!
+      _debug("> IAX_EVENT_CONNECT (receive)\n");
 
+      id = Manager::instance().getNewCallID();
 
-    if (event->ies.calling_number)
-      call->setPeerNumber(std::string(event->ies.calling_number));
-    if (event->ies.calling_name)
-      call->setPeerName(std::string(event->ies.calling_name));
 
-    if (Manager::instance().incomingCall(call, getAccountID())) {
-      /** @todo Faudra considérer éventuellement le champ CODEC PREFS pour
-       * l'établissement du codec de transmission */
+      call = new IAXCall(id, Call::Incoming);
 
-      // Remote lists its capabilities
-      int format = call->getFirstMatchingFormat(event->ies.capability);
-      // Remote asks for preferred codec voiceformat
-      int pref_format = call->getFirstMatchingFormat(event->ies.format);
+      if (!call) {
+	_debug("! IAX Failure: unable to create an incoming call");
+	return;
+      }
 
-      // Priority to remote's suggestion. In case it's a forwarding, no transcoding
-      // will be needed from the server, thus less latency.
-      if (pref_format)
-	format = pref_format;
+      // Setup the new IAXCall
+      // Associate the call to the session.
+      call->setSession(event->session);
 
-      iax_accept(event->session, format);
-      iax_ring_announce(event->session);
+      // setCallAudioLocal(call);
+      call->setCodecMap(Manager::instance().getCodecDescriptorMap());
+      call->setConnectionState(Call::Progressing);
 
-      addCall(call);
-    } else {
-      // reject call, unable to add it
-      iax_reject(event->session, (char*)reason.c_str());
 
-      delete call; call = NULL;
-    }
+      if (event->ies.calling_number)
+	call->setPeerNumber(std::string(event->ies.calling_number));
+      if (event->ies.calling_name)
+	call->setPeerName(std::string(event->ies.calling_name));
 
-    break;
-    
-  case IAX_EVENT_HANGUP:
-    // Remote peer hung up
-    call = iaxFindCallBySession(event->session);
-    id = call->getCallId();
-
-    Manager::instance().peerHungupCall(id);
-    removeCall(id);
-    break;
-    
-  case IAX_EVENT_TIMEOUT: // timeout for an unknown session
-    
-    break;
-    
-  case IAX_IE_MSGCOUNT:	
-    //_debug("messssssssssssssssssssssssssssssssssssssssssssssssages\n");
-    break;
-
-  default:
-    _debug("Unknown event type (in precall): %d\n", event->etype);
+      if (Manager::instance().incomingCall(call, getAccountID())) {
+	/** @todo Faudra considérer éventuellement le champ CODEC PREFS pour
+	 * l'établissement du codec de transmission */
+
+	// Remote lists its capabilities
+	int format = call->getFirstMatchingFormat(event->ies.capability);
+	// Remote asks for preferred codec voiceformat
+	int pref_format = call->getFirstMatchingFormat(event->ies.format);
+
+	// Priority to remote's suggestion. In case it's a forwarding, no transcoding
+	// will be needed from the server, thus less latency.
+	if (pref_format)
+	  format = pref_format;
+
+	iax_accept(event->session, format);
+	iax_ring_announce(event->session);
+
+	addCall(call);
+      } else {
+	// reject call, unable to add it
+	iax_reject(event->session, (char*)reason.c_str());
+
+	delete call; call = NULL;
+      }
+
+      break;
+
+    case IAX_EVENT_HANGUP:
+      // Remote peer hung up
+      call = iaxFindCallBySession(event->session);
+      id = call->getCallId();
+
+      Manager::instance().peerHungupCall(id);
+      removeCall(id);
+      break;
+
+    case IAX_EVENT_TIMEOUT: // timeout for an unknown session
+
+      break;
+
+    case IAX_IE_MSGCOUNT:	
+      //_debug("messssssssssssssssssssssssssssssssssssssssssssssssages\n");
+      break;
+
+    default:
+      _debug("Unknown event type (in precall): %d\n", event->etype);
   }
-  
+
 }
 
-int 
+  int 
 IAXVoIPLink::iaxCodecMapToFormat(IAXCall* call)
 {
   CodecOrder map = call->getCodecMap().getActiveCodecs();
diff --git a/src/iaxvoiplink.h b/src/iaxvoiplink.h
index ea67145ede0534d38fd60a0dca6d392dd3b04250..3a8c3fbd4a11b183e6cd58b4f99a0cce81cc238d 100644
--- a/src/iaxvoiplink.h
+++ b/src/iaxvoiplink.h
@@ -1,8 +1,8 @@
 /*
- *  Copyright (C) 2006-2007 Savoir-Faire Linux inc.
+ *  Copyright (C) 2006-2007-2008 Savoir-Faire Linux inc.
+ *  Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
  *  Author: Alexandre Bourget <alexandre.bourget@savoirfairelinux.com>
  *  Author: Yan Morin <yan.morin@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
@@ -24,9 +24,9 @@
 #include "voiplink.h"
 #include <iax2/iax-client.h>
 #include "global.h"
-#include <samplerate.h>
 
 #include "audio/codecDescriptor.h"
+#include "samplerateconverter.h"
 
 class EventThread;
 class IAXCall;
@@ -279,31 +279,17 @@ class IAXVoIPLink : public VoIPLink
     /** Connection to audio card/device */
     AudioLayer* audiolayer;
 
-    /** When we receive data, we decode it inside this buffer */
-    int16* _receiveDataDecoded;
-    /** When we send data, we encode it inside this buffer*/
-    unsigned char* _sendDataEncoded;
-
-    /** After that we send the data inside this buffer if there is a format conversion or rate conversion. */
-    /* Also use for getting mic-ringbuffer data */
-    SFLDataFormat* _dataAudioLayer;
-
-    /** Buffer for 8000hz samples in conversion */
-    float32* _floatBuffer8000;
-    /** Buffer for 48000hz samples in conversion */ 
-    float32* _floatBuffer48000;
-
-    /** Buffer for 8000hz samples for mic conversion */
-    int16* _intBuffer8000;
-
-    /** libsamplerate converter for incoming voice */
-    SRC_STATE*    _src_state_spkr;
+    /** Mic-data related buffers */
+    SFLDataFormat* micData;
+    SFLDataFormat* micDataConverted;
+    unsigned char* micDataEncoded;
 
-    /** libsamplerate converter for outgoing voice */
-    SRC_STATE*    _src_state_mic;
+    /** Speaker-data related buffers */
+    SFLDataFormat* spkrDataDecoded;
+    SFLDataFormat* spkrDataConverted;
 
-    /** libsamplerate error */
-    int           _src_err;
+    /** Sample rate converter object */
+    SamplerateConverter* converter;
 
 };
 
diff --git a/src/samplerateconverter.cpp b/src/samplerateconverter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..126c5d957cf7a9712bfbf4b105a0d817d6f653aa
--- /dev/null
+++ b/src/samplerateconverter.cpp
@@ -0,0 +1,116 @@
+/*
+ *  Copyright (C) 2008 Savoir-Faire Linux inc.
+ *  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
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ * 
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "samplerateconverter.h"
+
+SamplerateConverter::SamplerateConverter( void ) {
+  // Default values
+  _frequence = Manager::instance().getConfigInt( AUDIO , ALSA_SAMPLE_RATE ); // 44100;
+  _framesize = Manager::instance().getConfigInt( AUDIO , ALSA_FRAME_SIZE );
+
+  init();
+}
+
+SamplerateConverter::SamplerateConverter( int freq , int fs ) {
+
+  _frequence = freq ;
+  _framesize = fs ;
+  
+  init();
+}
+
+SamplerateConverter::~SamplerateConverter( void ) {
+
+  delete [] _floatBufferUpMic; _floatBufferUpMic = NULL;
+  delete [] _floatBufferDownMic; _floatBufferDownMic = NULL;
+
+  delete [] _floatBufferUpSpkr; _floatBufferUpSpkr = NULL;
+  delete [] _floatBufferDownSpkr; _floatBufferDownSpkr = NULL;
+
+  // libSamplerateConverter-related
+  _src_state_mic  = src_delete(_src_state_mic);
+  _src_state_spkr = src_delete(_src_state_spkr);
+}
+
+void SamplerateConverter::init( void ) {
+  
+  // libSamplerateConverter-related
+  // Set the converter type for the upsampling and the downsampling
+  // interpolator SRC_SINC_BEST_QUALITY
+  _src_state_mic  = src_new(SRC_SINC_BEST_QUALITY, 1, &_src_err);
+  _src_state_spkr = src_new(SRC_SINC_BEST_QUALITY, 1, &_src_err);
+
+  int nbSamplesMax = (int) ( getFrequence() * getFramesize() / 1000 );
+  _floatBufferDownMic  = new float32[nbSamplesMax];
+  _floatBufferUpMic = new float32[nbSamplesMax];
+  _floatBufferDownSpkr  = new float32[nbSamplesMax];
+  _floatBufferUpSpkr = new float32[nbSamplesMax];
+}
+
+//TODO Add ifdef for int16 or float32 type
+int SamplerateConverter::upsampleData(  SFLDataFormat* dataIn , SFLDataFormat* dataOut, int samplerate1 , int samplerate2 , int nbSamples ){
+  
+  double upsampleFactor = (double)samplerate2 / samplerate1 ;
+  int nbSamplesMax = (int) ( samplerate2 * getFramesize() / 1000 );
+  if( upsampleFactor != 1 && dataIn != NULL )
+  {
+    SRC_DATA src_data;
+    src_data.data_in = _floatBufferDownSpkr;
+    src_data.data_out = _floatBufferUpSpkr;
+    src_data.input_frames = nbSamples;
+    src_data.output_frames = (int) floor(upsampleFactor * nbSamples);
+    src_data.src_ratio = upsampleFactor;
+    src_data.end_of_input = 0; // More data will come
+  //_debug("upsample %d %d %f %d\n" , src_data.input_frames , src_data.output_frames, src_data.src_ratio , nbSamples);
+    src_short_to_float_array( dataIn , _floatBufferDownSpkr, nbSamples);
+  //_debug("upsample %d %f %d\n" ,  src_data.output_frames, src_data.src_ratio , nbSamples);
+    src_process(_src_state_spkr, &src_data);
+  //_debug("upsample %d %d %d\n" , samplerate1, samplerate2 , nbSamples);
+    nbSamples  = ( src_data.output_frames_gen > nbSamplesMax) ? nbSamplesMax : src_data.output_frames_gen;		
+    src_float_to_short_array(_floatBufferUpSpkr, dataOut, nbSamples);
+  //_debug("upsample %d %d %d\n" , samplerate1, samplerate2 , nbSamples);
+  }
+  return nbSamples;
+}
+
+//TODO Add ifdef for int16 or float32 type
+int SamplerateConverter::downsampleData(  SFLDataFormat* dataIn , SFLDataFormat* dataOut , int samplerate1 , int samplerate2 , int nbSamples ){
+
+  double downsampleFactor = (double)samplerate1 / samplerate2;
+  //_debug("factor = %f\n" , downsampleFactor);
+  int nbSamplesMax = (int) ( samplerate1 * getFramesize() / 1000 );
+  if ( downsampleFactor != 1)
+  {
+    SRC_DATA src_data;	
+    src_data.data_in = _floatBufferUpMic;
+    src_data.data_out = _floatBufferDownMic;
+    src_data.input_frames = nbSamples;
+    src_data.output_frames = (int) floor(downsampleFactor * nbSamples);
+    src_data.src_ratio = downsampleFactor;
+    src_data.end_of_input = 0; // More data will come
+  //_debug("downsample %d %f %d\n" ,  src_data.output_frames, src_data.src_ratio , nbSamples);
+    src_short_to_float_array( dataIn, _floatBufferUpMic, nbSamples );
+  //_debug("downsample %d %f %d\n" ,  src_data.output_frames, src_data.src_ratio , nbSamples);
+    src_process(_src_state_mic, &src_data);
+  //_debug("downsample %d %f %d\n" ,  src_data.output_frames, src_data.src_ratio , nbSamples);
+    nbSamples  = ( src_data.output_frames_gen > nbSamplesMax) ? nbSamplesMax : src_data.output_frames_gen;
+  //_debug("downsample %d %f %d\n" ,  src_data.output_frames, src_data.src_ratio , nbSamples);
+    src_float_to_short_array( _floatBufferDownMic , dataOut , nbSamples );
+  }
+  return nbSamples;
+}
diff --git a/src/samplerateconverter.h b/src/samplerateconverter.h
new file mode 100644
index 0000000000000000000000000000000000000000..86ea175319c44fd36660d3fdf8b33a7ef9de1e46
--- /dev/null
+++ b/src/samplerateconverter.h
@@ -0,0 +1,83 @@
+/*
+ *  Copyright (C) 2008 Savoir-Faire Linux inc.
+ *  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
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ * 
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _SAMPLE_RATE_H
+#define _SAMPLE_RATE_H
+
+#include <samplerate.h>
+#include <math.h>
+
+#include "global.h"
+#include "manager.h"
+
+class SamplerateConverter {
+  public:
+    /** Constructor */
+    SamplerateConverter( void );
+    SamplerateConverter( int freq , int fs );
+    /** Destructor */
+    ~SamplerateConverter( void );
+
+    /** 
+     * Upsample from the samplerate1 to the samplerate2
+     * @param data  The data buffer
+     * @param SamplerateConverter1 The lower sample rate
+     * @param SamplerateConverter2 The higher sample rate
+     * @param nbSamples	  The number of samples to process
+     * @return int The number of samples after the operation
+     */
+    int upsampleData( SFLDataFormat* dataIn , SFLDataFormat* dataOut , int samplerate1 , int samplerate2 , int nbSamples );
+
+    /**
+     * Downsample from the samplerate1 to the samplerate2
+     * @param data  The data buffer
+     * @param SamplerateConverter1 The lower sample rate
+     * @param SamplerateConverter2 The higher sample rate
+     * @param nbSamples	  The number of samples to process
+     * @return int The number of samples after the operation
+     */
+    int downsampleData( SFLDataFormat* dataIn , SFLDataFormat* dataOut , int samplerate1 , int samplerate2 , int nbSamples );
+
+    int getFrequence( void ) { return _frequence; }
+
+    int getFramesize( void ) { return _framesize; } 
+
+  private:
+    void init( void );
+
+    /** Audio layer caracteristics */
+    int _frequence;
+    int _framesize;
+
+    /** Downsampled/Upsampled float buffers for the mic data processing */
+    float32* _floatBufferDownMic;
+    float32* _floatBufferUpMic;
+    /** libSamplerateConverter converter for outgoing voice */
+    SRC_STATE*    _src_state_mic;
+
+    /** Downsampled/Upsampled float buffers for the speaker data processing */
+    float32* _floatBufferDownSpkr;
+    float32* _floatBufferUpSpkr;
+    /** libSamplerateConverter converter for incoming voice */
+    SRC_STATE*    _src_state_spkr;
+    /** libSamplerateConverter error */
+    int _src_err;
+};
+
+#endif //_SAMPLE_RATE_H
+
diff --git a/src/voiplink.cpp b/src/voiplink.cpp
index 59aca9d19989c81e01e7a5da13eb410cf880366d..1a762036ed9a44f0c84b2b0458da5dfabc09d22e 100644
--- a/src/voiplink.cpp
+++ b/src/voiplink.cpp
@@ -25,8 +25,9 @@
 #include "voiplink.h"
 #include "manager.h"
 
-VoIPLink::VoIPLink(const AccountID& accountID) : _accountID(accountID), _localIPAddress("127.0.0.1"), _localPort(0), _registrationError(NO_ERROR), _initDone(false) 
+VoIPLink::VoIPLink(const AccountID& accountID) : _accountID(accountID), _localIPAddress("127.0.0.1"), _localPort(0),  _initDone(false) 
 {
+  _registrationError = NO_ERROR;
 }
 
 VoIPLink::~VoIPLink (void)