diff --git a/src/audio/Makefile.am b/src/audio/Makefile.am
index 13bb710847217ab361407cd1306492841f5b7030..c65f297c5a4906131d65769d2e21be80c7d80783 100644
--- a/src/audio/Makefile.am
+++ b/src/audio/Makefile.am
@@ -23,15 +23,15 @@ endif
 SUBDIRS = codecs
 
 libaudio_la_SOURCES =    audiofile.cpp	 tonelist.cpp    \
-audiortp.cpp         dtmf.cpp   tone.cpp  alsalayer.cpp pulselayer.cpp audiodevice.cpp  dtmfgenerator.cpp   \
-tonegenerator.cpp   codecDescriptor.cpp \
+audiortp.cpp    audiostream.cpp     dtmf.cpp   tone.cpp  alsalayer.cpp pulselayer.cpp audiodevice.cpp  dtmfgenerator.cpp   \
+tonegenerator.cpp   codecDescriptor.cpp samplecache.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) \
  	      -DCODECS_DIR=\""$(sflcodecdir)"\" $(SPEEX_FLAG) $(GSM_FLAG) $(ILBC_FLAG) 
 
-noinst_HEADERS = audioloop.h    common.h ringbuffer.h    audiofile.h  \
+noinst_HEADERS = audioloop.h   audiostream.h common.h ringbuffer.h    audiofile.h  \
  tonelist.h         audiortp.h   audiolayer.h alsalayer.h  pulselayer.h audiodevice.h \
- dtmfgenerator.h         tonegenerator.h     \
+ dtmfgenerator.h         tonegenerator.h    samplecache.h \
  codecDescriptor.h    dtmf.h tone.h 
 
