diff --git a/src/audio/Makefile.am b/src/audio/Makefile.am
index 061c6c33db9f8991696968064b34193e30e588b4..22c0c99e45c3036718111ba701ec8294d6a50943 100644
--- a/src/audio/Makefile.am
+++ b/src/audio/Makefile.am
@@ -23,7 +23,7 @@ endif
 SUBDIRS = codecs
 
 libaudio_la_SOURCES =    audiofile.cpp	 tonelist.cpp    \
-audiortp.cpp         dtmf.cpp   tone.cpp  audiolayer.cpp audiolayer-pulse.cpp audiodevice.cpp  dtmfgenerator.cpp   \
+audiortp.cpp         dtmf.cpp   tone.cpp  alsalayer.cpp pulselayer.cpp audiodevice.cpp  dtmfgenerator.cpp   \
 tonegenerator.cpp   codecDescriptor.cpp \
 audioloop.cpp ringbuffer.cpp $(SPEEX_SOURCES_CPP)
 
@@ -31,7 +31,7 @@ AM_CXXFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/libs $(libccext2_CFLAGS) $
  	      -DCODECS_DIR=\""$(sflcodecdir)"\" $(SPEEX_FLAG) $(GSM_FLAG) $(ILBC_FLAG)	
 
 noinst_HEADERS = audioloop.h    common.h ringbuffer.h    audiofile.h  \
- tonelist.h         audiortp.h   audiolayer.h audiolayer.h audiodevice.h \
+ tonelist.h         audiortp.h   audiolayer.h alsalayer.h  pulselayer.h audiodevice.h \
  dtmfgenerator.h         tonegenerator.h     \
  codecDescriptor.h    dtmf.h tone.h 
 
