]> git.saurik.com Git - wxWidgets.git/commitdiff
Fixed wxMemoryOutputStream (it wasn't working at all)
authorGuilhem Lavaux <lavaux@easynet.fr>
Sat, 6 Nov 1999 17:44:03 +0000 (17:44 +0000)
committerGuilhem Lavaux <lavaux@easynet.fr>
Sat, 6 Nov 1999 17:44:03 +0000 (17:44 +0000)
Fixed wxStreamBuffer to support features of wxMemoryOutputStream
wxMMedia2 updates (various fixes)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@4406 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

20 files changed:
src/common/mstream.cpp
src/common/stream.cpp
utils/wxMMedia2/README
utils/wxMMedia2/lib/sndaiff.cpp
utils/wxMMedia2/lib/sndaiff.h
utils/wxMMedia2/lib/sndbase.h
utils/wxMMedia2/lib/sndcodec.cpp
utils/wxMMedia2/lib/sndcodec.h
utils/wxMMedia2/lib/sndcpcm.cpp
utils/wxMMedia2/lib/sndesd.cpp
utils/wxMMedia2/lib/sndesd.h
utils/wxMMedia2/lib/sndfile.cpp
utils/wxMMedia2/lib/sndfile.h
utils/wxMMedia2/lib/sndg72x.cpp
utils/wxMMedia2/lib/sndulaw.cpp
utils/wxMMedia2/lib/sndulaw.h
utils/wxMMedia2/lib/sndwav.cpp
utils/wxMMedia2/lib/sndwin.cpp
utils/wxMMedia2/lib/sndwin.h
utils/wxMMedia2/sample/test_med2.cpp

index 3e656ba3e8ac25dd8e30339ea29b2a666971c353..aed7cae179c214efb077790d6877b94328bfac0c 100644 (file)
@@ -77,7 +77,8 @@ wxMemoryOutputStream::wxMemoryOutputStream(char *data, size_t len)
   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()
index 31760bb58240c68625ef9f6634236911a16dd185..ed5190b1dc8480c49c0b3b40eac53bd2a987992c 100644 (file)
@@ -165,10 +165,17 @@ void wxStreamBuffer::PutToBuffer(const void *buffer, size_t size)
   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)
@@ -306,7 +313,7 @@ size_t wxStreamBuffer::Write(const void *buffer, size_t 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));
 
   // ------------------