diff --git a/src/audio/audiostream.cpp b/src/audio/audiostream.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..02deda2559781a3a81756e31af42bf144c67010a
--- /dev/null
+++ b/src/audio/audiostream.cpp
@@ -0,0 +1,95 @@
+/*
+ *  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 <audiostream.h>
+
+static pa_channel_map channel_map ;
+
+AudioStream::AudioStream( pa_context* context, int type, std::string desc )
+{ 
+  _streamType = type;
+  _streamDescription = desc; 
+  sample_spec.format = PA_SAMPLE_S16LE; 
+  sample_spec.rate = 44100; 
+  sample_spec.channels = 1; 
+  channel_map.channels = 1; 
+  flag = PA_STREAM_AUTO_TIMING_UPDATE;
+
+  _audiostream =  createStream( context );
+} 
+
+AudioStream::~AudioStream()
+{ 
+} 
+
+  void 
+AudioStream::stream_state_callback( pa_stream* s, void* user_data )
+{
+  _debug("The state of the stream changed\n");
+  assert(s);
+  switch(pa_stream_get_state(s)){
+    case PA_STREAM_CREATING:
+    case PA_STREAM_TERMINATED:
+      _debug("Stream is creating...\n");
+      break;
+    case PA_STREAM_READY:
+      _debug("Stream successfully created\n");
+      break;
+    case PA_STREAM_FAILED:
+    default:
+      _debug("Stream error: %s\n" , pa_strerror(pa_context_errno(pa_stream_get_context(s))));
+      break;
+  }
+}
+
+
+  pa_stream*
+AudioStream::createStream( pa_context* c )
+{
+  _debug("Creating %s stream...\n" , _streamDescription.c_str());
+  pa_stream* s;
+
+  assert(pa_sample_spec_valid(&sample_spec));
+  assert(pa_channel_map_valid(&channel_map));
+
+  if( !( s = pa_stream_new( c, _streamDescription.c_str() , &sample_spec, &channel_map ) ) ) 
+    _debug("%s: pa_stream_new() failed : %s\n" , _streamDescription.c_str(), pa_strerror( pa_context_errno( c)));
+
+  assert( s );
+
+  if( _streamType == PLAYBACK_STREAM ){
+    pa_stream_connect_playback( s , NULL , NULL , flag , NULL, NULL );
+    //pa_stream_set_write_callback( s , audioCallback, this);
+  }
+  else if( _streamType == CAPTURE_STREAM ){
+    pa_stream_connect_record( s , NULL , NULL , flag );
+    //pa_stream_set_read_callback( s , audioCallback, this);
+  }
+  else if( _streamType == UPLOAD_STREAM ){
+    //pa_stream_connect_upload( s , 1024  );
+  }
+  else{
+    _debug( "Stream type unknown \n");
+  }
+
+  pa_stream_set_state_callback( s , stream_state_callback, NULL);
+
+  return s;
+}
+
diff --git a/src/audio/audiostream.h b/src/audio/audiostream.h
new file mode 100644
index 0000000000000000000000000000000000000000..a4464500f58759463daf1affaf9ef64b36169565
--- /dev/null
+++ b/src/audio/audiostream.h
@@ -0,0 +1,65 @@
+/*
+ *  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 _AUDIO_STREAM_H
+#define _AUDIO_STREAM_H
+
+#include <pulse/pulseaudio.h>
+#include <string>
+
+#include "../global.h"
+#include "ringbuffer.h"
+#include "audioloop.h"
+
+enum STREAM_TYPE {
+  PLAYBACK_STREAM,
+  CAPTURE_STREAM,
+  UPLOAD_STREAM
+};
+
+
+class AudioStream {
+  public:
+    AudioStream(pa_context* context , int type, std::string desc);
+    ~AudioStream();
+
+    int putMain( void* buffer , int toCopy );
+    int putUrgent( void* buffer , int toCopy );
+
+    pa_stream* pulseStream(){ return _audiostream; }
+
+  private:
+    pa_stream* createStream( pa_context* c ); 
+
+    static void stream_state_callback( pa_stream* s, void* user_data );	
+    static void audioCallback ( pa_stream* s, size_t bytes, void* userdata );
+    void write( void );
+
+    int _streamType;
+    std::string _streamDescription;
+
+
+    pa_stream* _audiostream;
+    pa_stream_flags_t flag;
+    pa_sample_spec sample_spec ;
+    //pa_channel_map channel_map;
+
+};
+
+#endif // _AUDIO_STREAM_H
diff --git a/src/audio/dtmf.cpp b/src/audio/dtmf.cpp
index a5e9f7fa6b2e6cd796033b3234dbf7d90df2a8aa..faabf1d69aad7fe79369b669e157756066534d15 100644
--- a/src/audio/dtmf.cpp
+++ b/src/audio/dtmf.cpp
@@ -77,3 +77,4 @@ DTMF::generateDTMF (SFLDataFormat* buffer, size_t n)
     return false;
   }
 }
+
diff --git a/src/audio/pulselayer.cpp b/src/audio/pulselayer.cpp
index 6e1be72dc20e747842d1b9640b7d5723d51c069b..121c7f0048913e25b6d81a1fbfad51a69eef6430 100644
--- a/src/audio/pulselayer.cpp
+++ b/src/audio/pulselayer.cpp
@@ -19,23 +19,13 @@
 
 #include "pulselayer.h"
 
-static pa_context *context = NULL;
-static pa_stream* playback = NULL;
-static pa_stream* record = NULL;
-static pa_mainloop_api *mainloop_api = NULL;
-static pa_threaded_mainloop *m = NULL;
 
-static pa_sample_spec sample_spec ;
+int framesPerBuffer = 1024;
 
-static pa_channel_map channel_map;
-
-static std::string pcm_p, pcm_r;
-
-int framesPerBuffer = 882;
-
-  PulseLayer::PulseLayer(ManagerImpl* manager)
+PulseLayer::PulseLayer(ManagerImpl* manager)
   : AudioLayer( manager , PULSEAUDIO )    
-    , _mainSndRingBuffer( SIZEBUF )
+  , _urgentRingBuffer( SIZEBUF)
+    ,_mainSndRingBuffer( SIZEBUF )
 {
   _debug("Pulse audio constructor: Create context\n");
 }
@@ -43,11 +33,10 @@ int framesPerBuffer = 882;
 // Destructor
 PulseLayer::~PulseLayer (void) 
 { 
-  assert(mainloop_api);
-  //mainloop_api->quit( mainloop_api, 0 );
-   pa_stream_flush( playback , NULL, NULL);
-   pa_stream_disconnect( playback );
-   pa_context_disconnect(context);
+  delete playback;
+  delete record;
+  ////delete cache;
+  pa_context_disconnect(context);
 }
 
   void
@@ -75,33 +64,12 @@ PulseLayer::connectPulseServer( void )
   _debug("Context creation done\n");
 }
 
-  void 
-PulseLayer::stream_state_callback( pa_stream* s, void* user_data )
-{
-  _debug("The state of the stream changed\n");
-  assert(s);
-  switch(pa_stream_get_state(s)){
-    case PA_STREAM_CREATING:
-    case PA_STREAM_TERMINATED:
-      _debug("Stream is creating...\n");
-      break;
-    case PA_STREAM_READY:
-      _debug("Stream successfully created\n");
-      break;
-    case PA_STREAM_FAILED:
-    default:
-      _debug("Stream error: %s\n" , pa_strerror(pa_context_errno(pa_stream_get_context(s))));
-      break;
-  }
-}
-
   void 
 PulseLayer::context_state_callback( pa_context* c, void* user_data )
 {
   _debug("The state of the context changed\n");
   PulseLayer* pulse = (PulseLayer*)user_data;
-  //pa_stream_flags_t flag = PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_AUTO_TIMING_UPDATE ;  
-  assert(c && m);
+  assert(c && pulse->m);
   switch(pa_context_get_state(c)){
     case PA_CONTEXT_CONNECTING:
     case PA_CONTEXT_AUTHORIZING:
@@ -110,7 +78,6 @@ PulseLayer::context_state_callback( pa_context* c, void* user_data )
       break;
     case PA_CONTEXT_READY:
       pa_cvolume cv;
-      assert(c && !playback && !record);
       pulse->createStreams( c );
       _debug("Connection to PulseAudio server established\n");	
       break;
@@ -119,7 +86,7 @@ PulseLayer::context_state_callback( pa_context* c, void* user_data )
       break;
     case PA_CONTEXT_FAILED:
     default:
-      _debug(" Error : %s" , pa_strerror(pa_context_errno(context)));
+      _debug(" Error : %s" , pa_strerror(pa_context_errno(c)));
       exit(1);
   }
 }
@@ -127,47 +94,13 @@ PulseLayer::context_state_callback( pa_context* c, void* user_data )
   void
 PulseLayer::createStreams( pa_context* c )
 {
-  _debug( " Create Audio Streams \n ");
-  //pa_stream_flags_t flag = PA_STREAM_AUTO_TIMING_UPDATE;
-  pa_stream_flags_t flag = PA_STREAM_FIX_RATE;
-  sample_spec.format = PA_SAMPLE_S16LE; 
-  sample_spec.rate = 44100; 
-  sample_spec.channels = 1; 
-  channel_map.channels = 1; 
-
-  if( !pa_sample_spec_valid( &sample_spec ) ){
-    _debug("Invalid sample specifications\n");
-    exit(0);
-  }
-
-  if(!(playback = pa_stream_new( c, "SFLphone out" , &sample_spec, &channel_map))){
-    _debug("Playback: pa_stream_new() failed : %s\n" , pa_strerror( pa_context_errno( c)));
-    exit(0);
-  }
-
-  if(!(record = pa_stream_new( c, "SFLphone Mic" , &sample_spec, &channel_map))){
-    _debug("Capture: pa_stream_new() failed : %s\n" , pa_strerror( pa_context_errno( c)));
-    exit(0);
-  }
-
-  assert(playback);
-  assert(record);
-  assert(m);
-
-  // Set up the parameters required to open a (Callback)Stream:
-
-  pa_stream_connect_playback( playback, NULL , NULL , flag , NULL, NULL );
-  pa_stream_set_state_callback(playback, stream_state_callback, NULL);
-  // Transferring Data - Asynchronous Mode
-  pa_stream_set_write_callback(playback, audioCallback, this);
+  playback = new AudioStream(c, PLAYBACK_STREAM, "SFLphone out");
+  pa_stream_set_write_callback( playback->pulseStream() , audioCallback, this);
+  record = new AudioStream(c, CAPTURE_STREAM, "SFLphone in");
+  pa_stream_set_read_callback( record->pulseStream() , audioCallback, this);
+  //cache = new AudioStream(c, UPLOAD_STREAM, "Cache samples");
 
   pa_threaded_mainloop_signal(m , 0);
-
-  pa_stream_set_state_callback(record, stream_state_callback, NULL);
-  // Transferring Data - Asynchronous Mode
-  pa_stream_set_read_callback(record, audioCallback, this);
-  pa_stream_connect_record( record, NULL , NULL , flag  );
-
 }
 
   bool 
@@ -223,7 +156,6 @@ PulseLayer::putMain(void* buffer, int toCopy)
     _debug("Chopping sound, Ouch! RingBuffer full ?\n");
     return _mainSndRingBuffer.Put(buffer, a, 100);
   }
-
   return 0;
 }
 
@@ -235,6 +167,13 @@ PulseLayer::flushMain()
   int
 PulseLayer::putUrgent(void* buffer, int toCopy)
 {
+  int a = _urgentRingBuffer.AvailForPut();
+  if ( a >= toCopy ) {
+    return _urgentRingBuffer.Put(buffer, toCopy, 100 );
+  } else {
+    return _urgentRingBuffer.Put(buffer, a, 100 );
+  }
+  return 0;
 }
 
   int
@@ -254,23 +193,22 @@ PulseLayer::flushMic()
 {
 }
 
-  bool
+/*  bool
 PulseLayer::isStreamStopped (void) 
 {
 }
-
+*/
   void 
 PulseLayer::startStream (void) 
 {
   _debug("Start stream\n");
-  //pa_stream_cork( playback , 0, NULL, NULL);
 }
 
   void 
 PulseLayer::stopStream (void) 
 {
   _debug("Stop stream\n");
-  pa_stream_drop( playback );
+  //pa_stream_drop( playback );
 }
 
   bool 