diff --git a/src/audio/alsalayer.cpp b/src/audio/alsalayer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..44c11dcba46c0954841e1c33c5209aacc524ce5d
--- /dev/null
+++ b/src/audio/alsalayer.cpp
@@ -0,0 +1,635 @@
+/*
+ *  Copyright (C) 2008 Savoir-Faire Linux inc.
+ *  Author: Yan Morin <yan.morin@savoirfairelinux.com>
+ *  Author: Jerome Oufella <jerome.oufella@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
+ *  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 "alsalayer.h"
+
+
+// Constructor
+AlsaLayer::AlsaLayer( ManagerImpl* manager ) 
+  : AudioLayer( manager ) 
+  , _PlaybackHandle(NULL)
+  , _CaptureHandle(NULL)
+{
+  _debug(" Constructor of AlsaLayer called\n");
+  _defaultVolume = 100;
+}
+
+// Destructor
+AlsaLayer::~AlsaLayer (void) 
+{ 
+  _debugAlsa("Close ALSA streams\n");
+  closeCaptureStream();
+  closePlaybackStream();
+  deviceClosed = true;
+}
+
+
+  bool 
+AlsaLayer::openDevice (int indexIn, int indexOut, int sampleRate, int frameSize, int stream , std::string plugin) 
+{
+
+  if(deviceClosed == false)
+  {
+    if( stream == SFL_PCM_CAPTURE )
+      closeCaptureStream();
+    else if( stream == SFL_PCM_PLAYBACK)
+      closePlaybackStream();
+    else
+    {
+      closeCaptureStream();
+      closePlaybackStream();
+    }
+  }
+
+  _indexIn = indexIn;
+  _indexOut = indexOut;
+  _sampleRate = sampleRate;
+  _frameSize = frameSize;	
+  _audioPlugin = plugin;
+
+  _debugAlsa(" Setting AlsaLayer: device     in=%2d, out=%2d\n", _indexIn, _indexOut);
+  _debugAlsa("                   : alsa plugin=%s\n", _audioPlugin.c_str());
+  _debugAlsa("                   : nb channel in=%2d, out=%2d\n", _inChannel, _outChannel);
+  _debugAlsa("                   : sample rate=%5d, format=%s\n", _sampleRate, SFLDataFormatString);
+
+  ost::MutexLock lock( _mutex );
+
+  std::string pcmp = buildDeviceTopo( plugin , indexOut , 0);
+  std::string pcmc = buildDeviceTopo( PCM_PLUGHW , indexIn , 0);
+  return open_device( pcmp , pcmc , stream);
+}
+
+  void
+AlsaLayer::startStream(void) 
+{
+  if( _CaptureHandle && _PlaybackHandle )
+  {
+    _talk = true ;
+    _debugAlsa(" Start stream\n");
+    int err;
+    //ost::MutexLock lock( _mutex );
+    snd_pcm_prepare( _CaptureHandle );
+    snd_pcm_start( _CaptureHandle ) ;
+
+    snd_pcm_prepare( _PlaybackHandle );
+    if( err = snd_pcm_start( _PlaybackHandle) < 0 )  _debugAlsa(" Cannot start (%s)\n", snd_strerror(err));
+  }
+} 
+
+  void
+AlsaLayer::stopStream(void) 
+{
+  if( _CaptureHandle && _PlaybackHandle )
+  {
+    //ost::MutexLock lock( _mutex );
+    _debugAlsa(" Stop Stream\n ");
+    _talk = false;
+    snd_pcm_drop( _CaptureHandle );
+    snd_pcm_prepare( _CaptureHandle );
+    snd_pcm_drop( _PlaybackHandle );
+    snd_pcm_prepare( _PlaybackHandle );
+    _urgentBuffer.flush();
+  }
+}
+
+void AlsaLayer::AlsaCallBack( snd_async_handler_t* pcm_callback )
+{ 
+  ( ( AlsaLayer *)snd_async_handler_get_callback_private( pcm_callback )) -> playTones();
+}
+
+  void 
+AlsaLayer::fillHWBuffer( void)
+{
+  unsigned char* data;
+  int pcmreturn, l1, l2;
+  short s1, s2;
+  int periodSize = 128 ;
+  int frames = periodSize >> 2 ;
+  _debug("frames  = %d\n");
+
+  data = (unsigned char*)malloc(periodSize);
+  for(l1 = 0; l1 < 100; l1++) {
+    for(l2 = 0; l2 < frames; l2++) {
+      s1 = 0;
+      s2 = 0;
+      data[4*l2] = (unsigned char)s1;
+      data[4*l2+1] = s1 >> 8;
+      data[4*l2+2] = (unsigned char)s2;
+      data[4*l2+3] = s2 >> 8;
+    }
+    while ((pcmreturn = snd_pcm_writei(_PlaybackHandle, data, frames)) < 0) {
+      snd_pcm_prepare(_PlaybackHandle);
+      //_debugAlsa("< Buffer Underrun >\n");
+    }
+  }
+}
+
+  bool
+AlsaLayer::isStreamActive (void) 
+{
+  ost::MutexLock lock( _mutex );
+  return (isPlaybackActive() && isCaptureActive());
+}
+
+
+  int 
+AlsaLayer::playSamples(void* buffer, int toCopy, bool isTalking)
+{
+  //ost::MutexLock lock( _mutex );
+  if( isTalking )
+    _talk = true;
+  if ( _PlaybackHandle ){ 
+    write( adjustVolume( buffer , toCopy , SFL_PCM_PLAYBACK ) , toCopy );
+  }
+  return 0;
+}
+
+  int
+AlsaLayer::putUrgent(void* buffer, int toCopy)
+{
+  if ( _PlaybackHandle ){ 
+    fillHWBuffer();
+    int a = _urgentBuffer.AvailForPut();
+    if( a >= toCopy ){
+      return _urgentBuffer.Put( buffer , toCopy , _defaultVolume );
+    } else {
+      return _urgentBuffer.Put( buffer , a , _defaultVolume ) ;
+    }
+  }
+  return 0;
+}
+
+  int
+AlsaLayer::canGetMic()
+{
+  int avail;
+  if ( _CaptureHandle ) {
+    avail = snd_pcm_avail_update( _CaptureHandle );
+    //printf("%d\n", avail ); 
+    if(avail > 0)
+      return avail;
+    else 
+      return 0;  
+  }
+  else
+    return 0;
+}
+
+  int 
+AlsaLayer::getMic(void *buffer, int toCopy)
+{
+  int res = 0 ; 
+  if( _CaptureHandle ) 
+  {
+    res = read( buffer, toCopy );
+    adjustVolume( buffer , toCopy , SFL_PCM_CAPTURE );
+  }
+  return res ;
+}
+
+
+  bool
+AlsaLayer::isStreamStopped (void) 
+{
+  ost::MutexLock lock( _mutex );
+  return !(isStreamActive());
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////   ALSA PRIVATE FUNCTIONS   ////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////
+
+
+
+  void
+AlsaLayer::playTones( void )
+{
+  int frames = _periodSize ; 
+  int maxBytes = frames * sizeof(SFLDataFormat) ;
+  SFLDataFormat* out = (SFLDataFormat*)malloc(maxBytes * sizeof(SFLDataFormat));
+  if( _talk ) {}
+  else {
+    AudioLoop *tone = _manager -> getTelephoneTone();
+    int spkrVol = _manager -> getSpkrVolume();
+    if( tone != 0 ){
+      tone -> getNext( out , frames , spkrVol );
+      write( out , maxBytes );
+    } 
+    else if( ( tone=_manager->getTelephoneFile() ) != 0 ){
+      tone ->getNext( out , frames , spkrVol );
+      write( out , maxBytes );
+    }
+  }
+  // free the temporary data buffer 
+  free( out ); out = 0;
+}
+
+bool
+AlsaLayer::isPlaybackActive(void) {
+  ost::MutexLock guard( _mutex );
+  if( _PlaybackHandle )
+    return (snd_pcm_state(_PlaybackHandle) == SND_PCM_STATE_RUNNING ? true : false); 
+  else
+    return false;
+}
+
+bool
+AlsaLayer::isCaptureActive(void) {
+  ost::MutexLock guard( _mutex );
+  if( _CaptureHandle )
+    return (snd_pcm_state( _CaptureHandle) == SND_PCM_STATE_RUNNING ? true : false); 
+  else
+    return false;
+}
+
+
+  bool 
+AlsaLayer::open_device(std::string pcm_p, std::string pcm_c, int flag)
+{
+  std::stringstream errMsg;
+  int err;
+  snd_pcm_hw_params_t* hwParams = NULL;
+  snd_pcm_sw_params_t *swparams = NULL;
+  unsigned int rate_in = getSampleRate();
+  unsigned int rate_out = getSampleRate();
+  int dir = 0;
+  snd_pcm_uframes_t period_size = 2048;
+  snd_pcm_uframes_t buffer_size = period_size * 4 ; 
+  snd_pcm_uframes_t threshold = 1024 ;
+  snd_pcm_uframes_t period_size_out =  getFrameSize() * getSampleRate() / 1000 *  2;//1024 ;
+  snd_pcm_uframes_t buffer_size_out = period_size_out * 4 ;
+
+  unsigned int buffer_time = 80000; //80ms
+  unsigned int period_time = buffer_time / 4 ; //20ms
+
+  if(flag == SFL_PCM_BOTH || flag == SFL_PCM_CAPTURE)
+  {
+    _debugAlsa("Opening capture device %s\n", pcm_c.c_str());
+    if(err = snd_pcm_open(&_CaptureHandle,  pcm_c.c_str(),  SND_PCM_STREAM_CAPTURE, 0) < 0){
+      _debugAlsa("Error while opening capture device %s\n",  pcm_c.c_str());
+      setErrorMessage( ALSA_CAPTURE_DEVICE );
+      return false;
+    }
+
+    if( err = snd_pcm_hw_params_malloc( &hwParams ) < 0 ) {
+      _debugAlsa(" Cannot allocate hardware parameter structure (%s)\n", snd_strerror(err));
+      return false;
+    }
+    if( err = snd_pcm_hw_params_any(_CaptureHandle, hwParams) < 0) _debugAlsa(" Cannot initialize hardware parameter structure (%s)\n", snd_strerror(err));
+    if( err = snd_pcm_hw_params_set_access( _CaptureHandle, hwParams, SND_PCM_ACCESS_MMAP_INTERLEAVED) < 0) _debugAlsa(" Cannot set access type (%s)\n", snd_strerror(err));
+    if( err = snd_pcm_hw_params_set_format( _CaptureHandle, hwParams, SND_PCM_FORMAT_S16_LE) < 0) _debugAlsa(" Cannot set sample format (%s)\n", snd_strerror(err));
+    if( err = snd_pcm_hw_params_set_rate_near( _CaptureHandle, hwParams, &rate_in, &dir) < 0) _debugAlsa(" Cannot set sample rate (%s)\n", snd_strerror(err));
+    if( err = snd_pcm_hw_params_set_channels( _CaptureHandle, hwParams, 1) < 0) _debugAlsa(" Cannot set channel count (%s)\n", snd_strerror(err));
+    if( err = snd_pcm_hw_params_set_period_time_near( _CaptureHandle, hwParams, &period_time , &dir) < 0) _debugAlsa(" Cannot set period time (%s)\n", snd_strerror(err));
+    if( err = snd_pcm_hw_params_set_buffer_time_near( _CaptureHandle, hwParams, &buffer_time , &dir) < 0) _debugAlsa(" Cannot set buffer time (%s)\n", snd_strerror(err));
+    if( err = snd_pcm_hw_params( _CaptureHandle, hwParams ) < 0) _debugAlsa(" Cannot set hw parameters (%s)\n", snd_strerror(err));
+    snd_pcm_hw_params_free( hwParams );
+
+    snd_pcm_uframes_t val ;
+    snd_pcm_sw_params_malloc( &swparams );
+    snd_pcm_sw_params_current( _CaptureHandle, swparams );
+
+    if( err = snd_pcm_sw_params_set_start_threshold( _CaptureHandle, swparams, period_size_out) < 0 ) _debugAlsa(" Cannot set start threshold (%s)\n", snd_strerror(err)); 
+    snd_pcm_sw_params_get_start_threshold( swparams , &val);
+    _debug("Start threshold = %d\n" ,val);
+    if( err = snd_pcm_sw_params_set_avail_min( _CaptureHandle, swparams, period_size_out) < 0) _debugAlsa(" Cannot set min avail (%s)\n" , snd_strerror(err)); 
+    snd_pcm_sw_params_get_avail_min( swparams , &val);
+    _debug("Min available = %d\n" ,val);
+    if( err = snd_pcm_sw_params( _CaptureHandle, swparams ) < 0 ) _debugAlsa(" Cannot set sw parameters (%s)\n", snd_strerror(err)); 
+    snd_pcm_sw_params_free( swparams );
+    deviceClosed = false;
+  }
+
+  if(flag == SFL_PCM_BOTH || flag == SFL_PCM_PLAYBACK)
+  {
+
+    _debugAlsa(" Opening playback device %s\n", pcm_p.c_str());
+    if(err = snd_pcm_open(&_PlaybackHandle, pcm_p.c_str(),  SND_PCM_STREAM_PLAYBACK, 0 ) < 0){
+      _debugAlsa("Error while opening playback device %s\n",  pcm_p.c_str());
+      setErrorMessage( ALSA_PLAYBACK_DEVICE );
+      return false;
+    }
+    if( err = snd_pcm_hw_params_malloc( &hwParams ) < 0 ) {
+      _debugAlsa(" Cannot allocate hardware parameter structure (%s)\n", snd_strerror(err));
+      return false;
+    }
+    if( err = snd_pcm_hw_params_any( _PlaybackHandle,hwParams) < 0) _debugAlsa(" Cannot initialize hardware parameter structure (%s)\n", snd_strerror(err));
+    if( err = snd_pcm_hw_params_set_access( _PlaybackHandle, hwParams, SND_PCM_ACCESS_RW_INTERLEAVED) < 0) _debugAlsa(" Cannot set access type (%s)\n", snd_strerror(err));
+    if( err = snd_pcm_hw_params_set_format( _PlaybackHandle, hwParams, SND_PCM_FORMAT_S16_LE) < 0) _debugAlsa(" Cannot set sample format (%s)\n", snd_strerror(err));
+    if( err = snd_pcm_hw_params_set_rate( _PlaybackHandle, hwParams, rate_out, dir) < 0) _debugAlsa(" Cannot set sample rate (%s)\n", snd_strerror(err));
+    if( err = snd_pcm_hw_params_set_channels( _PlaybackHandle, hwParams, 1) < 0) _debugAlsa(" Cannot set channel count (%s)\n", snd_strerror(err));
+
+    if( err = snd_pcm_hw_params_set_buffer_size( _PlaybackHandle, hwParams, buffer_size ) < 0) _debugAlsa(" Cannot set buffer size (%s)\n", snd_strerror(err));
+    if( err = snd_pcm_hw_params_set_period_size_near( _PlaybackHandle, hwParams, &period_size , &dir) < 0) _debugAlsa(" Cannot set period size (%s)\n", snd_strerror(err));
+
+    if( err = snd_pcm_hw_params( _PlaybackHandle, hwParams ) < 0) _debugAlsa(" Cannot set hw parameters (%s)\n", snd_strerror(err));
+
+
+    snd_pcm_hw_params_free( hwParams );
+
+    snd_pcm_uframes_t val ;
+    snd_pcm_sw_params_malloc( &swparams );
+    snd_pcm_sw_params_current( _PlaybackHandle, swparams );
+
+    if( err = snd_pcm_sw_params_set_start_threshold( _PlaybackHandle, swparams, period_size_out) < 0 ) _debugAlsa(" Cannot set start threshold (%s)\n", snd_strerror(err)); 
+    snd_pcm_sw_params_get_start_threshold( swparams , &val);
+    _debug("Start threshold = %d\n" ,val);
+    //if( err = snd_pcm_sw_params_set_stop_threshold( _PlaybackHandle, swparams, buffer_size_out ) < 0 ) _debugAlsa(" Cannot set stop threshold (%s)\n", snd_strerror(err)); 
+    //snd_pcm_sw_params_get_stop_threshold( swparams , &val);
+    //_debug("Stop threshold = %d\n" ,val);
+    if( err = snd_pcm_sw_params_set_avail_min( _PlaybackHandle, swparams, period_size_out) < 0) _debugAlsa(" Cannot set min avail (%s)\n" , snd_strerror(err)); 
+    if( err = snd_pcm_sw_params_set_xfer_align( _PlaybackHandle, swparams, 1) < 0) _debugAlsa(" Cannot set xfer align (%s)\n" , snd_strerror(err)); 
+    snd_pcm_sw_params_get_avail_min( swparams , &val);
+    _debug("Min available = %d\n" ,val);
+    //if( err = snd_pcm_sw_params_set_silence_threshold( _PlaybackHandle, swparams, period_size_out) < 0) _debugAlsa(" Cannot set silence threshold (%s)\n" , snd_strerror(err)); 
+    //snd_pcm_sw_params_get_silence_threshold( swparams , &val);
+    //  _debug("Silence threshold = %d\n" ,val);
+    if( err = snd_pcm_sw_params( _PlaybackHandle, swparams ) < 0 ) _debugAlsa(" Cannot set sw parameters (%s)\n", snd_strerror(err)); 
+    snd_pcm_sw_params_free( swparams );
+
+    //if ( err = snd_async_add_pcm_handler( &_AsyncHandler, _PlaybackHandle , AlsaCallBack, this ) < 0)	_debugAlsa(" Unable to install the async callback handler (%s)\n", snd_strerror(err));
+    deviceClosed = false;
+  }
+  //fillHWBuffer();
+
+  _talk = false;
+  return true;
+}
+
+//TODO	first frame causes broken pipe (underrun) because not enough data are send --> make the handle wait to be ready
+  int
+AlsaLayer::write(void* buffer, int length)
+{
+  snd_pcm_uframes_t frames = snd_pcm_bytes_to_frames( _PlaybackHandle, length);
+  //int err = snd_pcm_mmap_writei( _PlaybackHandle , buffer , frames );
+  int err = snd_pcm_writei( _PlaybackHandle , buffer , frames );
+  switch(err) {
+    case -EAGAIN: 
+      _debugAlsa("EAGAIN (%s)\n", snd_strerror( err ));
+      //snd_pcm_resume( _PlaybackHandle );
+      break;
+    case -EPIPE: 
+      _debugAlsa(" UNDERRUN (%s)\n", snd_strerror(err));
+      handle_xrun_playback();
+      //snd_pcm_mmap_writei( _PlaybackHandle , buffer , frames );
+      //snd_pcm_writei( _PlaybackHandle , buffer , frames );
+      break;
+    case -ESTRPIPE:
+      _debugAlsa("ESTRPIPE (%s)\n", snd_strerror(err));
+      //snd_pcm_resume( _PlaybackHandle );
+      break;
+    case -EBADFD:
+      _debugAlsa("EBADFD (%s)\n", snd_strerror( err ));
+      break;
+  }
+
+  if( err >=0 && err < frames )
+    _debugAlsa("Short write : %d out of %d\n", err , frames);
+
+  return ( err > 0 )? err : 0 ;
+}
+
+  int
+AlsaLayer::read( void* buffer, int toCopy)
+{
+  if(deviceClosed || _CaptureHandle == NULL)
+    return 0;
+  int err;
+  if(snd_pcm_state( _CaptureHandle ) == SND_PCM_STATE_XRUN)
+  {
+    snd_pcm_prepare( _CaptureHandle );
+    snd_pcm_start( _CaptureHandle );
+  }
+  snd_pcm_uframes_t frames = snd_pcm_bytes_to_frames( _CaptureHandle, toCopy );
+  if( err = snd_pcm_mmap_readi( _CaptureHandle, buffer, frames) < 0 ) {
+    switch(err){
+      case EPERM:
+	_debugAlsa(" Capture EPERM (%s)\n", snd_strerror(err));
+	snd_pcm_prepare( _CaptureHandle);
+	snd_pcm_start( _CaptureHandle );
+	break;
+      case -ESTRPIPE:
+	_debugAlsa(" Capture ESTRPIPE (%s)\n", snd_strerror(err));
+	snd_pcm_resume( _CaptureHandle);
+	break;
+      case -EAGAIN:
+	_debugAlsa(" Capture EAGAIN (%s)\n", snd_strerror(err));
+	break;
+      case -EBADFD:
+	_debugAlsa(" Capture EBADFD (%s)\n", snd_strerror(err));
+	break;
+      case -EPIPE:
+	_debugAlsa(" Capture EPIPE (%s)\n", snd_strerror(err));
+	handle_xrun_capture();
+	break;
+    }
+    return 0;
+  }
+
+  return toCopy;
+
+}
+
+  void
+AlsaLayer::handle_xrun_capture( void )
+{
+  snd_pcm_status_t* status;
+  snd_pcm_status_alloca( &status );
+
+  int res = snd_pcm_status( _CaptureHandle, status );
+  if( res <= 0){
+    if(snd_pcm_status_get_state(status) == SND_PCM_STATE_XRUN ){
+      snd_pcm_drop( _CaptureHandle );
+      snd_pcm_prepare( _CaptureHandle );
+      snd_pcm_start( _CaptureHandle ); 
+    }
+  }
+  else
+    _debugAlsa(" Get status failed\n");
+}
+
+  void
+AlsaLayer::handle_xrun_playback( void )
+{
+  int state; 
+  snd_pcm_status_t* status;
+  snd_pcm_status_alloca( &status );
+
+  if( state = snd_pcm_status( _PlaybackHandle, status ) < 0 )   _debugAlsa(" Error: Cannot get playback handle status (%s)\n" , snd_strerror( state ) );
+  else 
+  { 
+    state = snd_pcm_status_get_state( status );
+    if( state  == SND_PCM_STATE_XRUN )
+    {
+      //snd_pcm_drop( _PlaybackHandle );
+      _debug("Underrun\n");
+      snd_pcm_prepare( _PlaybackHandle );
+      //snd_pcm_start( _PlaybackHandle ); 
+    }
+  }
+}
+
+  std::string
+AlsaLayer::buildDeviceTopo( std::string plugin, int card, int subdevice )
+{
+  std::string pcm = plugin;
+  std::stringstream ss,ss1;
+  if( pcm == "default" || pcm == "pulse")
+    return pcm;
+  ss << card;
+  pcm.append(":");
+  pcm.append(ss.str());
+  if( subdevice != 0 ){
+    pcm.append(",");
+    ss1 << subdevice;
+    pcm.append(ss1.str());
+  }
+  return pcm;
+}
+
+  std::vector<std::string>
+AlsaLayer::getSoundCardsInfo( int stream )
+{
+  std::vector<std::string> cards_id;
+  HwIDPair p;
+
+  snd_ctl_t* handle;
+  snd_ctl_card_info_t *info;
+  snd_pcm_info_t* pcminfo;
+  snd_ctl_card_info_alloca( &info );
+  snd_pcm_info_alloca( &pcminfo );
+
+  int numCard = -1 ;
+  int err;
+  std::string description;
+
+  if(snd_card_next( &numCard ) < 0 || numCard < 0)
+    return cards_id;
+
+  while(numCard >= 0){
+    std::stringstream ss;
+    ss << numCard;
+    std::string name= "hw:";
+    name.append(ss.str());
+
+    if( snd_ctl_open( &handle, name.c_str(), 0) == 0 ){
+      if( snd_ctl_card_info( handle, info) == 0){
+	snd_pcm_info_set_device( pcminfo , 0);
+	snd_pcm_info_set_stream( pcminfo, ( stream == SFL_PCM_CAPTURE )? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK );
+	if( snd_ctl_pcm_info ( handle ,pcminfo ) < 0) _debugAlsa(" Cannot get info\n");
+	else{
+	  _debugAlsa("card %i : %s [%s]\n", 
+	      numCard, 
+	      snd_ctl_card_info_get_id(info),
+	      snd_ctl_card_info_get_name( info ));
+	  description = snd_ctl_card_info_get_name( info );
+	  description.append(" - ");
+	  description.append(snd_pcm_info_get_name( pcminfo ));
+	  cards_id.push_back( description );
+	  // The number of the sound card is associated with a string description 
+	  p = HwIDPair( numCard , description );
+	  IDSoundCards.push_back( p );
+	}
+      }
+      snd_ctl_close( handle );
+    }
+    if ( snd_card_next( &numCard ) < 0 ) {
+      break;
+    }
+  }
+  return cards_id;
+}
+
+  void
+AlsaLayer::closeCaptureStream( void)
+{
+  if(_CaptureHandle){
+    snd_pcm_drop( _CaptureHandle );
+    snd_pcm_close( _CaptureHandle );
+    _CaptureHandle = 0;
+  }
+}
+
+  void
+AlsaLayer::closePlaybackStream( void)
+{
+  if(_PlaybackHandle){
+    snd_pcm_drop( _PlaybackHandle );
+    snd_pcm_close( _PlaybackHandle );
+    _PlaybackHandle = 0;
+  }
+}
+
+  bool
+AlsaLayer::soundCardIndexExist( int card , int stream )
+{
+  snd_ctl_t* handle;
+  snd_pcm_info_t *pcminfo;
+  snd_pcm_info_alloca( &pcminfo );
+  std::string name = "hw:";
+  std::stringstream ss;
+  ss << card ;
+  name.append(ss.str());
+  if(snd_ctl_open( &handle, name.c_str(), 0) == 0 ){
+    snd_pcm_info_set_stream( pcminfo , ( stream == SFL_PCM_PLAYBACK )? SND_PCM_STREAM_PLAYBACK : SND_PCM_STREAM_CAPTURE );
+    if( snd_ctl_pcm_info( handle , pcminfo ) < 0) return false;
+    else
+      return true;
+  }
+  else
+    return false;
+}  
+
+  int
+AlsaLayer::soundCardGetIndex( std::string description )
+{
+  int i;
+  for( i = 0 ; i < IDSoundCards.size() ; i++ )
+  {
+    HwIDPair p = IDSoundCards[i];
+    if( p.second == description )
+      return  p.first ;
+  }
+  // else return the default one
+  return 0;
+}
+
+  void*
+AlsaLayer::adjustVolume( void* buffer , int len, int stream )
+{
+  int vol;
+  if( stream == SFL_PCM_PLAYBACK )
+    vol = _manager->getSpkrVolume();
+  else
+    vol = _manager->getMicVolume();
+
+  SFLDataFormat* src = (SFLDataFormat*) buffer;
+  if( vol != 100 )
+  {
+    int size = len / sizeof(SFLDataFormat);
+    int i;
+    for( i = 0 ; i < size ; i++ ){
+      src[i] = src[i] * vol  / 100 ;
+    }
+  }
+  return src ; 
+}
diff --git a/src/audio/alsalayer.h b/src/audio/alsalayer.h
new file mode 100644
index 0000000000000000000000000000000000000000..05f5ebd79470ee1b542b8f1060aa6de886e683c2
--- /dev/null
+++ b/src/audio/alsalayer.h
@@ -0,0 +1,314 @@
+/*
+ *  Copyright (C) 2007 - 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 _ALSA_LAYER_H
+#define _ALSA_LAYER_H
+
+#include "audiolayer.h"
+
+class RingBuffer;
+class ManagerImpl;
+
+/** Associate a sound card index to its string description */
+typedef std::pair<int , std::string> HwIDPair;
+
+/**
+ * @file  AlsaLayer.h
+ * @brief Main sound class. Manages the data transfers between the application and the hardware. 
+ */
+
+class AlsaLayer : public AudioLayer {
+  public:
+    /**
+     * Constructor
+     * @param manager An instance of managerimpl
+     */
+    AlsaLayer( ManagerImpl* manager );  
+
+    /**
+     * Destructor
+     */
+    ~AlsaLayer(void);
+
+    /**
+     * Check if no devices are opened, otherwise close them.
+     * Then open the specified devices by calling the private functions open_device
+     * @param indexIn	The number of the card choosen for capture
+     * @param indexOut	The number of the card choosen for playback
+     * @param sampleRate  The sample rate 
+     * @param frameSize	  The frame size
+     * @param stream	  To indicate which kind of stream you want to open
+     *			  SFL_PCM_CAPTURE
+     *			  SFL_PCM_PLAYBACK
+     *			  SFL_PCM_BOTH
+     * @param plugin	  The alsa plugin ( dmix , default , front , surround , ...)
+     */
+    bool openDevice(int indexIn, int indexOut, int sampleRate, int frameSize, int stream, std::string plugin);
+
+    /**
+     * Start the capture stream and prepare the playback stream. 
+     * The playback starts accordingly to its threshold
+     * ALSA Library API
+     */
+    void startStream(void);
+
+    /**
+     * Stop the playback and capture streams. 
+     * Drops the pending frames and put the capture and playback handles to PREPARED state
+     * ALSA Library API
+     */
+    void stopStream(void);
+    
+    /**
+     * Check if the playback is running
+     * @return true if the state of the playback handle equals SND_PCM_STATE_RUNNING
+     *	       false otherwise
+     */
+    bool isPlaybackActive( void );
+
+    /**
+     * Check if the capture is running
+     * @return true if the state of the capture handle equals SND_PCM_STATE_RUNNING
+     *	       false otherwise
+     */
+    bool isCaptureActive( void );
+
+    /**
+     * Check if both capture and playback are running
+     * @return true if capture and playback are running
+     *	       false otherwise
+     */
+    bool isStreamActive(void);
+
+    /**
+     * Check if both capture and playback are stopped
+     * @return true if capture and playback are stopped
+     *	       false otherwise
+     */
+    bool isStreamStopped(void);
+
+    /**
+     * Send samples to the audio device. 
+     * @param buffer The buffer containing the data to be played ( voice and DTMF )
+     * @param toCopy The number of samples, in bytes
+     * @param isTalking	If whether or not the conversation is running
+     * @return int The number of bytes played
+     */
+    int playSamples(void* buffer, int toCopy, bool isTalking);
+
+    /**
+     * Send a chunk of data to the hardware buffer to start the playback
+     * Copy data in the urgent buffer. 
+     * @param buffer The buffer containing the data to be played ( ringtones )
+     * @param toCopy The size of the buffer
+     * @return int  The number of bytes copied in the urgent buffer
+     */
+    int putUrgent(void* buffer, int toCopy);
+
+    /**
+     * Query the capture device for number of bytes available in the hardware ring buffer
+     * @return int The number of bytes available
+     */
+    int canGetMic();
+
+    /**
+     * Get data from the capture device
+     * @param buffer The buffer for data
+     * @param toCopy The number of bytes to get
+     * @return int The number of bytes acquired ( 0 if an error occured)
+     */
+    int getMic(void * buffer, int toCopy);
+    
+    /**
+     * Concatenate two strings. Used to build a valid pcm device name. 
+     * @param plugin the alsa PCM name
+     * @param card the sound card number
+     * @param subdevice the subdevice number
+     * @return std::string the concatenated string
+     */
+    std::string buildDeviceTopo( std::string plugin, int card, int subdevice );
+
+    /**
+     * Scan the sound card available on the system
+     * @param stream To indicate whether we are looking for capture devices or playback devices
+     *		   SFL_PCM_CAPTURE
+     *		   SFL_PCM_PLAYBACK
+     *		   SFL_PCM_BOTH
+     * @return std::vector<std::string> The vector containing the string description of the card
+     */
+    std::vector<std::string> getSoundCardsInfo( int stream );
+
+    /**
+     * Check if the given index corresponds to an existing sound card and supports the specified streaming mode
+     * @param card   An index
+     * @param stream  The stream mode
+     *		  SFL_PCM_CAPTURE
+     *		  SFL_PCM_PLAYBACK
+     *		  SFL_PCM_BOTH
+     * @return bool True if it exists and supports the mode
+     *		    false otherwise
+     */
+    bool soundCardIndexExist( int card , int stream );
+    
+    /**
+     * An index is associated with its string description
+     * @param description The string description
+     * @return	int	  Its index
+     */
+    int soundCardGetIndex( std::string description );
+
+    /**
+     * Get the current audio plugin.
+     * @return std::string  The name of the audio plugin
+     */
+    std::string getAudioPlugin( void ) { return _audioPlugin; }
+
+  private:
+
+    /**
+     * Drop the pending frames and close the capture device
+     * ALSA Library API
+     */
+    void closeCaptureStream( void );
+
+    /**
+     * Drop the pending frames and close the playback device
+     * ALSA Library API
+     */
+    void closePlaybackStream( void );
+
+    /**
+     * Fill the alsa internal ring buffer with chunks of data
+     */
+    void fillHWBuffer( void) ;
+
+    /**
+     * Callback used for asynchronous playback.
+     * Called when a certain amount of data is written ot the device
+     * @param pcm_callback  The callback pointer
+     */
+    static void AlsaCallBack( snd_async_handler_t* pcm_callback);
+
+    /**
+     * Callback used for asynchronous playback.
+     * Write tones buffer to the alsa internal ring buffer.
+     */
+    void playTones( void );
+
+    /**
+     * Open the specified device.
+     * ALSA Library API
+     * @param pcm_p The string name for the playback device
+     * @param pcm_c The string name for the capture device
+     * @param flag  To indicate which kind of stream you want to open
+     *		    SFL_PCM_CAPTURE
+     *		    SFL_PCM_PLAYBACK
+     *		    SFL_PCM_BOTH
+     * @return true if successful
+     *	       false otherwise
+     */
+    bool open_device( std::string pcm_p, std::string pcm_c, int flag); 
+
+    /**
+     * Copy a data buffer in the internal ring buffer
+     * ALSA Library API
+     * @param buffer The data to be copied
+     * @param length The size of the buffer
+     * @return int The number of frames actually copied
+     */
+    int write( void* buffer, int length);
+    
+    /**
+     * Read data from the internal ring buffer
+     * ALSA Library API
+     * @param buffer  The buffer to stock the read data
+     * @param toCopy  The number of bytes to get
+     * @return int The number of frames actually read
+     */
+    int read( void* buffer, int toCopy);
+    
+    /**
+     * Recover from XRUN state for capture
+     * ALSA Library API
+     */
+    void handle_xrun_capture( void );
+
+    /**
+     * Recover from XRUN state for playback
+     * ALSA Library API
+     */
+    void handle_xrun_playback( void );
+    
+    /**
+     * Handles to manipulate playback stream
+     * ALSA Library API
+     */
+    snd_pcm_t* _PlaybackHandle;
+
+    /**
+     * Handles to manipulate capture stream
+     * ALSA Library API
+     */
+    snd_pcm_t* _CaptureHandle;
+    
+    /**
+     * Alsa parameter - Size of a period in the hardware ring buffer
+     */
+    snd_pcm_uframes_t _periodSize;
+
+    /**
+     * Handle on asynchronous event
+     */
+    snd_async_handler_t *_AsyncHandler;
+    
+    /**
+     * Volume is controlled by the application. Data buffer are modified here to adjust to the right volume selected by the user on the main interface
+     * @param buffer  The buffer to adjust
+     * @param len The number of bytes
+     * @param stream  The stream mode ( PLAYBACK - CAPTURE )
+     */
+    void * adjustVolume( void * , int , int);
+
+    /**
+     * name of the alsa audio plugin used
+     */
+    std::string _audioPlugin;
+
+    /**
+     * Input channel (mic) should be 1 mono
+     */
+    unsigned int _inChannel; 
+
+    /**
+     * Output channel (stereo) should be 1 mono
+     */
+    unsigned int _outChannel; 
+
+    /**
+     * Default volume for incoming RTP and Urgent sounds.
+     */
+    unsigned short _defaultVolume; // 100
+
+
+    /** Vector to manage all soundcard index - description association of the system */
+    std::vector<HwIDPair> IDSoundCards;
+
+};
+
+#endif // _ALSA_LAYER_H_
diff --git a/src/audio/audiolayer-pulse.h b/src/audio/audiolayer-pulse.h
deleted file mode 100644
index e58f3d01dfbc679a02ada63a280933cf5e595ad5..0000000000000000000000000000000000000000
--- a/src/audio/audiolayer-pulse.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- *  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_LAYER_PULSE_H
-#define _AUDIO_LAYER_PULSE_H
-
-#include <cc++/thread.h> // for ost::Mutex
-
-
-#include "../global.h"
-#include "ringbuffer.h"
-#include "audiodevice.h"
-
-#define FRAME_PER_BUFFER	160
-
-class RingBuffer;
-class ManagerImpl;
-
-class PulseLayer {
-	public:
-		PulseLayer(ManagerImpl* manager);
-		~PulseLayer(void);
-
-		/*
-		 * @param indexIn
-		 * @param indexOut
-		 * @param sampleRate
-		 * @param frameSize
-		 */
-		void openDevice(int, int, int, int);
-		void startStream(void);
-		void stopStream(void);
-		void sleep(int);
-		bool hasStream(void);
-		bool isStreamActive(void);
-		bool isStreamStopped(void);
-
-		void flushMain();
-		int putMain(void* buffer, int toCopy);
-		int putUrgent(void* buffer, int toCopy);
-		int canGetMic();
-		int getMic(void *, int);
-		void flushMic();
-
-		int audioCallback ();
-
-
-
-		void setErrorMessage(const std::string& error) { _errorMessage = error; }
-		std::string getErrorMessage() { return _errorMessage; }
-
-		/**
-		 * Get the sample rate of PulseLayer
-		 * accessor only
-		 */
-		unsigned int getSampleRate() { return _sampleRate; }
-		unsigned int getFrameSize() { return _frameSize; }
-
-		/**
-		 * Toggle echo testing on/off
-		 */
-		void toggleEchoTesting();
-
-	private:
-		void closeStream (void);
-		RingBuffer _urgentRingBuffer;
-		RingBuffer _mainSndRingBuffer;
-		RingBuffer _micRingBuffer;
-		ManagerImpl* _manager; // augment coupling, reduce indirect access
-		// a PulseLayer can't live without manager
-
-		pa_stream* playback;
-		pa_stream* record;
-
-		/**
-		 * Sample Rate SFLphone should send sound data to the sound card 
-		 * The value can be set in the user config file- now: 44100HZ
-		 */
-		unsigned int _sampleRate;
-		
-		/**
- 		 * Length of the sound frame we capture or read in ms
- 		 * The value can be set in the user config file - now: 20ms
- 		 */	 		
-		unsigned int _frameSize;
-		
-		/**
-		 * Input channel (mic) should be 1 mono
-		 */
-		unsigned int _inChannel; // mic
-
-		/**
-		 * Output channel (stereo) should be 1 mono
-		 */
-		unsigned int _outChannel; // speaker
-
-		/**
-		 * Default volume for incoming RTP and Urgent sounds.
-		 */
-		//unsigned short _defaultVolume; // 100
-		pa_volume_t _defaultVolume;
-
-		/**
-		 * Echo testing or not
-		 */
-		bool _echoTesting;
-
-		std::string _errorMessage;
-		ost::Mutex _mutex;
-
-		float *table_;
-		int tableSize_;
-		int leftPhase_;
-};
-
-#endif // _AUDIO_LAYER_PULSE_H_
-
diff --git a/src/audio/audiolayer.h b/src/audio/audiolayer.h
index f303167348215b7cf36ec4608351739e997891f1..3a0f549936a46dc67e468588ac9e35bcf6c43330 100644
--- a/src/audio/audiolayer.h
+++ b/src/audio/audiolayer.h
@@ -23,22 +23,22 @@
 #define _AUDIO_LAYER_H
 
 #include "../global.h"
+#include "../manager.h"
 #include "audiodevice.h"
 #include "ringbuffer.h"
 
 #include <cc++/thread.h> // for ost::Mutex
 #include <vector>
+
 #include <alsa/asoundlib.h>
+#include <pulse/pulseaudio.h>
+
 #include <iostream>
 #include <istream>
 #include <sstream>
-#define FRAME_PER_BUFFER	160
 
-class RingBuffer;
-class ManagerImpl;
+#define FRAME_PER_BUFFER	160
 
-/** Associate a sound card index to its string description */
-typedef std::pair<int , std::string> HwIDPair;
 
 /**
  * @file  audiolayer.h
@@ -51,12 +51,21 @@ class AudioLayer {
      * Constructor
      * @param manager An instance of managerimpl
      */
-    AudioLayer(ManagerImpl* manager);
+    AudioLayer( ManagerImpl* manager )
+      :	  _manager(manager)
+	, _urgentBuffer( SIZEBUF )
+    {
+      _inChannel  = 1; // don't put in stereo
+      _outChannel = 1; // don't put in stereo
+
+      deviceClosed = true;
+
+    }
     
     /**
      * Destructor
      */
-    ~AudioLayer(void);
+    ~AudioLayer(void){}
 
     /**
      * Check if no devices are opened, otherwise close them.
@@ -71,49 +80,35 @@ class AudioLayer {
      *			  SFL_PCM_BOTH
      * @param plugin	  The alsa plugin ( dmix , default , front , surround , ...)
      */
