* 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:
@@ -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;
|
||||||
|
@@ -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;
|
||||||
|
@@ -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);
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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();
|
||||||
|
Reference in New Issue
Block a user