@@ -281,67 +219,47 @@ PulseLayer::isStreamActive (void)
   void 
 PulseLayer::audioCallback ( pa_stream* s, size_t bytes, void* userdata )
 { 
-  pa_threaded_mainloop_signal( m , 0);
-
-  assert( s && bytes );
-
   PulseLayer* pulse = (PulseLayer*) userdata;
+  assert( s && bytes );
   pulse->write();
-  //if(pa_stream_get_state(s) == PA_STREAM_READY )
-  //{
-  //if( bytes > 0 ){
-  //  pa_stream_write( s, user_data, bytes, pa_xfree, 0, PA_SEEK_RELATIVE );
-  //}
-  //}
-  // pa_stream_write
-  //  // pa_stream_peek ( to read the next fragment from the buffer ) / pa_stream_drop( to remove the data from the buffer )
-  //
-  //  int toPut;
-  //  int urgentAvail; // number of data right and data left  
-  //  int micAvailPut;
-  //
-  //  // AvailForGet tell the number of chars inside the buffer
-  //  // framePerBuffer are the number of data for one channel (left)
-  //  urgentAvail = _urgentRingBuffer.AvailForGet();
-  //  if (urgentAvail > 0) {
-  //    // Urgent data (dtmf, incoming call signal) come first.		
-  //    toGet = (urgentAvail < (int)(framesPerBuffer * sizeof(SFLDataFormat))) ? urgentAvail : framesPerBuffer * sizeof(SFLDataFormat);
-  //    _urgentRingBuffer.Get(out, toGet, spkrVolume);
-  //    // Consume the regular one as well (same amount of bytes)
-  //    _mainSndRingBuffer.Discard(toGet);
-  //  } else {
-  //    AudioLoop* tone = _manager->getTelephoneTone();
-  //    if ( tone != 0) {
-  //      tone->getNext(out, framesPerBuffer, spkrVolume);
-  //    } else if ( (tone=_manager->getTelephoneFile()) != 0 ) {
-  //      tone->getNext(out, framesPerBuffer, spkrVolume);
-  //    } else {
-
-  //    }
-  //  }
-  //
-  //  // Additionally handle the mic's audio stream 
-  //  micAvailPut = _micRingBuffer.AvailForPut();
-  //  toPut = (micAvailPut <= (int)(framesPerBuffer * sizeof(SFLDataFormat))) ? micAvailPut : framesPerBuffer * sizeof(SFLDataFormat);
-  //  //_debug("AL: Nb sample: %d char, [0]=%f [1]=%f [2]=%f\n", toPut, in[0], in[1], in[2]);
-  //  _micRingBuffer.Put(in, toPut, micVolume);
-
 }
 
   void
 PulseLayer::write( void )
 {
   int toGet; 
+  int urgentAvail; // number of data right and data left  
   int normalAvail; // number of data right and data left
   SFLDataFormat* out = (SFLDataFormat*)malloc(framesPerBuffer * sizeof(SFLDataFormat));
-  normalAvail = _mainSndRingBuffer.AvailForGet();
-  toGet = (normalAvail < (int)(framesPerBuffer * sizeof(SFLDataFormat))) ? normalAvail : framesPerBuffer * sizeof(SFLDataFormat);
-  if (toGet) {
-    _mainSndRingBuffer.Get(out, toGet, 100);
-    _debug("Write %i bytes\n" , toGet);
-    pa_stream_write( playback , out , toGet  , pa_xfree, 0 , PA_SEEK_RELATIVE);
+  urgentAvail = _urgentRingBuffer.AvailForGet();
+  if (urgentAvail > 0) {
+    // Urgent data (dtmf, incoming call signal) come first.		
+    _debug("Play urgent!\n");
+    toGet = (urgentAvail < (int)(framesPerBuffer * sizeof(SFLDataFormat))) ? urgentAvail : framesPerBuffer * sizeof(SFLDataFormat);
+    _urgentRingBuffer.Get(out, toGet, 100);
+    // Consume the regular one as well (same amount of bytes)
     _mainSndRingBuffer.Discard(toGet);
-  } else {
-    bzero(out, framesPerBuffer * sizeof(SFLDataFormat));
   }
-} 
+  else
+  {
+    AudioLoop* tone = _manager->getTelephoneTone();
+    if ( tone != 0) {
+      tone->getNext(out, framesPerBuffer, 100);
+      toGet = framesPerBuffer;
+    } else if ( (tone=_manager->getTelephoneFile()) != 0 ) {
+      tone->getNext(out, framesPerBuffer, 100);
+      toGet = framesPerBuffer;
+    } else {
+      normalAvail = _mainSndRingBuffer.AvailForGet();
+      toGet = (normalAvail < (int)(framesPerBuffer * sizeof(SFLDataFormat))) ? normalAvail : framesPerBuffer * sizeof(SFLDataFormat);
+      if (toGet) {
+	_mainSndRingBuffer.Get(out, toGet, 100);
+	_debug("Write %i bytes\n" , toGet);
+	_mainSndRingBuffer.Discard(toGet);
+      } else {
+	bzero(out, framesPerBuffer * sizeof(SFLDataFormat));
+      }
+    }
+  }
+  pa_stream_write( playback->pulseStream() , out , toGet  , pa_xfree, 0 , PA_SEEK_RELATIVE);
+}
diff --git a/src/audio/pulselayer.h b/src/audio/pulselayer.h
index a63ce2319b635c524061e1722e5c4a3c658dd173..1593862c1eded324eef11c55d6e1d5b1d30e69fe 100644
--- a/src/audio/pulselayer.h
+++ b/src/audio/pulselayer.h
@@ -21,6 +21,7 @@
 #define _PULSE_LAYER_H
 
 #include "audiolayer.h"
