]> git.saurik.com Git - wxWidgets.git/commitdiff
Inserted "stdio catch" in wxExecute. The activation is controlled by wxProcess.
authorGuilhem Lavaux <lavaux@easynet.fr>
Sun, 27 Feb 2000 10:44:49 +0000 (10:44 +0000)
committerGuilhem Lavaux <lavaux@easynet.fr>
Sun, 27 Feb 2000 10:44:49 +0000 (10:44 +0000)
Completed some TODO in wxMMedia (wxSoundUlaw, ...)
Reworked the PCM converted: it should be simpler to add converters now and it is
cleaner.
Implemented status information in wxVideoWindows but it doesn't work on my
Win98SE (UNSUPPORTED_FUNCTION)
Changed *ERR into *ERROR
Added a TODO: we must detect the best format in wxSoundWindows

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

23 files changed:
include/wx/process.h
src/common/process.cpp
src/msw/utilsexc.cpp
src/unix/utilsunx.cpp
utils/wxMMedia2/board/mmbman.cpp
utils/wxMMedia2/board/mmboard.cpp
utils/wxMMedia2/lib/cdbase.cpp
utils/wxMMedia2/lib/converter.def
utils/wxMMedia2/lib/sndaiff.cpp
utils/wxMMedia2/lib/sndbase.cpp
utils/wxMMedia2/lib/sndbase.h
utils/wxMMedia2/lib/sndcpcm.cpp
utils/wxMMedia2/lib/sndcpcm.h
utils/wxMMedia2/lib/sndesd.cpp
utils/wxMMedia2/lib/sndfile.cpp
utils/wxMMedia2/lib/sndg72x.cpp
utils/wxMMedia2/lib/sndoss.cpp
utils/wxMMedia2/lib/sndulaw.cpp
utils/wxMMedia2/lib/sndulaw.h
utils/wxMMedia2/lib/sndwav.cpp
utils/wxMMedia2/lib/sndwin.cpp
utils/wxMMedia2/lib/vidwin.cpp
utils/wxMMedia2/lib/vidwin.h

index b612306a661a2c313f557da3c16fe4547860af19..19ae35c1f65b9b88dbf5c4fce978d6c338b55e58 100644 (file)
@@ -19,6 +19,7 @@
 #include "wx/defs.h"
 #include "wx/object.h"
 #include "wx/event.h"
+#include "wx/stream.h"
 
 // Process Event handling
 class WXDLLEXPORT wxProcessEvent : public wxEvent
@@ -51,7 +52,8 @@ class WXDLLEXPORT wxProcess : public wxEvtHandler
 DECLARE_DYNAMIC_CLASS(wxProcess)
 
 public:
-    wxProcess(wxEvtHandler *parent = (wxEvtHandler *) NULL, int id = -1);
+    wxProcess(wxEvtHandler *parent = (wxEvtHandler *) NULL, bool needPipe = FALSE, int id = -1);
+    ~wxProcess();
 
     virtual void OnTerminate(int pid, int status);
 
@@ -59,8 +61,21 @@ public:
     // before the process it started terminates
     void Detach();
 
+    // Pipe handling
+    wxInputStream *GetInputStream() const;
+    wxOutputStream *GetOutputStream() const;
+
+    // These functions should not be called by the usual user. They are only
+    // intended to be used by wxExecute.
+    // Install pipes
+    void SetPipeStreams(wxInputStream *in_stream, wxOutputStream *out_stream);
+    bool NeedPipe() const;
+
 protected:
     int m_id;
+    bool m_needPipe;
+    wxInputStream *m_in_stream;
+    wxOutputStream *m_out_stream;
 };
 
 typedef void (wxObject::*wxProcessEventFunction)(wxProcessEvent&);
index 6440993d20363b7011338c325bab4888058e00ec..e573fe8e0d995ba5682845f407c927d3a27cda94 100644 (file)
 IMPLEMENT_DYNAMIC_CLASS(wxProcess, wxEvtHandler)
 IMPLEMENT_DYNAMIC_CLASS(wxProcessEvent, wxEvent)
 
-wxProcess::wxProcess(wxEvtHandler *parent, int id)
+wxProcess::wxProcess(wxEvtHandler *parent, bool needPipe, int id)
 {
     if (parent)
         SetNextHandler(parent);
 
-    m_id = id;
+    m_id         = id;
+    m_needPipe   = needPipe;
+    m_in_stream  = NULL;
+    m_out_stream = NULL;
+}
+
+wxProcess::~wxProcess()
+{
+    if (m_in_stream)
+      delete m_in_stream;
+    if (m_out_stream)
+      delete m_out_stream;
 }
 
 void wxProcess::OnTerminate(int pid, int status)
@@ -51,3 +62,24 @@ void wxProcess::Detach()
 {
     SetNextHandler(NULL);
 }
+
+void wxProcess::SetPipeStreams(wxInputStream *in_stream, wxOutputStream *out_stream)
+{
+    m_in_stream  = in_stream;
+    m_out_stream = out_stream;
+}
+
+wxInputStream *wxProcess::GetInputStream() const
+{
+    return m_in_stream;
+}
+
+wxOutputStream *wxProcess::GetOutputStream() const
+{
+    return m_out_stream;
+}
+
+bool wxProcess::NeedPipe() const
+{
+    return m_needPipe;
+}
index 12a78c001a5370194cfcd84e6cbc42de2f9c35df..411eaeaf44c33cfcc8d4ee1229b8b1561502fffb 100644 (file)
@@ -37,6 +37,7 @@
 #include "wx/log.h"
 
 #ifdef __WIN32__
+    #include "wx/stream.h"
     #include "wx/process.h"
 #endif
 
@@ -120,6 +121,94 @@ public:
     bool       state;         // set to FALSE when the process finishes
 };
 
+
+#ifdef __WIN32__
+// ----------------------------------------------------------------------------
+// wxPipeStreams
+// ----------------------------------------------------------------------------
+
+class wxPipeInputStream: public wxInputStream {
+public:
+    wxPipeInputStream(HANDLE hInput);
+    ~wxPipeInputStream();
+
+protected:
+    size_t OnSysRead(void *buffer, size_t len);
+
+protected:
+    HANDLE m_hInput;
+};
+
+class wxPipeOutputStream: public wxOutputStream {
+public:
+    wxPipeOutputStream(HANDLE hOutput);
+    ~wxPipeOutputStream();
+
+protected:
+    size_t OnSysWrite(const void *buffer, size_t len);
+
+protected:
+    HANDLE m_hOutput;
+};
+
+// ==================
+// wxPipeInputStream
+// ==================
+
+wxPipeInputStream::wxPipeInputStream(HANDLE hInput)
+{
+    m_hInput = hInput;
+}   
+
+wxPipeInputStream::~wxPipeInputStream()
+{
+    ::CloseHandle(m_hInput);
+}
+
+size_t wxPipeInputStream::OnSysRead(void *buffer, size_t len)
+{
+    DWORD bytesRead;
+
+    m_lasterror = wxSTREAM_NOERROR;
+    if (! ::ReadFile(m_hInput, buffer, len, &bytesRead, NULL) ) {
+        if (GetLastError() == ERROR_BROKEN_PIPE)
+            m_lasterror = wxSTREAM_EOF;
+        else
+            m_lasterror = wxSTREAM_READ_ERROR;
+    }
+    return bytesRead;
+}
+
+// ==================
+// wxPipeOutputStream
+// ==================
+
+wxPipeOutputStream::wxPipeOutputStream(HANDLE hOutput)
+{
+    m_hOutput = hOutput;
+}   
+
+wxPipeOutputStream::~wxPipeOutputStream()
+{
+    ::CloseHandle(m_hOutput);
+}
+
+size_t wxPipeOutputStream::OnSysWrite(const void *buffer, size_t len)
+{
+    DWORD bytesRead;
+
+    m_lasterror = wxSTREAM_NOERROR;
+    if (! ::WriteFile(m_hOutput, buffer, len, &bytesRead, NULL) ) {
+        if (GetLastError() == ERROR_BROKEN_PIPE)
+            m_lasterror = wxSTREAM_EOF;
+        else
+            m_lasterror = wxSTREAM_READ_ERROR;
+    }
+    return bytesRead;
+}
+
+#endif // __WIN32__
+
 // ============================================================================
 // implementation
 // ============================================================================
@@ -289,7 +378,6 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler)
         // only reached for space not inside quotes
         break;
     }
-
     wxString commandArgs = pc;
 
     wxWindow *winTop = wxTheApp->GetTopWindow();
@@ -313,6 +401,46 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler)
 
     return result;
 #else // 1
+                     
+    HANDLE h_readPipe[2];
+    HANDLE h_writePipe[2];
+    HANDLE h_oldreadPipe;
+    HANDLE h_oldwritePipe;
+    BOOL inheritHandles;
+
+    // ------------------------------------
+    // Pipe handling
+    // We are in the case of opening a pipe
+    inheritHandles = FALSE;
+    if (handler && handler->NeedPipe()) {
+        SECURITY_ATTRIBUTES security;
+
+        security.nLength              = sizeof(security);
+        security.lpSecurityDescriptor = NULL;
+        security.bInheritHandle       = TRUE;
+
+        if (! ::CreatePipe(&h_readPipe[0], &h_readPipe[1], &security, 0) ) {
+            wxLogSysError(_T("Can't create the inter-process read pipe"));
+
+            return 0;
+        }
+
+        if (! ::CreatePipe(&h_writePipe[0], &h_writePipe[1], &security, 0) ) {
+            wxLogSysError(_T("Can't create the inter-process read pipe"));
+
+            return 0;
+        }
+
+        // We need to save the old stdio handles to restore them after the call
+        // to CreateProcess
+        h_oldreadPipe  = GetStdHandle(STD_INPUT_HANDLE);
+        h_oldwritePipe = GetStdHandle(STD_OUTPUT_HANDLE);
+
+        SetStdHandle(STD_INPUT_HANDLE, h_readPipe[0]);
+        SetStdHandle(STD_OUTPUT_HANDLE, h_writePipe[1]);
+
+        inheritHandles = TRUE;
+    }
 
     // create the process
     STARTUPINFO si;
