* 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:
parent
db2e2242ef
commit
7d533797a0
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user