+#include "audiostream.h"
 
 class RingBuffer;
 class ManagerImpl;
@@ -48,8 +49,6 @@ class PulseLayer : public AudioLayer {
 
     void startStream(void);
     void stopStream(void);
-    bool isStreamActive(void);
-    bool isStreamStopped(void);
 
     /**
      * Check if the capture is running
@@ -57,6 +56,7 @@ class PulseLayer : public AudioLayer {
      *	       false otherwise
      */
     bool isCaptureActive( void ) { return true; }
+    bool isStreamActive (void); 
 
     void flushMain();
     int putMain(void* buffer, int toCopy);
@@ -76,7 +76,6 @@ class PulseLayer : public AudioLayer {
 
     static void audioCallback ( pa_stream* s, size_t bytes, void* userdata );
 
-    static void stream_state_callback( pa_stream* s, void* user_data );	
     static void context_state_callback( pa_context* c, void* user_data );	
 
     /**
@@ -117,6 +116,8 @@ class PulseLayer : public AudioLayer {
      */
     std::string getAudioPlugin( void ) { return "default"; }
 
+    //pa_stream* getCacheStream( void ) { return caching; }
+
   private:
     /**
      * Drop the pending frames and close the capture device
@@ -132,10 +133,17 @@ class PulseLayer : public AudioLayer {
 
     void connectPulseServer( void );
 
+    /** Ringbuffers for data */
     RingBuffer _mainSndRingBuffer;
+    RingBuffer _urgentRingBuffer;
+
+    /** PulseAudio streams and context */
+    pa_context* context;
+    pa_threaded_mainloop* m;
 
-    //pa_stream* playback;
-    //pa_stream* record;
+    AudioStream* playback;
+    AudioStream* record;
+    AudioStream* cache;
 
 };
 
diff --git a/src/audio/samplecache.cpp b/src/audio/samplecache.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2d15d82c64a682c892ddf003039bff5926a64fb8
--- /dev/null
+++ b/src/audio/samplecache.cpp
@@ -0,0 +1,37 @@
+/*
+ *  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 <samplecache.h>
+
+SampleCache::SampleCache( pa_stream* s )
+{
+  _stream = s ;
+}
+
+SampleCache::~SampleCache()
+{
+  //delete _pulse;
+}
+
+bool
+SampleCache::uploadSample( SFLDataFormat* buffer , size_t size )
+{
+  //pa_stream_write( pulse->caching , buffer , size  , pa_xfree, 0 , PA_SEEK_RELATIVE);
+  //pa_stream_finish_upload( pulse->caching );
+}  
diff --git a/src/audio/samplecache.h b/src/audio/samplecache.h
new file mode 100644
index 0000000000000000000000000000000000000000..655f791197134d2dddc60736e40d6ebd266de4d1
--- /dev/null
+++ b/src/audio/samplecache.h
@@ -0,0 +1,41 @@
+/*
+ *  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_CACHE_H
+#define _SAMPLE_CACHE_H
+
+#include <pulse/pulseaudio.h>
+#include <audiolayer.h>
+
+class SampleCache {
+ 
+  public:
+    SampleCache( pa_stream* stream );
+    ~SampleCache();
+
+    bool uploadSample( SFLDataFormat* buffer, size_t size );
+    bool removeSample( );
+    bool isSampleCached( );
+
+  private:
+    pa_stream* _stream;
+
+};
+
+#endif // _SAMPLE_CACHE_H
diff --git a/src/global.h b/src/global.h
index f6e9cd00f09f1a9476535cf569452198d965b7bb..a89b070f3e31b868b4fb8f48e21787a4b0b84ec0 100644
--- a/src/global.h
+++ b/src/global.h
@@ -124,7 +124,6 @@ typedef short int16;
 
 #define ALSA			  0 
 #define PULSEAUDIO		  1
-//#define AUDIODRIVER		  ALSA
-#define CHECK_INTERFACE( layer , api )		  (layer == api) 
+#define CHECK_INTERFACE( layer , api )		  (layer != api) 
 
 #endif	// __GLOBAL_H__
diff --git a/src/managerimpl.cpp b/src/managerimpl.cpp
index 08f0360d4f35879c86b950b657e165a5d9042c39..7c176428fd3dfb19cacf4f1aae08b30c9243334c 100644
--- a/src/managerimpl.cpp
+++ b/src/managerimpl.cpp
@@ -473,6 +473,7 @@ ManagerImpl::playDtmf(char code, bool isTalking)
   // numbers of int = length in milliseconds / 1000 (number of seconds)
   //                = number of seconds * SAMPLING_RATE by SECONDS
   AudioLayer* audiolayer = getAudioDriver();
+  int layer = audiolayer->getLayerType();
 
   // fast return, no sound, so no dtmf
   if (audiolayer==0 || _dtmfKey == 0) { return false; }
@@ -496,7 +497,13 @@ ManagerImpl::playDtmf(char code, bool isTalking)
     // Put buffer to urgentRingBuffer 
     // put the size in bytes...
     // so size * 1 channel (mono) * sizeof (bytes for the data)
+#if CHECK_INTERFACE( layer , ALSA )
+    _debug("%i No good\n", layer);
     audiolayer->playSamples(_buf, size * sizeof(SFLDataFormat), isTalking);
+#else
+    _debug("%i Good\n" , layer);
+    audiolayer->putUrgent( _buf, size * sizeof(SFLDataFormat) );
+#endif
   }
   returnValue = true;
 
@@ -822,13 +829,14 @@ ManagerImpl::ringtone()
       _audiofile.start();
       _toneMutex.leaveMutex(); 
 #if CHECK_INTERFACE( layer, ALSA )
+      _debug()
       int size = _audiofile.getSize();
       SFLDataFormat output[ size ];
       _audiofile.getNext(output, size , 100);
       audiolayer->putUrgent( output , size );
 #else
       // pulseaudio code
-      startStream();
+      audiolayer->startStream();
 #endif
     } else {
       ringback();
@@ -1491,7 +1499,6 @@ ManagerImpl::selectAudioDriver (void)
   int layer = _audiodriver->getLayerType();
   _debug("Audio layer type: %i\n" , layer);
 
-#if CHECK_INTERFACE( layer , ALSA )
   std::string alsaPlugin = getConfigString( AUDIO , ALSA_PLUGIN );
   int numCardIn  = getConfigInt( AUDIO , ALSA_CARD_ID_IN );
   int numCardOut = getConfigInt( AUDIO , ALSA_CARD_ID_OUT );
@@ -1514,13 +1521,15 @@ ManagerImpl::selectAudioDriver (void)
     setConfig( AUDIO , ALSA_CARD_ID_OUT , ALSA_DFT_CARD_ID );
   }
 
+#if CHECK_INTERFACE( layer , ALSA )
+  _debug("No good\n");
   _debugInit(" AudioLayer Opening Device");
   _audiodriver->setErrorMessage(-1);
   _audiodriver->openDevice( numCardIn , numCardOut, sampleRate, frameSize, SFL_PCM_BOTH, alsaPlugin ); 
   if( _audiodriver -> getErrorMessage() != -1 )
     notifyErrClient( _audiodriver -> getErrorMessage());
 #else
-  
+  _debug("Good\n");
   _debug(" Pulse audio driver \n");
   _audiodriver->openDevice( numCardIn , numCardOut, sampleRate, frameSize, SFL_PCM_BOTH, alsaPlugin ); 
   if( _audiodriver -> getErrorMessage() != -1 )