From 0662cd3286d6da0be81ef063633fec13c5cf741b Mon Sep 17 00:00:00 2001
From: Guilhem Lavaux <lavaux@easynet.fr>
Date: Fri, 27 Aug 1999 17:40:40 +0000
Subject: [PATCH] Implemented Read in the PCM converter Changed size_t to
 wxUint32 Added support for G72X WAV format multi-codec handling

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@3508 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 utils/wxMMedia2/lib/Makefile.in   |   2 +-
 utils/wxMMedia2/lib/converter.def |   6 +-
 utils/wxMMedia2/lib/sndaiff.cpp   |   4 +-
 utils/wxMMedia2/lib/sndaiff.h     |   4 +-
 utils/wxMMedia2/lib/sndbase.h     |   8 +-
 utils/wxMMedia2/lib/sndcpcm.cpp   |  67 ++++++--
 utils/wxMMedia2/lib/sndcpcm.h     |   6 +-
 utils/wxMMedia2/lib/sndesd.cpp    |   8 +-
 utils/wxMMedia2/lib/sndesd.h      |   4 +-
 utils/wxMMedia2/lib/sndfile.cpp   |  15 +-
 utils/wxMMedia2/lib/sndfile.h     |  12 +-
 utils/wxMMedia2/lib/sndg72x.cpp   | 268 ++++++++++++++++++++++++++++++
 utils/wxMMedia2/lib/sndg72x.h     |  81 +++++++++
 utils/wxMMedia2/lib/sndoss.cpp    |   8 +-
 utils/wxMMedia2/lib/sndoss.h      |   4 +-
 utils/wxMMedia2/lib/sndulaw.cpp   |   6 +-
 utils/wxMMedia2/lib/sndulaw.h     |   4 +-
 utils/wxMMedia2/lib/sndwav.cpp    |  64 +++++--
 utils/wxMMedia2/lib/sndwav.h      |  13 +-
 utils/wxMMedia2/lib/sndwin.cpp    |   8 +-
 utils/wxMMedia2/lib/sndwin.h      |   4 +-
 21 files changed, 515 insertions(+), 81 deletions(-)
 create mode 100644 utils/wxMMedia2/lib/sndg72x.cpp
 create mode 100644 utils/wxMMedia2/lib/sndg72x.h

diff --git a/utils/wxMMedia2/lib/Makefile.in b/utils/wxMMedia2/lib/Makefile.in
index 310d9b9628..fd733926d8 100644
--- a/utils/wxMMedia2/lib/Makefile.in
+++ b/utils/wxMMedia2/lib/Makefile.in
@@ -17,7 +17,7 @@ VPATH= $(top_srcdir)/utils/wxMMedia2/lib
 LIBTARGET=libwxmmedia2
 
 OBJECTS=sndbase.o sndcodec.o sndpcm.o sndcpcm.o sndulaw.o sndfile.o sndoss.o\
-	sndaiff.o sndwav.o \
+	sndaiff.o sndwav.o sndg72x.o \
 	g711.o g721.o g723_24.o g723_40.o g72x.o \
 	cdbase.o cdunix.o \
 	vidbase.o vidxanm.o
diff --git a/utils/wxMMedia2/lib/converter.def b/utils/wxMMedia2/lib/converter.def
index dc8074b06e..b5279cc03f 100644
--- a/utils/wxMMedia2/lib/converter.def
+++ b/utils/wxMMedia2/lib/converter.def
@@ -1,5 +1,5 @@
 #define DEFINE_CONV_8(name) \
