From 7d533797a0cca03359b6a23e7e54fb1c648eb998 Mon Sep 17 00:00:00 2001 From: Guilhem Lavaux Date: Fri, 18 Feb 2000 19:05:27 +0000 Subject: [PATCH] * ESD works in full duplex (theorically) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@6139 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- utils/wxMMedia2/lib/sndesd.cpp | 101 +++++++++++++++++++++++++------- utils/wxMMedia2/lib/sndesd.h | 4 +- utils/wxMMedia2/lib/vidbase.h | 3 + utils/wxMMedia2/lib/vidxanm.cpp | 42 +++++++++++-- utils/wxMMedia2/lib/vidxanm.h | 12 +++- 5 files changed, 133 insertions(+), 29 deletions(-) diff --git a/utils/wxMMedia2/lib/sndesd.cpp b/utils/wxMMedia2/lib/sndesd.cpp index 39713d3dd9..700bb1baa6 100644 --- a/utils/wxMMedia2/lib/sndesd.cpp +++ b/utils/wxMMedia2/lib/sndesd.cpp @@ -24,41 +24,64 @@ #define MY_ESD_NAME "wxWindows/wxSoundStreamESD" +// ----------------------------------------------------------------------------------------------- +// wxSoundStreamESD: ESD sound driver + + +// -------------------------------------------------------------------------------------------- +// Constructors/Destructors +// -------------------------------------------------------------------------------------------- + wxSoundStreamESD::wxSoundStreamESD(const wxString& hostname) { wxSoundFormatPcm pcm_default; - m_fd = esd_play_stream(ESD_PLAY | ESD_STREAM | ESD_MONO | ESD_BITS8, 22050, -// hostname.mb_str(), MY_ESD_NAME); - NULL, MY_ESD_NAME); + // First, we make some basic test: is there ESD on this computer ? - if (m_fd == -1) { + if (hostname.IsNull()) + m_fd_output = esd_play_stream(ESD_PLAY | ESD_STREAM, 22050, + hostname.mb_str(), MY_ESD_NAME); + else + m_fd_output = esd_play_stream(ESD_PLAY | ESD_STREAM, 22050, + NULL, MY_ESD_NAME); + if (m_fd_output == -1) { + // Answer: no. We return with an error. m_snderror = wxSOUND_INVDEV; return; } - esd_close(m_fd); + // Close this unuseful stream. + esd_close(m_fd_output); m_hostname = hostname; + // Set the default audio format SetSoundFormat(pcm_default); + // Initialize some variable m_snderror = wxSOUND_NOERR; m_esd_stop = TRUE; m_q_filled = TRUE; + m_fd_output= -1; } wxSoundStreamESD::~wxSoundStreamESD() { - if (m_fd > 0) - esd_close(m_fd); + // Close all remaining streams + if (m_fd_output > 0) + esd_close(m_fd_output); + if (m_fd_input > 0) + esd_close(m_fd_input); } +// -------------------------------------------------------------------------------------------- +// Read several samples +// -------------------------------------------------------------------------------------------- wxSoundStream& wxSoundStreamESD::Read(void *buffer, wxUint32 len) { int ret; - m_lastcount = (wxUint32)ret = read(m_fd, buffer, len); + m_lastcount = (wxUint32)ret = read(m_fd_input, buffer, len); if (ret < 0) m_snderror = wxSOUND_IOERR; @@ -68,11 +91,14 @@ wxSoundStream& wxSoundStreamESD::Read(void *buffer, wxUint32 len) return *this; } +// -------------------------------------------------------------------------------------------- +// Write several samples +// -------------------------------------------------------------------------------------------- wxSoundStream& wxSoundStreamESD::Write(const void *buffer, wxUint32 len) { int ret; - m_lastcount = (wxUint32)ret = write(m_fd, buffer, len); + m_lastcount = (wxUint32)ret = write(m_fd_output, buffer, len); if (ret < 0) m_snderror = wxSOUND_IOERR; @@ -84,6 +110,10 @@ wxSoundStream& wxSoundStreamESD::Write(const void *buffer, wxUint32 len) return *this; } +// -------------------------------------------------------------------------------------------- +// SetSoundFormat(): this function specifies which format we want and which format is available +// -------------------------------------------------------------------------------------------- + bool wxSoundStreamESD::SetSoundFormat(const wxSoundFormatBase& format) { wxSoundFormatPcm *pcm_format; @@ -93,7 +123,7 @@ bool wxSoundStreamESD::SetSoundFormat(const wxSoundFormatBase& format) return FALSE; } - if (m_fd == -1) { + if (m_fd_input == -1 && m_fd_output == -1) { m_snderror = wxSOUND_INVDEV; return FALSE; } @@ -119,6 +149,10 @@ bool wxSoundStreamESD::SetSoundFormat(const wxSoundFormatBase& format) return TRUE; } +// -------------------------------------------------------------------------------------------- +// _wxSound_OSS_CBack (internal): it is called when the driver (ESD) is ready for a next +// buffer. +// -------------------------------------------------------------------------------------------- #ifdef __WXGTK__ static void _wxSound_OSS_CBack(gpointer data, int source, GdkInputCondition condition) @@ -138,12 +172,18 @@ static void _wxSound_OSS_CBack(gpointer data, int source, } #endif +// -------------------------------------------------------------------------------------------- +// WakeUpEvt() (internal): it is called by _wxSound_OSS_CBack to bypass the C++ protection +// -------------------------------------------------------------------------------------------- void wxSoundStreamESD::WakeUpEvt(int evt) { m_q_filled = FALSE; OnSoundEvent(evt); } +// -------------------------------------------------------------------------------------------- +// StartProduction(): see wxSoundStream +// -------------------------------------------------------------------------------------------- bool wxSoundStreamESD::StartProduction(int evt) { wxSoundFormatPcm *pcm; @@ -157,21 +197,25 @@ bool wxSoundStreamESD::StartProduction(int evt) flag |= (pcm->GetBPS() == 16) ? ESD_BITS16 : ESD_BITS8; flag |= (pcm->GetChannels() == 2) ? ESD_STEREO : ESD_MONO; - if (evt == wxSOUND_OUTPUT) { + if ((evt & wxSOUND_OUTPUT) != 0) { flag |= ESD_PLAY | ESD_STREAM; - m_fd = esd_play_stream(flag, pcm->GetSampleRate(), NULL, - MY_ESD_NAME); - } else { + m_fd_output = esd_play_stream(flag, pcm->GetSampleRate(), NULL, + MY_ESD_NAME); + } + + if ((evt & wxSOUND_INPUT) != 0) { flag |= ESD_RECORD | ESD_STREAM; - m_fd = esd_record_stream(flag, pcm->GetSampleRate(), NULL, - MY_ESD_NAME); + m_fd_input = esd_record_stream(flag, pcm->GetSampleRate(), NULL, + MY_ESD_NAME); } #ifdef __WXGTK__ - if (evt == wxSOUND_OUTPUT) - m_tag = gdk_input_add(m_fd, GDK_INPUT_WRITE, _wxSound_OSS_CBack, (gpointer)this); - else - m_tag = gdk_input_add(m_fd, GDK_INPUT_READ, _wxSound_OSS_CBack, (gpointer)this); + if ((evt & wxSOUND_OUTPUT) != 0) { + m_tag_output = gdk_input_add(m_fd_output, GDK_INPUT_WRITE, _wxSound_OSS_CBack, (gpointer)this); + } + if ((evt & wxSOUND_INPUT) != 0) { + m_tag_input = gdk_input_add(m_fd_input, GDK_INPUT_READ, _wxSound_OSS_CBack, (gpointer)this); + } #endif m_esd_stop = FALSE; @@ -185,8 +229,21 @@ bool wxSoundStreamESD::StopProduction() if (m_esd_stop) return FALSE; - gdk_input_remove(m_tag); - esd_close(m_fd); + if (m_fd_input != -1) { + esd_close(m_fd_input); +#ifdef __WXGTK__ + gdk_input_remove(m_tag_input); +#endif + } + if (m_fd_output != -1) { + esd_close(m_fd_output); +#ifdef __WXGTK__ + gdk_input_remove(m_tag_output); +#endif + } + + m_fd_input = -1; + m_fd_output= -1; m_esd_stop = TRUE; m_q_filled = TRUE; return TRUE; diff --git a/utils/wxMMedia2/lib/sndesd.h b/utils/wxMMedia2/lib/sndesd.h index 523d76cc75..73988e7c83 100644 --- a/utils/wxMMedia2/lib/sndesd.h +++ b/utils/wxMMedia2/lib/sndesd.h @@ -38,8 +38,8 @@ class wxSoundStreamESD : public wxSoundStream { bool QueueFilled() const { return m_q_filled; } protected: - int m_fd; - int m_tag; + int m_fd_input, m_fd_output; + int m_tag_input, m_tag_output; bool m_esd_stop; wxString m_hostname; bool m_q_filled; diff --git a/utils/wxMMedia2/lib/vidbase.h b/utils/wxMMedia2/lib/vidbase.h index 4d2166a0c5..4498131a62 100644 --- a/utils/wxMMedia2/lib/vidbase.h +++ b/utils/wxMMedia2/lib/vidbase.h @@ -77,6 +77,9 @@ public: virtual bool AttachOutput(wxWindow& output); // virtual void DetachOutput(); + + virtual bool IsPaused() = 0; + virtual bool IsStopped() = 0; }; extern wxFrame *wxVideoCreateFrame(wxVideoBaseDriver *vid_drv); diff --git a/utils/wxMMedia2/lib/vidxanm.cpp b/utils/wxMMedia2/lib/vidxanm.cpp index 6f9ff545e6..4ff0454b90 100644 --- a/utils/wxMMedia2/lib/vidxanm.cpp +++ b/utils/wxMMedia2/lib/vidxanm.cpp @@ -37,10 +37,32 @@ IMPLEMENT_DYNAMIC_CLASS(wxVideoXANIM, wxVideoBaseDriver) +class wxVideoXANIMProcess: public wxProcess { + public: + wxVideoXANIMProcess(wxVideoXANIM *xanim); + + void OnTerminate(int pid, int status); + + protected: + wxVideoXANIM *m_vid_xanim; +}; + + +wxVideoXANIMProcess::wxVideoXANIMProcess(wxVideoXANIM *xanim) +{ + m_vid_xanim = xanim; +} + +void wxVideoXANIMProcess::OnTerminate(int WXUNUSED(pid), int WXUNUSED(status)) +{ + m_vid_xanim->m_xanim_started = FALSE; +} + wxVideoXANIM::wxVideoXANIM() : wxVideoBaseDriver() { m_internal = new wxXANIMinternal; + m_xanim_detector = new wxVideoXANIMProcess(this); m_xanim_started = FALSE; m_paused = FALSE; m_filename = ""; @@ -50,6 +72,7 @@ wxVideoXANIM::wxVideoXANIM(wxInputStream& str) : wxVideoBaseDriver(str) { m_internal = new wxXANIMinternal; + m_xanim_detector = new wxVideoXANIMProcess(this); m_xanim_started = FALSE; m_paused = FALSE; @@ -64,6 +87,7 @@ wxVideoXANIM::~wxVideoXANIM() if (m_xanim_started) Stop(); delete m_internal; + delete m_xanim_detector; wxRemoveFile(m_filename); } @@ -148,6 +172,16 @@ bool wxVideoXANIM::IsCapable(wxVideoType v_type) return FALSE; } +bool wxVideoXANIM::IsPaused() +{ + return m_paused; +} + +bool wxVideoXANIM::IsStopped() +{ + return !m_xanim_started; +} + bool wxVideoXANIM::AttachOutput(wxWindow& out) { if (!wxVideoBaseDriver::AttachOutput(out)) @@ -228,22 +262,22 @@ bool wxVideoXANIM::RestartXANIM() WXSTRINGCAST m_filename); // Execute it - if (!wxExecute(xanim_command, FALSE)) + if (!wxExecute(xanim_command, FALSE, m_xanim_detector)) return FALSE; // Wait for XAnim to be ready nitems = 0; - while (nitems == 0) { + m_xanim_started = TRUE; + while (nitems == 0 && m_xanim_started) { ret = XGetWindowProperty(m_internal->xanim_dpy, m_internal->xanim_window, m_internal->xanim_atom, 0, 4, False, AnyPropertyType, &prop_type, &prop_format, &nitems, &extra, (unsigned char **)&prop); -// wxYield(); + wxYield(); } m_paused = FALSE; - m_xanim_started = TRUE; return TRUE; } diff --git a/utils/wxMMedia2/lib/vidxanm.h b/utils/wxMMedia2/lib/vidxanm.h index 91df160a94..2400be1510 100644 --- a/utils/wxMMedia2/lib/vidxanm.h +++ b/utils/wxMMedia2/lib/vidxanm.h @@ -12,9 +12,13 @@ #define __VID_xanim_H__ #ifdef __GNUG__ -#pragma interface + #pragma interface "vidxanm.h" #endif +#include "wx/defs.h" +#include "wx/string.h" +#include "wx/process.h" + #if defined(WXMMEDIA_INTERNAL) && (defined(__X__) || defined(__WXGTK__)) #include #include @@ -40,6 +44,7 @@ protected: bool m_xanim_started, m_paused; struct wxXANIMinternal *m_internal; wxString m_filename; + wxProcess *m_xanim_detector; public: wxVideoXANIM(); wxVideoXANIM(wxInputStream& str); @@ -59,6 +64,11 @@ public: bool AttachOutput(wxWindow& output); void DetachOutput(); + bool IsPaused(); + bool IsStopped(); + + friend class wxVideoXANIMProcess; + protected: /// bool RestartXANIM();