Inserted "stdio catch" in wxExecute. The activation is controlled by wxProcess.
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
This commit is contained in:
@@ -19,6 +19,7 @@
|
|||||||
#include "wx/defs.h"
|
#include "wx/defs.h"
|
||||||
#include "wx/object.h"
|
#include "wx/object.h"
|
||||||
#include "wx/event.h"
|
#include "wx/event.h"
|
||||||
|
#include "wx/stream.h"
|
||||||
|
|
||||||
// Process Event handling
|
// Process Event handling
|
||||||
class WXDLLEXPORT wxProcessEvent : public wxEvent
|
class WXDLLEXPORT wxProcessEvent : public wxEvent
|
||||||
@@ -51,7 +52,8 @@ class WXDLLEXPORT wxProcess : public wxEvtHandler
|
|||||||
DECLARE_DYNAMIC_CLASS(wxProcess)
|
DECLARE_DYNAMIC_CLASS(wxProcess)
|
||||||
|
|
||||||
public:
|
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);
|
virtual void OnTerminate(int pid, int status);
|
||||||
|
|
||||||
@@ -59,8 +61,21 @@ public:
|
|||||||
// before the process it started terminates
|
// before the process it started terminates
|
||||||
void Detach();
|
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:
|
protected:
|
||||||
int m_id;
|
int m_id;
|
||||||
|
bool m_needPipe;
|
||||||
|
wxInputStream *m_in_stream;
|
||||||
|
wxOutputStream *m_out_stream;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void (wxObject::*wxProcessEventFunction)(wxProcessEvent&);
|
typedef void (wxObject::*wxProcessEventFunction)(wxProcessEvent&);
|
||||||
|
@@ -29,12 +29,23 @@
|
|||||||
IMPLEMENT_DYNAMIC_CLASS(wxProcess, wxEvtHandler)
|
IMPLEMENT_DYNAMIC_CLASS(wxProcess, wxEvtHandler)
|
||||||
IMPLEMENT_DYNAMIC_CLASS(wxProcessEvent, wxEvent)
|
IMPLEMENT_DYNAMIC_CLASS(wxProcessEvent, wxEvent)
|
||||||
|
|
||||||
wxProcess::wxProcess(wxEvtHandler *parent, int id)
|
wxProcess::wxProcess(wxEvtHandler *parent, bool needPipe, int id)
|
||||||
{
|
{
|
||||||
if (parent)
|
if (parent)
|
||||||
SetNextHandler(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)
|
void wxProcess::OnTerminate(int pid, int status)
|
||||||
@@ -51,3 +62,24 @@ void wxProcess::Detach()
|
|||||||
{
|
{
|
||||||
SetNextHandler(NULL);
|
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;
|
||||||
|
}
|
||||||
|
@@ -37,6 +37,7 @@
|
|||||||
#include "wx/log.h"
|
#include "wx/log.h"
|
||||||
|
|
||||||
#ifdef __WIN32__
|
#ifdef __WIN32__
|
||||||
|
#include "wx/stream.h"
|
||||||
#include "wx/process.h"
|
#include "wx/process.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -120,6 +121,94 @@ public:
|
|||||||
bool state; // set to FALSE when the process finishes
|
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
|
// implementation
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@@ -289,7 +378,6 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler)
|
|||||||
// only reached for space not inside quotes
|
// only reached for space not inside quotes
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString commandArgs = pc;
|
wxString commandArgs = pc;
|
||||||
|
|
||||||
wxWindow *winTop = wxTheApp->GetTopWindow();
|
wxWindow *winTop = wxTheApp->GetTopWindow();
|
||||||
@@ -314,6 +402,46 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler)
|
|||||||
return result;
|
return result;
|
||||||
#else // 1
|
#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
|
// create the process
|
||||||
STARTUPINFO si;
|
STARTUPINFO si;
|
||||||
wxZeroMemory(si);
|
wxZeroMemory(si);
|
||||||
@@ -327,7 +455,7 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler)
|
|||||||
(wxChar *)command.c_str(), // full command line
|
(wxChar *)command.c_str(), // full command line
|
||||||
NULL, // security attributes: defaults for both
|
NULL, // security attributes: defaults for both
|
||||||
NULL, // the process and its main thread
|
NULL, // the process and its main thread
|
||||||
FALSE, // don't inherit handles
|
inheritHandles, // inherit handles if we need pipes
|
||||||
CREATE_DEFAULT_ERROR_MODE |
|
CREATE_DEFAULT_ERROR_MODE |
|
||||||
CREATE_SUSPENDED, // flags
|
CREATE_SUSPENDED, // flags
|
||||||
NULL, // environment (use the same)
|
NULL, // environment (use the same)
|
||||||
@@ -336,11 +464,31 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler)
|
|||||||
&pi // process info
|
&pi // process info
|
||||||
) == 0 )
|
) == 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());
|
wxLogSysError(_("Execution of command '%s' failed"), command.c_str());
|
||||||
|
|
||||||
return 0;
|
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
|
// register the class for the hidden window used for the notifications
|
||||||
if ( !gs_classForHiddenWindow )
|
if ( !gs_classForHiddenWindow )
|
||||||
{
|
{
|
||||||
|
@@ -25,6 +25,8 @@
|
|||||||
#include "wx/process.h"
|
#include "wx/process.h"
|
||||||
#include "wx/thread.h"
|
#include "wx/thread.h"
|
||||||
|
|
||||||
|
#include "wx/stream.h"
|
||||||
|
|
||||||
#if wxUSE_GUI
|
#if wxUSE_GUI
|
||||||
#include "wx/unix/execute.h"
|
#include "wx/unix/execute.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -274,6 +276,83 @@ void wxHandleProcessTermination(wxEndProcessData *proc_data)
|
|||||||
#define WXUNUSED_UNLESS_GUI(p)
|
#define WXUNUSED_UNLESS_GUI(p)
|
||||||
#endif
|
#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,
|
long wxExecute(wxChar **argv,
|
||||||
bool sync,
|
bool sync,
|
||||||
wxProcess * WXUNUSED_UNLESS_GUI(process))
|
wxProcess * WXUNUSED_UNLESS_GUI(process))
|
||||||
@@ -316,6 +395,26 @@ long wxExecute(wxChar **argv,
|
|||||||
}
|
}
|
||||||
#endif // wxUSE_GUI
|
#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
|
// fork the process
|
||||||
#ifdef HAVE_VFORK
|
#ifdef HAVE_VFORK
|
||||||
pid_t pid = vfork();
|
pid_t pid = vfork();
|
||||||
@@ -324,6 +423,14 @@ long wxExecute(wxChar **argv,
|
|||||||
#endif
|
#endif
|
||||||
if (pid == -1)
|
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") );
|
wxLogSysError( _("Fork failed") );
|
||||||
|
|
||||||
ARGS_CLEANUP;
|
ARGS_CLEANUP;
|
||||||
@@ -347,7 +454,7 @@ long wxExecute(wxChar **argv,
|
|||||||
for ( int fd = 0; fd < FD_SETSIZE; fd++ )
|
for ( int fd = 0; fd < FD_SETSIZE; fd++ )
|
||||||
{
|
{
|
||||||
#if wxUSE_GUI
|
#if wxUSE_GUI
|
||||||
if ( fd == end_proc_detect[1] )
|
if ( fd == end_proc_detect[1] || fd == in_pipe[0] || fd == out_pipe[1] )
|
||||||
continue;
|
continue;
|
||||||
#endif // wxUSE_GUI
|
#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
|
#if 0
|
||||||
close(STDERR_FILENO);
|
close(STDERR_FILENO);
|
||||||
|
|
||||||
@@ -403,6 +520,20 @@ long wxExecute(wxChar **argv,
|
|||||||
}
|
}
|
||||||
else
|
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
|
// async execution, nothing special to do - caller will be
|
||||||
// notified about the process termination if process != NULL, data
|
// notified about the process termination if process != NULL, data
|
||||||
// will be deleted in GTK_EndProcessDetector
|
// will be deleted in GTK_EndProcessDetector
|
||||||
|
@@ -298,7 +298,9 @@ wxString MMBoardSoundFile::GetStringInformation()
|
|||||||
case wxSOUND_PCM: {
|
case wxSOUND_PCM: {
|
||||||
wxSoundFormatPcm *pcm_format = (wxSoundFormatPcm *)format;
|
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")
|
info += wxString::Format(wxT("Sampling rate: %d\n")
|
||||||
wxT("Bits per sample: %d\n")
|
wxT("Bits per sample: %d\n")
|
||||||
wxT("Number of channels: %d\n"),
|
wxT("Number of channels: %d\n"),
|
||||||
|
@@ -202,7 +202,7 @@ wxUint8 MMBoardApp::TestMultimediaCaps()
|
|||||||
// We now test the ESD support
|
// We now test the ESD support
|
||||||
|
|
||||||
dev = new wxSoundStreamESD();
|
dev = new wxSoundStreamESD();
|
||||||
if (dev->GetError() == wxSOUND_NOERR)
|
if (dev->GetError() == wxSOUND_NOERROR)
|
||||||
caps |= MM_SOUND_ESD;
|
caps |= MM_SOUND_ESD;
|
||||||
delete dev;
|
delete dev;
|
||||||
|
|
||||||
@@ -210,7 +210,7 @@ wxUint8 MMBoardApp::TestMultimediaCaps()
|
|||||||
// WARNING: There is a conflict between ESD and ALSA
|
// WARNING: There is a conflict between ESD and ALSA
|
||||||
|
|
||||||
dev = new wxSoundStreamOSS();
|
dev = new wxSoundStreamOSS();
|
||||||
if (dev->GetError() == wxSOUND_NOERR)
|
if (dev->GetError() == wxSOUND_NOERROR)
|
||||||
caps |= MM_SOUND_OSS;
|
caps |= MM_SOUND_OSS;
|
||||||
delete dev;
|
delete dev;
|
||||||
#endif
|
#endif
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Name: sndsnd.cpp
|
// Name: cdbase.cpp
|
||||||
// Purpose: wxMMedia
|
// Purpose: wxMMedia
|
||||||
// Author: Guilhem Lavaux
|
// Author: Guilhem Lavaux
|
||||||
// Created: 1997
|
// Created: 1997
|
||||||
|
@@ -1,7 +1,5 @@
|
|||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#define DEFINE_CONV(name, input_type, output_type, convert) \
|
#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 input_type src; \
|
||||||
register const input_type *t_buf_in = (input_type *)buf_in; \
|
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_8_sign, wxUint8, wxUint8, (src ^ 0x80))
|
||||||
|
|
||||||
DEFINE_CONV(8_16, wxUint8, wxUint16, (((wxUint16)src) << 8))
|
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, wxUint16, wxUint8, (wxUint8)(src & 0xff))
|
||||||
DEFINE_CONV(16_swap_8_sign, wxUint16, wxUint8, (wxUint8)((src & 0xff) ^ 0x80))
|
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_sign, wxUint16, wxUint16, (src ^ 0x8000))
|
||||||
DEFINE_CONV(16_swap, wxUint16, wxUint16, (((src & 0xff) << 8) | ((src >> 8) & 0xff)))
|
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))
|
// Problem.
|
||||||
DEFINE_CONV(16_sign_16_swap, wxUint16, wxUint16, ((((src & 0xff) << 8) | ((src >> 8) & 0xff)) ^ 0x80))
|
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))
|
DEFINE_CONV(16_swap_16_sign_swap, wxUint16, wxUint16, (src ^ 0x80))
|
||||||
|
@@ -99,6 +99,7 @@ bool wxSoundAiff::PrepareToPlay()
|
|||||||
m_snderror = wxSOUND_INVSTRM;
|
m_snderror = wxSOUND_INVSTRM;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
m_snderror = wxSOUND_NOERROR;
|
||||||
|
|
||||||
data.BigEndianOrdered(TRUE);
|
data.BigEndianOrdered(TRUE);
|
||||||
|
|
||||||
@@ -130,8 +131,10 @@ bool wxSoundAiff::PrepareToPlay()
|
|||||||
double srate;
|
double srate;
|
||||||
wxSoundFormatPcm sndformat;
|
wxSoundFormatPcm sndformat;
|
||||||
|
|
||||||
|
// Get sound data informations
|
||||||
data >> channels >> num_samples >> bps >> srate;
|
data >> channels >> num_samples >> bps >> srate;
|
||||||
|
|
||||||
|
// Convert them in a wxSoundFormat object
|
||||||
sndformat.SetSampleRate((wxUint32) srate);
|
sndformat.SetSampleRate((wxUint32) srate);
|
||||||
sndformat.SetBPS(bps);
|
sndformat.SetBPS(bps);
|
||||||
sndformat.SetChannels(channels);
|
sndformat.SetChannels(channels);
|
||||||
@@ -140,6 +143,7 @@ bool wxSoundAiff::PrepareToPlay()
|
|||||||
|
|
||||||
if (!SetSoundFormat(sndformat))
|
if (!SetSoundFormat(sndformat))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
// We pass all data left
|
||||||
m_input->SeekI(len-18, wxFromCurrent);
|
m_input->SeekI(len-18, wxFromCurrent);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -149,6 +153,7 @@ bool wxSoundAiff::PrepareToPlay()
|
|||||||
// m_input->SeekI(len-4, wxFromCurrent); // Pass the rest
|
// m_input->SeekI(len-4, wxFromCurrent); // Pass the rest
|
||||||
m_input->SeekI(ssnd + 4, wxFromCurrent);
|
m_input->SeekI(ssnd + 4, wxFromCurrent);
|
||||||
m_base_offset = m_input->TellI();
|
m_base_offset = m_input->TellI();
|
||||||
|
// len-8 bytes of samples
|
||||||
FinishPreparation(len - 8);
|
FinishPreparation(len - 8);
|
||||||
end_headers = TRUE;
|
end_headers = TRUE;
|
||||||
break;
|
break;
|
||||||
@@ -175,6 +180,7 @@ bool wxSoundAiff::FinishRecording()
|
|||||||
|
|
||||||
bool wxSoundAiff::RepositionStream(wxUint32 position)
|
bool wxSoundAiff::RepositionStream(wxUint32 position)
|
||||||
{
|
{
|
||||||
|
// If the stream is not seekable "TellI() returns wxInvalidOffset" we cannot reposition stream
|
||||||
if (m_base_offset == wxInvalidOffset)
|
if (m_base_offset == wxInvalidOffset)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
m_input->SeekI(m_base_offset, wxFromStart);
|
m_input->SeekI(m_base_offset, wxFromStart);
|
||||||
|
@@ -46,7 +46,7 @@ wxSoundStream::wxSoundStream()
|
|||||||
// Reset all variables to their neutral value.
|
// Reset all variables to their neutral value.
|
||||||
m_sndformat = NULL;
|
m_sndformat = NULL;
|
||||||
m_handler = NULL;
|
m_handler = NULL;
|
||||||
m_snderror = wxSOUND_NOERR;
|
m_snderror = wxSOUND_NOERROR;
|
||||||
m_lastcount = 0;
|
m_lastcount = 0;
|
||||||
for (i=0;i<2;i++)
|
for (i=0;i<2;i++)
|
||||||
m_callback[i] = NULL;
|
m_callback[i] = NULL;
|
||||||
@@ -85,7 +85,7 @@ bool wxSoundStream::SetSoundFormat(const wxSoundFormatBase& format)
|
|||||||
// call twice this function the previous registered callback is absolutely
|
// call twice this function the previous registered callback is absolutely
|
||||||
// ignored.
|
// ignored.
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
void wxSoundStream::Register(int evt, wxSoundCallback cbk, char *cdata)
|
void wxSoundStream::SetCallback(int evt, wxSoundCallback cbk, void *cdata)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
|
@@ -63,14 +63,14 @@ typedef enum {
|
|||||||
// - wxSOUND_MEMERR: Not enough memory.
|
// - wxSOUND_MEMERR: Not enough memory.
|
||||||
// ---------------------
|
// ---------------------
|
||||||
typedef enum {
|
typedef enum {
|
||||||
wxSOUND_NOERR,
|
wxSOUND_NOERROR,
|
||||||
wxSOUND_IOERR,
|
wxSOUND_IOERROR,
|
||||||
wxSOUND_INVFRMT,
|
wxSOUND_INVFRMT,
|
||||||
wxSOUND_INVDEV,
|
wxSOUND_INVDEV,
|
||||||
wxSOUND_NOEXACT,
|
wxSOUND_NOEXACT,
|
||||||
wxSOUND_INVSTRM,
|
wxSOUND_INVSTRM,
|
||||||
wxSOUND_NOCODEC,
|
wxSOUND_NOCODEC,
|
||||||
wxSOUND_MEMERR
|
wxSOUND_MEMERROR
|
||||||
} wxSoundError;
|
} wxSoundError;
|
||||||
|
|
||||||
class WXDLLEXPORT wxSoundStream;
|
class WXDLLEXPORT wxSoundStream;
|
||||||
@@ -83,7 +83,7 @@ class WXDLLEXPORT wxSoundStream;
|
|||||||
// - cdata: User callback data
|
// - cdata: User callback data
|
||||||
// ---------------------
|
// ---------------------
|
||||||
typedef void (*wxSoundCallback)(wxSoundStream *stream, int evt,
|
typedef void (*wxSoundCallback)(wxSoundStream *stream, int evt,
|
||||||
char *cdata);
|
void *cdata);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Base class for sound format specification
|
// Base class for sound format specification
|
||||||
@@ -128,7 +128,7 @@ class wxSoundStream {
|
|||||||
wxSoundFormatBase& GetSoundFormat() const { return *m_sndformat; }
|
wxSoundFormatBase& GetSoundFormat() const { return *m_sndformat; }
|
||||||
|
|
||||||
// Register a callback for a specified async event.
|
// 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
|
// Starts the async notifier. After this call, the stream begins either
|
||||||
// recording or playing or the two at the same time.
|
// recording or playing or the two at the same time.
|
||||||
@@ -158,7 +158,7 @@ class wxSoundStream {
|
|||||||
wxSoundStream *m_handler;
|
wxSoundStream *m_handler;
|
||||||
|
|
||||||
wxSoundCallback m_callback[2];
|
wxSoundCallback m_callback[2];
|
||||||
char *m_cdata[2];
|
void *m_cdata[2];
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Handles event
|
// Handles event
|
||||||
|
@@ -8,8 +8,13 @@
|
|||||||
#ifdef __GNUG__
|
#ifdef __GNUG__
|
||||||
#pragma implementation "sndcpcm.cpp"
|
#pragma implementation "sndcpcm.cpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <wx/wxprec.h>
|
#include <wx/wxprec.h>
|
||||||
|
|
||||||
|
#ifndef WX_PRECOMP
|
||||||
|
#include <wx/debug.h>
|
||||||
|
#include <wx/log.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "sndbase.h"
|
#include "sndbase.h"
|
||||||
#include "sndpcm.h"
|
#include "sndpcm.h"
|
||||||
#include "sndcpcm.h"
|
#include "sndcpcm.h"
|
||||||
@@ -19,59 +24,108 @@ wxSoundStreamPcm::wxSoundStreamPcm(wxSoundStream& sndio)
|
|||||||
{
|
{
|
||||||
m_function_in = NULL;
|
m_function_in = NULL;
|
||||||
m_function_out = NULL;
|
m_function_out = NULL;
|
||||||
|
m_prebuffer = NULL;
|
||||||
|
m_prebuffer_size = 0;
|
||||||
|
m_best_size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxSoundStreamPcm::~wxSoundStreamPcm()
|
wxSoundStreamPcm::~wxSoundStreamPcm()
|
||||||
{
|
{
|
||||||
|
if (m_prebuffer)
|
||||||
|
delete[] m_prebuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxUint32 wxSoundStreamPcm::GetBestSize() const
|
||||||
|
{
|
||||||
|
return m_best_size;
|
||||||
|
}
|
||||||
|
|
||||||
#include "converter.def"
|
#include "converter.def"
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
// Main PCM stream converter table
|
// Main PCM stream converter table
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
wxSoundStreamPcm::ConverterType s_converters[] = {
|
// Definition
|
||||||
NULL,
|
// XX -> YY
|
||||||
Convert_8_8_sign, /* 8 -> 8 sign */
|
// XX -> YY sign
|
||||||
NULL,
|
//
|
||||||
NULL,
|
// XX swapped -> YY
|
||||||
NULL,
|
// XX swapped -> YY sign
|
||||||
NULL,
|
//
|
||||||
|
// 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, /* 8 -> 16 */
|
||||||
Convert_8_16_sign, /* 8 -> 16 sign */
|
Convert_8_16_sign /* 8 -> 16 sign */
|
||||||
|
},
|
||||||
|
{
|
||||||
Convert_8_16_swap, /* 8 -> 16 swapped */
|
Convert_8_16_swap, /* 8 -> 16 swapped */
|
||||||
Convert_8_16_sign_swap, /* 8 -> 16 sign swapped */
|
Convert_8_16_sign_swap /* 8 -> 16 sign swapped */
|
||||||
|
},
|
||||||
|
{
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{
|
||||||
Convert_16_8, /* 16 -> 8 */
|
Convert_16_8, /* 16 -> 8 */
|
||||||
Convert_16_8_sign, /* 16 -> 8 sign */
|
Convert_16_8_sign /* 16 -> 8 sign */
|
||||||
|
},
|
||||||
|
{
|
||||||
Convert_16_swap_8, /* 16 swapped -> 8 */
|
Convert_16_swap_8, /* 16 swapped -> 8 */
|
||||||
Convert_16_swap_8_sign, /* 16 swapped -> 8 sign */
|
Convert_16_swap_8_sign /* 16 swapped -> 8 sign */
|
||||||
NULL,
|
},
|
||||||
|
{
|
||||||
NULL,
|
NULL,
|
||||||
|
NULL
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
{
|
||||||
NULL, /* 16 -> 16 */
|
NULL, /* 16 -> 16 */
|
||||||
Convert_16_sign, /* 16 -> 16 sign */
|
Convert_16_sign /* 16 -> 16 sign */
|
||||||
|
},
|
||||||
|
{
|
||||||
Convert_16_swap, /* 16 swapped -> 16 */
|
Convert_16_swap, /* 16 swapped -> 16 */
|
||||||
Convert_16_swap_16_sign, /* 16 swapped -> 16 sign */
|
Convert_16_swap_16_sign /* 16 swapped -> 16 sign */
|
||||||
Convert_16_sign_16_swap, /* 16 sign -> 16 swapped */
|
},
|
||||||
|
{
|
||||||
|
NULL,
|
||||||
Convert_16_swap_16_sign_swap /* 16 swapped -> 16 sign swapped */
|
Convert_16_swap_16_sign_swap /* 16 swapped -> 16 sign swapped */
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CONVERT_BPS 0
|
// This is the buffer size multiplier. It gives the needed size of the output size.
|
||||||
#define CONVERT_SIGN 1
|
static float s_converters_multip[] = {1, 2, 0.5, 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
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// TODO: Read() and Write() aren't really safe. If you give it a buffer which
|
// TODO: Read() and Write() aren't really safe. If you give it a buffer which
|
||||||
@@ -80,8 +134,10 @@ wxSoundStreamPcm::ConverterType s_converters[] = {
|
|||||||
|
|
||||||
wxSoundStream& wxSoundStreamPcm::Read(void *buffer, wxUint32 len)
|
wxSoundStream& wxSoundStreamPcm::Read(void *buffer, wxUint32 len)
|
||||||
{
|
{
|
||||||
wxUint32 real_len;
|
wxUint32 in_bufsize;
|
||||||
char *tmp_buf;
|
|
||||||
|
// We must have a multiple of 2
|
||||||
|
len &= 0x01;
|
||||||
|
|
||||||
if (!m_function_in) {
|
if (!m_function_in) {
|
||||||
m_sndio->Read(buffer, len);
|
m_sndio->Read(buffer, len);
|
||||||
@@ -90,43 +146,79 @@ wxSoundStream& wxSoundStreamPcm::Read(void *buffer, wxUint32 len)
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
real_len = (m_16_to_8) ? len / 2 : len;
|
in_bufsize = GetReadSize(len);
|
||||||
|
|
||||||
tmp_buf = new char[real_len];
|
if (len <= m_best_size) {
|
||||||
|
m_sndio->Read(m_prebuffer, in_bufsize);
|
||||||
m_sndio->Read(tmp_buf, real_len);
|
|
||||||
m_lastcount = m_sndio->GetLastAccess();
|
|
||||||
m_snderror = m_sndio->GetError();
|
m_snderror = m_sndio->GetError();
|
||||||
if (m_snderror != wxSOUND_NOERR)
|
if (m_snderror != wxSOUND_NOERROR) {
|
||||||
|
m_lastcount = 0;
|
||||||
return *this;
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
m_function_in(tmp_buf, (char *)buffer, m_lastcount);
|
m_function_in(m_prebuffer, buffer, m_sndio->GetLastAccess());
|
||||||
|
} else {
|
||||||
|
char *temp_buffer;
|
||||||
|
|
||||||
delete[] tmp_buf;
|
temp_buffer = new char[in_bufsize];
|
||||||
|
m_sndio->Read(temp_buffer, in_bufsize);
|
||||||
|
|
||||||
if (m_16_to_8)
|
m_snderror = m_sndio->GetError();
|
||||||
m_lastcount *= 2;
|
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;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxSoundStream& wxSoundStreamPcm::Write(const void *buffer, wxUint32 len)
|
wxSoundStream& wxSoundStreamPcm::Write(const void *buffer, wxUint32 len)
|
||||||
{
|
{
|
||||||
char *tmp_buf;
|
wxUint32 out_bufsize;
|
||||||
wxUint32 len2;
|
|
||||||
|
|
||||||
if (!m_function_out)
|
if (!m_function_out) {
|
||||||
return m_sndio->Write(buffer, len);
|
m_sndio->Write(buffer, len);
|
||||||
|
m_lastcount = m_sndio->GetLastAccess();
|
||||||
|
m_snderror = m_sndio->GetError();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
len2 = (m_16_to_8) ? len / 2 : len;
|
out_bufsize = GetWriteSize(len);
|
||||||
|
|
||||||
tmp_buf = new char[len2];
|
if (len <= m_best_size) {
|
||||||
m_function_out((const char *)buffer, tmp_buf, len2);
|
out_bufsize = GetWriteSize(len);
|
||||||
m_sndio->Write(tmp_buf, len);
|
|
||||||
delete[] tmp_buf;
|
|
||||||
|
|
||||||
m_lastcount = (m_16_to_8) ?
|
m_function_out(buffer, m_prebuffer, len);
|
||||||
(m_sndio->GetLastAccess() * 2) : m_sndio->GetLastAccess();
|
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 = (wxUint32)(m_sndio->GetLastAccess() / m_multiplier_out);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -135,9 +227,6 @@ bool wxSoundStreamPcm::SetSoundFormat(const wxSoundFormatBase& format)
|
|||||||
{
|
{
|
||||||
wxSoundFormatBase *new_format;
|
wxSoundFormatBase *new_format;
|
||||||
wxSoundFormatPcm *pcm_format, *pcm_format2;
|
wxSoundFormatPcm *pcm_format, *pcm_format2;
|
||||||
ConverterType *current_table_out, *current_table_in;
|
|
||||||
int index;
|
|
||||||
bool change_sign;
|
|
||||||
|
|
||||||
if (m_sndio->SetSoundFormat(format)) {
|
if (m_sndio->SetSoundFormat(format)) {
|
||||||
m_function_out = NULL;
|
m_function_out = NULL;
|
||||||
@@ -155,6 +244,22 @@ bool wxSoundStreamPcm::SetSoundFormat(const wxSoundFormatBase& format)
|
|||||||
pcm_format = (wxSoundFormatPcm *)&format;
|
pcm_format = (wxSoundFormatPcm *)&format;
|
||||||
pcm_format2 = (wxSoundFormatPcm *)new_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:
|
// Select table to use:
|
||||||
// * 8 bits -> 8 bits
|
// * 8 bits -> 8 bits
|
||||||
@@ -162,25 +267,30 @@ bool wxSoundStreamPcm::SetSoundFormat(const wxSoundFormatBase& format)
|
|||||||
// * 8 bits -> 16 bits
|
// * 8 bits -> 16 bits
|
||||||
// * 16 bits -> 16 bits
|
// * 16 bits -> 16 bits
|
||||||
|
|
||||||
m_16_to_8 = FALSE;
|
int table_no, table_no2;
|
||||||
if (pcm_format->GetBPS() != pcm_format2->GetBPS()) {
|
int i_sign, i_swap;
|
||||||
m_16_to_8 = TRUE;
|
|
||||||
if (pcm_format2->GetBPS() == 8) {
|
switch (pcm_format->GetBPS()) {
|
||||||
current_table_out = &s_converters[CONVERT_BASE_16_8];
|
case 8:
|
||||||
current_table_in = &s_converters[CONVERT_BASE_8_16];
|
table_no = 0;
|
||||||
} else {
|
break;
|
||||||
current_table_out = &s_converters[CONVERT_BASE_8_16];
|
case 16:
|
||||||
current_table_in = &s_converters[CONVERT_BASE_16_8];
|
table_no = 1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else if (pcm_format->GetBPS() == 16) {
|
switch (pcm_format2->GetBPS()) {
|
||||||
current_table_out = &s_converters[CONVERT_BASE_16_16];
|
case 8:
|
||||||
current_table_in = &s_converters[CONVERT_BASE_16_16];
|
table_no2 = 0;
|
||||||
} else {
|
break;
|
||||||
current_table_out = &s_converters[CONVERT_BASE_8_8];
|
case 16:
|
||||||
current_table_in = &s_converters[CONVERT_BASE_8_8];
|
table_no2 = 1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
change_sign = (pcm_format2->Signed() != pcm_format->Signed());
|
if (pcm_format2->Signed() != pcm_format->Signed())
|
||||||
|
i_sign = 1;
|
||||||
|
else
|
||||||
|
i_sign = 0;
|
||||||
|
|
||||||
#define MY_ORDER wxBYTE_ORDER
|
#define MY_ORDER wxBYTE_ORDER
|
||||||
#if wxBYTE_ORDER == wxLITTLE_ENDIAN
|
#if wxBYTE_ORDER == wxLITTLE_ENDIAN
|
||||||
@@ -192,33 +302,88 @@ bool wxSoundStreamPcm::SetSoundFormat(const wxSoundFormatBase& format)
|
|||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
// Find the good converter !
|
// Find the good converter !
|
||||||
|
|
||||||
|
if (pcm_format->GetOrder() == OTHER_ORDER) {
|
||||||
if (pcm_format->GetOrder() == OTHER_ORDER &&
|
if (pcm_format->GetOrder() == pcm_format2->GetOrder())
|
||||||
pcm_format2->GetOrder() == OTHER_ORDER && change_sign)
|
i_swap = 2;
|
||||||
index = CONVERT_SWAP_SIGN_SWAP;
|
|
||||||
|
|
||||||
else if (pcm_format->GetOrder() == OTHER_ORDER &&
|
|
||||||
pcm_format2->GetOrder() == MY_ORDER && change_sign)
|
|
||||||
index = CONVERT_SWAP_SIGN;
|
|
||||||
|
|
||||||
else if (pcm_format->GetOrder() == MY_ORDER &&
|
|
||||||
pcm_format->GetOrder() == OTHER_ORDER && change_sign)
|
|
||||||
index = CONVERT_SIGN_SWAP;
|
|
||||||
|
|
||||||
else if (change_sign)
|
|
||||||
index = CONVERT_SIGN;
|
|
||||||
|
|
||||||
else if (!change_sign &&
|
|
||||||
pcm_format->GetOrder() != pcm_format2->GetOrder())
|
|
||||||
index = CONVERT_SWAP;
|
|
||||||
|
|
||||||
else
|
else
|
||||||
index = CONVERT_BPS;
|
i_swap = 1;
|
||||||
|
} else {
|
||||||
|
if (pcm_format->GetOrder() == pcm_format2->GetOrder())
|
||||||
|
i_swap = 0;
|
||||||
|
else
|
||||||
|
i_swap = 1;
|
||||||
|
}
|
||||||
|
|
||||||
m_function_out = current_table_out[index];
|
m_function_out = s_converters[table_no*2+table_no2][i_swap][i_sign];
|
||||||
m_function_in = current_table_in[index];
|
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];
|
||||||
|
|
||||||
|
if (m_prebuffer)
|
||||||
|
delete[] m_prebuffer;
|
||||||
|
|
||||||
|
// 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_sndio->SetSoundFormat(*new_format);
|
|
||||||
m_sndformat = new_format;
|
m_sndformat = new_format;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
#define FLOATBITS 16
|
||||||
|
#define INTBITS 16
|
||||||
|
#define FLOATMASK 0xffff
|
||||||
|
#define INTMASK 0xffff0000
|
||||||
|
|
||||||
|
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
|
||||||
|
@@ -20,8 +20,9 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
class wxSoundStreamPcm: public wxSoundStreamCodec {
|
class wxSoundStreamPcm: public wxSoundStreamCodec {
|
||||||
public:
|
public:
|
||||||
typedef void (*ConverterType)(const char *buf_in, char *buf_out, wxUint32 len);
|
typedef void (*ConverterType)(const void *buf_in, void *buf_out,
|
||||||
|
wxUint32 len);
|
||||||
|
|
||||||
wxSoundStreamPcm(wxSoundStream& sndio);
|
wxSoundStreamPcm(wxSoundStream& sndio);
|
||||||
~wxSoundStreamPcm();
|
~wxSoundStreamPcm();
|
||||||
@@ -31,10 +32,22 @@ class wxSoundStreamPcm: public wxSoundStreamCodec {
|
|||||||
|
|
||||||
bool SetSoundFormat(const wxSoundFormatBase& format);
|
bool SetSoundFormat(const wxSoundFormatBase& format);
|
||||||
|
|
||||||
protected:
|
wxUint32 GetBestSize() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
wxUint32 GetReadSize(wxUint32 len) const;
|
||||||
|
wxUint32 GetWriteSize(wxUint32 len) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
ConverterType m_function_out, m_function_in;
|
ConverterType m_function_out, m_function_in;
|
||||||
|
|
||||||
bool m_16_to_8;
|
// 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
|
#endif
|
||||||
|
@@ -59,7 +59,7 @@ wxSoundStreamESD::wxSoundStreamESD(const wxString& hostname)
|
|||||||
SetSoundFormat(pcm_default);
|
SetSoundFormat(pcm_default);
|
||||||
|
|
||||||
// Initialize some variable
|
// Initialize some variable
|
||||||
m_snderror = wxSOUND_NOERR;
|
m_snderror = wxSOUND_NOERROR;
|
||||||
m_esd_stop = TRUE;
|
m_esd_stop = TRUE;
|
||||||
m_q_filled = TRUE;
|
m_q_filled = TRUE;
|
||||||
m_fd_output= -1;
|
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);
|
m_lastcount = (wxUint32)ret = read(m_fd_input, buffer, len);
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
m_snderror = wxSOUND_IOERR;
|
m_snderror = wxSOUND_IOERROR;
|
||||||
else
|
else
|
||||||
m_snderror = wxSOUND_NOERR;
|
m_snderror = wxSOUND_NOERROR;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -101,9 +101,9 @@ wxSoundStream& wxSoundStreamESD::Write(const void *buffer, wxUint32 len)
|
|||||||
m_lastcount = (wxUint32)ret = write(m_fd_output, buffer, len);
|
m_lastcount = (wxUint32)ret = write(m_fd_output, buffer, len);
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
m_snderror = wxSOUND_IOERR;
|
m_snderror = wxSOUND_IOERROR;
|
||||||
else
|
else
|
||||||
m_snderror = wxSOUND_NOERR;
|
m_snderror = wxSOUND_NOERROR;
|
||||||
|
|
||||||
m_q_filled = TRUE;
|
m_q_filled = TRUE;
|
||||||
|
|
||||||
@@ -133,7 +133,7 @@ bool wxSoundStreamESD::SetSoundFormat(const wxSoundFormatBase& format)
|
|||||||
|
|
||||||
m_sndformat = format.Clone();
|
m_sndformat = format.Clone();
|
||||||
if (!m_sndformat) {
|
if (!m_sndformat) {
|
||||||
m_snderror = wxSOUND_MEMERR;
|
m_snderror = wxSOUND_MEMERROR;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
pcm_format = (wxSoundFormatPcm *)m_sndformat;
|
pcm_format = (wxSoundFormatPcm *)m_sndformat;
|
||||||
@@ -141,7 +141,7 @@ bool wxSoundStreamESD::SetSoundFormat(const wxSoundFormatBase& format)
|
|||||||
// Detect the best format
|
// Detect the best format
|
||||||
DetectBest(pcm_format);
|
DetectBest(pcm_format);
|
||||||
|
|
||||||
m_snderror = wxSOUND_NOERR;
|
m_snderror = wxSOUND_NOERROR;
|
||||||
if (*pcm_format != format) {
|
if (*pcm_format != format) {
|
||||||
m_snderror = wxSOUND_NOEXACT;
|
m_snderror = wxSOUND_NOEXACT;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -256,7 +256,7 @@ void wxSoundStreamESD::DetectBest(wxSoundFormatPcm *pcm)
|
|||||||
{
|
{
|
||||||
wxSoundFormatPcm best_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.SetSampleRate(pcm->GetSampleRate());
|
||||||
best_pcm.SetChannels(pcm->GetChannels());
|
best_pcm.SetChannels(pcm->GetChannels());
|
||||||
|
@@ -325,7 +325,7 @@ wxString wxSoundFileStream::GetCodecName() const
|
|||||||
|
|
||||||
wxUint32 wxSoundFileStream::GetLength()
|
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 (PrepareToPlay()) ? m_length : 0;
|
||||||
|
|
||||||
return m_length;
|
return m_length;
|
||||||
@@ -333,7 +333,7 @@ wxUint32 wxSoundFileStream::GetLength()
|
|||||||
|
|
||||||
wxUint32 wxSoundFileStream::GetPosition()
|
wxUint32 wxSoundFileStream::GetPosition()
|
||||||
{
|
{
|
||||||
if (!m_prepared && m_input != NULL && GetError() == wxSOUND_NOERR)
|
if (!m_prepared && m_input != NULL && GetError() == wxSOUND_NOERROR)
|
||||||
PrepareToPlay();
|
PrepareToPlay();
|
||||||
|
|
||||||
return m_length-m_bytes_left;
|
return m_length-m_bytes_left;
|
||||||
@@ -341,7 +341,7 @@ wxUint32 wxSoundFileStream::GetPosition()
|
|||||||
|
|
||||||
wxUint32 wxSoundFileStream::SetPosition(wxUint32 new_position)
|
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();
|
PrepareToPlay();
|
||||||
|
|
||||||
if (!m_prepared)
|
if (!m_prepared)
|
||||||
|
@@ -71,7 +71,7 @@ wxUint32 wxSoundFormatG72X::GetTimeFromBytes(wxUint32 bytes) const
|
|||||||
n_bits = 0;
|
n_bits = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return (wxUint32)((bytes / m_srate) * ((float)n_bits / 8));
|
return (wxUint32)((bytes / m_srate) * n_bits) / 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxUint32 wxSoundFormatG72X::GetBytesFromTime(wxUint32 time) const
|
wxUint32 wxSoundFormatG72X::GetBytesFromTime(wxUint32 time) const
|
||||||
@@ -91,7 +91,7 @@ wxUint32 wxSoundFormatG72X::GetBytesFromTime(wxUint32 time) const
|
|||||||
default:
|
default:
|
||||||
n_bits = 0;
|
n_bits = 0;
|
||||||
}
|
}
|
||||||
return (wxUint32)(time * (m_srate * ((float)n_bits / 8)));
|
return (wxUint32)((time * m_srate * n_bits) / 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxSoundFormatG72X::operator !=(const wxSoundFormatBase& frmt2) const
|
bool wxSoundFormatG72X::operator !=(const wxSoundFormatBase& frmt2) const
|
||||||
@@ -204,7 +204,7 @@ bool wxSoundStreamG72X::SetSoundFormat(const wxSoundFormatBase& format)
|
|||||||
// Set PCM as the output format of the codec
|
// Set PCM as the output format of the codec
|
||||||
pcm.SetSampleRate(g72x->GetSampleRate());
|
pcm.SetSampleRate(g72x->GetSampleRate());
|
||||||
pcm.SetBPS(16);
|
pcm.SetBPS(16);
|
||||||
pcm.SetChannels(1);
|
pcm.SetChannels(1); // Only mono supported
|
||||||
pcm.Signed(TRUE);
|
pcm.Signed(TRUE);
|
||||||
pcm.SetOrder(wxBYTE_ORDER);
|
pcm.SetOrder(wxBYTE_ORDER);
|
||||||
|
|
||||||
@@ -239,6 +239,7 @@ wxUint8 wxSoundStreamG72X::GetBits()
|
|||||||
{
|
{
|
||||||
register wxUint8 bits;
|
register wxUint8 bits;
|
||||||
|
|
||||||
|
// We have two bytes to compute
|
||||||
if (m_current_b_pos < m_n_bits) {
|
if (m_current_b_pos < m_n_bits) {
|
||||||
register wxUint8 b_left;
|
register wxUint8 b_left;
|
||||||
|
|
||||||
|
@@ -41,7 +41,7 @@ wxSoundStreamOSS::wxSoundStreamOSS(const wxString& dev_name)
|
|||||||
|
|
||||||
ioctl(m_fd, SNDCTL_DSP_GETBLKSIZE, &m_bufsize);
|
ioctl(m_fd, SNDCTL_DSP_GETBLKSIZE, &m_bufsize);
|
||||||
|
|
||||||
m_snderror = wxSOUND_NOERR;
|
m_snderror = wxSOUND_NOERROR;
|
||||||
|
|
||||||
close(m_fd);
|
close(m_fd);
|
||||||
|
|
||||||
@@ -68,9 +68,9 @@ wxSoundStream& wxSoundStreamOSS::Read(void *buffer, wxUint32 len)
|
|||||||
m_q_filled = TRUE;
|
m_q_filled = TRUE;
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
m_snderror = wxSOUND_IOERR;
|
m_snderror = wxSOUND_IOERROR;
|
||||||
else
|
else
|
||||||
m_snderror = wxSOUND_NOERR;
|
m_snderror = wxSOUND_NOERROR;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -83,9 +83,9 @@ wxSoundStream& wxSoundStreamOSS::Write(const void *buffer, wxUint32 len)
|
|||||||
m_q_filled = TRUE;
|
m_q_filled = TRUE;
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
m_snderror = wxSOUND_IOERR;
|
m_snderror = wxSOUND_IOERROR;
|
||||||
else
|
else
|
||||||
m_snderror = wxSOUND_NOERR;
|
m_snderror = wxSOUND_NOERROR;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -110,7 +110,7 @@ bool wxSoundStreamOSS::SetSoundFormat(const wxSoundFormatBase& format)
|
|||||||
|
|
||||||
m_sndformat = format.Clone();
|
m_sndformat = format.Clone();
|
||||||
if (!m_sndformat) {
|
if (!m_sndformat) {
|
||||||
m_snderror = wxSOUND_MEMERR;
|
m_snderror = wxSOUND_MEMERROR;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
pcm_format = (wxSoundFormatPcm *)m_sndformat;
|
pcm_format = (wxSoundFormatPcm *)m_sndformat;
|
||||||
@@ -129,7 +129,7 @@ bool wxSoundStreamOSS::SetSoundFormat(const wxSoundFormatBase& format)
|
|||||||
ioctl(m_fd, SNDCTL_DSP_CHANNELS, &tmp);
|
ioctl(m_fd, SNDCTL_DSP_CHANNELS, &tmp);
|
||||||
pcm_format->SetChannels(tmp);
|
pcm_format->SetChannels(tmp);
|
||||||
|
|
||||||
m_snderror = wxSOUND_NOERR;
|
m_snderror = wxSOUND_NOERROR;
|
||||||
if (*pcm_format != format) {
|
if (*pcm_format != format) {
|
||||||
m_snderror = wxSOUND_NOEXACT;
|
m_snderror = wxSOUND_NOEXACT;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -236,7 +236,7 @@ bool wxSoundStreamOSS::StartProduction(int evt)
|
|||||||
|
|
||||||
old_frmt = m_sndformat->Clone();
|
old_frmt = m_sndformat->Clone();
|
||||||
if (!old_frmt) {
|
if (!old_frmt) {
|
||||||
m_snderror = wxSOUND_MEMERR;
|
m_snderror = wxSOUND_MEMERROR;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -253,20 +253,19 @@ bool wxSoundStreamOSS::StartProduction(int evt)
|
|||||||
SetSoundFormat(*old_frmt);
|
SetSoundFormat(*old_frmt);
|
||||||
delete old_frmt;
|
delete old_frmt;
|
||||||
|
|
||||||
#ifdef __WXGTK__
|
|
||||||
int trig;
|
int trig;
|
||||||
|
|
||||||
if (evt == wxSOUND_OUTPUT) {
|
if (evt == wxSOUND_OUTPUT) {
|
||||||
|
#ifdef __WXGTK__
|
||||||
m_tag = gdk_input_add(m_fd, GDK_INPUT_WRITE, _wxSound_OSS_CBack, (gpointer)this);
|
m_tag = gdk_input_add(m_fd, GDK_INPUT_WRITE, _wxSound_OSS_CBack, (gpointer)this);
|
||||||
|
#endif
|
||||||
trig = PCM_ENABLE_OUTPUT;
|
trig = PCM_ENABLE_OUTPUT;
|
||||||
} else {
|
} else {
|
||||||
|
#ifdef __WXGTK__
|
||||||
m_tag = gdk_input_add(m_fd, GDK_INPUT_READ, _wxSound_OSS_CBack, (gpointer)this);
|
m_tag = gdk_input_add(m_fd, GDK_INPUT_READ, _wxSound_OSS_CBack, (gpointer)this);
|
||||||
|
#endif
|
||||||
trig = PCM_ENABLE_INPUT;
|
trig = PCM_ENABLE_INPUT;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
while (!m_oss_stop)
|
|
||||||
OnSoundEvent(evt);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ioctl(m_fd, SNDCTL_DSP_SETTRIGGER, &trig);
|
ioctl(m_fd, SNDCTL_DSP_SETTRIGGER, &trig);
|
||||||
|
|
||||||
|
@@ -25,7 +25,7 @@
|
|||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
wxSoundFormatUlaw::wxSoundFormatUlaw()
|
wxSoundFormatUlaw::wxSoundFormatUlaw()
|
||||||
: m_srate(22050)
|
: m_srate(22050), m_channels(1)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,11 +43,22 @@ wxUint32 wxSoundFormatUlaw::GetSampleRate() const
|
|||||||
return m_srate;
|
return m_srate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxUint8 wxSoundFormatUlaw::GetChannels() const
|
||||||
|
{
|
||||||
|
return m_channels;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxSoundFormatUlaw::SetChannels(wxUint8 nchannels)
|
||||||
|
{
|
||||||
|
m_channels = nchannels;
|
||||||
|
}
|
||||||
|
|
||||||
wxSoundFormatBase *wxSoundFormatUlaw::Clone() const
|
wxSoundFormatBase *wxSoundFormatUlaw::Clone() const
|
||||||
{
|
{
|
||||||
wxSoundFormatUlaw *ulaw = new wxSoundFormatUlaw();
|
wxSoundFormatUlaw *ulaw = new wxSoundFormatUlaw();
|
||||||
|
|
||||||
ulaw->m_srate = m_srate;
|
ulaw->m_srate = m_srate;
|
||||||
|
ulaw->m_channels = m_channels;
|
||||||
return ulaw;
|
return ulaw;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,8 +99,29 @@ wxSoundStreamUlaw::~wxSoundStreamUlaw()
|
|||||||
|
|
||||||
wxSoundStream& wxSoundStreamUlaw::Read(void *buffer, wxUint32 len)
|
wxSoundStream& wxSoundStreamUlaw::Read(void *buffer, wxUint32 len)
|
||||||
{
|
{
|
||||||
// TODO
|
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;
|
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)
|
wxSoundStream& wxSoundStreamUlaw::Write(const void *buffer, wxUint32 len)
|
||||||
@@ -102,7 +134,7 @@ wxSoundStream& wxSoundStreamUlaw::Write(const void *buffer, wxUint32 len)
|
|||||||
old_linear = linear_buffer = new wxUint16[len*2];
|
old_linear = linear_buffer = new wxUint16[len*2];
|
||||||
ulaw_buffer = (const wxUint8 *)buffer;
|
ulaw_buffer = (const wxUint8 *)buffer;
|
||||||
|
|
||||||
while (countdown != 0) {
|
while (countdown > 0) {
|
||||||
*linear_buffer++ = ulaw2linear(*ulaw_buffer++);
|
*linear_buffer++ = ulaw2linear(*ulaw_buffer++);
|
||||||
countdown--;
|
countdown--;
|
||||||
}
|
}
|
||||||
@@ -126,6 +158,9 @@ bool wxSoundStreamUlaw::SetSoundFormat(const wxSoundFormatBase& format)
|
|||||||
return FALSE;
|
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;
|
wxSoundFormatPcm pcm;
|
||||||
wxSoundFormatUlaw *ulaw;
|
wxSoundFormatUlaw *ulaw;
|
||||||
|
|
||||||
@@ -135,7 +170,7 @@ bool wxSoundStreamUlaw::SetSoundFormat(const wxSoundFormatBase& format)
|
|||||||
|
|
||||||
pcm.SetSampleRate(ulaw->GetSampleRate());
|
pcm.SetSampleRate(ulaw->GetSampleRate());
|
||||||
pcm.SetBPS(16);
|
pcm.SetBPS(16);
|
||||||
pcm.SetChannels(1);
|
pcm.SetChannels(ulaw->GetChannels());
|
||||||
pcm.Signed(TRUE);
|
pcm.Signed(TRUE);
|
||||||
pcm.SetOrder(wxBYTE_ORDER);
|
pcm.SetOrder(wxBYTE_ORDER);
|
||||||
|
|
||||||
|
@@ -12,6 +12,8 @@
|
|||||||
#pragma interface "sndulaw.h"
|
#pragma interface "sndulaw.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "wx/defs.h"
|
||||||
|
|
||||||
#include "sndcodec.h"
|
#include "sndcodec.h"
|
||||||
#include "sndbase.h"
|
#include "sndbase.h"
|
||||||
|
|
||||||
@@ -19,7 +21,7 @@
|
|||||||
// ULAW format
|
// ULAW format
|
||||||
//
|
//
|
||||||
class WXDLLEXPORT wxSoundFormatUlaw: public wxSoundFormatBase {
|
class WXDLLEXPORT wxSoundFormatUlaw: public wxSoundFormatBase {
|
||||||
public:
|
public:
|
||||||
wxSoundFormatUlaw();
|
wxSoundFormatUlaw();
|
||||||
~wxSoundFormatUlaw();
|
~wxSoundFormatUlaw();
|
||||||
|
|
||||||
@@ -37,8 +39,9 @@ class WXDLLEXPORT wxSoundFormatUlaw: public wxSoundFormatBase {
|
|||||||
|
|
||||||
bool operator !=(const wxSoundFormatBase& frmt2) const;
|
bool operator !=(const wxSoundFormatBase& frmt2) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
wxUint32 m_srate;
|
wxUint32 m_srate;
|
||||||
|
wxUint8 m_channels;
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -47,7 +50,7 @@ class WXDLLEXPORT wxSoundFormatUlaw: public wxSoundFormatBase {
|
|||||||
|
|
||||||
class WXDLLEXPORT wxSoundRouterStream;
|
class WXDLLEXPORT wxSoundRouterStream;
|
||||||
class WXDLLEXPORT wxSoundStreamUlaw: public wxSoundStreamCodec {
|
class WXDLLEXPORT wxSoundStreamUlaw: public wxSoundStreamCodec {
|
||||||
public:
|
public:
|
||||||
wxSoundStreamUlaw(wxSoundStream& sndio);
|
wxSoundStreamUlaw(wxSoundStream& sndio);
|
||||||
~wxSoundStreamUlaw();
|
~wxSoundStreamUlaw();
|
||||||
|
|
||||||
@@ -58,7 +61,7 @@ class WXDLLEXPORT wxSoundStreamUlaw: public wxSoundStreamCodec {
|
|||||||
|
|
||||||
wxUint32 GetBestSize() const;
|
wxUint32 GetBestSize() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
wxSoundRouterStream *m_router;
|
wxSoundRouterStream *m_router;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -60,7 +60,7 @@ wxString wxSoundWave::GetCodecName() const
|
|||||||
bool wxSoundWave::CanRead()
|
bool wxSoundWave::CanRead()
|
||||||
{
|
{
|
||||||
wxUint32 len, signature1, signature2;
|
wxUint32 len, signature1, signature2;
|
||||||
m_snderror = wxSOUND_NOERR;
|
m_snderror = wxSOUND_NOERROR;
|
||||||
|
|
||||||
// Test the main signatures:
|
// Test the main signatures:
|
||||||
// "RIFF"
|
// "RIFF"
|
||||||
|
@@ -651,6 +651,7 @@ void wxSoundStreamWin::NotifyDoneBuffer(wxUint32 dev_handle, int flag)
|
|||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
bool wxSoundStreamWin::SetSoundFormat(wxSoundFormatBase& base)
|
bool wxSoundStreamWin::SetSoundFormat(wxSoundFormatBase& base)
|
||||||
{
|
{
|
||||||
|
// TODO: detect best format
|
||||||
return wxSoundStream::SetSoundFormat(base);
|
return wxSoundStream::SetSoundFormat(base);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
// -----------------------------------------------------------------------------
|
||||||
// Name: vidwin.h
|
// Name: vidwin.h
|
||||||
// Purpose: wxMMedia
|
// Purpose: wxMMedia
|
||||||
// Author: Guilhem Lavaux
|
// Author: Guilhem Lavaux
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
// Updated:
|
// Updated:
|
||||||
// Copyright: (C) 1998, 1999, 2000 Guilhem Lavaux
|
// Copyright: (C) 1998, 1999, 2000 Guilhem Lavaux
|
||||||
// License: wxWindows license
|
// License: wxWindows license
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
#ifdef __GNUG__
|
#ifdef __GNUG__
|
||||||
#pragma implementation "vidwin.h"
|
#pragma implementation "vidwin.h"
|
||||||
@@ -45,6 +45,7 @@ wxVideoWindows::wxVideoWindows(wxInputStream& str)
|
|||||||
m_filename = wxGetTempFileName("wxvid");
|
m_filename = wxGetTempFileName("wxvid");
|
||||||
m_paused = FALSE;
|
m_paused = FALSE;
|
||||||
m_stopped = TRUE;
|
m_stopped = TRUE;
|
||||||
|
m_frameRate = 1.0;
|
||||||
|
|
||||||
wxFileOutputStream temp_file(m_filename);
|
wxFileOutputStream temp_file(m_filename);
|
||||||
temp_file << str;
|
temp_file << str;
|
||||||
@@ -60,6 +61,7 @@ wxVideoWindows::wxVideoWindows(const wxString& filename)
|
|||||||
m_filename = filename;
|
m_filename = filename;
|
||||||
m_paused = FALSE;
|
m_paused = FALSE;
|
||||||
m_stopped = TRUE;
|
m_stopped = TRUE;
|
||||||
|
m_frameRate = 1.0;
|
||||||
OpenFile();
|
OpenFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,17 +75,41 @@ wxVideoWindows::~wxVideoWindows(void)
|
|||||||
|
|
||||||
void wxVideoWindows::OpenFile()
|
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;
|
DWORD ret;
|
||||||
|
|
||||||
open_struct.lpstrDeviceType = "avivideo";
|
openStruct.lpstrDeviceType = "avivideo";
|
||||||
open_struct.lpstrElementName = (LPSTR)(m_filename.mb_str());
|
openStruct.lpstrElementName = (LPSTR)(m_filename.mb_str());
|
||||||
open_struct.hWndParent = 0;
|
openStruct.hWndParent = 0;
|
||||||
|
|
||||||
ret = mciSendCommand(0, MCI_OPEN,
|
ret = mciSendCommand(0, MCI_OPEN,
|
||||||
MCI_OPEN_ELEMENT|MCI_DGV_OPEN_PARENT|MCI_OPEN_TYPE|MCI_DGV_OPEN_32BIT,
|
MCI_OPEN_ELEMENT|MCI_DGV_OPEN_PARENT|MCI_OPEN_TYPE|MCI_DGV_OPEN_32BIT,
|
||||||
(DWORD)(LPVOID)&open_struct);
|
(DWORD)(LPVOID)&openStruct);
|
||||||
m_internal->m_dev_id = open_struct.wDeviceID;
|
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()
|
bool wxVideoWindows::Pause()
|
||||||
@@ -91,7 +117,7 @@ bool wxVideoWindows::Pause()
|
|||||||
if (m_paused || m_stopped)
|
if (m_paused || m_stopped)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
m_paused = 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()
|
bool wxVideoWindows::Resume()
|
||||||
@@ -114,7 +140,6 @@ bool wxVideoWindows::IsStopped() const
|
|||||||
|
|
||||||
bool wxVideoWindows::GetSize(wxSize& size) const
|
bool wxVideoWindows::GetSize(wxSize& size) const
|
||||||
{
|
{
|
||||||
// Two random numbers.
|
|
||||||
size.SetWidth(200);
|
size.SetWidth(200);
|
||||||
size.SetHeight(200);
|
size.SetHeight(200);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@@ -169,16 +194,17 @@ bool wxVideoWindows::Stop()
|
|||||||
if (m_stopped)
|
if (m_stopped)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
m_stopped = TRUE;
|
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;
|
return FALSE;
|
||||||
|
|
||||||
seekStruct.dwCallback = 0;
|
seekStruct.dwCallback = 0;
|
||||||
seekStruct.dwTo = 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
|
// 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
|
wxString wxVideoWindows::GetMovieCodec() const
|
||||||
{
|
{
|
||||||
@@ -202,12 +228,12 @@ wxUint8 wxVideoWindows::GetChannels() const
|
|||||||
|
|
||||||
wxUint8 wxVideoWindows::GetBPS() const
|
wxUint8 wxVideoWindows::GetBPS() const
|
||||||
{
|
{
|
||||||
return 8;
|
return m_bps;
|
||||||
}
|
}
|
||||||
|
|
||||||
double wxVideoWindows::GetFrameRate() const
|
double wxVideoWindows::GetFrameRate() const
|
||||||
{
|
{
|
||||||
return 1.0;
|
return m_frameRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxUint32 wxVideoWindows::GetNbFrames() const
|
wxUint32 wxVideoWindows::GetNbFrames() const
|
||||||
|
@@ -59,6 +59,8 @@ protected:
|
|||||||
struct VIDW_Internal *m_internal;
|
struct VIDW_Internal *m_internal;
|
||||||
bool m_paused, m_stopped, m_remove_file;
|
bool m_paused, m_stopped, m_remove_file;
|
||||||
wxString m_filename;
|
wxString m_filename;
|
||||||
|
double m_frameRate;
|
||||||
|
wxUint8 m_bps;
|
||||||
|
|
||||||
void OpenFile();
|
void OpenFile();
|
||||||
public:
|
public:
|
||||||
|
Reference in New Issue
Block a user