-    bool openDevice(int indexIn, int indexOut, int sampleRate, int frameSize, int stream, std::string plugin);
+    virtual bool openDevice(int indexIn, int indexOut, int sampleRate, int frameSize, int stream, std::string plugin) = 0;
 
     /**
      * Start the capture stream and prepare the playback stream. 
      * The playback starts accordingly to its threshold
      * ALSA Library API
      */
-    void startStream(void);
+    virtual void startStream(void) = 0;
 
     /**
      * Stop the playback and capture streams. 
      * Drops the pending frames and put the capture and playback handles to PREPARED state
      * ALSA Library API
      */
-    void stopStream(void);
+    virtual void stopStream(void) = 0;
     
-    /**
-     * Check if the playback is running
-     * @return true if the state of the playback handle equals SND_PCM_STATE_RUNNING
-     *	       false otherwise
-     */
-    bool isPlaybackActive( void );
-
-    /**
-     * Check if the capture is running
-     * @return true if the state of the capture handle equals SND_PCM_STATE_RUNNING
-     *	       false otherwise
-     */
-    bool isCaptureActive( void );
-
     /**
      * Check if both capture and playback are running
      * @return true if capture and playback are running
      *	       false otherwise
      */
-    bool isStreamActive(void);
+    virtual bool isStreamActive(void) = 0;
 
     /**
-     * Check if both capture and playback are stopped
-     * @return true if capture and playback are stopped
+     * Check if the capture is running
+     * @return true if the state of the capture handle equals SND_PCM_STATE_RUNNING
      *	       false otherwise
      */
-    bool isStreamStopped(void);
+    virtual bool isCaptureActive( void ) = 0;
 
     /**
      * Send samples to the audio device. 
@@ -122,7 +117,7 @@ class AudioLayer {
      * @param isTalking	If whether or not the conversation is running
      * @return int The number of bytes played
      */
-    int playSamples(void* buffer, int toCopy, bool isTalking);
+    virtual int playSamples(void* buffer, int toCopy, bool isTalking) = 0;
 
     /**
      * Send a chunk of data to the hardware buffer to start the playback
@@ -131,13 +126,13 @@ class AudioLayer {
      * @param toCopy The size of the buffer
      * @return int  The number of bytes copied in the urgent buffer
      */
-    int putUrgent(void* buffer, int toCopy);
+    virtual int putUrgent(void* buffer, int toCopy) = 0; 
 
     /**
      * Query the capture device for number of bytes available in the hardware ring buffer
      * @return int The number of bytes available
      */
-    int canGetMic();
+    virtual int canGetMic() = 0;
 
     /**
      * Get data from the capture device
@@ -145,17 +140,8 @@ class AudioLayer {
      * @param toCopy The number of bytes to get
      * @return int The number of bytes acquired ( 0 if an error occured)
      */
-    int getMic(void * buffer, int toCopy);
+    virtual int getMic(void * buffer, int toCopy) = 0;
     
-    /**
-     * Concatenate two strings. Used to build a valid pcm device name. 
-     * @param plugin the alsa PCM name
-     * @param card the sound card number
-     * @param subdevice the subdevice number
-     * @return std::string the concatenated string
-     */
-    std::string buildDeviceTopo( std::string plugin, int card, int subdevice );
-
     /**
      * Scan the sound card available on the system
      * @param stream To indicate whether we are looking for capture devices or playback devices
@@ -164,7 +150,7 @@ class AudioLayer {
      *		   SFL_PCM_BOTH
      * @return std::vector<std::string> The vector containing the string description of the card
      */
-    std::vector<std::string> getSoundCardsInfo( int stream );
+    virtual std::vector<std::string> getSoundCardsInfo( int stream ) = 0;
 
     /**
      * Check if the given index corresponds to an existing sound card and supports the specified streaming mode
@@ -176,14 +162,20 @@ class AudioLayer {
      * @return bool True if it exists and supports the mode
      *		    false otherwise
      */
-    bool soundCardIndexExist( int card , int stream );
+    virtual bool soundCardIndexExist( int card , int stream ) = 0;
     
     /**
      * An index is associated with its string description
      * @param description The string description
      * @return	int	  Its index
      */
-    int soundCardGetIndex( std::string description );
+    virtual int soundCardGetIndex( std::string description ) = 0;
+
+    /**
+     * Get the current audio plugin.
+     * @return std::string  The name of the audio plugin
+     */
+    virtual std::string getAudioPlugin( void ) = 0; 
 
     /**
      * Write accessor to the error state
@@ -227,11 +219,6 @@ class AudioLayer {
      */
     unsigned int getFrameSize() { return _frameSize; }
 