-static void Convert_##name##_8(const char *buf_in, char *buf_out, size_t len) \
+static void Convert_##name##_8(const char *buf_in, char *buf_out, wxUint32 len) \
 {\
   wxUint16 val; \
 \
@@ -10,7 +10,7 @@ static void Convert_##name##_8(const char *buf_in, char *buf_out, size_t len) \
 #if SWAP_BYTES==0
 
 #define DEFINE_CONV_16(name) \
-static void Convert_##name##_16_no(const char *buf_in, char *buf_out, size_t len) \
+static void Convert_##name##_16_no(const char *buf_in, char *buf_out, wxUint32 len) \
 {\
   wxUint16 val; \
 \
@@ -22,7 +22,7 @@ static void Convert_##name##_16_no(const char *buf_in, char *buf_out, size_t len
 #else
 
 #define DEFINE_CONV_16(name) \
-static void Convert_##name##_16_yes(const char *buf_in, char *buf_out, size_t len) \
+static void Convert_##name##_16_yes(const char *buf_in, char *buf_out, wxUint32 len) \
 {\
   wxUint16 val; \
 \
diff --git a/utils/wxMMedia2/lib/sndaiff.cpp b/utils/wxMMedia2/lib/sndaiff.cpp
index 9ea8eb0af9..70a6a6a21c 100644
--- a/utils/wxMMedia2/lib/sndaiff.cpp
+++ b/utils/wxMMedia2/lib/sndaiff.cpp
@@ -126,12 +126,12 @@ bool wxSoundAiff::FinishRecording()
   return FALSE;
 }
 
-size_t wxSoundAiff::GetData(void *buffer, size_t len)
+wxUint32 wxSoundAiff::GetData(void *buffer, wxUint32 len)
 {
   return m_input->Read(buffer, len).LastRead();
 }
 
-size_t wxSoundAiff::PutData(const void *buffer, size_t len)
+wxUint32 wxSoundAiff::PutData(const void *buffer, wxUint32 len)
 {
   return m_output->Write(buffer, len).LastWrite();
 }
diff --git a/utils/wxMMedia2/lib/sndaiff.h b/utils/wxMMedia2/lib/sndaiff.h
index b2ab01ccb5..3f88a1a84e 100644
--- a/utils/wxMMedia2/lib/sndaiff.h
+++ b/utils/wxMMedia2/lib/sndaiff.h
@@ -32,8 +32,8 @@ class wxSoundAiff: public wxSoundFileStream {
   bool PrepareToRecord(unsigned long time);
   bool FinishRecording();
 
-  size_t GetData(void *buffer, size_t len);
-  size_t PutData(const void *buffer, size_t len);
+  wxUint32 GetData(void *buffer, wxUint32 len);
+  wxUint32 PutData(const void *buffer, wxUint32 len);
 };
 
 #endif
diff --git a/utils/wxMMedia2/lib/sndbase.h b/utils/wxMMedia2/lib/sndbase.h
index f7ecfc6fa5..50e57c7e80 100644
--- a/utils/wxMMedia2/lib/sndbase.h
+++ b/utils/wxMMedia2/lib/sndbase.h
@@ -71,9 +71,9 @@ class wxSoundStream {
   virtual ~wxSoundStream();
 
   // Reads "len" bytes from the sound stream.
-  virtual wxSoundStream& Read(void *buffer, size_t len) = 0;
+  virtual wxSoundStream& Read(void *buffer, wxUint32 len) = 0;
   // Writes "len" byte to the sound stream.
-  virtual wxSoundStream& Write(const void *buffer, size_t len) = 0;
+  virtual wxSoundStream& Write(const void *buffer, wxUint32 len) = 0;
   // Returns the best size for IO calls
   virtual wxUint32 GetBestSize() const { return 1024; }
 
@@ -97,7 +97,7 @@ class wxSoundStream {
   virtual void SetDuplexMode(bool duplex) = 0;
 
   wxSoundError GetError() const { return m_snderror; }
-  size_t GetLastAccess() const { return m_lastcount; }
+  wxUint32 GetLastAccess() const { return m_lastcount; }
 
   // This is only useful for device (I think).
   virtual bool QueueFilled() const { return TRUE; }
@@ -110,7 +110,7 @@ class wxSoundStream {
   wxSoundError m_snderror;
 
   // Last access
-  size_t m_lastcount;
+  wxUint32 m_lastcount;
 
   // Event handler
   wxSoundStream *m_handler;
diff --git a/utils/wxMMedia2/lib/sndcpcm.cpp b/utils/wxMMedia2/lib/sndcpcm.cpp
index 8f54607ec1..e18908b231 100644
--- a/utils/wxMMedia2/lib/sndcpcm.cpp
+++ b/utils/wxMMedia2/lib/sndcpcm.cpp
@@ -34,16 +34,16 @@ wxSoundStreamPcm::~wxSoundStreamPcm()
 #include "converter.def"
 #undef SWAP_BYTES
 
-wxSoundStreamPcm::ConverterType s_convert_16_to_8[] = {
+wxSoundStreamPcm::ConverterType s_convert_out_16_to_8[] = {
   Convert_16to8_16_no,
   Convert_16to8_U2S_16_no,
   NULL,
   NULL,
   Convert_16to8_U2S_16_yes,
-  Convert_16to8_16_yes,
+  Convert_16to8_16_yes
 };
 
-wxSoundStreamPcm::ConverterType s_convert_16[] = {
+wxSoundStreamPcm::ConverterType s_convert_out_16[] = {
   NULL,
   Convert_U2S_16_no,
   Convert_U2S_SWAP_16_no,
@@ -52,7 +52,7 @@ wxSoundStreamPcm::ConverterType s_convert_16[] = {
   Convert_SWAP_16_no
 };
 
-wxSoundStreamPcm::ConverterType s_convert_8[] = {
+wxSoundStreamPcm::ConverterType s_convert_out_8[] = {
   NULL,
   Convert_U2S_8,
   Convert_U2S_8,
@@ -61,6 +61,19 @@ wxSoundStreamPcm::ConverterType s_convert_8[] = {
   NULL
 };
 
+wxSoundStreamPcm::ConverterType s_convert_in_8_to_16[] = {
+  Convert_8to16_8,
+  Convert_8to16_U2S_8,
+  Convert_8to16_U2S_SWAP_8,
+  NULL,
+  NULL,
+  Convert_8to16_SWAP_8
+};
+
+wxSoundStreamPcm::ConverterType *s_convert_in_16 = s_convert_out_16;
+
+wxSoundStreamPcm::ConverterType *s_convert_in_8 = s_convert_out_8;
+
 #define CONVERTER 0
 #define CONVERTER_SIGN 1
 #define CONVERTER_SIGN_SWAP 2
@@ -68,8 +81,11 @@ wxSoundStreamPcm::ConverterType s_convert_8[] = {
 #define CONVERTER_SWAP_SIGN 4
 #define CONVERTER_SWAP 5
 
-wxSoundStream& wxSoundStreamPcm::Read(void *buffer, size_t len)
+wxSoundStream& wxSoundStreamPcm::Read(void *buffer, wxUint32 len)
 {
+  wxUint32 real_len;
+  char *tmp_buf;
+
   if (!m_function_in) {
     m_sndio->Read(buffer, len);
     m_lastcount = m_sndio->GetLastAccess();
@@ -77,17 +93,30 @@ wxSoundStream& wxSoundStreamPcm::Read(void *buffer, size_t len)
     return *this;
   }
 
-  // TODO
-  m_sndio->Read(buffer, len);
+  real_len = (m_16_to_8) ? len / 2 : len;
+
+  tmp_buf = new char[real_len];
+
+  m_sndio->Read(tmp_buf, real_len);
   m_lastcount = m_sndio->GetLastAccess();
   m_snderror = m_sndio->GetError();
+  if (m_snderror != wxSOUND_NOERR)
+    return *this;
+
+  m_function_in(tmp_buf, (char *)buffer, m_lastcount);
+
+  delete[] tmp_buf;
+
+  if (m_16_to_8)
+    m_lastcount *= 2;
+
   return *this;
 }
 
-wxSoundStream& wxSoundStreamPcm::Write(const void *buffer, size_t len)
+wxSoundStream& wxSoundStreamPcm::Write(const void *buffer, wxUint32 len)
 {
   char *tmp_buf;
-  size_t len2;
+  wxUint32 len2;
 
   if (!m_function_out)
     return m_sndio->Write(buffer, len);
@@ -109,7 +138,7 @@ bool wxSoundStreamPcm::SetSoundFormat(const wxSoundFormatBase& format)
 {
   wxSoundFormatBase *new_format;
   wxSoundFormatPcm *pcm_format, *pcm_format2;
-  ConverterType *current_table;
+  ConverterType *current_table_out, *current_table_in;
   int index;
   bool change_sign;
 
@@ -132,11 +161,15 @@ bool wxSoundStreamPcm::SetSoundFormat(const wxSoundFormatBase& format)
   m_16_to_8 = FALSE;
   if (pcm_format->GetBPS() == 16 && pcm_format2->GetBPS() == 8) {
     m_16_to_8 = TRUE;
-    current_table = s_convert_16_to_8;
-  } else if (pcm_format->GetBPS() == 16)
-    current_table = s_convert_16;
-  else
-    current_table = s_convert_8;
+    current_table_out = s_convert_out_16_to_8;
+    current_table_in  = s_convert_in_8_to_16;
+  } else if (pcm_format->GetBPS() == 16) {
+    current_table_out = s_convert_out_16;
+    current_table_in  = s_convert_in_16;
+  } else {
+    current_table_out = s_convert_out_8;
+    current_table_in  = s_convert_in_8;
+  }
 
   change_sign = (pcm_format2->Signed() != pcm_format->Signed());
 
@@ -166,8 +199,8 @@ bool wxSoundStreamPcm::SetSoundFormat(const wxSoundFormatBase& format)
   else
     index = CONVERTER;
 
-  m_function_out = current_table[index];
-//  m_function_in = current_table[index+1];
+  m_function_out = current_table_out[index];
+  m_function_in  = current_table_in[index];
 
   m_sndio->SetSoundFormat(*new_format);
   m_sndformat = new_format;
diff --git a/utils/wxMMedia2/lib/sndcpcm.h b/utils/wxMMedia2/lib/sndcpcm.h
index e2a5db1fef..6880d8b7d0 100644
--- a/utils/wxMMedia2/lib/sndcpcm.h
+++ b/utils/wxMMedia2/lib/sndcpcm.h
@@ -21,13 +21,13 @@
 
 class wxSoundStreamPcm: public wxSoundStreamCodec {
  public:
-  typedef void (*ConverterType)(const char *buf_in, char *buf_out, size_t len);
+  typedef void (*ConverterType)(const char *buf_in, char *buf_out, wxUint32 len);
 
   wxSoundStreamPcm(wxSoundStream& sndio);
   ~wxSoundStreamPcm();
 
-  wxSoundStream& Read(void *buffer, size_t len);
-  wxSoundStream& Write(const void *buffer, size_t len);
+  wxSoundStream& Read(void *buffer, wxUint32 len);
+  wxSoundStream& Write(const void *buffer, wxUint32 len);
 
   bool SetSoundFormat(const wxSoundFormatBase& format);
 
diff --git a/utils/wxMMedia2/lib/sndesd.cpp b/utils/wxMMedia2/lib/sndesd.cpp
index 79cb1f10b3..85314f40c3 100644
--- a/utils/wxMMedia2/lib/sndesd.cpp
+++ b/utils/wxMMedia2/lib/sndesd.cpp
@@ -52,11 +52,11 @@ wxSoundStreamESD::~wxSoundStreamESD()
     esd_close(m_fd);
 }
 
-wxSoundStream& wxSoundStreamESD::Read(void *buffer, size_t len)
+wxSoundStream& wxSoundStreamESD::Read(void *buffer, wxUint32 len)
 {
   int ret;
 
-  m_lastcount = (size_t)ret = read(m_fd, buffer, len);
+  m_lastcount = (wxUint32)ret = read(m_fd, buffer, len);
 
   if (ret < 0)
     m_snderror = wxSOUND_IOERR;
@@ -66,11 +66,11 @@ wxSoundStream& wxSoundStreamESD::Read(void *buffer, size_t len)
   return *this;
 }
 
-wxSoundStream& wxSoundStreamESD::Write(const void *buffer, size_t len)
+wxSoundStream& wxSoundStreamESD::Write(const void *buffer, wxUint32 len)
 {
   int ret;
 
-  m_lastcount = (size_t)ret = write(m_fd, buffer, len);
+  m_lastcount = (wxUint32)ret = write(m_fd, buffer, len);
 
   if (ret < 0)
     m_snderror = wxSOUND_IOERR;
diff --git a/utils/wxMMedia2/lib/sndesd.h b/utils/wxMMedia2/lib/sndesd.h
index 56e44f88d2..19e8c95d5e 100644
--- a/utils/wxMMedia2/lib/sndesd.h
+++ b/utils/wxMMedia2/lib/sndesd.h
@@ -25,8 +25,8 @@ class wxSoundStreamESD : public wxSoundStream {
   wxSoundStreamESD(const wxString& hostname = _T("localhost"));
   ~wxSoundStreamESD();
 
-  wxSoundStream& Read(void *buffer, size_t len);
-  wxSoundStream& Write(const void *buffer, size_t len);
+  wxSoundStream& Read(void *buffer, wxUint32 len);
+  wxSoundStream& Write(const void *buffer, wxUint32 len);
 
   bool SetSoundFormat(const wxSoundFormatBase& format);
 
diff --git a/utils/wxMMedia2/lib/sndfile.cpp b/utils/wxMMedia2/lib/sndfile.cpp
index e3dfd1e7c8..1234726300 100644
--- a/utils/wxMMedia2/lib/sndfile.cpp
+++ b/utils/wxMMedia2/lib/sndfile.cpp
@@ -16,6 +16,7 @@
 #include "sndfile.h"
 #include "sndcpcm.h"
 #include "sndulaw.h"
+#include "sndg72x.h"
 
 // --------------------------------------------------------------------------
 // Sound codec router
@@ -33,7 +34,7 @@ wxSoundRouterStream::~wxSoundRouterStream()
     delete m_router;
 }
 
-wxSoundStream& wxSoundRouterStream::Read(void *buffer, size_t len)
+wxSoundStream& wxSoundRouterStream::Read(void *buffer, wxUint32 len)
 {
   if (m_router) {
     m_router->Read(buffer, len);
@@ -47,7 +48,7 @@ wxSoundStream& wxSoundRouterStream::Read(void *buffer, size_t len)
   return *this;
 }
 
-wxSoundStream& wxSoundRouterStream::Write(const void *buffer, size_t len)
+wxSoundStream& wxSoundRouterStream::Write(const void *buffer, wxUint32 len)
 {
   if (m_router) {
     m_router->Write(buffer, len);
@@ -82,6 +83,10 @@ bool wxSoundRouterStream::SetSoundFormat(const wxSoundFormatBase& format)
     m_router = new wxSoundStreamUlaw(*m_sndio);
     m_router->SetSoundFormat(format);
     break;
+  case wxSOUND_G72X:
+    m_router = new wxSoundStreamG72X(*m_sndio);
+    m_router->SetSoundFormat(format);
+    break;
   }
   wxSoundStream::SetSoundFormat(m_router->GetSoundFormat());
   return TRUE;
@@ -230,13 +235,13 @@ bool wxSoundFileStream::Resume()
   return TRUE;
 }
 
-wxSoundStream& wxSoundFileStream::Read(void *buffer, size_t len)
+wxSoundStream& wxSoundFileStream::Read(void *buffer, wxUint32 len)
 {
   m_lastcount = GetData(buffer, len);
   return *this;
 }
 
-wxSoundStream& wxSoundFileStream::Write(const void *buffer, size_t len)
+wxSoundStream& wxSoundFileStream::Write(const void *buffer, wxUint32 len)
 {
   m_lastcount = PutData(buffer, len);
   return *this;
@@ -263,7 +268,7 @@ bool wxSoundFileStream::StopProduction()
 
 void wxSoundFileStream::OnSoundEvent(int evt)
 {
-  size_t len = m_sndio->GetBestSize();
+  wxUint32 len = m_sndio->GetBestSize();
   char *buffer;
 
   buffer = new char[len];
diff --git a/utils/wxMMedia2/lib/sndfile.h b/utils/wxMMedia2/lib/sndfile.h
index f08a1db83a..d710a2f1a6 100644
--- a/utils/wxMMedia2/lib/sndfile.h
+++ b/utils/wxMMedia2/lib/sndfile.h
@@ -25,8 +25,8 @@ class WXDLLEXPORT wxSoundRouterStream: public wxSoundStreamCodec {
   wxSoundRouterStream(wxSoundStream& sndio);
   ~wxSoundRouterStream();
 
-  wxSoundStream& Read(void *buffer, size_t len);
-  wxSoundStream& Write(const void *buffer, size_t len);
+  wxSoundStream& Read(void *buffer, wxUint32 len);
+  wxSoundStream& Write(const void *buffer, wxUint32 len);
 
   bool SetSoundFormat(const wxSoundFormatBase& format);
 
@@ -67,8 +67,8 @@ class wxSoundFileStream: public wxSoundStream {
 
   unsigned long GetLength() const;
 
-  wxSoundStream& Read(void *buffer, size_t len); 
-  wxSoundStream& Write(const void *buffer, size_t len);
+  wxSoundStream& Read(void *buffer, wxUint32 len); 
+  wxSoundStream& Write(const void *buffer, wxUint32 len);
 
   void SetDuplexMode(bool duplex);
 
@@ -90,8 +90,8 @@ class wxSoundFileStream: public wxSoundStream {
   virtual bool PrepareToRecord(unsigned long time) = 0;
   virtual bool FinishRecording() = 0;
 
-  virtual size_t GetData(void *buffer, size_t len) = 0;
-  virtual size_t PutData(const void *buffer, size_t len) = 0;
+  virtual wxUint32 GetData(void *buffer, wxUint32 len) = 0;
+  virtual wxUint32 PutData(const void *buffer, wxUint32 len) = 0;
 
   void OnSoundEvent(int evt);
 };
diff --git a/utils/wxMMedia2/lib/sndg72x.cpp b/utils/wxMMedia2/lib/sndg72x.cpp
new file mode 100644
index 0000000000..a14fbd12e6
--- /dev/null
+++ b/utils/wxMMedia2/lib/sndg72x.cpp
@@ -0,0 +1,268 @@
+// --------------------------------------------------------------------------
+// Name: sndulaw.cpp
+// Purpose:
+// Date: 08/11/1999
+// Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
+// CVSID: $Id$
+// --------------------------------------------------------------------------
+#ifdef __GNUG__
+#pragma implementation "sndulaw.cpp"
+#endif
+
+#include <wx/wxprec.h>
+#include "sndbase.h"
+#include "sndfile.h"
+#include "sndpcm.h"
+#include "sndulaw.h"
+#include "sndg72x.h"
+#include "g72x.h"
+
+// --------------------------------------------------------------------------
+// wxSoundFormatG72X
+// --------------------------------------------------------------------------
+
+wxSoundFormatG72X::wxSoundFormatG72X()
+  : m_srate(22050)
+{
+}
+
+wxSoundFormatG72X::~wxSoundFormatG72X()
+{
+}
+
+void wxSoundFormatG72X::SetSampleRate(wxUint32 srate)
+{
+  m_srate = srate;
+}
+
+wxUint32 wxSoundFormatG72X::GetSampleRate() const
+{
+  return m_srate;
+}
+
+void wxSoundFormatG72X::SetG72XType(wxSoundG72XType type)
+{
+  m_g72x_type = type;
+}
+
+wxSoundFormatBase *wxSoundFormatG72X::Clone() const
+{
+  wxSoundFormatG72X *g72x = new wxSoundFormatG72X();
+
+  g72x->m_srate = m_srate;
+  g72x->m_g72x_type = m_g72x_type;
+  return g72x;
+}
+
+wxUint32 wxSoundFormatG72X::GetTimeFromBytes(wxUint32 bytes) const
+{
+  int n_bits;
+
+  switch (m_g72x_type) {
+  case wxSOUND_G721:
+    n_bits = 4;
+    break;
+  case wxSOUND_G723_24:
+    n_bits = 3;
+    break;
+  case wxSOUND_G723_40:
+    n_bits = 5;
+    break;
+  default:
+    n_bits = 0;
+    break;
+  }
+  return (wxUint32)((bytes / m_srate) * ((float)n_bits / 8));
+}
+
+wxUint32 wxSoundFormatG72X::GetBytesFromTime(wxUint32 time) const
+{
+  int n_bits;
+
+  switch (m_g72x_type) {
+  case wxSOUND_G721:
+    n_bits = 4;
+    break;
+  case wxSOUND_G723_24:
+    n_bits = 3;
+    break;
+  case wxSOUND_G723_40:
+    n_bits = 5;
+    break;
+  default:
+    n_bits = 0;
+  }
+  return (wxUint32)(time * (m_srate * ((float)n_bits / 8)));
+}
+
+bool wxSoundFormatG72X::operator !=(const wxSoundFormatBase& frmt2) const
+{
+  wxSoundFormatG72X *g72x = (wxSoundFormatG72X *)&frmt2;
+
+  if (frmt2.GetType() != wxSOUND_G72X)
+    return TRUE;
+
+  return (g72x->m_srate != m_srate || g72x->m_g72x_type != m_g72x_type);
+}
+
+// --------------------------------------------------------------------------
+// wxSoundStreamG72X
+// --------------------------------------------------------------------------
+wxSoundStreamG72X::wxSoundStreamG72X(wxSoundStream& sndio)
+ : wxSoundStreamCodec(sndio)
+{
+  // PCM converter
+  m_router = new wxSoundRouterStream(sndio);
+  m_state  = new struct g72x_state;
+  g72x_init_state(m_state);
+}
+
+wxSoundStreamG72X::~wxSoundStreamG72X()
+{
+  delete m_router;
+}
+
+wxSoundStream& wxSoundStreamG72X::Read(void *buffer, wxUint32 len)
+{
+  return *this;
+}
+
+wxSoundStream& wxSoundStreamG72X::Write(const void *buffer, wxUint32 len)
+{
+  wxUint16 *old_linear;
+  register wxUint16 *linear_buffer;
+  register wxUint32 countdown = len;
+  register wxUint32 real_len;
+
+  real_len = (wxUint32)(len * ((float)m_n_bits / 8));
+
+  old_linear = linear_buffer = new wxUint16[real_len];
+
+  // Bad, we override the const
+  m_io_buffer = (wxUint8 *)buffer;
+  m_current_b_pos = 0;
+
+  while (countdown != 0) {
+    *linear_buffer++ = m_decoder(GetBits(), AUDIO_ENCODING_LINEAR, m_state);
+    countdown--;
+  }
+  m_lastcount = len;
+
+  m_router->Write(old_linear, real_len);
+
+  delete[] old_linear;
+
+  return *m_router;
+}
+
+bool wxSoundStreamG72X::SetSoundFormat(const wxSoundFormatBase& format)
+{
+  if (format.GetType() != wxSOUND_G72X) {
+    m_snderror = wxSOUND_INVFRMT;
+    return FALSE;
+  }
+
+  wxSoundFormatPcm pcm;
+  wxSoundFormatG72X *g72x;
+
+  wxSoundStreamCodec::SetSoundFormat(format);
+
+  g72x = (wxSoundFormatG72X *)m_sndformat;
+
+  pcm.SetSampleRate(g72x->GetSampleRate());
+  pcm.SetBPS(16);
+  pcm.SetChannels(1);
+  pcm.Signed(TRUE);
+  pcm.SetOrder(wxBYTE_ORDER);
+
+  switch (g72x->GetG72XType()) {
+  case wxSOUND_G721:
+    m_n_bits  = 4;
+    m_coder   = g721_encoder;
+    m_decoder = g721_decoder;
+    break;
+  case wxSOUND_G723_24:
+    m_n_bits  = 3;
+    m_coder   = g723_24_encoder;
+    m_decoder = g723_24_decoder;
+    break;
+  case wxSOUND_G723_40:
+    m_n_bits  = 5;
+    m_coder   = g723_40_encoder;
+    m_decoder = g723_40_decoder;
+    break;
+  }
+
+  m_router->SetSoundFormat(pcm);
+
+  return TRUE;
+}
+
+#define BYTE_SIZE 8
+
+wxUint8 wxSoundStreamG72X::GetBits()
+{
+  register wxUint8 bits;
+
+  if (m_current_b_pos < m_n_bits) {
+    register wxUint8 b_left;
+
+    // TRANSLATE the mask
+    m_current_mask >>= m_current_b_pos;
+
+    // GET the last bits: 0001..1
+    bits = (m_current_byte & m_current_mask) << (m_n_bits - m_current_b_pos);
+    
+    // GEN: 1. n times .1000
+    b_left = BYTE_SIZE-m_n_bits;
+    m_current_mask = ((1 << m_n_bits) - 1) << b_left;
+ 
+    // GET the next byte
+    m_current_byte = *m_io_buffer++;
+ 
+    register wxUint8 tmp_mask;
+
+    // COMPUTE a new temporary mask to get the last bits
+    b_left = m_n_bits - b_left;
+    tmp_mask = (1 << b_left) - 1;
+    // TRANSLATE the old mask to get ready for the next time
+    m_current_mask >>= b_left;
+
+    // COMPUTE the new bit position
+    b_left = BYTE_SIZE - b_left; 
+    m_current_b_pos = b_left;
+    tmp_mask <<= b_left;
+ 
+    // GET the last bits
+    bits |= (m_current_byte & tmp_mask) >> b_left;
+  } else {
+    m_current_mask >>= m_n_bits;
+    m_current_b_pos -= m_n_bits;
+    bits = (m_current_byte & m_current_mask) >> m_current_b_pos;
+  }
+  return bits;
+}
+
+void wxSoundStreamG72X::PutBits(wxUint8 bits)
+{
+  if (m_current_b_pos < m_n_bits) {
+    register wxUint8 tmp_mask;
+    register wxUint8 diff;
+
+    diff = m_n_bits - m_current_b_pos;
+    // Pack bits and put the byte in the buffer
+    m_current_byte |= bits >> diff;
+    *m_io_buffer++ = m_current_byte;
+
+    // Gen a mask
+    tmp_mask = ~((1 << diff) - 1);
+
+    m_current_b_pos = BYTE_SIZE - (m_n_bits - m_current_b_pos);
+
+    m_current_byte = (bits & (tmp_mask)) << m_current_b_pos;
+  } else {
+    m_current_b_pos -= m_n_bits;
+    bits           <<= m_current_b_pos;
+    m_current_byte |= bits;
+  }
+}
diff --git a/utils/wxMMedia2/lib/sndg72x.h b/utils/wxMMedia2/lib/sndg72x.h
new file mode 100644
index 0000000000..53d6b8bd5c
--- /dev/null
+++ b/utils/wxMMedia2/lib/sndg72x.h
@@ -0,0 +1,81 @@
+// --------------------------------------------------------------------------
+// Name: sndg.h
+// Purpose:
+// Date: 08/11/1999
+// Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
+// CVSID: $Id$
+// --------------------------------------------------------------------------
+#ifndef _WX_SNDG72X_H
+#define _WX_SNDG72X_H
+
+#ifdef __GNUG__
+#pragma interface "sndg72x.h"
+#endif
+
+#include <stddef.h>
+#include "sndcodec.h"
+#include "sndbase.h"
+
+typedef enum {
+  wxSOUND_G721,
+  wxSOUND_G723_24,
+  wxSOUND_G723_40
+} wxSoundG72XType;
+
+//
+// G72X format
+//
+class WXDLLEXPORT wxSoundFormatG72X: public wxSoundFormatBase {
+ public:
+  wxSoundFormatG72X();
+  ~wxSoundFormatG72X();
+
+  void SetG72XType(wxSoundG72XType type);
+  wxSoundG72XType GetG72XType() const { return m_g72x_type; }
+
+  void SetSampleRate(wxUint32 srate);
+  wxUint32 GetSampleRate() const;
+
+  wxSoundFormatType GetType() const { return wxSOUND_G72X; }
+  wxSoundFormatBase *Clone() const;
+
+  wxUint32 GetTimeFromBytes(wxUint32 bytes) const;
+  wxUint32 GetBytesFromTime(wxUint32 time) const;
+
+  bool operator !=(const wxSoundFormatBase& frmt2) const;
+
+ protected:
+  wxUint32 m_srate;
+  wxSoundG72XType m_g72x_type;
+};
+
+//
+// ULAW converter class
+//
+
+class WXDLLEXPORT wxSoundRouterStream;
+class WXDLLEXPORT wxSoundStreamG72X: public wxSoundStreamCodec {
+ public:
+  wxSoundStreamG72X(wxSoundStream& sndio);
+  ~wxSoundStreamG72X();
+
+  wxSoundStream& Read(void *buffer, wxUint32 len);
+  wxSoundStream& Write(const void *buffer, wxUint32 len);
+
+  bool SetSoundFormat(const wxSoundFormatBase& format);
+
+ protected:
+  wxSoundRouterStream *m_router;
+  wxUint8 m_n_bits, m_current_mask, m_current_b_pos, m_current_byte;
+  wxUint8 *m_io_buffer;
+  struct g72x_state *m_state;
+
+  int (*m_coder)(int code, int in_code, struct g72x_state *state);
+  int (*m_decoder)(int code, int out_code, struct g72x_state *state);
+
+ protected:
+  void PutBits(wxUint8 bits);
+  wxUint8 GetBits();
+};
+
+#endif
diff --git a/utils/wxMMedia2/lib/sndoss.cpp b/utils/wxMMedia2/lib/sndoss.cpp
index e794b20032..60fb82a2bd 100644
--- a/utils/wxMMedia2/lib/sndoss.cpp
+++ b/utils/wxMMedia2/lib/sndoss.cpp
@@ -60,11 +60,11 @@ wxUint32 wxSoundStreamOSS::GetBestSize() const
   return m_bufsize;
 }
 
-wxSoundStream& wxSoundStreamOSS::Read(void *buffer, size_t len)
+wxSoundStream& wxSoundStreamOSS::Read(void *buffer, wxUint32 len)
 {
   int ret;
 
-  m_lastcount = (size_t)ret = read(m_fd, buffer, len);
+  m_lastcount = (wxUint32)ret = read(m_fd, buffer, len);
   m_q_filled  = TRUE;
 
   if (ret < 0)
@@ -75,11 +75,11 @@ wxSoundStream& wxSoundStreamOSS::Read(void *buffer, size_t len)
   return *this;
 }
 
-wxSoundStream& wxSoundStreamOSS::Write(const void *buffer, size_t len)
+wxSoundStream& wxSoundStreamOSS::Write(const void *buffer, wxUint32 len)
 {
   int ret;
 
-  m_lastcount = (size_t)ret = write(m_fd, buffer, len);
+  m_lastcount = (wxUint32)ret = write(m_fd, buffer, len);
   m_q_filled  = TRUE;
 
   if (ret < 0)
diff --git a/utils/wxMMedia2/lib/sndoss.h b/utils/wxMMedia2/lib/sndoss.h
index 84fc3f314e..4d0e79e08b 100644
--- a/utils/wxMMedia2/lib/sndoss.h
+++ b/utils/wxMMedia2/lib/sndoss.h
@@ -25,8 +25,8 @@ class wxSoundStreamOSS : public wxSoundStream {
   wxSoundStreamOSS(const wxString& dev_name = _T("/dev/dsp"));
   ~wxSoundStreamOSS();
 
-  wxSoundStream& Read(void *buffer, size_t len);
-  wxSoundStream& Write(const void *buffer, size_t len);
+  wxSoundStream& Read(void *buffer, wxUint32 len);
+  wxSoundStream& Write(const void *buffer, wxUint32 len);
   wxUint32 GetBestSize() const;
 
   bool SetSoundFormat(const wxSoundFormatBase& format);
diff --git a/utils/wxMMedia2/lib/sndulaw.cpp b/utils/wxMMedia2/lib/sndulaw.cpp
index 3142d173c5..620abb7aa1 100644
--- a/utils/wxMMedia2/lib/sndulaw.cpp
+++ b/utils/wxMMedia2/lib/sndulaw.cpp
@@ -82,17 +82,17 @@ wxSoundStreamUlaw::~wxSoundStreamUlaw()
   delete m_router;
 }
 
-wxSoundStream& wxSoundStreamUlaw::Read(void *buffer, size_t len)
+wxSoundStream& wxSoundStreamUlaw::Read(void *buffer, wxUint32 len)
 {
   return *this;
 }
 
-wxSoundStream& wxSoundStreamUlaw::Write(const void *buffer, size_t len)
+wxSoundStream& wxSoundStreamUlaw::Write(const void *buffer, wxUint32 len)
 {
   wxUint16 *old_linear;
   register wxUint16 *linear_buffer;
   register const wxUint8 *ulaw_buffer;
-  register size_t countdown = len;
+  register wxUint32 countdown = len;
 
   old_linear = linear_buffer = new wxUint16[len*2];
   ulaw_buffer = (const wxUint8 *)buffer;
diff --git a/utils/wxMMedia2/lib/sndulaw.h b/utils/wxMMedia2/lib/sndulaw.h
index ef893d2e85..67129da083 100644
--- a/utils/wxMMedia2/lib/sndulaw.h
+++ b/utils/wxMMedia2/lib/sndulaw.h
@@ -49,8 +49,8 @@ class WXDLLEXPORT wxSoundStreamUlaw: public wxSoundStreamCodec {
   wxSoundStreamUlaw(wxSoundStream& sndio);
   ~wxSoundStreamUlaw();
 
-  wxSoundStream& Read(void *buffer, size_t len);
-  wxSoundStream& Write(const void *buffer, size_t len);
+  wxSoundStream& Read(void *buffer, wxUint32 len);
+  wxSoundStream& Write(const void *buffer, wxUint32 len);
 
   bool SetSoundFormat(const wxSoundFormatBase& format);
 
diff --git a/utils/wxMMedia2/lib/sndwav.cpp b/utils/wxMMedia2/lib/sndwav.cpp
index f0d3f66a29..b4fa4faaa0 100644
--- a/utils/wxMMedia2/lib/sndwav.cpp
+++ b/utils/wxMMedia2/lib/sndwav.cpp
@@ -19,6 +19,7 @@
 #include "sndcodec.h"
 #include "sndfile.h"
 #include "sndpcm.h"
+#include "sndg72x.h"
 #include "sndwav.h"
 
 #define BUILD_SIGNATURE(a,b,c,d) (((wxUint32)a) | (((wxUint32)b) << 8) | (((wxUint32)c) << 16)  | (((wxUint32)d) << 24)) 
@@ -76,6 +77,39 @@ bool wxSoundWave::CanRead()
   return TRUE;
 }
 
+bool wxSoundWave::HandlePCM(wxDataInputStream& data, wxUint16 channels, 
+                            wxUint32 sample_fq, wxUint32 byte_p_sec,
+                            wxUint16 byte_p_spl, wxUint16 bits_p_spl)
+{
+  wxSoundFormatPcm sndformat;
+
+  sndformat.SetSampleRate(sample_fq);
+  sndformat.SetBPS(bits_p_spl);
+  sndformat.SetChannels(channels);
+  sndformat.Signed(TRUE);
+  sndformat.SetOrder(wxLITTLE_ENDIAN);
+
+  if (!SetSoundFormat(sndformat))
+    return FALSE;
+
+  return TRUE;
+}
+
+bool wxSoundWave::HandleG721(wxDataInputStream& data, wxUint16 channels,
+                             wxUint32 sample_fq, wxUint32 byte_p_sec,
+                             wxUint16 byte_p_spl, wxUint16 bits_p_spl)
+{
+  wxSoundFormatG72X sndformat;
+
+  sndformat.SetSampleRate(sample_fq);
+  sndformat.SetG72XType(wxSOUND_G721);
+ 
+  if (!SetSoundFormat(sndformat))
+    return FALSE;
+
+  return TRUE;
+}
+
 bool wxSoundWave::PrepareToPlay()
 {
   wxUint32 signature, len;
@@ -112,21 +146,25 @@ bool wxSoundWave::PrepareToPlay()
     case FMT_SIGNATURE: {  // "fmt "
       wxUint16 format, channels, byte_p_spl, bits_p_spl;
       wxUint32 sample_fq, byte_p_sec;
-      wxSoundFormatPcm sndformat;
 
       data >> format >> channels >> sample_fq 
            >> byte_p_sec >> byte_p_spl >> bits_p_spl;
-      FAIL_WITH(format != 1, wxSOUND_NOCODEC);
-      
-      sndformat.SetSampleRate(sample_fq);
-      sndformat.SetBPS(bits_p_spl);
-      sndformat.SetChannels(channels);
-      sndformat.Signed(TRUE);
-      sndformat.SetOrder(wxLITTLE_ENDIAN);
-
-      if (!SetSoundFormat(sndformat))
+
+      switch (format) {
+      case 0x01:
+        if (!HandlePCM(data, channels, sample_fq,
+                       byte_p_sec, byte_p_spl, bits_p_spl))
+          return FALSE;
+        break;
+      case 0x40:
+        if (!HandleG721(data, channels, sample_fq,
+                        byte_p_sec, byte_p_spl, bits_p_spl))
+          return FALSE;
+        break;
+      default: 
+        m_snderror = wxSOUND_NOCODEC;
         return FALSE;
-      m_input->SeekI(len-16, wxFromCurrent);
+      }
       break;
     }
     case DATA_SIGNATURE: // "data"
@@ -212,12 +250,12 @@ bool wxSoundWave::FinishRecording()
   return TRUE;
 }
 
-size_t wxSoundWave::GetData(void *buffer, size_t len)
+wxUint32 wxSoundWave::GetData(void *buffer, wxUint32 len)
 {
   return m_input->Read(buffer, len).LastRead();
 }
 
-size_t wxSoundWave::PutData(const void *buffer, size_t len)
+wxUint32 wxSoundWave::PutData(const void *buffer, wxUint32 len)
 {
   return m_output->Write(buffer, len).LastWrite();
 }
diff --git a/utils/wxMMedia2/lib/sndwav.h b/utils/wxMMedia2/lib/sndwav.h
index 32b66737e0..295b4d86a7 100644
--- a/utils/wxMMedia2/lib/sndwav.h
+++ b/utils/wxMMedia2/lib/sndwav.h
@@ -12,7 +12,9 @@
 #pragma interface "sndwav.h"
 #endif
 
+#include <wx/defs.h>
 #include <wx/stream.h>
+#include <wx/datstrm.h>
 #include "sndbase.h"
 #include "sndcodec.h"
 #include "sndfile.h"
@@ -34,8 +36,15 @@ class wxSoundWave: public wxSoundFileStream {
   bool PrepareToRecord(unsigned long time);
   bool FinishRecording();
 
-  size_t GetData(void *buffer, size_t len);
-  size_t PutData(const void *buffer, size_t len);
+  wxUint32 GetData(void *buffer, wxUint32 len);
+  wxUint32 PutData(const void *buffer, wxUint32 len);
+
+  bool HandlePCM(wxDataInputStream& data, wxUint16 channels,
+                 wxUint32 sample_fq, wxUint32 byte_p_sec,
+                 wxUint16 byte_p_spl, wxUint16 bits_p_spl);
+  bool HandleG721(wxDataInputStream& data, wxUint16 channels,
+                  wxUint32 sample_fq, wxUint32 byte_p_sec,
+                  wxUint16 byte_p_spl, wxUint16 bits_p_spl);
 };
 
 #endif
diff --git a/utils/wxMMedia2/lib/sndwin.cpp b/utils/wxMMedia2/lib/sndwin.cpp
index 2b892094b6..b4527bd17f 100644
--- a/utils/wxMMedia2/lib/sndwin.cpp
+++ b/utils/wxMMedia2/lib/sndwin.cpp
@@ -379,7 +379,7 @@ wxSoundInfoHeader *wxSoundStreamWin::NextFragmentOutput()
   return m_headers_play[m_current_frag_out];
 }
 
-wxSoundStream& wxSoundStreamWin::Write(const void *buffer, size_t len)
+wxSoundStream& wxSoundStreamWin::Write(const void *buffer, wxUint32 len)
 {
   m_lastcount = 0;
   if (!m_internal->m_output_enabled)
@@ -387,7 +387,7 @@ wxSoundStream& wxSoundStreamWin::Write(const void *buffer, size_t len)
 
   while (len > 0) {
     wxSoundInfoHeader *header;
-    size_t to_copy;
+    wxUint32 to_copy;
 
     header              = NextFragmentOutput();
 
@@ -423,10 +423,10 @@ wxSoundInfoHeader *wxSoundStreamWin::NextFragmentInput()
   return header;
 }
 
-wxSoundStream& wxSoundStreamWin::Read(void *buffer, size_t len)
+wxSoundStream& wxSoundStreamWin::Read(void *buffer, wxUint32 len)
 {
   wxSoundInfoHeader *header;
-  size_t to_copy;
+  wxUint32 to_copy;
 
   m_lastcount = 0;
   if (!m_internal->m_input_enabled)
diff --git a/utils/wxMMedia2/lib/sndwin.h b/utils/wxMMedia2/lib/sndwin.h
index 8d9a89bbde..549d533eaf 100644
--- a/utils/wxMMedia2/lib/sndwin.h
+++ b/utils/wxMMedia2/lib/sndwin.h
@@ -19,8 +19,8 @@ class WXDLLEXPORT wxSoundStreamWin : public wxSoundStream {
   wxSoundStreamWin();
   ~wxSoundStreamWin();
 
-  wxSoundStream& Write(const void *buffer, size_t len);
-  wxSoundStream& Read(void *buffer, size_t len); 
+  wxSoundStream& Write(const void *buffer, wxUint32 len);
+  wxSoundStream& Read(void *buffer, wxUint32 len); 
 
   bool SetSoundFormat(wxSoundFormatBase& base);
   void SetDuplexMode(bool on) {}
-- 
2.45.2

