* 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"
// -----------------------------------------------------------------------------------------------
// 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;

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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 <X11/Xlib.h>
#include <X11/Xatom.h>
@ -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();