-    /**
-     * Get the current audio plugin.
-     * @return std::string  The name of the audio plugin
-     */
-    std::string getAudioPlugin( void ) { return _audioPlugin; }
     /**
      * Get the current state. Conversation or not
      * @return bool true if playSamples has been called  
@@ -239,124 +226,25 @@ class AudioLayer {
      */
     bool getCurrentState( void ) { return _talk; }
 
-    /**
-     * Toggle echo testing on/off
-     */
-    void toggleEchoTesting();
-
-  private:
+  protected:
 
     /**
      * Drop the pending frames and close the capture device
-     * ALSA Library API
      */
-    void closeCaptureStream( void );
+    virtual void closeCaptureStream( void ) = 0;
 
     /**
      * Drop the pending frames and close the playback device
-     * ALSA Library API
-     */
-    void closePlaybackStream( void );
-
-    /**
-     * Fill the alsa internal ring buffer with chunks of data
-     */
-    void fillHWBuffer( void) ;
-
-    /**
-     * Callback used for asynchronous playback.
-     * Called when a certain amount of data is written ot the device
-     * @param pcm_callback  The callback pointer
-     */
-    static void AlsaCallBack( snd_async_handler_t* pcm_callback);
-
-    /**
-     * Callback used for asynchronous playback.
-     * Write tones buffer to the alsa internal ring buffer.
-     */
-    void playTones( void );
-
-    /**
-     * Open the specified device.
-     * ALSA Library API
-     * @param pcm_p The string name for the playback device
-     * @param pcm_c The string name for the capture device
-     * @param flag  To indicate which kind of stream you want to open
-     *		    SFL_PCM_CAPTURE
-     *		    SFL_PCM_PLAYBACK
-     *		    SFL_PCM_BOTH
-     * @return true if successful
-     *	       false otherwise
      */
-    bool open_device( std::string pcm_p, std::string pcm_c, int flag); 
+    virtual void closePlaybackStream( void ) = 0;
 
-    /**
-     * Copy a data buffer in the internal ring buffer
-     * ALSA Library API
-     * @param buffer The data to be copied
-     * @param length The size of the buffer
-     * @return int The number of frames actually copied
-     */
-    int write( void* buffer, int length);
-    
-    /**
-     * Read data from the internal ring buffer
-     * ALSA Library API
-     * @param buffer  The buffer to stock the read data
-     * @param toCopy  The number of bytes to get
-     * @return int The number of frames actually read
-     */
-    int read( void* buffer, int toCopy);
-    
-    /**
-     * Recover from XRUN state for capture
-     * ALSA Library API
-     */
-    void handle_xrun_capture( void );
-
-    /**
-     * Recover from XRUN state for playback
-     * ALSA Library API
-     */
-    void handle_xrun_playback( void );
-    
     /** Augment coupling, reduce indirect access */
     ManagerImpl* _manager; 
 
-    /**
-     * Handles to manipulate playback stream
-     * ALSA Library API
-     */
-    snd_pcm_t* _PlaybackHandle;
-
-    /**
-     * Handles to manipulate capture stream
-     * ALSA Library API
-     */
-    snd_pcm_t* _CaptureHandle;
-    
-    /**
-     * Alsa parameter - Size of a period in the hardware ring buffer
-     */
-    snd_pcm_uframes_t _periodSize;
-
-    /**
-     * Handle on asynchronous event
-     */
-    snd_async_handler_t *_AsyncHandler;
-    
     /**
      * Urgent ring buffer used for ringtones
      */
     RingBuffer _urgentBuffer;
-    
-    /**
-     * Volume is controlled by the application. Data buffer are modified here to adjust to the right volume selected by the user on the main interface
-     * @param buffer  The buffer to adjust
-     * @param len The number of bytes
-     * @param stream  The stream mode ( PLAYBACK - CAPTURE )
-     */
-    void * adjustVolume( void * , int , int);
 
     /**
      * Determine if both endpoints hang up.
@@ -394,11 +282,6 @@ class AudioLayer {
      */	 		
     unsigned int _frameSize;
 
-    /**
-     * name of the alsa audio plugin used
-     */
-    std::string _audioPlugin;
-
     /**
      * Input channel (mic) should be 1 mono
      */
