* ESD works in full duplex (theorically)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@6139 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Guilhem Lavaux
2000-02-18 19:05:27 +00:00
parent db2e2242ef
commit 7d533797a0
5 changed files with 133 additions and 29 deletions

View File

@@ -24,41 +24,64 @@
#define MY_ESD_NAME "wxWindows/wxSoundStreamESD" #define MY_ESD_NAME "wxWindows/wxSoundStreamESD"
// -----------------------------------------------------------------------------------------------
// wxSoundStreamESD: ESD sound driver
// --------------------------------------------------------------------------------------------
// Constructors/Destructors
// --------------------------------------------------------------------------------------------
wxSoundStreamESD::wxSoundStreamESD(const wxString& hostname) wxSoundStreamESD::wxSoundStreamESD(const wxString& hostname)
{ {
wxSoundFormatPcm pcm_default; wxSoundFormatPcm pcm_default;
m_fd = esd_play_stream(ESD_PLAY | ESD_STREAM | ESD_MONO | ESD_BITS8, 22050, // First, we make some basic test: is there ESD on this computer ?
// hostname.mb_str(), MY_ESD_NAME);
NULL, MY_ESD_NAME);
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; m_snderror = wxSOUND_INVDEV;
return; return;
} }
esd_close(m_fd); // Close this unuseful stream.
esd_close(m_fd_output);
m_hostname = hostname; m_hostname = hostname;
// Set the default audio format
SetSoundFormat(pcm_default); SetSoundFormat(pcm_default);
// Initialize some variable
m_snderror = wxSOUND_NOERR; m_snderror = wxSOUND_NOERR;
m_esd_stop = TRUE; m_esd_stop = TRUE;
m_q_filled = TRUE; m_q_filled = TRUE;
m_fd_output= -1;
} }
wxSoundStreamESD::~wxSoundStreamESD() wxSoundStreamESD::~wxSoundStreamESD()
{ {
if (m_fd > 0) // Close all remaining streams
esd_close(m_fd); 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) wxSoundStream& wxSoundStreamESD::Read(void *buffer, wxUint32 len)
{ {
int ret; int ret;
m_lastcount = (wxUint32)ret = read(m_fd, 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_IOERR;
@@ -68,11 +91,14 @@ wxSoundStream& wxSoundStreamESD::Read(void *buffer, wxUint32 len)
return *this; return *this;
} }
// --------------------------------------------------------------------------------------------
// Write several samples
// --------------------------------------------------------------------------------------------
wxSoundStream& wxSoundStreamESD::Write(const void *buffer, wxUint32 len) wxSoundStream& wxSoundStreamESD::Write(const void *buffer, wxUint32 len)
{ {
int ret; int ret;
m_lastcount = (wxUint32)ret = write(m_fd, 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_IOERR;
@@ -84,6 +110,10 @@ wxSoundStream& wxSoundStreamESD::Write(const void *buffer, wxUint32 len)
return *this; return *this;
} }
// --------------------------------------------------------------------------------------------
// SetSoundFormat(): this function specifies which format we want and which format is available
// --------------------------------------------------------------------------------------------
bool wxSoundStreamESD::SetSoundFormat(const wxSoundFormatBase& format) bool wxSoundStreamESD::SetSoundFormat(const wxSoundFormatBase& format)
{ {
wxSoundFormatPcm *pcm_format; wxSoundFormatPcm *pcm_format;
@@ -93,7 +123,7 @@ bool wxSoundStreamESD::SetSoundFormat(const wxSoundFormatBase& format)
return FALSE; return FALSE;
} }
if (m_fd == -1) { if (m_fd_input == -1 && m_fd_output == -1) {
m_snderror = wxSOUND_INVDEV; m_snderror = wxSOUND_INVDEV;
return FALSE; return FALSE;
} }
@@ -119,6 +149,10 @@ bool wxSoundStreamESD::SetSoundFormat(const wxSoundFormatBase& format)
return TRUE; return TRUE;
} }
// --------------------------------------------------------------------------------------------
// _wxSound_OSS_CBack (internal): it is called when the driver (ESD) is ready for a next
// buffer.
// --------------------------------------------------------------------------------------------
#ifdef __WXGTK__ #ifdef __WXGTK__
static void _wxSound_OSS_CBack(gpointer data, int source, static void _wxSound_OSS_CBack(gpointer data, int source,
GdkInputCondition condition) GdkInputCondition condition)
@@ -138,12 +172,18 @@ static void _wxSound_OSS_CBack(gpointer data, int source,
} }
#endif #endif
// --------------------------------------------------------------------------------------------
// WakeUpEvt() (internal): it is called by _wxSound_OSS_CBack to bypass the C++ protection
// --------------------------------------------------------------------------------------------
void wxSoundStreamESD::WakeUpEvt(int evt) void wxSoundStreamESD::WakeUpEvt(int evt)
{ {
m_q_filled = FALSE; m_q_filled = FALSE;
OnSoundEvent(evt); OnSoundEvent(evt);
} }
// --------------------------------------------------------------------------------------------
// StartProduction(): see wxSoundStream
// --------------------------------------------------------------------------------------------
bool wxSoundStreamESD::StartProduction(int evt) bool wxSoundStreamESD::StartProduction(int evt)
{ {
wxSoundFormatPcm *pcm; wxSoundFormatPcm *pcm;
@@ -157,21 +197,25 @@ bool wxSoundStreamESD::StartProduction(int evt)
flag |= (pcm->GetBPS() == 16) ? ESD_BITS16 : ESD_BITS8; flag |= (pcm->GetBPS() == 16) ? ESD_BITS16 : ESD_BITS8;
flag |= (pcm->GetChannels() == 2) ? ESD_STEREO : ESD_MONO; flag |= (pcm->GetChannels() == 2) ? ESD_STEREO : ESD_MONO;
if (evt == wxSOUND_OUTPUT) { if ((evt & wxSOUND_OUTPUT) != 0) {
flag |= ESD_PLAY | ESD_STREAM; flag |= ESD_PLAY | ESD_STREAM;
m_fd = esd_play_stream(flag, pcm->GetSampleRate(), NULL, m_fd_output = esd_play_stream(flag, pcm->GetSampleRate(), NULL,
MY_ESD_NAME); MY_ESD_NAME);
} else { }
if ((evt & wxSOUND_INPUT) != 0) {
flag |= ESD_RECORD | ESD_STREAM; flag |= ESD_RECORD | ESD_STREAM;
m_fd = esd_record_stream(flag, pcm->GetSampleRate(), NULL, m_fd_input = esd_record_stream(flag, pcm->GetSampleRate(), NULL,
MY_ESD_NAME); MY_ESD_NAME);
} }
#ifdef __WXGTK__ #ifdef __WXGTK__
if (evt == wxSOUND_OUTPUT) if ((evt & wxSOUND_OUTPUT) != 0) {
m_tag = gdk_input_add(m_fd, GDK_INPUT_WRITE, _wxSound_OSS_CBack, (gpointer)this); m_tag_output = gdk_input_add(m_fd_output, 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_INPUT) != 0) {
m_tag_input = gdk_input_add(m_fd_input, GDK_INPUT_READ, _wxSound_OSS_CBack, (gpointer)this);
}
#endif #endif
m_esd_stop = FALSE; m_esd_stop = FALSE;
@@ -185,8 +229,21 @@ bool wxSoundStreamESD::StopProduction()
if (m_esd_stop) if (m_esd_stop)
return FALSE; return FALSE;
gdk_input_remove(m_tag); if (m_fd_input != -1) {
esd_close(m_fd); 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_esd_stop = TRUE;
m_q_filled = TRUE; m_q_filled = TRUE;
return TRUE; return TRUE;

View File

@@ -38,8 +38,8 @@ class wxSoundStreamESD : public wxSoundStream {
bool QueueFilled() const { return m_q_filled; } bool QueueFilled() const { return m_q_filled; }
protected: protected:
int m_fd; int m_fd_input, m_fd_output;
int m_tag; int m_tag_input, m_tag_output;
bool m_esd_stop; bool m_esd_stop;
wxString m_hostname; wxString m_hostname;
bool m_q_filled; bool m_q_filled;

View File

@@ -77,6 +77,9 @@ public:
virtual bool AttachOutput(wxWindow& output); virtual bool AttachOutput(wxWindow& output);
// //
virtual void DetachOutput(); virtual void DetachOutput();
virtual bool IsPaused() = 0;
virtual bool IsStopped() = 0;
}; };
extern wxFrame *wxVideoCreateFrame(wxVideoBaseDriver *vid_drv); extern wxFrame *wxVideoCreateFrame(wxVideoBaseDriver *vid_drv);

View File

@@ -37,10 +37,32 @@
IMPLEMENT_DYNAMIC_CLASS(wxVideoXANIM, wxVideoBaseDriver) 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() wxVideoXANIM::wxVideoXANIM()
: wxVideoBaseDriver() : wxVideoBaseDriver()
{ {
m_internal = new wxXANIMinternal; m_internal = new wxXANIMinternal;
m_xanim_detector = new wxVideoXANIMProcess(this);
m_xanim_started = FALSE; m_xanim_started = FALSE;
m_paused = FALSE; m_paused = FALSE;
m_filename = ""; m_filename = "";
@@ -50,6 +72,7 @@ wxVideoXANIM::wxVideoXANIM(wxInputStream& str)
: wxVideoBaseDriver(str) : wxVideoBaseDriver(str)
{ {
m_internal = new wxXANIMinternal; m_internal = new wxXANIMinternal;
m_xanim_detector = new wxVideoXANIMProcess(this);
m_xanim_started = FALSE; m_xanim_started = FALSE;
m_paused = FALSE; m_paused = FALSE;
@@ -64,6 +87,7 @@ wxVideoXANIM::~wxVideoXANIM()
if (m_xanim_started) if (m_xanim_started)
Stop(); Stop();
delete m_internal; delete m_internal;
delete m_xanim_detector;
wxRemoveFile(m_filename); wxRemoveFile(m_filename);
} }
@@ -148,6 +172,16 @@ bool wxVideoXANIM::IsCapable(wxVideoType v_type)
return FALSE; return FALSE;
} }
bool wxVideoXANIM::IsPaused()
{
return m_paused;
}
bool wxVideoXANIM::IsStopped()
{
return !m_xanim_started;
}
bool wxVideoXANIM::AttachOutput(wxWindow& out) bool wxVideoXANIM::AttachOutput(wxWindow& out)
{ {
if (!wxVideoBaseDriver::AttachOutput(out)) if (!wxVideoBaseDriver::AttachOutput(out))
@@ -228,22 +262,22 @@ bool wxVideoXANIM::RestartXANIM()
WXSTRINGCAST m_filename); WXSTRINGCAST m_filename);
// Execute it // Execute it
if (!wxExecute(xanim_command, FALSE)) if (!wxExecute(xanim_command, FALSE, m_xanim_detector))
return FALSE; return FALSE;
// Wait for XAnim to be ready // Wait for XAnim to be ready
nitems = 0; 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, ret = XGetWindowProperty(m_internal->xanim_dpy, m_internal->xanim_window,
m_internal->xanim_atom, m_internal->xanim_atom,
0, 4, False, AnyPropertyType, &prop_type, 0, 4, False, AnyPropertyType, &prop_type,
&prop_format, &nitems, &extra, &prop_format, &nitems, &extra,
(unsigned char **)&prop); (unsigned char **)&prop);
// wxYield(); wxYield();
} }
m_paused = FALSE; m_paused = FALSE;
m_xanim_started = TRUE;
return TRUE; return TRUE;
} }