@@ -320,7 +327,9 @@ size_t wxStreamBuffer::Write(const void *buffer, size_t 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.
@@ -493,7 +502,6 @@ char *wxInputStream::AllocSpaceWBack(size_t needed_size)
   if (!temp_b)
     return NULL;
   m_wback = temp_b;
-  m_wbackcur += needed_size;
 
   memmove(m_wback+needed_size, m_wback, old_size);
   
@@ -502,7 +510,7 @@ char *wxInputStream::AllocSpaceWBack(size_t needed_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;
@@ -510,10 +518,10 @@ size_t wxInputStream::GetWBack(char *buf, size_t bsize)
   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;
index 05faac97fe1f357d0f086441e931e5ee9549a015..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 (file)
@@ -1,8 +0,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.
index bfcb149f8c231dba28d3f7f95c1ab022f3a2cc4b..674141f653d4d8430a843d3b23bd827d71ac2465 100644 (file)
@@ -42,6 +42,44 @@ wxSoundAiff::~wxSoundAiff()
 {
 }
 
+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()
index 3f88a1a84eefa47caa129c7a34bbb09f64270e94..bd9750380b9b9a2bd474332daef9fa9bf33ca7b2 100644 (file)
@@ -27,6 +27,8 @@ class wxSoundAiff: public wxSoundFileStream {
   wxSoundAiff(wxOutputStream& stream, wxSoundStream& io_sound);
   ~wxSoundAiff();
 
+  bool CanRead();
+
  protected:
   bool PrepareToPlay(); 
   bool PrepareToRecord(unsigned long time);
index 50e57c7e80d915418f3e2b86f5f71c52eb3e9d70..0f4fa4d8b750b1f8faeffee878d006705b6e8991 100644 (file)
@@ -119,9 +119,6 @@ class wxSoundStream {
   char *m_cdata[2];
 
  protected:
-  // Do the async stuff.
-  void DoAsyncStuff(int evt);
-
   // Handles event
   virtual void OnSoundEvent(int evt);
 };
index a21281b7b528418a83872975b4bb3774d7dfd779..bef4e8326a91fcdb294d648d21d5fee09b257d82 100644 (file)
@@ -36,3 +36,8 @@ void wxSoundStreamCodec::SetDuplexMode(bool duplex)
 {
   m_sndio->SetDuplexMode(duplex);
 }
+
+wxUint32 wxSoundStreamCodec::GetBestSize() const
+{
+  return m_sndio->GetBestSize();
+}
index 209dc91da278ed86c0b488f9baa317a9ee166652..841d24677b3c3808fa3e353cb676f31ffaf81ae0 100644 (file)
@@ -23,6 +23,7 @@ class wxSoundStreamCodec: public wxSoundStream {
   bool StopProduction();
 
   void SetDuplexMode(bool duplex);
+  wxUint32 GetBestSize() const;
 
  protected:
   wxSoundStream *m_sndio;
index a6f0a18d07820e745766d746507d68936f805629..27dba75dfdebf2c0817a8477586c7fd9a32f1d4c 100644 (file)
@@ -59,6 +59,12 @@ wxSoundStreamPcm::ConverterType s_convert_out_8[] = {
   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[] = {
@@ -80,6 +86,17 @@ wxSoundStreamPcm::ConverterType *s_convert_in_8 = s_convert_out_8;
 #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)
 {
index 85314f40c3f55c31a6ff9a80db01a35d0284020f..b31dfd12508a9b173fc1d150be1520f35088d6f1 100644 (file)
@@ -28,8 +28,9 @@ wxSoundStreamESD::wxSoundStreamESD(const wxString& hostname)
 {
   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;
@@ -44,6 +45,7 @@ wxSoundStreamESD::wxSoundStreamESD(const wxString& hostname)
 
   m_snderror = wxSOUND_NOERR;
   m_esd_stop = TRUE;
+  m_q_filled = TRUE;
 }
 
 wxSoundStreamESD::~wxSoundStreamESD()
@@ -77,6 +79,8 @@ wxSoundStream& wxSoundStreamESD::Write(const void *buffer, wxUint32 len)
   else
     m_snderror = wxSOUND_NOERR;
 
+  m_q_filled = TRUE;
+
   return *this;
 }
 
@@ -136,6 +140,7 @@ static void _wxSound_OSS_CBack(gpointer data, int source,
 
 void wxSoundStreamESD::WakeUpEvt(int evt)
 {
+  m_q_filled = FALSE;
   OnSoundEvent(evt);
 }
 
@@ -154,11 +159,11 @@ bool wxSoundStreamESD::StartProduction(int 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);
   }
 
@@ -170,6 +175,7 @@ bool wxSoundStreamESD::StartProduction(int evt)
 #endif
 
   m_esd_stop = FALSE;
+  m_q_filled = FALSE;
 
   return TRUE;
 }
@@ -182,6 +188,7 @@ bool wxSoundStreamESD::StopProduction()
   gdk_input_remove(m_tag);
   esd_close(m_fd);
   m_esd_stop = TRUE;
+  m_q_filled = TRUE;
   return TRUE;
 }
 
index 19e8c95d5ebb83d8a2074b6c09fcb80730b1c828..5484f9dc3740ad5579da0eaffa2df99744a1eeb9 100644 (file)
@@ -37,11 +37,14 @@ class wxSoundStreamESD : public wxSoundStream {
 
   // 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);
index 1234726300e0fec31e4142c34577f8ea97a7cd6f..b1be59501fef8d608016b58fce4ff6ea72f1fd52 100644 (file)
@@ -92,6 +92,14 @@ bool wxSoundRouterStream::SetSoundFormat(const wxSoundFormatBase& format)
   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) {
@@ -268,7 +276,7 @@ bool wxSoundFileStream::StopProduction()
 
 void wxSoundFileStream::OnSoundEvent(int evt)
 {
-  wxUint32 len = m_sndio->GetBestSize();
+  wxUint32 len = m_codec.GetBestSize();
   char *buffer;
 
   buffer = new char[len];
@@ -285,6 +293,7 @@ void wxSoundFileStream::OnSoundEvent(int evt)
       m_len -= len;
       if (m_len == 0) {
         Stop();
+        delete[] buffer;
         return;
       }
       break;
@@ -292,6 +301,7 @@ void wxSoundFileStream::OnSoundEvent(int evt)
       len = GetData(buffer, len);
       if (len == 0) {
         Stop();
+        delete[] buffer;
         return;
       }
       m_codec.Write(buffer, len);
index d710a2f1a64152950cf3703b13e8ba4404105edc..10e77f8610a0baef90e1d0833c35c59fa02b95a5 100644 (file)
@@ -33,6 +33,8 @@ class WXDLLEXPORT wxSoundRouterStream: public wxSoundStreamCodec {
   bool StartProduction(int evt);
   bool StopProduction();
 
+  wxUint32 GetBestSize() const;
+
  protected:
   wxSoundStream *m_router;
 };
@@ -74,7 +76,7 @@ class wxSoundFileStream: public wxSoundStream {
 
   bool SetSoundFormat(const wxSoundFormatBase& format);
 
-  virtual bool CanRead() { return TRUE; }
+  virtual bool CanRead() { return FALSE; }
 
  protected:
   wxSoundRouterStream m_codec; 
index 798c0bc66573ff725321489bd50f02e7c9c54ec3..37d6c4453fd79f8cbdbdb43d281b8a9871d5ceef 100644 (file)
@@ -123,6 +123,33 @@ wxSoundStreamG72X::~wxSoundStreamG72X()
 
 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;
 }
 
@@ -133,22 +160,27 @@ wxSoundStream& wxSoundStreamG72X::Write(const void *buffer, wxUint32 len)
   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;
@@ -168,12 +200,14 @@ bool wxSoundStreamG72X::SetSoundFormat(const wxSoundFormatBase& format)
 
   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;
@@ -192,6 +226,7 @@ bool wxSoundStreamG72X::SetSoundFormat(const wxSoundFormatBase& format)
     break;
   }
 
+  // Let the router finish the work
   m_router->SetSoundFormat(pcm);
 
   return TRUE;
index 620abb7aa11e92b1bd9cd9cf9a4d438406d59a83..5fb3153f9cbe1f4d307c3bdf4b71490620eec8d8 100644 (file)
@@ -109,6 +109,11 @@ wxSoundStream& wxSoundStreamUlaw::Write(const void *buffer, wxUint32 len)
   return *m_router;
 }
 
+wxUint32 wxSoundStreamUlaw::GetBestSize() const
+{
+  return m_sndio->GetBestSize() / 2;
+}
+
 bool wxSoundStreamUlaw::SetSoundFormat(const wxSoundFormatBase& format)
 {
   if (format.GetType() != wxSOUND_ULAW) {
index 67129da0831f77b198a65141478d529120e007be..8b2487a6d94d792dfba06286cc27524a7d91494e 100644 (file)
@@ -54,6 +54,8 @@ class WXDLLEXPORT wxSoundStreamUlaw: public wxSoundStreamCodec {
 
   bool SetSoundFormat(const wxSoundFormatBase& format);
 
+  wxUint32 GetBestSize() const;
+
  protected:
   wxSoundRouterStream *m_router;
 };
index 79c1d20257eb5dce12c18828630303e99b47ddd4..618cbfcab36aa0c2c4d06e31e7be9e397106ffc1 100644 (file)
@@ -14,6 +14,7 @@
 #include <wx/stream.h>
 #include <wx/datstrm.h>
 #include <wx/filefn.h>
+#include <wx/mstream.h>
 
 #include "sndbase.h"
 #include "sndcodec.h"
@@ -51,28 +52,26 @@ wxSoundWave::~wxSoundWave()
 
 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;
 }
@@ -234,12 +233,13 @@ wxSoundFormatBase *wxSoundWave::HandleInputG72X(wxDataOutputStream& data)
 
 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;
@@ -247,30 +247,28 @@ FAIL_WITH(m_output->Write(&signature, 4).LastWrite() != 4, 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;
@@ -287,7 +285,19 @@ FAIL_WITH(m_output->Write(&signature, 4).LastWrite() != 4, wxSOUND_INVSTRM);
     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;
 }
index d89af5f82a84728e3f899faad013cb79c9bd78a7..d4b73f23701ff3c2a999ad651d31d6daab279525 100644 (file)
@@ -51,7 +51,7 @@ struct _wxSoundInfoHeader {
   wxSoundStreamWin *m_driver;
 };
 
-#define WXSOUND_MAX_QUEUE 128
+#define WXSOUND_MAX_QUEUE 10
 
 wxSoundStreamWin::wxSoundStreamWin()
 {
@@ -84,10 +84,12 @@ LRESULT APIENTRY _EXPORT _wxSoundHandlerWndProc(HWND hWnd, UINT message,
                  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;
   }
@@ -155,9 +157,9 @@ bool wxSoundStreamWin::OpenDevice(int mode)
 
   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;
 
@@ -198,16 +200,25 @@ bool wxSoundStreamWin::OpenDevice(int mode)
       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;
 }
 
@@ -217,20 +228,20 @@ bool wxSoundStreamWin::OpenDevice(int mode)
 // -------------------------------------------------------------------------
 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;
 }
 
 // -------------------------------------------------------------------------
@@ -412,15 +423,17 @@ void wxSoundStreamWin::FreeHeaders(int mode)
 // -------------------------------------------------------------------------
 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)
@@ -443,7 +456,6 @@ bool wxSoundStreamWin::AddToQueue(wxSoundInfoHeader *info)
 
   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)
@@ -537,9 +549,11 @@ wxSoundInfoHeader *wxSoundStreamWin::NextFragmentInput()
 {
   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;
@@ -589,18 +603,25 @@ wxSoundStream& wxSoundStreamWin::Read(void *buffer, wxUint32 len)
 // 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;
   }
@@ -634,6 +655,8 @@ bool wxSoundStreamWin::StartProduction(int evt)
     int i;
     for (i=0;i<WXSOUND_MAX_QUEUE;i++)
       AddToQueue(m_headers_rec[i]);
+
+    waveInStart(m_internal->m_devin);
   }
 
   return TRUE;
@@ -643,6 +666,9 @@ bool wxSoundStreamWin::StartProduction(int evt)
 // -------------------------------------------------------------------------
 bool wxSoundStreamWin::StopProduction()
 {
+  if (m_internal->m_input_enabled)
+    waveInStop(m_internal->m_devin);
+
   m_production_started = FALSE;
   CloseDevice();
   return TRUE;
index 549d533eaf025c1522b8aa32fd9be8eba196ada8..e6f979ed7d64d50061dfd72f22a44da7ea32d55d 100644 (file)
@@ -31,7 +31,7 @@ class WXDLLEXPORT wxSoundStreamWin : public wxSoundStream {
   bool QueueFilled() const;
 
   // Internal but defined as public
-  void NotifyDoneBuffer(wxUint32 dev_handle);
+  void NotifyDoneBuffer(wxUint32 dev_handle, int flag);
 
  protected:
   wxSoundInternal *m_internal;
index a6bc06ddaa755dee198a436f43d4ad4e3c744ad3..26b7dfaaf235c703a220ecd3657c0e6372c44ae5 100644 (file)
@@ -9,14 +9,16 @@
 #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;
 
@@ -25,6 +27,13 @@ class MyApp: public wxApp {
      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;