@@ -409,20 +292,7 @@ class AudioLayer {
      */
     unsigned int _outChannel; 
 
-    /**
-     * Default volume for incoming RTP and Urgent sounds.
-     */
-    unsigned short _defaultVolume; // 100
-
-    /**
-     * Echo testing or not
-     */
-    bool _echoTesting;
-
-    /** Vector to manage all soundcard index - description association of the system */
-    std::vector<HwIDPair> IDSoundCards;
-
-    /** Contains the current error code */
+   /** Contains the current error code */
     int _errorMessage;
 
     ost::Mutex _mutex;
diff --git a/src/audio/audiolayer-pulse.cpp b/src/audio/pulselayer.cpp
similarity index 76%
rename from src/audio/audiolayer-pulse.cpp
rename to src/audio/pulselayer.cpp
index 88e0a8cb6245d2a756c05ce916503e5aca9b2aea..9755ced1e3b8e247b3030444250570962d44d4e2 100644
--- a/src/audio/audiolayer-pulse.cpp
+++ b/src/audio/pulselayer.cpp
@@ -1,7 +1,5 @@
 /*
- *  Copyright (C) 2005 Savoir-Faire Linux inc.
- *  Author: Yan Morin <yan.morin@savoirfairelinux.com>
- *  Author: Jerome Oufella <jerome.oufella@savoirfairelinux.com> 
+ *  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
@@ -19,14 +17,8 @@
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include <stdio.h>
-#include <stdlib.h>
 
-#include <pulse/pulseaudio.h>
-
-#include "audiolayer-pulse.h"
-#include "../global.h"
-#include "../manager.h"
+#include "pulselayer.h"
 
 static pa_context *context = NULL;
 static pa_mainloop_api *mainloop_api = NULL;
@@ -37,21 +29,11 @@ static std::string stream_p = NULL;
 static std::string stream_r = NULL;
 
 
-  PulseLayer::PulseLayer(ManagerImpl* manager)
-  : _urgentRingBuffer(SIZEBUF)
-  , _mainSndRingBuffer(SIZEBUF)
-  , _micRingBuffer(SIZEBUF)
-  , _defaultVolume(PA_VOLUME_NORM)
-  , playback(NULL)  
-    , record(NULL)  
-  , _errorMessage("")
-    , _manager(manager)
+PulseLayer::PulseLayer(ManagerImpl* manager)
+  : AudioLayer( manager )    
 {
-  _sampleRate = 8000;
-
-  _inChannel  = 1; // don't put in stereo
-  _outChannel = 1; // don't put in stereo
-  _echoTesting = false;
+  playback = NULL;   
+  record = NULL; 
 }
 
 // Destructor
@@ -63,6 +45,12 @@ PulseLayer::~PulseLayer (void)
   // pa_stream_disconnect();
 }
 
+void 
+PulseLayer::stream_state_callback( pa_stream* s, void* user_data )
+{
+  _debug("The state of the stream changed\n");
+}
+
 
   void
 PulseLayer::openDevice (int indexIn, int indexOut, int sampleRate, int frameSize) 
@@ -74,7 +62,7 @@ PulseLayer::openDevice (int indexIn, int indexOut, int sampleRate, int frameSize
   sample_spec.format = PA_SAMPLE_S16LE; 
   sample_spec.channels = 1; 
   channel_map.channels = 1; 
-
+  pa_stream_flags_t flag = PA_STREAM_START_CORKED ;  
 
   _debug(" Setting PulseLayer: device     in=%2d, out=%2d\n", indexIn, indexOut);
   _debug("                   : nb channel in=%2d, out=%2d\n", _inChannel, _outChannel);
@@ -101,24 +89,19 @@ PulseLayer::openDevice (int indexIn, int indexOut, int sampleRate, int frameSize
       pa_stream_set_state_callback(playback, stream_state_callback, NULL);
       // Transferring Data - Asynchronous Mode
       pa_stream_set_write_callback(playback, audioCallback, NULL);
-      pa_stream_connect_playback( playback, NULL , NULL , 0 , NULL, NULL );
+      pa_stream_connect_playback( playback, NULL , NULL , flag , NULL, NULL );
 
       break;
     case PA_CONTEXT_TERMINATED:
-      quit(0);
+      _debug("Context terminated\n");
       break;
     case PA_CONTEXT_FAILED:
     default:
-      _debug(" Error : %s" , pa_strerror(pa_context_errno(c)));
-      quit(1);
+      _debug(" Error : %s" , pa_strerror(pa_context_errno(context)));
+      exit(1);
   }
 }
 
-PulseLayer::stream_state_callback( void )
-{
-  _debug("The state of the stream changed\n");
-}
-
   int 
 PulseLayer::putMain(void* buffer, int toCopy)
 {
@@ -154,12 +137,9 @@ PulseLayer::isStreamStopped (void)
 {
 }
 
-void
-PulseLayer::toggleEchoTesting() {
-}
 
-  int 
-PulseLayer::audioCallback ()
+  void 
+PulseLayer::audioCallback ( pa_stream* s, size_t bytes, void* user_data )
 { 
   _debug("Audio callback: New data may be written to the stream\n");
   // pa_stream_write
diff --git a/src/audio/pulselayer.h b/src/audio/pulselayer.h
new file mode 100644
index 0000000000000000000000000000000000000000..9fc0d6a3d5cdb5756f2da029293d17142c224d31
--- /dev/null
+++ b/src/audio/pulselayer.h
@@ -0,0 +1,110 @@
+/*
+ *  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 _PULSE_LAYER_H
+#define _PULSE_LAYER_H
+
+#include "audiolayer.h"
+
+class RingBuffer;
+class ManagerImpl;
+
+class PulseLayer : public AudioLayer {
+  public:
+    PulseLayer(ManagerImpl* manager);
+    ~PulseLayer(void);
+
+    /*
+     * @param indexIn
+     * @param indexOut
+     * @param sampleRate
+     * @param frameSize
+     */
+    void openDevice(int, int, int, int);
+    void startStream(void);
+    void stopStream(void);
+    bool isStreamActive(void);
+    bool isStreamStopped(void);
+
+    /**
+     * Check if the capture is running
+     * @return true if the state of the capture handle equals SND_PCM_STATE_RUNNING
+     *	       false otherwise
+     */
+    bool isCaptureActive( void ) { return true; }
+
+    void flushMain();
+    int putMain(void* buffer, int toCopy);
+    int putUrgent(void* buffer, int toCopy);
+    int canGetMic();
+    int getMic(void *, int);
+    void flushMic();
+
+    static void audioCallback ( pa_stream* s, size_t bytes, void* user_data );
+
+    static void stream_state_callback( pa_stream* s, void* user_data );	
+
+    /**
+     * Scan the sound card available on the system
+     * @param stream To indicate whether we are looking for capture devices or playback devices
+     *		   SFL_PCM_CAPTURE
+     *		   SFL_PCM_PLAYBACK
+     *		   SFL_PCM_BOTH
+     * @return std::vector<std::string> The vector containing the string description of the card
+     */
+    std::vector<std::string> getSoundCardsInfo( int stream ) { 
+      std::vector<std::string> tmp;
+      return tmp; 
+    }
+
+    /**
+     * Check if the given index corresponds to an existing sound card and supports the specified streaming mode
+     * @param card   An index
+     * @param stream  The stream mode
+     *		  SFL_PCM_CAPTURE
+     *		  SFL_PCM_PLAYBACK
+     *		  SFL_PCM_BOTH
+     * @return bool True if it exists and supports the mode
+     *		    false otherwise
+     */
+    bool soundCardIndexExist( int card , int stream ) { return true; }
+    
+    /**
+     * An index is associated with its string description
+     * @param description The string description
+     * @return	int	  Its index
+     */
+    int soundCardGetIndex( std::string description ) { return 0;}
+
+    /**
+     * Get the current audio plugin.
+     * @return std::string  The name of the audio plugin
+     */
+    std::string getAudioPlugin( void ) { return ""; }
+
+  private:
+    void closeStream (void);
+
+    pa_stream* playback;
+    pa_stream* record;
+
+};
+
+#endif // _PULSE_LAYER_H_
+
diff --git a/src/managerimpl.cpp b/src/managerimpl.cpp
index 349413911f64ea168a9608cdff78607e850d14af..6b9f06e12fd79701817c3c86369568c0b9097cf1 100644
--- a/src/managerimpl.cpp
+++ b/src/managerimpl.cpp
@@ -38,6 +38,8 @@
 #include "manager.h"
 #include "account.h"
 #include "audio/audiolayer.h"
+#include "audio/alsalayer.h"
+#include "audio/pulselayer.h"
 #include "audio/tonelist.h"
 
 #include "accountcreator.h" // create new account
@@ -1431,7 +1433,8 @@ ManagerImpl::getCurrentAudioOutputPlugin( void )
 ManagerImpl::initAudioDriver(void) 
 {
   _debugInit("AudioLayer Creation");
-  _audiodriver = new AudioLayer(this);
+  //_audiodriver = new AudioLayer(this);
+  _audiodriver = new AlsaLayer( this );
   if (_audiodriver == 0) {
     _debug("Init audio driver error\n");
   } else {