View File

@@ -12,9 +12,13 @@
#define __VID_xanim_H__ #define __VID_xanim_H__
#ifdef __GNUG__ #ifdef __GNUG__
#pragma interface #pragma interface "vidxanm.h"
#endif #endif
#include "wx/defs.h"
#include "wx/string.h"
#include "wx/process.h"
#if defined(WXMMEDIA_INTERNAL) && (defined(__X__) || defined(__WXGTK__)) #if defined(WXMMEDIA_INTERNAL) && (defined(__X__) || defined(__WXGTK__))
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/Xatom.h> #include <X11/Xatom.h>
@@ -40,6 +44,7 @@ protected:
bool m_xanim_started, m_paused; bool m_xanim_started, m_paused;
struct wxXANIMinternal *m_internal; struct wxXANIMinternal *m_internal;
wxString m_filename; wxString m_filename;
wxProcess *m_xanim_detector;
public: public:
wxVideoXANIM(); wxVideoXANIM();
wxVideoXANIM(wxInputStream& str); wxVideoXANIM(wxInputStream& str);
@@ -59,6 +64,11 @@ public:
bool AttachOutput(wxWindow& output); bool AttachOutput(wxWindow& output);
void DetachOutput(); void DetachOutput();
bool IsPaused();
bool IsStopped();
friend class wxVideoXANIMProcess;
protected: protected:
/// ///
bool RestartXANIM(); bool RestartXANIM();