m_o_streambuf = new wxStreamBuffer(wxStreamBuffer::write);
   if (data)
     m_o_streambuf->SetBufferIO(data, data+len);
-  m_o_streambuf->Fixed(TRUE);
+  m_o_streambuf->Fixed(FALSE);
+  m_o_streambuf->Flushable(FALSE);
 }
 
 wxMemoryOutputStream::~wxMemoryOutputStream()
 
   size_t s_toput = m_buffer_end-m_buffer_pos;
 
   if (s_toput < size && !m_fixed) {
-    m_buffer_start = (char *)realloc(m_buffer_start, m_buffer_size+size);
-    // I round a bit
-    m_buffer_size += size;
-    m_buffer_end = m_buffer_start+m_buffer_size;
+    if (!m_buffer_start)
+      SetBufferIO(size);
+    else {
+      size_t delta = m_buffer_pos-m_buffer_start;
+
+      m_buffer_start = (char *)realloc(m_buffer_start, m_buffer_size+size);
+      m_buffer_pos   = m_buffer_start + delta;
+      // I round a bit
+      m_buffer_size += size;
+      m_buffer_end   = m_buffer_start+m_buffer_size;
+    }
     s_toput = size;
   }
   if (s_toput > size)
   // ------------------
 
   m_stream->m_lasterror = wxStream_NOERROR;
-  if (!m_buffer_size)
+  if (!m_buffer_size && m_fixed)
     return (m_stream->m_lastcount = m_stream->OnSysWrite(buffer, size));
 
   // ------------------
 
     // First case: the buffer to write is larger than the stream buffer,
     //             we split it
-    if (size > buf_left) {
+    // NB: If stream buffer isn't fixed (as for wxMemoryOutputStream),
+    // we always go to the second case.
+    if (size > buf_left && m_fixed) {
       PutToBuffer(buffer, buf_left);
       size -= buf_left;
       buffer = (char *)buffer + buf_left; // ANSI C++ violation.
   if (!temp_b)
     return NULL;
   m_wback = temp_b;
-  m_wbackcur += needed_size;
 
   memmove(m_wback+needed_size, m_wback, old_size);
   
 
 size_t wxInputStream::GetWBack(char *buf, size_t bsize)
 {
-  size_t s_toget = m_wbackcur;
+  size_t s_toget = m_wbacksize-m_wbackcur;
 
   if (!m_wback)
     return 0;
   if (bsize < s_toget)
     s_toget = bsize;
 
-  memcpy(buf, (m_wback+m_wbackcur-bsize), s_toget);
+  memcpy(buf, (m_wback+m_wbackcur), s_toget);
 
-  m_wbackcur -= s_toget;
-  if (m_wbackcur == 0) {
+  m_wbackcur += s_toget;
+  if (m_wbackcur == m_wbacksize) {
     free(m_wback);
     m_wback = (char *)NULL;
     m_wbacksize = 0;
 
-To build Makefile with automake:
-  in the top source directory type:
-    automake utils/wxMMedia2/Makefile
-  in the top build directory type:
-    mkdir -p utils/wxMMedia2
-    CONFIG_FILES="utils/wxMMedia2/Makefile utils/wxMMedia2/lib/Makefile utils/wxMMedia2/sample/Makefile" CONFIG_HEADERS= ./config.status
-
-and then you can run make in utils/wxMMedia2.
 
 {
 }
 
+bool wxSoundAiff::CanRead()
+{
+  wxUint32 signature1, signature2, len;
+
+  if (m_input->Read(&signature1, 4).LastRead() != 4)
+    return FALSE;
+
+  if (wxUINT32_SWAP_ON_BE(signature1) != FORM_SIGNATURE) {
+    m_input->Ungetch(&signature1, 4);
+    return FALSE;
+  }
+
+  m_input->Read(&len, 4);
+  if (m_input->LastRead() != 4) {
+    m_input->Ungetch(&len, m_input->LastRead());
+    m_input->Ungetch(&signature1, 4);
+    return FALSE;
+  }
+
+  if (m_input->Read(&signature2, 4).LastRead() != 4) {
+    m_input->Ungetch(&signature2, m_input->LastRead());
+    m_input->Ungetch(&len, 4);
+    m_input->Ungetch(&signature1, 4);
+    return FALSE;
+  }
+
+  m_input->Ungetch(&signature2, 4);
+  m_input->Ungetch(&len, 4);
+  m_input->Ungetch(&signature1, 4);
+
+  if (
+         wxUINT32_SWAP_ON_BE(signature2) != AIFF_SIGNATURE &&
+         wxUINT32_SWAP_ON_BE(signature2) != AIFC_SIGNATURE)
+    return FALSE;
+
+  return TRUE;
+}
+
 #define FAIL_WITH(condition, err) if (condition) { m_snderror = err; return FALSE; }
 
 bool wxSoundAiff::PrepareToPlay()
 
   wxSoundAiff(wxOutputStream& stream, wxSoundStream& io_sound);
   ~wxSoundAiff();
 
+  bool CanRead();
+
  protected:
   bool PrepareToPlay(); 
   bool PrepareToRecord(unsigned long time);
 
   char *m_cdata[2];
 
  protected:
-  // Do the async stuff.
-  void DoAsyncStuff(int evt);
-
   // Handles event
   virtual void OnSoundEvent(int evt);
 };
 
 {
   m_sndio->SetDuplexMode(duplex);
 }
+
+wxUint32 wxSoundStreamCodec::GetBestSize() const
+{
+  return m_sndio->GetBestSize();
+}
 
   bool StopProduction();
 
   void SetDuplexMode(bool duplex);
+  wxUint32 GetBestSize() const;
 
  protected:
   wxSoundStream *m_sndio;
 
   Convert_U2S_8,
   Convert_U2S_8,
   NULL
+/*,
+  Convert_U2S_S2M_8,
+  Convert_U2S_S2M_8,
+  Convert_U2S_S2M_8,
+  Convert_U2S_S2M_8,
+  Convert_S2M_8 */
 };
 
 wxSoundStreamPcm::ConverterType s_convert_in_8_to_16[] = {
 #define CONVERTER_SWAP_SIGN_SWAP 3
 #define CONVERTER_SWAP_SIGN 4
 #define CONVERTER_SWAP 5
+#define CONVERTER_SIGN_STEREO_MONO 6
+#define CONVERTER_SIGN_SWAP_STEREO_MONO 7
+#define CONVERTER_SWAP_SIGN_SWAP_STEREO_MONO 8
+#define CONVERTER_SWAP_SIGN_STEREO_MONO 9
+#define CONVERTER_SWAP_STEREO_MONO 10
+#define CONVERTER_STEREO_MONO 11
+
+//
+// TODO: Read() and Write() aren't really safe. If you give it a buffer which
+// is not aligned on 8, you may crash (See converter.def).
+//
 
 wxSoundStream& wxSoundStreamPcm::Read(void *buffer, wxUint32 len)
 {
 
 {
   wxSoundFormatPcm pcm_default;
 
-  m_fd = esd_monitor_stream(ESD_MONO | ESD_BITS8 | ESD_RECORD, 22050, 
-                            hostname.mb_str(), MY_ESD_NAME);
+  m_fd = esd_play_stream(ESD_PLAY | ESD_STREAM | ESD_MONO | ESD_BITS8, 22050, 
+//                            hostname.mb_str(), MY_ESD_NAME);
+                            NULL, MY_ESD_NAME);
 
   if (m_fd == -1) {
     m_snderror = wxSOUND_INVDEV;
 
   m_snderror = wxSOUND_NOERR;
   m_esd_stop = TRUE;
+  m_q_filled = TRUE;
 }
 
 wxSoundStreamESD::~wxSoundStreamESD()
   else
     m_snderror = wxSOUND_NOERR;
 
+  m_q_filled = TRUE;
+
   return *this;
 }
 
 
 void wxSoundStreamESD::WakeUpEvt(int evt)
 {
+  m_q_filled = FALSE;
   OnSoundEvent(evt);
 }
 
 
   if (evt == wxSOUND_OUTPUT) {
     flag |= ESD_PLAY | ESD_STREAM;
-    m_fd = esd_play_stream(flag, pcm->GetSampleRate(), m_hostname.mb_str(),
+    m_fd = esd_play_stream(flag, pcm->GetSampleRate(), NULL,
                           MY_ESD_NAME);
   } else {
     flag |= ESD_RECORD | ESD_STREAM;
-    m_fd = esd_record_stream(flag, pcm->GetSampleRate(), m_hostname.mb_str(),
+    m_fd = esd_record_stream(flag, pcm->GetSampleRate(), NULL,
                              MY_ESD_NAME);
   }
 
 #endif
 
   m_esd_stop = FALSE;
+  m_q_filled = FALSE;
 
   return TRUE;
 }
   gdk_input_remove(m_tag);
   esd_close(m_fd);
   m_esd_stop = TRUE;
+  m_q_filled = TRUE;
   return TRUE;
 }
 
 
 
   // You should not call this.
   void WakeUpEvt(int evt);
+
+  bool QueueFilled() const { return m_q_filled; }
  protected:
   int m_fd;
   int m_tag;
   bool m_esd_stop;
   wxString m_hostname;
+  bool m_q_filled;
 
  private:
   void DetectBest(wxSoundFormatPcm *pcm);
 
   return TRUE;
 }
 
+wxUint32 wxSoundRouterStream::GetBestSize() const
+{
+  if (m_router)
+    return m_router->GetBestSize();
+  else
+    return m_sndio->GetBestSize();
+}
+
 bool wxSoundRouterStream::StartProduction(int evt)
 {
   if (!m_router) {
 
 void wxSoundFileStream::OnSoundEvent(int evt)
 {
-  wxUint32 len = m_sndio->GetBestSize();
+  wxUint32 len = m_codec.GetBestSize();
   char *buffer;
 
   buffer = new char[len];
       m_len -= len;
       if (m_len == 0) {
         Stop();
+        delete[] buffer;
         return;
       }
       break;
       len = GetData(buffer, len);
       if (len == 0) {
         Stop();
+        delete[] buffer;
         return;
       }
       m_codec.Write(buffer, len);
 
   bool StartProduction(int evt);
   bool StopProduction();
 
+  wxUint32 GetBestSize() const;
+
  protected:
   wxSoundStream *m_router;
 };
 
   bool SetSoundFormat(const wxSoundFormatBase& format);
 
-  virtual bool CanRead() { return TRUE; }
+  virtual bool CanRead() { return FALSE; }
 
  protected:
   wxSoundRouterStream m_codec; 
 
 
 wxSoundStream& wxSoundStreamG72X::Read(void *buffer, wxUint32 len)
 {
+  wxUint16 *old_linear;
+  register wxUint16 *linear_buffer;
+  register wxUint32 real_len;
+  register wxUint32 countdown = len;
+
+  real_len = (len * 8 / m_n_bits);
+
+  old_linear = linear_buffer = new wxUint16[real_len];
+
+  m_router->Read(linear_buffer, real_len);
+
+  real_len = (wxUint32)(m_router->GetLastAccess() * ((float)m_n_bits / 8));
+  if (!real_len)
+    return *m_router;
+
+  m_io_buffer = (wxUint8 *)buffer; 
+  m_current_b_pos = 0;
+
+  while (countdown != 0) {
+    PutBits(m_coder(*linear_buffer++, AUDIO_ENCODING_LINEAR, m_state));
+    countdown--;
+  }
+  m_lastcount = real_len;
+  m_snderror = m_router->GetError();
+
+  delete[] old_linear;
+
   return *this;
 }
 
   register wxUint32 countdown = len;
   register wxUint32 real_len;
 
-  real_len = (wxUint32)(len * ((float)m_n_bits / 8));
+  // Compute the real length (PCM format) to sendt to the sound card
+  real_len = (len * m_n_bits / 8);
 
+  // Allocate a temporary buffer
   old_linear = linear_buffer = new wxUint16[real_len];
 
   // Bad, we override the const
   m_io_buffer = (wxUint8 *)buffer;
   m_current_b_pos = 0;
 
+  // Decode the datas
   while (countdown != 0) {
     *linear_buffer++ = m_decoder(GetBits(), AUDIO_ENCODING_LINEAR, m_state);
     countdown--;
   }
   m_lastcount = len;
 
+  // Send them to the sound card
   m_router->Write(old_linear, real_len);
 
+  // Destroy the temporary buffer
   delete[] old_linear;
 
   return *m_router;
 
   g72x = (wxSoundFormatG72X *)m_sndformat;
 
+  // Set PCM as the output format of the codec
   pcm.SetSampleRate(g72x->GetSampleRate());
   pcm.SetBPS(16);
   pcm.SetChannels(1);
   pcm.Signed(TRUE);
   pcm.SetOrder(wxBYTE_ORDER);
 
+  // Look for the correct codec to use and set its bit width
   switch (g72x->GetG72XType()) {
   case wxSOUND_G721:
     m_n_bits  = 4;
     break;
   }
 
+  // Let the router finish the work
   m_router->SetSoundFormat(pcm);
 
   return TRUE;
 
   return *m_router;
 }
 
+wxUint32 wxSoundStreamUlaw::GetBestSize() const
+{
+  return m_sndio->GetBestSize() / 2;
+}
+
 bool wxSoundStreamUlaw::SetSoundFormat(const wxSoundFormatBase& format)
 {
   if (format.GetType() != wxSOUND_ULAW) {
 
 
   bool SetSoundFormat(const wxSoundFormatBase& format);
 
+  wxUint32 GetBestSize() const;
+
  protected:
   wxSoundRouterStream *m_router;
 };
 
 #include <wx/stream.h>
 #include <wx/datstrm.h>
 #include <wx/filefn.h>
+#include <wx/mstream.h>
 
 #include "sndbase.h"
 #include "sndcodec.h"
 
 bool wxSoundWave::CanRead()
 {
-  wxUint32 len, signature;
+  wxUint32 len, signature1, signature2;
   m_snderror = wxSOUND_NOERR;
 
-  FAIL_WITH(m_input->Read(&signature, 4).LastRead() != 4, wxSOUND_INVSTRM);
+  FAIL_WITH(m_input->Read(&signature1, 4).LastRead() != 4, wxSOUND_INVSTRM);
 
-  if (wxUINT32_SWAP_ON_BE(signature) != RIFF_SIGNATURE) {
-    m_input->Ungetch(&signature, 4);
+  if (wxUINT32_SWAP_ON_BE(signature1) != RIFF_SIGNATURE) {
+    m_input->Ungetch(&signature1, 4);
     return FALSE;
   }
 
   m_input->Read(&len, 4);
   FAIL_WITH(m_input->LastRead() != 4, wxSOUND_INVSTRM);
 
-  FAIL_WITH(m_input->Read(&signature, 4).LastRead() != 4, wxSOUND_INVSTRM);
-  if (wxUINT32_SWAP_ON_BE(signature) != WAVE_SIGNATURE) {
-    m_input->Ungetch(&signature, 4);
-    return FALSE;
-  }
-
-  m_input->Ungetch("RIFF", 4);
+  FAIL_WITH(m_input->Read(&signature2, 4).LastRead() != 4, wxSOUND_INVSTRM);
+  m_input->Ungetch(&signature2, 4);
   m_input->Ungetch(&len, 4);
-  m_input->Ungetch("WAVE", 4);
+  m_input->Ungetch(&signature1, 4);
+
+  if (wxUINT32_SWAP_ON_BE(signature2) != WAVE_SIGNATURE)
+    return FALSE;
 
   return TRUE;
 }
 
 bool wxSoundWave::PrepareToRecord(unsigned long time)
 {
-#define WRITE_SIGNATURE(sig) \
+#define WRITE_SIGNATURE(s,sig) \
 signature = sig; \
 signature = wxUINT32_SWAP_ON_BE(signature); \
-FAIL_WITH(m_output->Write(&signature, 4).LastWrite() != 4, wxSOUND_INVSTRM);
+FAIL_WITH(s->Write(&signature, 4).LastWrite() != 4, wxSOUND_INVSTRM);
 
-  wxUint32 signature, len;
+  wxUint32 signature;
+  wxMemoryOutputStream fmt_data;
 
   if (!m_output) {
     m_snderror = wxSOUND_INVSTRM;
   }
 
   wxDataOutputStream data(*m_output);
-  data.BigEndianOrdered(FALSE);
+  wxDataOutputStream fmt_d_data(fmt_data);
 
-  len = m_sndformat->GetBytesFromTime(time);
-
-  len += HEADER_SIZE;
+  data.BigEndianOrdered(FALSE);
+  fmt_d_data.BigEndianOrdered(FALSE);
 
-  WRITE_SIGNATURE(RIFF_SIGNATURE);
+  WRITE_SIGNATURE(m_output, RIFF_SIGNATURE);
 
-  data << len;
   FAIL_WITH(m_output->LastWrite() != 4, wxSOUND_INVSTRM);
 
-  WRITE_SIGNATURE(WAVE_SIGNATURE);
+  WRITE_SIGNATURE((&fmt_data), WAVE_SIGNATURE);
 
   {
     wxSoundFormatBase *frmt;
 
-    WRITE_SIGNATURE(FMT_SIGNATURE);
+    WRITE_SIGNATURE((&fmt_data), FMT_SIGNATURE);
 
     switch (m_sndformat->GetType()) {
     case wxSOUND_PCM:
-      frmt = HandleInputPCM(data);
+      frmt = HandleInputPCM(fmt_d_data);
       break;
     case wxSOUND_G72X:
-      frmt = HandleInputG72X(data);
+      frmt = HandleInputG72X(fmt_d_data);
       break;
     default:
       m_snderror = wxSOUND_NOCODEC;
     delete frmt;
   }
 
-  WRITE_SIGNATURE(DATA_SIGNATURE);
+  data << (fmt_data.GetSize() + 8 + m_sndformat->GetBytesFromTime(time));
+
+  {
+    char *out_buf;
+    out_buf = new char[fmt_data.GetSize()];
+
+    fmt_data.CopyTo(out_buf, fmt_data.GetSize());
+    m_output->Write(out_buf, fmt_data.GetSize());
+
+    delete[] out_buf;
+  }
+
+  WRITE_SIGNATURE(m_output, DATA_SIGNATURE);
   data.Write32(m_sndformat->GetBytesFromTime(time));
   return TRUE;
 }
 
   wxSoundStreamWin *m_driver;
 };
 
-#define WXSOUND_MAX_QUEUE 128
+#define WXSOUND_MAX_QUEUE 10
 
 wxSoundStreamWin::wxSoundStreamWin()
 {
                  WPARAM wParam, LPARAM lParam)
 {
   switch (message) {
-  case MM_WOM_DONE: {
-    wxFindSoundFromHandle((WXHWND)hWnd)->NotifyDoneBuffer(wParam);
+  case MM_WOM_DONE:
+    wxFindSoundFromHandle((WXHWND)hWnd)->NotifyDoneBuffer(wParam, wxSOUND_OUTPUT);
+    break;
+  case MM_WIM_DATA:
+    wxFindSoundFromHandle((WXHWND)hWnd)->NotifyDoneBuffer(wParam, wxSOUND_INPUT);
     break;
-  }
   default:
     break;
   }
 
   wformat.wFormatTag      = WAVE_FORMAT_PCM;
   wformat.nChannels       = pcm->GetChannels();
-  wformat.nBlockAlign     = pcm->GetBPS() / 8 * wformat.nChannels;
-  wformat.nAvgBytesPerSec = pcm->GetBytesFromTime(1);
+  wformat.nBlockAlign     = wformat.nChannels * pcm->GetBPS() / 8;
   wformat.nSamplesPerSec  = pcm->GetSampleRate();
+  wformat.nAvgBytesPerSec = wformat.nSamplesPerSec * wformat.nBlockAlign;
   wformat.wBitsPerSample  = pcm->GetBPS();
   wformat.cbSize          = 0;
 
       return FALSE;
     }
 
-    m_input_frag_in   = WXSOUND_MAX_QUEUE-1;
-    m_current_frag_in = 0;
+    m_current_frag_in   = WXSOUND_MAX_QUEUE-1;
+    m_input_frag_in = 0;
 
     m_internal->m_input_enabled = TRUE;
   }
 
-  if (!AllocHeaders(mode)) {
-    CloseDevice();
-    return FALSE;
+  if (mode & wxSOUND_OUTPUT) {
+    if (!AllocHeaders(wxSOUND_OUTPUT)) {
+      CloseDevice();
+      return FALSE;
+    }
   }
+  if (mode & wxSOUND_INPUT) {
+    if (!AllocHeaders(wxSOUND_INPUT)) {
+      CloseDevice();
+      return FALSE;
+    }
+  }
+
   return TRUE;
 }
 
 // -------------------------------------------------------------------------
 void wxSoundStreamWin::CloseDevice()
 {
+  m_internal->m_output_enabled = FALSE;
+  m_internal->m_input_enabled  = FALSE;
+
   if (m_internal->m_output_enabled) {
-    FreeHeaders(wxSOUND_OUTPUT);
     waveOutReset(m_internal->m_devout);
+    FreeHeaders(wxSOUND_OUTPUT);
     waveOutClose(m_internal->m_devout);
   }
 
   if (m_internal->m_input_enabled) {
-    FreeHeaders(wxSOUND_INPUT);
     waveInReset(m_internal->m_devin);
+    FreeHeaders(wxSOUND_INPUT);
     waveInClose(m_internal->m_devin);
   }
-
-  m_internal->m_output_enabled = FALSE;
-  m_internal->m_input_enabled  = FALSE;
 }
 
 // -------------------------------------------------------------------------
 // -------------------------------------------------------------------------
 void wxSoundStreamWin::WaitFor(wxSoundInfoHeader *info)
 {
-  // We begun filling it: we must send it to the Windows queue
-  if (info->m_position != 0) {
-    memset(info->m_data + info->m_position, 0, info->m_size-info->m_position);
-    AddToQueue(info);
-  }
-
   // If the buffer is finished, we return immediately
-  if (!info->m_playing && !info->m_recording)
+  if (!info->m_playing) {
+
+    // We begun filling it: we must send it to the Windows queue
+    if (info->m_position != 0) {
+      memset(info->m_data + info->m_position, 0, info->m_size);
+      AddToQueue(info);
+    }
+
     return;
+  }
 
   // Else, we wait for its termination
   while (info->m_playing || info->m_recording)
 
   if (info->m_mode == wxSOUND_INPUT) {
     // Increment the input fragment pointer
-    m_current_frag_in = (m_current_frag_in + 1) % WXSOUND_MAX_QUEUE;
     result = waveInAddBuffer(m_internal->m_devin,
                              info->m_header, sizeof(WAVEHDR));
     if (result == MMSYSERR_NOERROR)
 {
   wxSoundInfoHeader *header;
 
-  // TODO //
   header = m_headers_rec[m_current_frag_in];
-  WaitFor(header);
+  if (header->m_recording)
+    WaitFor(header);
+
+  m_current_frag_in = (m_current_frag_in + 1) % WXSOUND_MAX_QUEUE;
 
   if (m_current_frag_in == m_input_frag_in)
     m_queue_filled = TRUE;
 // fragment finished. It reinitializes the parameters of the fragment and
 // sends an event to the clients.
 // -------------------------------------------------------------------------
-void wxSoundStreamWin::NotifyDoneBuffer(wxUint32 dev_handle)
+void wxSoundStreamWin::NotifyDoneBuffer(wxUint32 dev_handle, int flag)
 {
   wxSoundInfoHeader *info;
 
-  if (dev_handle == (wxUint32)m_internal->m_devout) {
+  if (flag == wxSOUND_OUTPUT) {
+    if (!m_internal->m_output_enabled)
+      return;
+
     m_output_frag_out = (m_output_frag_out + 1) % WXSOUND_MAX_QUEUE;
     info = m_headers_play[m_output_frag_out];
     ClearHeader(info);
     m_queue_filled = FALSE;
     OnSoundEvent(wxSOUND_OUTPUT);
   } else {
+    if (!m_internal->m_input_enabled)
+      return;
+
     m_input_frag_in = (m_input_frag_in + 1) % WXSOUND_MAX_QUEUE;
+    m_headers_rec[m_input_frag_in]->m_recording = FALSE;
     OnSoundEvent(wxSOUND_INPUT);
     m_queue_filled = FALSE;
   }
     int i;
     for (i=0;i<WXSOUND_MAX_QUEUE;i++)
       AddToQueue(m_headers_rec[i]);
+
+    waveInStart(m_internal->m_devin);
   }
 
   return TRUE;
 // -------------------------------------------------------------------------
 bool wxSoundStreamWin::StopProduction()
 {
+  if (m_internal->m_input_enabled)
+    waveInStop(m_internal->m_devin);
+
   m_production_started = FALSE;
   CloseDevice();
   return TRUE;
 
   bool QueueFilled() const;
 
   // Internal but defined as public
-  void NotifyDoneBuffer(wxUint32 dev_handle);
+  void NotifyDoneBuffer(wxUint32 dev_handle, int flag);
 
  protected:
   wxSoundInternal *m_internal;
 
 #include <wx/wfstream.h>
 #include <wx/frame.h>
 #include "../lib/sndoss.h"
+#include "../lib/sndesd.h"
 #include "../lib/sndwav.h"
 #include "../lib/sndaiff.h"
 
 class MyApp: public wxApp {
  bool OnInit() {
-   wxSoundStreamOSS *oss_dev = new wxSoundStreamOSS();
+//   wxSoundStreamOSS *oss_dev = new wxSoundStreamOSS();
+   wxSoundStreamESD *oss_dev = new wxSoundStreamESD();
    wxFileInputStream *f_input = new wxFileInputStream(argv[1]);
-   wxSoundFileStream *wav_file = new wxSoundAiff(*f_input, *oss_dev);
+   wxSoundFileStream *wav_file;
    wxFrame *frame = new wxFrame(NULL, -1, "My Frame");
    wxSoundFormatPcm pcm;
 
      return FALSE;
    }
 
+   wav_file = new wxSoundWave(*f_input, *oss_dev);
+   if (!wav_file->CanRead()) {
+     wav_file = new wxSoundAiff(*f_input, *oss_dev);
+     if (!wav_file->CanRead())
+       return FALSE;
+   }
+
    wav_file->Play();
    frame->Show(TRUE);
    return TRUE;