@@ -327,7 +455,7 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler)
                          (wxChar *)command.c_str(),  // full command line
                          NULL,       // security attributes: defaults for both
                          NULL,       //   the process and its main thread
-                         FALSE,      // don't inherit handles
+                         inheritHandles,      // inherit handles if we need pipes
                          CREATE_DEFAULT_ERROR_MODE |
                          CREATE_SUSPENDED,           // flags
                          NULL,       // environment (use the same)
@@ -336,11 +464,31 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler)
                          &pi         // process info
                         ) == 0 )
     {
+        if (inheritHandles) {
+            ::CloseHandle(h_writePipe[0]);
+            ::CloseHandle(h_writePipe[1]);
+            ::CloseHandle(h_readPipe[0]);
+            ::CloseHandle(h_readPipe[1]);
+        }
         wxLogSysError(_("Execution of command '%s' failed"), command.c_str());
 
         return 0;
     }
 
+    // Restore the old stdio handles
+    if (inheritHandles) {
+        SetStdHandle(STD_INPUT_HANDLE, h_oldreadPipe);
+        SetStdHandle(STD_OUTPUT_HANDLE, h_oldwritePipe);
+
+        ::CloseHandle(h_writePipe[1]);
+        ::CloseHandle(h_readPipe[0]);
+        // We can now initialize the wxStreams
+        wxInputStream *processOutput = new wxPipeInputStream(h_writePipe[0]);
+        wxOutputStream *processInput = new wxPipeOutputStream(h_readPipe[1]);
+
+        handler->SetPipeStreams(processOutput, processInput);
+    }
+
     // register the class for the hidden window used for the notifications
     if ( !gs_classForHiddenWindow )
     {
index 3b09340becb2edae82448469af9a0f83d3973a86..fe4abae50e27af316e99f050b2c25c83515d964a 100644 (file)
@@ -25,6 +25,8 @@
 #include "wx/process.h"
 #include "wx/thread.h"
 
+#include "wx/stream.h"
+
 #if wxUSE_GUI
     #include "wx/unix/execute.h"
 #endif
@@ -274,6 +276,83 @@ void wxHandleProcessTermination(wxEndProcessData *proc_data)
     #define WXUNUSED_UNLESS_GUI(p)
 #endif
 
+// New wxStream classes to clean up the data when the process terminates
+
+#if wxUSE_GUI
+class wxProcessFileInputStream: public wxInputStream {
+ public:
+    wxProcessFileInputStream(int fd);
+    ~wxProcessFileInputStream();
+
+ protected: 
+    size_t OnSysRead(void *buffer, size_t bufsize);
+
+ protected:
+    int m_fd;
+};
+
+class wxProcessFileOutputStream: public wxOutputStream {
+ public:
+    wxProcessFileOutputStream(int fd);
+    ~wxProcessFileOutputStream();
+
+ protected:
+    size_t OnSysWrite(const void *buffer, size_t bufsize);
+
+ protected:
+    int m_fd;
+};
+
+wxProcessFileInputStream::wxProcessFileInputStream(int fd)
+{
+    m_fd = fd;
+}
+
+wxProcessFileInputStream::~wxProcessFileInputStream()
+{
+    close(m_fd);
+}
+
+size_t wxProcessFileInputStream::OnSysRead(void *buffer, size_t bufsize)
+{
+    int ret;
+
+    ret = read(m_fd, buffer, bufsize);
+    m_lasterror = wxSTREAM_NOERROR;
+    if (ret == 0)
+      m_lasterror = wxSTREAM_EOF;
+    if (ret == -1) {
+      m_lasterror = wxSTREAM_READ_ERROR;
+      ret = 0;
+    }
+    return ret;
+}
+
+wxProcessFileOutputStream::wxProcessFileOutputStream(int fd)
+{
+    m_fd = fd;
+}
+
+wxProcessFileOutputStream::~wxProcessFileOutputStream()
+{
+    close(m_fd);
+}
+
+size_t wxProcessFileOutputStream::OnSysWrite(const void *buffer, size_t bufsize)
+{
+    int ret;
+
+    ret = write(m_fd, buffer, bufsize);
+    m_lasterror = wxSTREAM_NOERROR;
+    if (ret == -1) {
+      m_lasterror = wxSTREAM_WRITE_ERROR;
+      ret = 0;
+    }
+    return ret;
+}
+
+#endif
+      
 long wxExecute(wxChar **argv,
                bool sync,
                wxProcess * WXUNUSED_UNLESS_GUI(process))
@@ -316,6 +395,26 @@ long wxExecute(wxChar **argv,
     }
 #endif // wxUSE_GUI
 
+#if wxUSE_GUI
+    int in_pipe[2] = { -1, -1 };
+    int out_pipe[2] = { -1, -1 };
+    // Only asynchronous mode is interresting
+    if (!sync && process && process->NeedPipe())
+    {
+        if (pipe(in_pipe) == -1 || pipe(out_pipe) == -1)
+        {
+            /* Free fds */
+            close(end_proc_detect[0]);
+            close(end_proc_detect[1]);
+            wxLogSysError( _("Pipe creation failed (Console pipes)") );
+
+            ARGS_CLEANUP;
+
+            return 0;
+        }
+    }
+#endif // wxUSE_GUI
+
     // fork the process
 #ifdef HAVE_VFORK
     pid_t pid = vfork();
@@ -324,6 +423,14 @@ long wxExecute(wxChar **argv,
 #endif
     if (pid == -1)
     {
+#if wxUSE_GUI
+        close(end_proc_detect[0]);
+        close(end_proc_detect[1]);
+        close(in_pipe[0]);
+        close(in_pipe[1]);
+        close(out_pipe[0]);
+        close(out_pipe[1]);
+#endif
         wxLogSysError( _("Fork failed") );
 
         ARGS_CLEANUP;
@@ -347,7 +454,7 @@ long wxExecute(wxChar **argv,
             for ( int fd = 0; fd < FD_SETSIZE; fd++ )
             {
 #if wxUSE_GUI
-                if ( fd == end_proc_detect[1] )
+                if ( fd == end_proc_detect[1] || fd == in_pipe[0] || fd == out_pipe[1] )
                     continue;
 #endif // wxUSE_GUI
 
@@ -356,6 +463,16 @@ long wxExecute(wxChar **argv,
             }
         }
 
+        // Fake a console by duplicating pipes
+#if wxUSE_GUI
+        if (in_pipe[0] != -1) {
+            dup2(in_pipe[0], STDIN_FILENO);
+            dup2(out_pipe[1], STDOUT_FILENO);
+            close(in_pipe[0]);
+            close(out_pipe[1]);
+        }
+#endif // wxUSE_GUI
+
 #if 0
         close(STDERR_FILENO);
 
@@ -386,8 +503,8 @@ long wxExecute(wxChar **argv,
             data->process = NULL;
 
             // sync execution: indicate it by negating the pid
-            data->pid = -pid;
-            data->tag = wxAddProcessCallback(data, end_proc_detect[0]);
+            data->pid      = -pid;
+            data->tag      = wxAddProcessCallback(data, end_proc_detect[0]);
             // we're in parent
             close(end_proc_detect[1]); // close writing side
 
@@ -403,12 +520,26 @@ long wxExecute(wxChar **argv,
         }
         else
         {
+            // pipe initialization: construction of the wxStreams
+            if (process && process->NeedPipe()) {
+                // These two streams are relative to this process.
+                wxOutputStream *my_output_stream;
+                wxInputStream *my_input_stream;
+
+                my_output_stream = new wxProcessFileOutputStream(in_pipe[1]);
+                my_input_stream = new wxProcessFileInputStream(out_pipe[0]);
+                close(in_pipe[0]); // close reading side
+                close(out_pipe[1]); // close writing side
+
+                process->SetPipeStreams(my_input_stream, my_output_stream);
+            }
+
             // async execution, nothing special to do - caller will be
             // notified about the process termination if process != NULL, data
             // will be deleted in GTK_EndProcessDetector
-            data->process = process;
-            data->pid = pid;
-            data->tag = wxAddProcessCallback(data, end_proc_detect[0]);
+            data->process  = process;
+            data->pid      = pid;
+            data->tag      = wxAddProcessCallback(data, end_proc_detect[0]);
             // we're in parent
             close(end_proc_detect[1]); // close writing side
 
index 7f875c2b8f5bc97a3d97b77e5a2cc180e7af88bd..d14789453076c33120498a6bb9c5ad2b654a0053 100644 (file)
@@ -298,7 +298,9 @@ wxString MMBoardSoundFile::GetStringInformation()
     case wxSOUND_PCM: {
         wxSoundFormatPcm *pcm_format = (wxSoundFormatPcm *)format;
       
-       info += wxT("PCM\n");
+       info += wxString::Format(wxT("PCM %s %s\n"),
+                                 pcm_format->Signed() ? wxT("signed") : wxT("unsigned"),
+                                 pcm_format->GetOrder() == wxLITTLE_ENDIAN ? wxT("little endian") : wxT("big endian"));
        info += wxString::Format(wxT("Sampling rate: %d\n")
                                 wxT("Bits per sample: %d\n")
                                 wxT("Number of channels: %d\n"),
index 483b7cf6b8746d00b2fefdf55aa8fa4bc8c3c22e..f20d3ea6d9c94b4af6ca8f57af104a4546165d27 100644 (file)
@@ -202,7 +202,7 @@ wxUint8 MMBoardApp::TestMultimediaCaps()
     // We now test the ESD support
     
     dev = new wxSoundStreamESD();
-    if (dev->GetError() == wxSOUND_NOERR) 
+    if (dev->GetError() == wxSOUND_NOERROR
         caps |= MM_SOUND_ESD;
     delete dev;
     
@@ -210,7 +210,7 @@ wxUint8 MMBoardApp::TestMultimediaCaps()
     // WARNING: There is a conflict between ESD and ALSA
     
     dev = new wxSoundStreamOSS();
-    if (dev->GetError() == wxSOUND_NOERR)
+    if (dev->GetError() == wxSOUND_NOERROR)
         caps |= MM_SOUND_OSS;
     delete dev;
 #endif
index 0bbda32bd7c47d689f209c0095001b8935d8b831..7dc801c6b4f64fec6c180b576fd172345292d41b 100644 (file)
@@ -1,5 +1,5 @@
 // ---------------------------------------------------------------------------
-// Name:       sndsnd.cpp
+// Name:       cdbase.cpp
 // Purpose:    wxMMedia
 // Author:     Guilhem Lavaux
 // Created:    1997
index 31f58bd502397e060b0e3fbf3691480c56705b95..a558b234bc55808211c87e35114d8b5ff98987fe 100644 (file)
@@ -1,7 +1,5 @@
-#include <stdio.h>
-
 #define DEFINE_CONV(name, input_type, output_type, convert) \
-static void Convert_##name##(const char *buf_in, char *buf_out, wxUint32 len) \
+static void Convert_##name##(const void *buf_in, void *buf_out, wxUint32 len) \
 {\
   register input_type src; \
   register const input_type *t_buf_in = (input_type *)buf_in; \
@@ -14,6 +12,8 @@ static void Convert_##name##(const char *buf_in, char *buf_out, wxUint32 len) \
   } \
 }
 
+// TODO: define converters for all other formats (32, 24)
+
 DEFINE_CONV(8_8_sign, wxUint8, wxUint8, (src ^ 0x80))
 
 DEFINE_CONV(8_16, wxUint8, wxUint16, (((wxUint16)src) << 8))
@@ -26,8 +26,14 @@ DEFINE_CONV(16_8_sign, wxUint16, wxUint8, (wxUint8)((src >> 8) ^ 0x80))
 DEFINE_CONV(16_swap_8, wxUint16, wxUint8, (wxUint8)(src & 0xff))
 DEFINE_CONV(16_swap_8_sign, wxUint16, wxUint8, (wxUint8)((src & 0xff) ^ 0x80))
 
+//DEFINE_CONV(24_8, wxUint32, wxUint8, (wxUint8)(src >> 16))
+//DEFINE_CONV(24_8_sig, wxUint32, wxUint8, (wxUint8)((src >> 16) ^ 0x80))
+
+//DEFINE_CONV(32_8, wxUint32, wxUint8, (wxUint8)(src >> 24))
+
 DEFINE_CONV(16_sign, wxUint16, wxUint16, (src ^ 0x8000))
 DEFINE_CONV(16_swap, wxUint16, wxUint16, (((src & 0xff) << 8) | ((src >> 8) & 0xff)))
-DEFINE_CONV(16_swap_16_sign, wxUint16, wxUint16, ((((src & 0xff) << 8) | ((src >> 8) & 0xff)) ^ 0x8000))
-DEFINE_CONV(16_sign_16_swap, wxUint16, wxUint16, ((((src & 0xff) << 8) | ((src >> 8) & 0xff)) ^ 0x80))
+// Problem.
+DEFINE_CONV(16_swap_16_sign, wxUint16, wxUint16, ((((src & 0xff) << 8) | ((src >> 8) & 0xff)) ^ 0x80))
+// DEFINE_CONV(16_sign_16_swap, wxUint16, wxUint16, ((((src & 0xff) << 8) | ((src >> 8) & 0xff)) ^ 0x8000))
 DEFINE_CONV(16_swap_16_sign_swap, wxUint16, wxUint16, (src ^ 0x80))
index 7c6bfb4018269e1eff4a0d138bd710c5201fcbc4..e661d082ff913bea49eafdb3daafe0f6aeeed865 100644 (file)
@@ -99,6 +99,7 @@ bool wxSoundAiff::PrepareToPlay()
         m_snderror = wxSOUND_INVSTRM;
         return FALSE;
     }
+    m_snderror = wxSOUND_NOERROR;
     
     data.BigEndianOrdered(TRUE);
     
@@ -129,9 +130,11 @@ bool wxSoundAiff::PrepareToPlay()
                 wxUint32 num_samples;
                 double srate;
                 wxSoundFormatPcm sndformat;
-                
+
+                // Get sound data informations
                 data >> channels >> num_samples >> bps >> srate; 
-                
+
+                // Convert them in a wxSoundFormat object
                 sndformat.SetSampleRate((wxUint32) srate);
                 sndformat.SetBPS(bps);
                 sndformat.SetChannels(channels);
@@ -140,6 +143,7 @@ bool wxSoundAiff::PrepareToPlay()
                 
                 if (!SetSoundFormat(sndformat))
                     return FALSE;
+                // We pass all data left
                 m_input->SeekI(len-18, wxFromCurrent);
                 break;
             }
@@ -149,6 +153,7 @@ bool wxSoundAiff::PrepareToPlay()
                 // m_input->SeekI(len-4, wxFromCurrent); // Pass the rest
                 m_input->SeekI(ssnd + 4, wxFromCurrent);
                 m_base_offset = m_input->TellI();
+                // len-8 bytes of samples
                 FinishPreparation(len - 8);
                 end_headers = TRUE;
                 break;
@@ -175,6 +180,7 @@ bool wxSoundAiff::FinishRecording()
 
 bool wxSoundAiff::RepositionStream(wxUint32 position)
 {
+    // If the stream is not seekable "TellI() returns wxInvalidOffset" we cannot reposition stream
     if (m_base_offset == wxInvalidOffset)
         return FALSE;
     m_input->SeekI(m_base_offset, wxFromStart);
index be6d6d59c7a9f0e35098a47558dd975383e63dab..0a873500a9ed10b110662786068be633bc1d17a8 100644 (file)
@@ -46,7 +46,7 @@ wxSoundStream::wxSoundStream()
   // Reset all variables to their neutral value.
   m_sndformat = NULL;
   m_handler = NULL;
-  m_snderror = wxSOUND_NOERR;
+  m_snderror = wxSOUND_NOERROR;
   m_lastcount = 0;
   for (i=0;i<2;i++)
     m_callback[i] = NULL;
@@ -85,7 +85,7 @@ bool wxSoundStream::SetSoundFormat(const wxSoundFormatBase& format)
 // call twice this function the previous registered callback is absolutely
 // ignored.
 // --------------------------------------------------------------------------
-void wxSoundStream::Register(int evt, wxSoundCallback cbk, char *cdata)
+void wxSoundStream::SetCallback(int evt, wxSoundCallback cbk, void *cdata)
 {
   int c;
 
index b2436548efd2289c72a26ff096cecebd7f9e6291..1a828ae3fc6eb126f8c232c9e60f139cfd6ad216 100644 (file)
@@ -63,14 +63,14 @@ typedef enum {
 //   - wxSOUND_MEMERR:  Not enough memory.
 // ---------------------
 typedef enum {
-  wxSOUND_NOERR,
-  wxSOUND_IOERR,
+  wxSOUND_NOERROR,
+  wxSOUND_IOERROR,
   wxSOUND_INVFRMT,
   wxSOUND_INVDEV,
   wxSOUND_NOEXACT,
   wxSOUND_INVSTRM,
   wxSOUND_NOCODEC,
-  wxSOUND_MEMERR
+  wxSOUND_MEMERROR
 } wxSoundError;
 
 class WXDLLEXPORT wxSoundStream;
@@ -83,7 +83,7 @@ class WXDLLEXPORT wxSoundStream;
 //    - cdata: User callback data
 // ---------------------
 typedef void (*wxSoundCallback)(wxSoundStream *stream, int evt,
-                                char *cdata);
+                                void *cdata);
 
 //
 // Base class for sound format specification
@@ -128,7 +128,7 @@ class wxSoundStream {
   wxSoundFormatBase& GetSoundFormat() const { return *m_sndformat; }
 
   // Register a callback for a specified async event.
-  void Register(int evt, wxSoundCallback cbk, char *cdata);
+  void SetCallback(int evt, wxSoundCallback cbk, void *cdata);
 
   // Starts the async notifier. After this call, the stream begins either 
   // recording or playing or the two at the same time.
@@ -158,7 +158,7 @@ class wxSoundStream {
   wxSoundStream *m_handler;
 
   wxSoundCallback m_callback[2];
-  char *m_cdata[2];
+  void *m_cdata[2];
 
  protected:
   // Handles event
index c81fc890db2e485f6640d373736ddea374492599..0190874bf29ee341512713dd97742681f3f20106 100644 (file)
 #ifdef __GNUG__
 #pragma implementation "sndcpcm.cpp"
 #endif
-
 #include <wx/wxprec.h>
+
+#ifndef WX_PRECOMP
+#include <wx/debug.h>
+#include <wx/log.h>
+#endif
+
 #include "sndbase.h"
 #include "sndpcm.h"
 #include "sndcpcm.h"
 
 wxSoundStreamPcm::wxSoundStreamPcm(wxSoundStream& sndio)
- : wxSoundStreamCodec(sndio)
       : wxSoundStreamCodec(sndio)
 {
-  m_function_in = NULL;
-  m_function_out = NULL;
+    m_function_in = NULL;
+    m_function_out = NULL;
+    m_prebuffer = NULL;
+    m_prebuffer_size = 0;
+    m_best_size = 0;
 }
 
 wxSoundStreamPcm::~wxSoundStreamPcm()
 {
+    if (m_prebuffer)
+        delete[] m_prebuffer;
 }
 
+wxUint32 wxSoundStreamPcm::GetBestSize() const
+{
+    return m_best_size;
+}
 
 #include "converter.def"
 
 // -----------------------------------------------------------------------
 // Main PCM stream converter table
 // -----------------------------------------------------------------------
-wxSoundStreamPcm::ConverterType s_converters[] = {
-  NULL,
-  Convert_8_8_sign,                    /* 8 -> 8 sign */
-  NULL,
-  NULL,
-  NULL,
-  NULL,
-
-  Convert_8_16,                                /* 8 -> 16 */
-  Convert_8_16_sign,                   /* 8 -> 16 sign */
-  Convert_8_16_swap,                   /* 8 -> 16 swapped */
-  Convert_8_16_sign_swap,              /* 8 -> 16 sign swapped */
-  NULL,
-  NULL,
-
-  Convert_16_8,                                /* 16 -> 8 */
-  Convert_16_8_sign,                   /* 16 -> 8 sign */
-  Convert_16_swap_8,                   /* 16 swapped -> 8 */
-  Convert_16_swap_8_sign,              /* 16 swapped -> 8 sign */
-  NULL,
-  NULL,
-
-  NULL,                                        /* 16 -> 16 */
-  Convert_16_sign,                     /* 16 -> 16 sign */
-  Convert_16_swap,                     /* 16 swapped -> 16 */
-  Convert_16_swap_16_sign,             /* 16 swapped -> 16 sign */
-  Convert_16_sign_16_swap,             /* 16 sign -> 16 swapped */
-  Convert_16_swap_16_sign_swap         /* 16 swapped -> 16 sign swapped */
+// Definition
+//   XX -> YY
+//   XX -> YY sign
+//
+//   XX swapped -> YY
+//   XX swapped -> YY sign
+//
+//   XX swapped -> YY swapped
+//   XX swapped -> YY swapped sign
+//
+//   XX stereo -> YY mono
+//   XX stereo -> YY mono sign
+//
+//   XX swapped stereo -> YY swapped mono
+//   XX swapped stereo -> YY swapped mono sign
+//
+//   XX swapped stereo -> YY swapped mono
+//   XX swapped stereo -> YY swapped mono sign
+
+static wxSoundStreamPcm::ConverterType s_converters[4][3][2] = { 
+    {
+        {
+            NULL,
+            Convert_8_8_sign                    /* 8 -> 8 sign */
+        },
+        {
+            NULL,
+            NULL
+        },
+        {
+            NULL,
+            NULL
+        }
+    },
+    {
+        {
+            Convert_8_16,                       /* 8 -> 16 */
+            Convert_8_16_sign                   /* 8 -> 16 sign */
+        },
+        {
+            Convert_8_16_swap,                  /* 8 -> 16 swapped */
+            Convert_8_16_sign_swap              /* 8 -> 16 sign swapped */
+        },
+        {
+            NULL,
+            NULL
+        }
+    },
+    {
+        {
+            Convert_16_8,                       /* 16 -> 8 */
+            Convert_16_8_sign                   /* 16 -> 8 sign */
+        },
+        {
+            Convert_16_swap_8,                  /* 16 swapped -> 8 */
+            Convert_16_swap_8_sign              /* 16 swapped -> 8 sign */
+        },
+        {
+            NULL,
+            NULL 
+        },
+    },
+    
+    {
+        {
+            NULL,                               /* 16 -> 16 */
+            Convert_16_sign                     /* 16 -> 16 sign */
+        },
+        {
+            Convert_16_swap,                    /* 16 swapped -> 16 */
+            Convert_16_swap_16_sign             /* 16 swapped -> 16 sign */
+        },
+        {
+            NULL,
+            Convert_16_swap_16_sign_swap        /* 16 swapped -> 16 sign swapped */
+        }
+    }
 };
 
-#define CONVERT_BPS 0
-#define CONVERT_SIGN 1
-#define CONVERT_SWAP 2
-#define CONVERT_SIGN_SWAP 3
-#define CONVERT_SWAP_SIGN 4
-#define CONVERT_SWAP_SIGN_SWAP 5
-
-#define CONVERT_BASE_8_8 0
-#define CONVERT_BASE_8_16 6
-#define CONVERT_BASE_16_8 12 
-#define CONVERT_BASE_16_16 18
+// This is the buffer size multiplier. It gives the needed size of the output size.
+static float s_converters_multip[] = {1, 2, 0.5, 1};
 
 //
 // TODO: Read() and Write() aren't really safe. If you give it a buffer which
@@ -80,107 +134,163 @@ wxSoundStreamPcm::ConverterType s_converters[] = {
 
 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();
-    m_snderror = m_sndio->GetError();
-    return *this;
-  }
-
-  real_len = (m_16_to_8) ? len / 2 : len;
-
-  tmp_buf = new char[real_len];
+    wxUint32 in_bufsize;
+
+    // We must have a multiple of 2
+    len &= 0x01;
+    
+    if (!m_function_in) {
+        m_sndio->Read(buffer, len);
+        m_lastcount = m_sndio->GetLastAccess();
+        m_snderror = m_sndio->GetError();
+        return *this;
+    }
 
-  m_sndio->Read(tmp_buf, real_len);
-  m_lastcount = m_sndio->GetLastAccess();
-  m_snderror = m_sndio->GetError();
-  if (m_snderror != wxSOUND_NOERR)
+    in_bufsize = GetReadSize(len);
+    
+    if (len <= m_best_size) {
+        m_sndio->Read(m_prebuffer, in_bufsize);
+        m_snderror  = m_sndio->GetError();
+        if (m_snderror != wxSOUND_NOERROR) {
+            m_lastcount = 0;
+            return *this;
+        }
+        
+        m_function_in(m_prebuffer, buffer, m_sndio->GetLastAccess());
+    } else {
+        char *temp_buffer;
+        
+        temp_buffer = new char[in_bufsize];
+        m_sndio->Read(temp_buffer, in_bufsize);
+
+        m_snderror =  m_sndio->GetError();
+        if (m_snderror != wxSOUND_NOERROR) {
+            m_lastcount = 0;
+            return *this;
+        }
+        
+        m_function_in(temp_buffer, buffer, m_sndio->GetLastAccess());
+        
+        delete[] temp_buffer;
+    }
+    
+    m_lastcount = (wxUint32)(m_sndio->GetLastAccess() * m_multiplier_in);
+    
     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, wxUint32 len)
 {
-  char *tmp_buf;
-  wxUint32 len2;
+    wxUint32 out_bufsize;
+    
+    if (!m_function_out) {
+        m_sndio->Write(buffer, len);
+        m_lastcount = m_sndio->GetLastAccess();
+        m_snderror  = m_sndio->GetError();
+        return *this;
+    }
 
-  if (!m_function_out)
-    return m_sndio->Write(buffer, len);
+    out_bufsize = GetWriteSize(len);
 
-  len2 = (m_16_to_8) ? len / 2 : len;
+    if (len <= m_best_size) {
+        out_bufsize = GetWriteSize(len);
 
-  tmp_buf = new char[len2];
-  m_function_out((const char *)buffer, tmp_buf, len2);
-  m_sndio->Write(tmp_buf, len);
-  delete[] tmp_buf;
+        m_function_out(buffer, m_prebuffer, len);
+        m_sndio->Write(m_prebuffer, out_bufsize);
+        m_snderror  = m_sndio->GetError();
+        if (m_snderror != wxSOUND_NOERROR) {
+            m_lastcount = 0;
+            return *this;
+        }
+    } else {
+        char *temp_buffer;
+        
+        temp_buffer = new char[out_bufsize];
+        m_function_out(buffer, temp_buffer, len);
+        
+        m_sndio->Write(temp_buffer, out_bufsize);
+        m_snderror =  m_sndio->GetError();
+        if (m_snderror != wxSOUND_NOERROR) {
+            m_lastcount = 0;
+            return *this;
+        }
+        
+        delete[] temp_buffer;
+    }
 
-  m_lastcount = (m_16_to_8) ? 
-                    (m_sndio->GetLastAccess() * 2) : m_sndio->GetLastAccess();
+    m_lastcount = (wxUint32)(m_sndio->GetLastAccess() / m_multiplier_out);
 
-  return *this;
+    return *this;
 }
 
 bool wxSoundStreamPcm::SetSoundFormat(const wxSoundFormatBase& format)
 {
-  wxSoundFormatBase *new_format;
-  wxSoundFormatPcm *pcm_format, *pcm_format2;
-  ConverterType *current_table_out, *current_table_in;
-  int index;
-  bool change_sign;
-
-  if (m_sndio->SetSoundFormat(format)) {
-    m_function_out = NULL;
-    m_function_in = NULL;
-    return TRUE;
-  }
-  if (format.GetType() != wxSOUND_PCM) {
-    m_snderror = wxSOUND_INVFRMT;
-    return FALSE;
-  }
-  if (m_sndformat)
-    delete m_sndformat;
-
-  new_format = m_sndio->GetSoundFormat().Clone();
-  pcm_format = (wxSoundFormatPcm *)&format;
-  pcm_format2 = (wxSoundFormatPcm *)new_format;
-
-  // ----------------------------------------------------
-  // Select table to use:
-  //     * 8 bits -> 8 bits
-  //     * 16 bits -> 8 bits
-  //     * 8 bits -> 16 bits
-  //     * 16 bits -> 16 bits
-
-  m_16_to_8 = FALSE;
-  if (pcm_format->GetBPS() != pcm_format2->GetBPS()) {
-    m_16_to_8 = TRUE;
-    if (pcm_format2->GetBPS() == 8) {
-      current_table_out = &s_converters[CONVERT_BASE_16_8];
-      current_table_in  = &s_converters[CONVERT_BASE_8_16];
-    } else {
-      current_table_out = &s_converters[CONVERT_BASE_8_16];
-      current_table_in  = &s_converters[CONVERT_BASE_16_8];
+    wxSoundFormatBase *new_format;
+    wxSoundFormatPcm *pcm_format, *pcm_format2;
+    
+    if (m_sndio->SetSoundFormat(format)) {
+        m_function_out = NULL;
+        m_function_in = NULL;
+        return TRUE;
     }
-  } else if (pcm_format->GetBPS() == 16) {
-    current_table_out = &s_converters[CONVERT_BASE_16_16];
-    current_table_in  = &s_converters[CONVERT_BASE_16_16];
-  } else {
-    current_table_out = &s_converters[CONVERT_BASE_8_8];
-    current_table_in  = &s_converters[CONVERT_BASE_8_8];
-  }
-
-  change_sign = (pcm_format2->Signed() != pcm_format->Signed());
+    if (format.GetType() != wxSOUND_PCM) {
+        m_snderror = wxSOUND_INVFRMT;
+        return FALSE;
+    }
+    if (m_sndformat)
+        delete m_sndformat;
+    
+    new_format = m_sndio->GetSoundFormat().Clone();
+    pcm_format = (wxSoundFormatPcm *)&format;
+    pcm_format2 = (wxSoundFormatPcm *)new_format;
+
+#if 0
+    // ----------------------------------------------------
+    // Test whether we need to resample
+    if (pcm_format->GetSampleRate() != pcm_format2->GetSampleRate()) {
+        wxUint32 src_rate, dst_rate;
+
+        src_rate = pcm_format->GetSampleRate();
+        dst_rate = pcm_format2->GetSampleRate();
+        m_needResampling = TRUE;
+        if (src_rate < dst_rate)
+            m_expandSamples = TRUE;
+        else
+            m_expandSamples = FALSE;
+        m_pitch = (src_rate << FLOATBITS) / dst_rate;
+    }
+#endif
+    // ----------------------------------------------------
+    // Select table to use:
+    //     * 8 bits -> 8 bits
+    //     * 16 bits -> 8 bits
+    //     * 8 bits -> 16 bits
+    //     * 16 bits -> 16 bits
+
+    int table_no, table_no2;
+    int i_sign, i_swap;
+    
+    switch (pcm_format->GetBPS()) {
+        case 8:
+            table_no = 0;
+            break;
+        case 16:
+            table_no = 1;
+            break;
+    }
+    switch (pcm_format2->GetBPS()) {
+        case 8:
+            table_no2 = 0;
+            break;
+        case 16:
+            table_no2 = 1;
+            break;
+    }
+    
+    if (pcm_format2->Signed() != pcm_format->Signed())
+        i_sign = 1;
+    else
+        i_sign = 0;
 
 #define MY_ORDER wxBYTE_ORDER
 #if wxBYTE_ORDER == wxLITTLE_ENDIAN
@@ -189,36 +299,91 @@ bool wxSoundStreamPcm::SetSoundFormat(const wxSoundFormatBase& format)
 #define OTHER_ORDER wxLITTLE_ENDIAN
 #endif
 
-  // --------------------------------------------------------
-  // Find the good converter !
+    // --------------------------------------------------------
+    // Find the good converter !
 
+    if (pcm_format->GetOrder() == OTHER_ORDER) {
+        if (pcm_format->GetOrder() == pcm_format2->GetOrder())
+            i_swap = 2;
+        else
+            i_swap = 1;
+    } else {
+        if (pcm_format->GetOrder() == pcm_format2->GetOrder())
+            i_swap = 0;
+        else
+            i_swap = 1;
+    }
 
-  if (pcm_format->GetOrder() == OTHER_ORDER &&
-      pcm_format2->GetOrder() == OTHER_ORDER && change_sign) 
-    index = CONVERT_SWAP_SIGN_SWAP;
+    m_function_out = s_converters[table_no*2+table_no2][i_swap][i_sign];
+    m_function_in  = s_converters[table_no2*2+table_no][i_swap][i_sign];
+    m_multiplier_out = s_converters_multip[table_no*2+table_no2];
+    m_multiplier_in  = s_converters_multip[table_no2*2+table_no2];
 
-  else if (pcm_format->GetOrder() == OTHER_ORDER &&
-           pcm_format2->GetOrder() == MY_ORDER && change_sign) 
-    index = CONVERT_SWAP_SIGN;
+    if (m_prebuffer)
+        delete[] m_prebuffer;
 
-  else if (pcm_format->GetOrder() == MY_ORDER &&
-           pcm_format->GetOrder() == OTHER_ORDER && change_sign)
-    index = CONVERT_SIGN_SWAP;
+    // We try to minimize the need of dynamic memory allocation by preallocating a buffer. But
+    // to be sure it will be efficient we minimize the best size.
+    if (m_multiplier_in < m_multiplier_out) {
+        m_prebuffer_size = (wxUint32)(m_sndio->GetBestSize() * m_multiplier_out);
+        m_best_size = (wxUint32)(m_sndio->GetBestSize() * m_multiplier_in);
+    } else {
+        m_prebuffer_size = (wxUint32)(m_sndio->GetBestSize() * m_multiplier_in);
+        m_best_size = (wxUint32)(m_sndio->GetBestSize() * m_multiplier_out);
+    }
+    
+    m_prebuffer = new char[m_prebuffer_size];
+    
+    bool SetSoundFormatReturn;
+
+    SetSoundFormatReturn = m_sndio->SetSoundFormat(*new_format);
+    wxASSERT( SetSoundFormatReturn );
+    
+    m_sndformat = new_format;
+    return TRUE;
+}
 
-  else if (change_sign)
-    index = CONVERT_SIGN;
+wxUint32 wxSoundStreamPcm::GetWriteSize(wxUint32 len) const
+{
+    // For the moment, it is simple but next time it will become more complicated
+    // (Resampling)
+    return (wxUint32)(len * m_multiplier_out);
+}
 
-  else if (!change_sign &&
-           pcm_format->GetOrder() != pcm_format2->GetOrder())
-    index = CONVERT_SWAP;
+wxUint32 wxSoundStreamPcm::GetReadSize(wxUint32 len) const
+{
+    return (wxUint32)(len / m_multiplier_in);
+}
+
+// Resampling engine. NOT FINISHED and NOT INCLUDED but this is a first DRAFT.
 
-  else
-    index = CONVERT_BPS;
+#if 0
 
-  m_function_out = current_table_out[index];
-  m_function_in  = current_table_in[index];
+#define FLOATBITS 16
+#define INTBITS 16
+#define FLOATMASK 0xffff
+#define INTMASK 0xffff0000
 
-  m_sndio->SetSoundFormat(*new_format);
-  m_sndformat = new_format;
-  return TRUE;
+void ResamplingShrink_##DEPTH##(const void *source, void *destination, wxUint32 len)
+{
+    wxUint##DEPTH## *source_data, *dest_data;
+    wxUint32 pos;
+
+    source_data = (wxUint##DEPTH## *)source;
+    dest_data   = (wxUint##DEPTH## *)destination;
+    
+    pos = m_saved_pos;
+    while (len > 0) {
+        // Increment the position in the input buffer
+        pos += m_pitch;
+        if (pos & INTMASK) {
+            pos &= FLOATMASK;
+            
+            *dest_data ++ = *source_data;
+        }
+        len--;
+        source_data++;
+    }
+    m_saved_pos = pos;
 }
+#endif
index 6880d8b7d04ea40eb5075fb78cb391a6edb203ea..9064e5813c5e3486b7de5f50955c616fc2e8a696 100644 (file)
 //
 
 class wxSoundStreamPcm: public wxSoundStreamCodec {
- public:
-  typedef void (*ConverterType)(const char *buf_in, char *buf_out, wxUint32 len);
-
-  wxSoundStreamPcm(wxSoundStream& sndio);
-  ~wxSoundStreamPcm();
-
-  wxSoundStream& Read(void *buffer, wxUint32 len);
-  wxSoundStream& Write(const void *buffer, wxUint32 len);
-
-  bool SetSoundFormat(const wxSoundFormatBase& format);
-
- protected:
-  ConverterType m_function_out, m_function_in;
-
-  bool m_16_to_8;
+public:
+    typedef void (*ConverterType)(const void *buf_in, void *buf_out,
+                                  wxUint32 len);
+    
+    wxSoundStreamPcm(wxSoundStream& sndio);
+    ~wxSoundStreamPcm();
+    
+    wxSoundStream& Read(void *buffer, wxUint32 len);
+    wxSoundStream& Write(const void *buffer, wxUint32 len);
+    
+    bool SetSoundFormat(const wxSoundFormatBase& format);
+    
+    wxUint32 GetBestSize() const;
+    
+protected:
+    wxUint32 GetReadSize(wxUint32 len) const;
+    wxUint32 GetWriteSize(wxUint32 len) const;
+
+protected:
+    ConverterType m_function_out, m_function_in;
+
+    // Static temporary buffer
+    char *m_prebuffer;
+    wxUint32 m_prebuffer_size;
+    // Estimated best size to fit into the static buffer
+    wxUint32 m_best_size;
+    // Multiplier for IO buffer size
+    float m_multiplier_in, m_multiplier_out;
 };
 
 #endif
index 700bb1baa6491c7e387bb0afe56f9625b2788d74..59c737c04b7cdc21756e0b1f627e5112f3f7dbb0 100644 (file)
@@ -59,7 +59,7 @@ wxSoundStreamESD::wxSoundStreamESD(const wxString& hostname)
   SetSoundFormat(pcm_default);
 
   // Initialize some variable
-  m_snderror = wxSOUND_NOERR;
+  m_snderror = wxSOUND_NOERROR;
   m_esd_stop = TRUE;
   m_q_filled = TRUE;
   m_fd_output= -1;
@@ -84,9 +84,9 @@ wxSoundStream& wxSoundStreamESD::Read(void *buffer, wxUint32 len)
   m_lastcount = (wxUint32)ret = read(m_fd_input, buffer, len);
 
   if (ret < 0)
-    m_snderror = wxSOUND_IOERR;
+    m_snderror = wxSOUND_IOERROR;
   else
-    m_snderror = wxSOUND_NOERR;
+    m_snderror = wxSOUND_NOERROR;
 
   return *this;
 }
@@ -101,9 +101,9 @@ wxSoundStream& wxSoundStreamESD::Write(const void *buffer, wxUint32 len)
   m_lastcount = (wxUint32)ret = write(m_fd_output, buffer, len);
 
   if (ret < 0)
-    m_snderror = wxSOUND_IOERR;
+    m_snderror = wxSOUND_IOERROR;
   else
-    m_snderror = wxSOUND_NOERR;
+    m_snderror = wxSOUND_NOERROR;
 
   m_q_filled = TRUE;
 
@@ -133,7 +133,7 @@ bool wxSoundStreamESD::SetSoundFormat(const wxSoundFormatBase& format)
 
   m_sndformat = format.Clone();
   if (!m_sndformat) {
-    m_snderror = wxSOUND_MEMERR;
+    m_snderror = wxSOUND_MEMERROR;
     return FALSE;
   }
   pcm_format = (wxSoundFormatPcm *)m_sndformat;
@@ -141,7 +141,7 @@ bool wxSoundStreamESD::SetSoundFormat(const wxSoundFormatBase& format)
   // Detect the best format
   DetectBest(pcm_format);
 
-  m_snderror = wxSOUND_NOERR;
+  m_snderror = wxSOUND_NOERROR;
   if (*pcm_format != format) {
     m_snderror = wxSOUND_NOEXACT;
     return FALSE;
@@ -256,7 +256,7 @@ void wxSoundStreamESD::DetectBest(wxSoundFormatPcm *pcm)
 {
   wxSoundFormatPcm best_pcm;
 
-  // We change neither the number of channels nor the sample rate
+  // We change neither the number of channels nor the sample rate because ESD is clever.
 
   best_pcm.SetSampleRate(pcm->GetSampleRate());
   best_pcm.SetChannels(pcm->GetChannels());
index c92ea71d9e32988168320f869d989a5087971443..010529d142b150af8a7fdaf7f555df3526248e38 100644 (file)
@@ -325,7 +325,7 @@ wxString wxSoundFileStream::GetCodecName() const
 
 wxUint32 wxSoundFileStream::GetLength()
 {
-  if (m_input && !m_prepared && GetError() == wxSOUND_NOERR)
+  if (m_input && !m_prepared && GetError() == wxSOUND_NOERROR)
     return (PrepareToPlay()) ? m_length : 0;
 
   return m_length;
@@ -333,7 +333,7 @@ wxUint32 wxSoundFileStream::GetLength()
 
 wxUint32 wxSoundFileStream::GetPosition()
 {
-  if (!m_prepared && m_input != NULL && GetError() == wxSOUND_NOERR)
+  if (!m_prepared && m_input != NULL && GetError() == wxSOUND_NOERROR)
     PrepareToPlay();
 
   return m_length-m_bytes_left;
@@ -341,7 +341,7 @@ wxUint32 wxSoundFileStream::GetPosition()
 
 wxUint32 wxSoundFileStream::SetPosition(wxUint32 new_position)
 {
-  if (!m_prepared && m_input != NULL && GetError() == wxSOUND_NOERR)
+  if (!m_prepared && m_input != NULL && GetError() == wxSOUND_NOERROR)
     PrepareToPlay();
 
   if (!m_prepared)
index 11cd9d1d97476e18d26d95d1137fcc1a7e36d915..d2c94ec83aad5fbeb3a1055de50f77672d2de9fa 100644 (file)
@@ -21,7 +21,7 @@
 // --------------------------------------------------------------------------
 
 wxSoundFormatG72X::wxSoundFormatG72X()
-  : m_srate(22050)
+        : m_srate(22050)
 {
 }
 
@@ -31,77 +31,77 @@ wxSoundFormatG72X::~wxSoundFormatG72X()
 
 void wxSoundFormatG72X::SetSampleRate(wxUint32 srate)
 {
-  m_srate = srate;
+    m_srate = srate;
 }
 
 wxUint32 wxSoundFormatG72X::GetSampleRate() const
 {
-  return m_srate;
+    return m_srate;
 }
 
 void wxSoundFormatG72X::SetG72XType(wxSoundG72XType type)
 {
-  m_g72x_type = type;
+    m_g72x_type = type;
 }
 
 wxSoundFormatBase *wxSoundFormatG72X::Clone() const
 {
-  wxSoundFormatG72X *g72x = new wxSoundFormatG72X();
+    wxSoundFormatG72X *g72x = new wxSoundFormatG72X();
 
-  g72x->m_srate = m_srate;
-  g72x->m_g72x_type = m_g72x_type;
-  return g72x;
+    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));
+    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) * 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)));
+    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 * 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);
+    wxSoundFormatG72X *g72x = (wxSoundFormatG72X *)&frmt2;
+    
+    if (frmt2.GetType() != wxSOUND_G72X)
+        return TRUE;
+    
+    return (g72x->m_srate != m_srate || g72x->m_g72x_type != m_g72x_type);
 }
 
 // --------------------------------------------------------------------------
@@ -109,195 +109,196 @@ bool wxSoundFormatG72X::operator !=(const wxSoundFormatBase& frmt2) const
 // --------------------------------------------------------------------------
 
 wxSoundStreamG72X::wxSoundStreamG72X(wxSoundStream& sndio)
- : wxSoundStreamCodec(sndio)
       : wxSoundStreamCodec(sndio)
 {
-  // PCM converter
-  m_router = new wxSoundRouterStream(sndio);
-  m_state  = new g72state;
-  g72x_init_state(m_state);
+    // PCM converter
+    m_router = new wxSoundRouterStream(sndio);
+    m_state  = new g72state;
+    g72x_init_state(m_state);
 }
 
 wxSoundStreamG72X::~wxSoundStreamG72X()
 {
-  delete m_router;
+    delete m_router;
 }
 
 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;
+    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;
 }
 
 wxSoundStream& wxSoundStreamG72X::Write(const void *buffer, wxUint32 len)
 {
-  wxUint16 *old_linear;
-  register wxUint16 *linear_buffer;
-  register wxUint32 countdown = len;
-  register wxUint32 real_len;
-
-  // 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;
+    wxUint16 *old_linear;
+    register wxUint16 *linear_buffer;
+    register wxUint32 countdown = len;
+    register wxUint32 real_len;
+    
+    // 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;
 }
 
 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;
-
-  // 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;
-    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;
-  }
-
-  // Let the router finish the work
-  m_router->SetSoundFormat(pcm);
-
-  return TRUE;
+    if (format.GetType() != wxSOUND_G72X) {
+        m_snderror = wxSOUND_INVFRMT;
+        return FALSE;
+    }
+    
+    wxSoundFormatPcm pcm;
+    wxSoundFormatG72X *g72x;
+    
+    wxSoundStreamCodec::SetSoundFormat(format);
+    
+    g72x = (wxSoundFormatG72X *)m_sndformat;
+    
+    // Set PCM as the output format of the codec
+    pcm.SetSampleRate(g72x->GetSampleRate());
+    pcm.SetBPS(16);
+    pcm.SetChannels(1); // Only mono supported
+    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;
+            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;
+    }
+
+    // Let the router finish the work
+    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;
+    register wxUint8 bits;
+
+    // We have two bytes to compute
+    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;
-  }
+    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;
+    }
 }
index 77e8ec47b9f645b2867d1d3aae4666493b564c7d..33eb64f7f7995fbbf7e6e369ece7d0addf1822f7 100644 (file)
@@ -41,7 +41,7 @@ wxSoundStreamOSS::wxSoundStreamOSS(const wxString& dev_name)
 
   ioctl(m_fd, SNDCTL_DSP_GETBLKSIZE, &m_bufsize);
 
-  m_snderror = wxSOUND_NOERR;
+  m_snderror = wxSOUND_NOERROR;
 
   close(m_fd);
 
@@ -68,9 +68,9 @@ wxSoundStream& wxSoundStreamOSS::Read(void *buffer, wxUint32 len)
   m_q_filled  = TRUE;
 
   if (ret < 0)
-    m_snderror = wxSOUND_IOERR;
+    m_snderror = wxSOUND_IOERROR;
   else
-    m_snderror = wxSOUND_NOERR;
+    m_snderror = wxSOUND_NOERROR;
 
   return *this;
 }
@@ -83,9 +83,9 @@ wxSoundStream& wxSoundStreamOSS::Write(const void *buffer, wxUint32 len)
   m_q_filled  = TRUE;
 
   if (ret < 0)
-    m_snderror = wxSOUND_IOERR;
+    m_snderror = wxSOUND_IOERROR;
   else
-    m_snderror = wxSOUND_NOERR;
+    m_snderror = wxSOUND_NOERROR;
 
   return *this;
 }
@@ -110,7 +110,7 @@ bool wxSoundStreamOSS::SetSoundFormat(const wxSoundFormatBase& format)
 
   m_sndformat = format.Clone();
   if (!m_sndformat) {
-    m_snderror = wxSOUND_MEMERR;
+    m_snderror = wxSOUND_MEMERROR;
     return FALSE;
   }
   pcm_format = (wxSoundFormatPcm *)m_sndformat;
@@ -129,7 +129,7 @@ bool wxSoundStreamOSS::SetSoundFormat(const wxSoundFormatBase& format)
   ioctl(m_fd, SNDCTL_DSP_CHANNELS, &tmp);
   pcm_format->SetChannels(tmp);
 
-  m_snderror = wxSOUND_NOERR;
+  m_snderror = wxSOUND_NOERROR;
   if (*pcm_format != format) {
     m_snderror = wxSOUND_NOEXACT;
     return FALSE;
@@ -229,44 +229,43 @@ void wxSoundStreamOSS::WakeUpEvt(int evt)
 
 bool wxSoundStreamOSS::StartProduction(int evt)
 {
-  wxSoundFormatBase *old_frmt;
-
-  if (!m_oss_stop)
-    StopProduction();
-
-  old_frmt = m_sndformat->Clone();
-  if (!old_frmt) {
-    m_snderror = wxSOUND_MEMERR;
-    return FALSE;
-  }
-
-  if (evt == wxSOUND_OUTPUT)
-    m_fd = open(m_devname.mb_str(), O_WRONLY);
-  else if (evt == wxSOUND_INPUT)
-    m_fd = open(m_devname.mb_str(), O_RDONLY);
-
-  if (m_fd == -1) {
-    m_snderror = wxSOUND_INVDEV;
-    return FALSE;
-  }
-
-  SetSoundFormat(*old_frmt);
-  delete old_frmt;
-
+    wxSoundFormatBase *old_frmt;
+    
+    if (!m_oss_stop)
+        StopProduction();
+    
+    old_frmt = m_sndformat->Clone();
+    if (!old_frmt) {
+        m_snderror = wxSOUND_MEMERROR;
+        return FALSE;
+    }
+    
+    if (evt == wxSOUND_OUTPUT)
+        m_fd = open(m_devname.mb_str(), O_WRONLY);
+    else if (evt == wxSOUND_INPUT)
+        m_fd = open(m_devname.mb_str(), O_RDONLY);
+    
+    if (m_fd == -1) {
+        m_snderror = wxSOUND_INVDEV;
+        return FALSE;
+    }
+    
+    SetSoundFormat(*old_frmt);
+    delete old_frmt;
+    
+    int trig;
+    
+    if (evt == wxSOUND_OUTPUT) {
 #ifdef __WXGTK__
-  int trig;
-
-  if (evt == wxSOUND_OUTPUT) {
-    m_tag = gdk_input_add(m_fd, GDK_INPUT_WRITE, _wxSound_OSS_CBack, (gpointer)this);
-    trig = PCM_ENABLE_OUTPUT;
-  } else {
-    m_tag = gdk_input_add(m_fd, GDK_INPUT_READ, _wxSound_OSS_CBack, (gpointer)this);
-    trig = PCM_ENABLE_INPUT;
-  }
-#else
-  while (!m_oss_stop)
-    OnSoundEvent(evt);
+        m_tag = gdk_input_add(m_fd, GDK_INPUT_WRITE, _wxSound_OSS_CBack, (gpointer)this);
+#endif
+        trig = PCM_ENABLE_OUTPUT;
+    } else {
+#ifdef __WXGTK__
+        m_tag = gdk_input_add(m_fd, GDK_INPUT_READ, _wxSound_OSS_CBack, (gpointer)this);
 #endif
+        trig = PCM_ENABLE_INPUT;
+    }
 
   ioctl(m_fd, SNDCTL_DSP_SETTRIGGER, &trig);
 
index 371f68b64667e4616c3a348b7bbbf859f7aaefef..c5bc1011f7d043fc9a8b923460565083d30ae18e 100644 (file)
@@ -25,7 +25,7 @@
 // --------------------------------------------------------------------------
 
 wxSoundFormatUlaw::wxSoundFormatUlaw()
-  : m_srate(22050)
+        : m_srate(22050), m_channels(1)
 {
 }
 
@@ -35,40 +35,51 @@ wxSoundFormatUlaw::~wxSoundFormatUlaw()
 
 void wxSoundFormatUlaw::SetSampleRate(wxUint32 srate)
 {
-  m_srate = srate;
+    m_srate = srate;
 }
 
 wxUint32 wxSoundFormatUlaw::GetSampleRate() const
 {
-  return m_srate;
+    return m_srate;
 }
 
-wxSoundFormatBase *wxSoundFormatUlaw::Clone() const
+wxUint8 wxSoundFormatUlaw::GetChannels() const
 {
-  wxSoundFormatUlaw *ulaw = new wxSoundFormatUlaw();
+    return m_channels;
+}
 
-  ulaw->m_srate = m_srate;
-  return ulaw;
+void wxSoundFormatUlaw::SetChannels(wxUint8 nchannels)
+{
+    m_channels = nchannels;
+}
+
+wxSoundFormatBase *wxSoundFormatUlaw::Clone() const
+{
+    wxSoundFormatUlaw *ulaw = new wxSoundFormatUlaw();
+    
+    ulaw->m_srate = m_srate;
+    ulaw->m_channels = m_channels;
+    return ulaw;
 }
 
 wxUint32 wxSoundFormatUlaw::GetTimeFromBytes(wxUint32 bytes) const
 {
-  return (bytes / m_srate);
+    return (bytes / m_srate);
 }
 
 wxUint32 wxSoundFormatUlaw::GetBytesFromTime(wxUint32 time) const
 {
-  return time * m_srate;
+    return time * m_srate;
 }
 
 bool wxSoundFormatUlaw::operator !=(const wxSoundFormatBase& frmt2) const
 {
-  wxSoundFormatUlaw *ulaw = (wxSoundFormatUlaw *)&frmt2;
-
-  if (frmt2.GetType() != wxSOUND_ULAW)
-    return TRUE;
-
-  return (ulaw->m_srate != m_srate);
+    wxSoundFormatUlaw *ulaw = (wxSoundFormatUlaw *)&frmt2;
+    
+    if (frmt2.GetType() != wxSOUND_ULAW)
+        return TRUE;
+    
+    return (ulaw->m_srate != m_srate);
 }
 
 // --------------------------------------------------------------------------
@@ -88,58 +99,82 @@ wxSoundStreamUlaw::~wxSoundStreamUlaw()
 
 wxSoundStream& wxSoundStreamUlaw::Read(void *buffer, wxUint32 len)
 {
-    // TODO
-    return *this;
+    wxUint16 *old_linear;
+    register wxUint16 *linear_buffer;
+    register const wxUint8 *ulaw_buffer;
+    register wxUint32 countdown;
+
+    old_linear = linear_buffer = new wxUint16[len*2];
+    ulaw_buffer = (const wxUint8 *)buffer;
+    
+    m_router->Read(linear_buffer, len * 2);
+    
+    m_lastcount = countdown = m_router->GetLastAccess() / 2;
+    m_snderror  = m_router->GetError();
+    if (m_snderror != wxSOUND_NOERROR)
+        return *this;
+    
+    while (countdown > 0) {
+        *linear_buffer++ = ulaw2linear(*ulaw_buffer++);
+        countdown--;
+    }
+    
+    delete[] old_linear;
+    
+    return *m_router;    
 }
 
 wxSoundStream& wxSoundStreamUlaw::Write(const void *buffer, wxUint32 len)
 {
-  wxUint16 *old_linear;
-  register wxUint16 *linear_buffer;
-  register const wxUint8 *ulaw_buffer;
-  register wxUint32 countdown = len;
-
-  old_linear = linear_buffer = new wxUint16[len*2];
-  ulaw_buffer = (const wxUint8 *)buffer;
-
-  while (countdown != 0) {
-    *linear_buffer++ = ulaw2linear(*ulaw_buffer++);
-    countdown--;
-  }
-
-  m_router->Write(old_linear, len * 2);
-
-  delete[] old_linear;
-
-  return *m_router;
+    wxUint16 *old_linear;
+    register wxUint16 *linear_buffer;
+    register const wxUint8 *ulaw_buffer;
+    register wxUint32 countdown = len;
+    
+    old_linear = linear_buffer = new wxUint16[len*2];
+    ulaw_buffer = (const wxUint8 *)buffer;
+    
+    while (countdown > 0) {
+        *linear_buffer++ = ulaw2linear(*ulaw_buffer++);
+        countdown--;
+    }
+    
+    m_router->Write(old_linear, len * 2);
+    
+    delete[] old_linear;
+    
+    return *m_router;
 }
 
 wxUint32 wxSoundStreamUlaw::GetBestSize() const
 {
-  return m_sndio->GetBestSize() / 2;
+    return m_sndio->GetBestSize() / 2;
 }
 
 bool wxSoundStreamUlaw::SetSoundFormat(const wxSoundFormatBase& format)
 {
-  if (format.GetType() != wxSOUND_ULAW) {
-    m_snderror = wxSOUND_INVFRMT;
-    return FALSE;
-  }
-
-  wxSoundFormatPcm pcm;
-  wxSoundFormatUlaw *ulaw;
-
-  wxSoundStreamCodec::SetSoundFormat(format);
-
-  ulaw = (wxSoundFormatUlaw *)m_sndformat;
-
-  pcm.SetSampleRate(ulaw->GetSampleRate());
-  pcm.SetBPS(16);
-  pcm.SetChannels(1);
-  pcm.Signed(TRUE);
-  pcm.SetOrder(wxBYTE_ORDER);
-
-  m_router->SetSoundFormat(pcm);
-
-  return TRUE;
+    if (format.GetType() != wxSOUND_ULAW) {
+        m_snderror = wxSOUND_INVFRMT;
+        return FALSE;
+    }
+    
+    // As the codec only support 16 bits, Mono we must use a wxSoundRouter to filter the data and
+    // to translate them to a format supported by the sound card.
+    
+    wxSoundFormatPcm pcm;
+    wxSoundFormatUlaw *ulaw;
+    
+    wxSoundStreamCodec::SetSoundFormat(format);
+    
+    ulaw = (wxSoundFormatUlaw *)m_sndformat;
+    
+    pcm.SetSampleRate(ulaw->GetSampleRate());
+    pcm.SetBPS(16);
+    pcm.SetChannels(ulaw->GetChannels());
+    pcm.Signed(TRUE);
+    pcm.SetOrder(wxBYTE_ORDER);
+    
+    m_router->SetSoundFormat(pcm);
+    
+    return TRUE;
 }
index 4ddba8f577bb0f1aca3c30ac4b0118946ec75dfd..7b862e019aaa6e9ebc89b6e62fb99dcd041d1142 100644 (file)
@@ -12,6 +12,8 @@
 #pragma interface "sndulaw.h"
 #endif
 
+#include "wx/defs.h"
+
 #include "sndcodec.h"
 #include "sndbase.h"
 
 // ULAW format
 //
 class WXDLLEXPORT wxSoundFormatUlaw: public wxSoundFormatBase {
- public:
-  wxSoundFormatUlaw();
-  ~wxSoundFormatUlaw();
-
-  void SetSampleRate(wxUint32 srate);
-  wxUint32 GetSampleRate() const;
-
-  void SetChannels(wxUint8 channels);
-  wxUint8 GetChannels() const;
-
-  wxSoundFormatType GetType() const { return wxSOUND_ULAW; }
-  wxSoundFormatBase *Clone() const;
-
-  wxUint32 GetTimeFromBytes(wxUint32 bytes) const;
-  wxUint32 GetBytesFromTime(wxUint32 time) const;
-
-  bool operator !=(const wxSoundFormatBase& frmt2) const;
-
- protected:
-  wxUint32 m_srate;
+public:
+    wxSoundFormatUlaw();
+    ~wxSoundFormatUlaw();
+    
+    void SetSampleRate(wxUint32 srate);
+    wxUint32 GetSampleRate() const;
+    
+    void SetChannels(wxUint8 channels);
+    wxUint8 GetChannels() const;
+    
+    wxSoundFormatType GetType() const { return wxSOUND_ULAW; }
+    wxSoundFormatBase *Clone() const;
+    
+    wxUint32 GetTimeFromBytes(wxUint32 bytes) const;
+    wxUint32 GetBytesFromTime(wxUint32 time) const;
+    
+    bool operator !=(const wxSoundFormatBase& frmt2) const;
+    
+protected:
+    wxUint32 m_srate;
+    wxUint8 m_channels;
 };
 
 //
@@ -47,19 +50,19 @@ class WXDLLEXPORT wxSoundFormatUlaw: public wxSoundFormatBase {
 
 class WXDLLEXPORT wxSoundRouterStream;
 class WXDLLEXPORT wxSoundStreamUlaw: public wxSoundStreamCodec {
- public:
-  wxSoundStreamUlaw(wxSoundStream& sndio);
-  ~wxSoundStreamUlaw();
-
-  wxSoundStream& Read(void *buffer, wxUint32 len);
-  wxSoundStream& Write(const void *buffer, wxUint32 len);
-
-  bool SetSoundFormat(const wxSoundFormatBase& format);
-
-  wxUint32 GetBestSize() const;
-
- protected:
-  wxSoundRouterStream *m_router;
+public:
+    wxSoundStreamUlaw(wxSoundStream& sndio);
+    ~wxSoundStreamUlaw();
+    
+    wxSoundStream& Read(void *buffer, wxUint32 len);
+    wxSoundStream& Write(const void *buffer, wxUint32 len);
+    
+    bool SetSoundFormat(const wxSoundFormatBase& format);
+    
+    wxUint32 GetBestSize() const;
+    
+protected:
+    wxSoundRouterStream *m_router;
 };
 
 #endif
index 487ddfb3fc05f5d7784500abf4856570c770ce56..38b96186e0e19d0633cf280b9679b05ab3b091bc 100644 (file)
@@ -60,7 +60,7 @@ wxString wxSoundWave::GetCodecName() const
 bool wxSoundWave::CanRead()
 {
     wxUint32 len, signature1, signature2;
-    m_snderror = wxSOUND_NOERR;
+    m_snderror = wxSOUND_NOERROR;
 
     // Test the main signatures:
     //   "RIFF"
index f09231ee0d6813f096069b4ff95b1014fadd6635..a307c81ca217680b07bf34ce227895b225fe9843 100644 (file)
@@ -651,6 +651,7 @@ void wxSoundStreamWin::NotifyDoneBuffer(wxUint32 dev_handle, int flag)
 // -------------------------------------------------------------------------
 bool wxSoundStreamWin::SetSoundFormat(wxSoundFormatBase& base)
 {
+  // TODO: detect best format
   return wxSoundStream::SetSoundFormat(base);
 }
 
index b6f5ee9914d428e1b88e35614a183bd7ffed58ba..131b12503cee754d79df65c672bbe42dd0138dd8 100644 (file)
@@ -1,4 +1,4 @@
-////////////////////////////////////////////////////////////////////////////////
+// -----------------------------------------------------------------------------
 // Name:       vidwin.h
 // Purpose:    wxMMedia
 // Author:     Guilhem Lavaux
@@ -6,7 +6,7 @@
 // Updated:
 // Copyright:  (C) 1998, 1999, 2000 Guilhem Lavaux
 // License:    wxWindows license
-////////////////////////////////////////////////////////////////////////////////
+// -----------------------------------------------------------------------------
 
 #ifdef __GNUG__
 #pragma implementation "vidwin.h"
@@ -45,6 +45,7 @@ wxVideoWindows::wxVideoWindows(wxInputStream& str)
     m_filename    = wxGetTempFileName("wxvid");
     m_paused      = FALSE;
     m_stopped     = TRUE;
+    m_frameRate   = 1.0;
     
     wxFileOutputStream temp_file(m_filename);
     temp_file << str;
@@ -60,6 +61,7 @@ wxVideoWindows::wxVideoWindows(const wxString& filename)
     m_filename    = filename;
     m_paused      = FALSE;
     m_stopped     = TRUE;
+    m_frameRate   = 1.0;
     OpenFile();
 }
 
@@ -73,17 +75,41 @@ wxVideoWindows::~wxVideoWindows(void)
 
 void wxVideoWindows::OpenFile()
 {
-    MCI_DGV_OPEN_PARMS open_struct;
+    MCI_DGV_OPEN_PARMS openStruct;
+    MCI_DGV_SET_PARMS setStruct;
+    MCI_STATUS_PARMS statusStruct;
     DWORD ret;
 
-    open_struct.lpstrDeviceType = "avivideo";
-    open_struct.lpstrElementName = (LPSTR)(m_filename.mb_str());
-    open_struct.hWndParent = 0;
+    openStruct.lpstrDeviceType = "avivideo";
+    openStruct.lpstrElementName = (LPSTR)(m_filename.mb_str());
+    openStruct.hWndParent = 0;
     
     ret = mciSendCommand(0, MCI_OPEN,
                         MCI_OPEN_ELEMENT|MCI_DGV_OPEN_PARENT|MCI_OPEN_TYPE|MCI_DGV_OPEN_32BIT,
-                        (DWORD)(LPVOID)&open_struct);
-    m_internal->m_dev_id = open_struct.wDeviceID;
+                         (DWORD)(LPVOID)&openStruct);
+    m_internal->m_dev_id = openStruct.wDeviceID;
+
+
+    setStruct.dwCallback = 0;
+    setStruct.dwTimeFormat = MCI_FORMAT_FRAMES;
+
+    ret = mciSendCommand(m_internal->m_dev_id, MCI_SET, MCI_SET_TIME_FORMAT,
+                         (DWORD)(LPVOID)&setStruct);
+
+
+    statusStruct.dwCallback = 0;
+    statusStruct.dwItem = MCI_DGV_STATUS_FRAME_RATE;
+    ret = mciSendCommand(m_internal->m_dev_id, MCI_STATUS,
+                         MCI_STATUS_ITEM,
+                         (DWORD)(LPVOID)&statusStruct);
+
+    m_frameRate = ((double)statusStruct.dwReturn) / 1000;
+
+    statusStruct.dwItem = MCI_DGV_STATUS_BITSPERSAMPLE;
+    ret = mciSendCommand(m_internal->m_dev_id, MCI_STATUS, MCI_STATUS_ITEM,
+                         (DWORD)(LPVOID)&statusStruct);
+    m_bps = statusStruct.dwReturn;
+
 }
 
 bool wxVideoWindows::Pause()
@@ -91,7 +117,7 @@ bool wxVideoWindows::Pause()
     if (m_paused || m_stopped)
         return TRUE;
     m_paused = TRUE;
-    return (mciSendCommand(m_internal->m_dev_id, MCI_PAUSE, 0, 0) == 0);
+    return (mciSendCommand(m_internal->m_dev_id, MCI_PAUSE, MCI_WAIT, 0) == 0);
 }
 
 bool wxVideoWindows::Resume()
@@ -114,7 +140,6 @@ bool wxVideoWindows::IsStopped() const
 
 bool wxVideoWindows::GetSize(wxSize& size) const
 {
-    // Two random numbers.
     size.SetWidth(200);
     size.SetHeight(200);
     return TRUE;
@@ -169,16 +194,17 @@ bool wxVideoWindows::Stop()
     if (m_stopped)
         return FALSE;
     m_stopped = TRUE;
-    if (::mciSendCommand(m_internal->m_dev_id, MCI_STOP, 0, NULL) != 0)
+    if (::mciSendCommand(m_internal->m_dev_id, MCI_STOP, MCI_WAIT, NULL) != 0)
       return FALSE;
 
     seekStruct.dwCallback = 0;
     seekStruct.dwTo = 0;
-    return (::mciSendCommand(m_internal->m_dev_id, MCI_SEEK, 0, (DWORD)(LPVOID)&seekStruct) == 0);
+    return (::mciSendCommand(m_internal->m_dev_id, MCI_SEEK, MCI_SEEK_TO_START|MCI_WAIT, (DWORD)(LPVOID)&seekStruct) == 0);
 }
 
-
 // TODO TODO
+// I hate windows :-(. The doc says MCI_STATUS should return all info I want but when I call it
+// it returns to me with an UNSUPPORTED_FUNCTION error. I will have to do all by myself. Grrrr !
 
 wxString wxVideoWindows::GetMovieCodec() const
 {
@@ -202,12 +228,12 @@ wxUint8 wxVideoWindows::GetChannels() const
 
 wxUint8 wxVideoWindows::GetBPS() const
 {
-    return 8;
+    return m_bps;
 }
 
 double wxVideoWindows::GetFrameRate() const
 {
-    return 1.0;
+    return m_frameRate;
 }
 
 wxUint32 wxVideoWindows::GetNbFrames() const
index fd8a64b2b6b45f4e3c9afe2c7d5957f4a1346b80..eba6bd24707851789ca08340023de3723c084a7e 100644 (file)
@@ -59,6 +59,8 @@ protected:
     struct VIDW_Internal *m_internal;
     bool m_paused, m_stopped, m_remove_file;
     wxString m_filename;
+    double m_frameRate;
+    wxUint8 m_bps;
 
     void OpenFile();
 public: