* Fixes (WAV works on Linux, AIFF following)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1263 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -36,14 +36,16 @@
|
|||||||
|
|
||||||
wxStreamBuffer::wxStreamBuffer(wxStreamBase& stream, BufMode mode)
|
wxStreamBuffer::wxStreamBuffer(wxStreamBase& stream, BufMode mode)
|
||||||
: m_buffer_start(NULL), m_buffer_end(NULL), m_buffer_pos(NULL),
|
: m_buffer_start(NULL), m_buffer_end(NULL), m_buffer_pos(NULL),
|
||||||
m_buffer_size(0), m_fixed(TRUE), m_flushable(TRUE), m_stream(&stream),
|
m_buffer_size(0), m_wback(NULL), m_wbacksize(0), m_wbackcur(0),
|
||||||
|
m_fixed(TRUE), m_flushable(TRUE), m_stream(&stream),
|
||||||
m_mode(mode), m_destroybuf(FALSE), m_destroystream(FALSE)
|
m_mode(mode), m_destroybuf(FALSE), m_destroystream(FALSE)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
wxStreamBuffer::wxStreamBuffer(BufMode mode)
|
wxStreamBuffer::wxStreamBuffer(BufMode mode)
|
||||||
: m_buffer_start(NULL), m_buffer_end(NULL), m_buffer_pos(NULL),
|
: m_buffer_start(NULL), m_buffer_end(NULL), m_buffer_pos(NULL),
|
||||||
m_buffer_size(0), m_fixed(TRUE), m_flushable(FALSE), m_stream(NULL),
|
m_buffer_size(0), m_wback(NULL), m_wbacksize(0), m_wbackcur(0),
|
||||||
|
m_fixed(TRUE), m_flushable(FALSE), m_stream(NULL),
|
||||||
m_mode(mode), m_destroybuf(FALSE), m_destroystream(TRUE)
|
m_mode(mode), m_destroybuf(FALSE), m_destroystream(TRUE)
|
||||||
{
|
{
|
||||||
m_stream = new wxStreamBase();
|
m_stream = new wxStreamBase();
|
||||||
@@ -61,10 +63,15 @@ wxStreamBuffer::wxStreamBuffer(const wxStreamBuffer& buffer)
|
|||||||
m_mode = buffer.m_mode;
|
m_mode = buffer.m_mode;
|
||||||
m_destroybuf = FALSE;
|
m_destroybuf = FALSE;
|
||||||
m_destroystream = FALSE;
|
m_destroystream = FALSE;
|
||||||
|
m_wback = NULL;
|
||||||
|
m_wbacksize = 0;
|
||||||
|
m_wbackcur = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxStreamBuffer::~wxStreamBuffer()
|
wxStreamBuffer::~wxStreamBuffer()
|
||||||
{
|
{
|
||||||
|
if (m_wback)
|
||||||
|
free(m_wback);
|
||||||
if (m_destroybuf)
|
if (m_destroybuf)
|
||||||
wxDELETEA(m_buffer_start);
|
wxDELETEA(m_buffer_start);
|
||||||
if (m_destroystream)
|
if (m_destroystream)
|
||||||
@@ -148,13 +155,16 @@ char *wxStreamBuffer::AllocSpaceWBack(size_t needed_size)
|
|||||||
|
|
||||||
if (!temp_b)
|
if (!temp_b)
|
||||||
return NULL;
|
return NULL;
|
||||||
return (char *)((size_t)m_wback+(m_wbacksize-needed_size));
|
m_wback = temp_b;
|
||||||
|
printf("Buffer(0x%x)->Write: 0x%x, %d\n", this, m_wback, m_wbacksize);
|
||||||
|
return (char *)(m_wback+(m_wbacksize-needed_size));
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t wxStreamBuffer::GetWBack(char *buf, size_t bsize)
|
size_t wxStreamBuffer::GetWBack(char *buf, size_t bsize)
|
||||||
{
|
{
|
||||||
size_t s_toget = m_wbacksize-m_wbackcur;
|
size_t s_toget = m_wbacksize-m_wbackcur;
|
||||||
|
|
||||||
|
printf("Buffer(0x%x): 0x%x, %d\n", this, m_wback, m_wbacksize);
|
||||||
if (bsize < s_toget)
|
if (bsize < s_toget)
|
||||||
s_toget = bsize;
|
s_toget = bsize;
|
||||||
|
|
||||||
@@ -374,15 +384,13 @@ size_t wxStreamBuffer::Write(const void *buffer, size_t size)
|
|||||||
size_t wxStreamBuffer::Write(wxStreamBuffer *sbuf)
|
size_t wxStreamBuffer::Write(wxStreamBuffer *sbuf)
|
||||||
{
|
{
|
||||||
char buf[BUF_TEMP_SIZE];
|
char buf[BUF_TEMP_SIZE];
|
||||||
size_t s = 0, bytes_count = BUF_TEMP_SIZE;
|
size_t s = 0, bytes_count = BUF_TEMP_SIZE, b_count2;
|
||||||
size_t s_size;
|
|
||||||
|
|
||||||
while (bytes_count == BUF_TEMP_SIZE) {
|
while (bytes_count == BUF_TEMP_SIZE) {
|
||||||
s_size = (sbuf->GetDataLeft() < GetDataLeft()) ? sbuf->GetDataLeft() : GetDataLeft();
|
b_count2 = sbuf->Read(buf, bytes_count);
|
||||||
if (s_size < bytes_count)
|
bytes_count = Write(buf, b_count2);
|
||||||
bytes_count = s_size;
|
if (b_count2 > bytes_count)
|
||||||
bytes_count = sbuf->Read(buf, bytes_count);
|
sbuf->WriteBack(buf+bytes_count, b_count2-bytes_count);
|
||||||
bytes_count = Write(buf, bytes_count);
|
|
||||||
s += bytes_count;
|
s += bytes_count;
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
|
@@ -283,6 +283,8 @@ wxUint32 wxSndFileCodec::GetSize() const
|
|||||||
|
|
||||||
wxUint32 wxSndFileCodec::Available() const
|
wxUint32 wxSndFileCodec::Available() const
|
||||||
{
|
{
|
||||||
|
if (m_fstate == wxSFILE_STOPPED)
|
||||||
|
return 0;
|
||||||
return m_fsize-m_fpos;
|
return m_fsize-m_fpos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -165,6 +165,8 @@ wxSoundCodec::wxSoundCodec()
|
|||||||
|
|
||||||
wxSoundCodec::~wxSoundCodec()
|
wxSoundCodec::~wxSoundCodec()
|
||||||
{
|
{
|
||||||
|
if (m_mode != WAITING)
|
||||||
|
ExitMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxSoundCodec::InitIO(const wxSoundDataFormat& format)
|
void wxSoundCodec::InitIO(const wxSoundDataFormat& format)
|
||||||
@@ -172,13 +174,13 @@ void wxSoundCodec::InitIO(const wxSoundDataFormat& format)
|
|||||||
m_io_format = format;
|
m_io_format = format;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxSoundCodec::InitMode(int mode)
|
void wxSoundCodec::InitMode(ModeType mode)
|
||||||
{
|
{
|
||||||
wxStreamBuffer *buf_snd;
|
wxStreamBuffer *buf_snd;
|
||||||
|
|
||||||
m_mode = (mode == 0) ? ENCODING : DECODING;
|
m_mode = mode;
|
||||||
if (!m_chain_codec) {
|
if (!m_chain_codec) {
|
||||||
if (mode == ENCODING) {
|
if (m_mode == ENCODING) {
|
||||||
m_out_sound = new wxStreamBuffer(*this, wxStreamBuffer::write);
|
m_out_sound = new wxStreamBuffer(*this, wxStreamBuffer::write);
|
||||||
m_out_sound->SetBufferIO(1024);
|
m_out_sound->SetBufferIO(1024);
|
||||||
} else {
|
} else {
|
||||||
@@ -219,6 +221,7 @@ void wxSoundCodec::ExitMode()
|
|||||||
m_out_sound = m_chain_codec->GetOutStream();
|
m_out_sound = m_chain_codec->GetOutStream();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
m_mode = WAITING;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxSoundCodec::ChainCodecBefore(wxSoundDataFormat& format)
|
bool wxSoundCodec::ChainCodecBefore(wxSoundDataFormat& format)
|
||||||
|
@@ -62,6 +62,12 @@ class wxSoundDataFormat {
|
|||||||
|
|
||||||
class wxSoundCodec : public wxObject, public wxStreamBase {
|
class wxSoundCodec : public wxObject, public wxStreamBase {
|
||||||
DECLARE_ABSTRACT_CLASS(wxSoundCodec)
|
DECLARE_ABSTRACT_CLASS(wxSoundCodec)
|
||||||
|
public:
|
||||||
|
typedef enum {
|
||||||
|
WAITING = 0,
|
||||||
|
ENCODING,
|
||||||
|
DECODING
|
||||||
|
} ModeType;
|
||||||
public:
|
public:
|
||||||
wxSoundCodec();
|
wxSoundCodec();
|
||||||
virtual ~wxSoundCodec();
|
virtual ~wxSoundCodec();
|
||||||
@@ -70,8 +76,6 @@ class wxSoundCodec : public wxObject, public wxStreamBase {
|
|||||||
size_t Available();
|
size_t Available();
|
||||||
|
|
||||||
void InitIO(const wxSoundDataFormat& format);
|
void InitIO(const wxSoundDataFormat& format);
|
||||||
void InitMode(int mode);
|
|
||||||
void ExitMode();
|
|
||||||
|
|
||||||
inline void SetInStream(wxStreamBuffer *s)
|
inline void SetInStream(wxStreamBuffer *s)
|
||||||
{ m_in_sound = s; }
|
{ m_in_sound = s; }
|
||||||
@@ -87,6 +91,8 @@ class wxSoundCodec : public wxObject, public wxStreamBase {
|
|||||||
virtual size_t GetByteRate() const = 0;
|
virtual size_t GetByteRate() const = 0;
|
||||||
virtual wxSoundDataFormat GetPreferredFormat(int codec = 0) const = 0;
|
virtual wxSoundDataFormat GetPreferredFormat(int codec = 0) const = 0;
|
||||||
|
|
||||||
|
virtual void InitMode(ModeType mode);
|
||||||
|
virtual void ExitMode();
|
||||||
virtual void Decode() = 0;
|
virtual void Decode() = 0;
|
||||||
virtual void Encode() = 0;
|
virtual void Encode() = 0;
|
||||||
|
|
||||||
@@ -113,11 +119,7 @@ class wxSoundCodec : public wxObject, public wxStreamBase {
|
|||||||
wxStreamBuffer *m_in_sound, *m_out_sound;
|
wxStreamBuffer *m_in_sound, *m_out_sound;
|
||||||
wxSoundCodec *m_chain_codec;
|
wxSoundCodec *m_chain_codec;
|
||||||
bool m_init, m_chain_before;
|
bool m_init, m_chain_before;
|
||||||
|
ModeType m_mode;
|
||||||
enum {
|
|
||||||
ENCODING = 0,
|
|
||||||
DECODING
|
|
||||||
} m_mode;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -38,10 +38,8 @@ wxSoundDataFormat wxSoundPcmCodec::GetPreferredFormat(int codec) const
|
|||||||
|
|
||||||
void wxSoundPcmCodec::Decode()
|
void wxSoundPcmCodec::Decode()
|
||||||
{
|
{
|
||||||
InitMode(DECODING);
|
|
||||||
if (m_io_format == m_orig_format) {
|
if (m_io_format == m_orig_format) {
|
||||||
CopyToOutput();
|
CopyToOutput();
|
||||||
ExitMode();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,7 +56,6 @@ void wxSoundPcmCodec::Decode()
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ExitMode();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -179,10 +176,8 @@ void wxSoundPcmCodec::OutputSwapAndSign16()
|
|||||||
|
|
||||||
void wxSoundPcmCodec::Encode()
|
void wxSoundPcmCodec::Encode()
|
||||||
{
|
{
|
||||||
InitMode(ENCODING);
|
|
||||||
if (m_io_format == m_orig_format) {
|
if (m_io_format == m_orig_format) {
|
||||||
CopyToOutput();
|
CopyToOutput();
|
||||||
ExitMode();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,5 +194,4 @@ void wxSoundPcmCodec::Encode()
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ExitMode();
|
|
||||||
}
|
}
|
||||||
|
@@ -103,7 +103,7 @@ void wxUssSound::USS_Sleep()
|
|||||||
bool wxUssSound::DoInput(wxSndBuffer *buf)
|
bool wxUssSound::DoInput(wxSndBuffer *buf)
|
||||||
{
|
{
|
||||||
wxUint32 bufsize;
|
wxUint32 bufsize;
|
||||||
wxSoundCodec *codec = buf->GetFormat().GetCodec();
|
wxSoundCodec *codec = buf->GetCurrentCodec();
|
||||||
|
|
||||||
m_sndbuf->ResetBuffer();
|
m_sndbuf->ResetBuffer();
|
||||||
codec->SetInStream(m_sndbuf);
|
codec->SetInStream(m_sndbuf);
|
||||||
@@ -117,7 +117,7 @@ bool wxUssSound::DoInput(wxSndBuffer *buf)
|
|||||||
buf->Clear(wxSND_BUFLOCKED | wxSND_BUFREADY);
|
buf->Clear(wxSND_BUFLOCKED | wxSND_BUFREADY);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
read(m_fd, m_sndbuf, bufsize);
|
read(m_fd, m_sndbuf->GetBufferStart(), bufsize);
|
||||||
codec->Encode();
|
codec->Encode();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -128,20 +128,36 @@ bool wxUssSound::DoOutput(wxSndBuffer *buf)
|
|||||||
wxSoundCodec *codec = buf->GetCurrentCodec();
|
wxSoundCodec *codec = buf->GetCurrentCodec();
|
||||||
|
|
||||||
m_sndbuf->ResetBuffer();
|
m_sndbuf->ResetBuffer();
|
||||||
codec->SetOutStream(m_sndbuf);
|
|
||||||
codec->InitIO(m_ussformat);
|
|
||||||
|
|
||||||
if (!codec->Available()) {
|
if (!codec->Available()) {
|
||||||
buf->Clear(wxSND_BUFLOCKED | wxSND_BUFREADY);
|
buf->Clear(wxSND_BUFLOCKED | wxSND_BUFREADY);
|
||||||
return false;
|
return FALSE;
|
||||||
}
|
}
|
||||||
codec->Decode();
|
codec->Decode();
|
||||||
write(m_fd, m_sndbuf, m_sndbuf->GetIntPosition());
|
write(m_fd, m_sndbuf->GetBufferStart(), m_sndbuf->GetIntPosition());
|
||||||
|
|
||||||
// Well ... it's not accurate ! :-|
|
// Well ... it's not accurate ! :-|
|
||||||
buf->OnBufferOutFinished();
|
buf->OnBufferOutFinished();
|
||||||
|
|
||||||
return true;
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxUssSound::InitBuffer(wxSndBuffer *buf)
|
||||||
|
{
|
||||||
|
wxSoundCodec *codec;
|
||||||
|
|
||||||
|
if (!OnSetupDriver(*buf, buf->GetMode())) {
|
||||||
|
if (buf->IsNotSet(wxSND_BUFREADY))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
codec = buf->GetCurrentCodec();
|
||||||
|
codec->SetOutStream(m_sndbuf);
|
||||||
|
codec->InitIO(m_ussformat);
|
||||||
|
// TODO: We need more tests here.
|
||||||
|
codec->InitMode((m_mode == wxSND_OUTPUT) ? wxSoundCodec::DECODING : wxSoundCodec::ENCODING);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *wxUssSound::Entry()
|
void *wxUssSound::Entry()
|
||||||
@@ -149,36 +165,45 @@ void *wxUssSound::Entry()
|
|||||||
wxNode *node;
|
wxNode *node;
|
||||||
wxSndBuffer *buf;
|
wxSndBuffer *buf;
|
||||||
|
|
||||||
while (!m_stop_thrd) {
|
node = m_buffers.First();
|
||||||
node = m_buffers.First();
|
if (!node) {
|
||||||
if (!node) {
|
m_stop_thrd = FALSE;
|
||||||
USS_Sleep();
|
return NULL;
|
||||||
continue;
|
}
|
||||||
}
|
|
||||||
buf = (wxSndBuffer *)node->Data();
|
|
||||||
if (!OnSetupDriver(*buf, buf->GetMode()))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
|
buf = (wxSndBuffer *)node->Data();
|
||||||
|
InitBuffer(buf);
|
||||||
|
|
||||||
|
while (!m_stop_thrd) {
|
||||||
buf->HardLock();
|
buf->HardLock();
|
||||||
if (buf->IsSet(wxSND_BUFSTOP)) {
|
if (buf->IsSet(wxSND_BUFSTOP)) {
|
||||||
buf->HardUnlock();
|
buf->HardUnlock();
|
||||||
delete node;
|
goto sound_clean_buffer;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
switch(m_mode) {
|
switch(m_mode) {
|
||||||
case wxSND_INPUT:
|
case wxSND_INPUT:
|
||||||
if (!DoInput(buf))
|
if (!DoInput(buf))
|
||||||
delete node;
|
goto sound_clean_buffer;
|
||||||
break;
|
break;
|
||||||
case wxSND_OUTPUT:
|
case wxSND_OUTPUT:
|
||||||
if (!DoOutput(buf))
|
if (!DoOutput(buf))
|
||||||
delete node;
|
goto sound_clean_buffer;
|
||||||
break;
|
break;
|
||||||
case wxSND_DUPLEX:
|
case wxSND_DUPLEX:
|
||||||
case wxSND_OTHER_IO:
|
case wxSND_OTHER_IO:
|
||||||
|
goto sound_clean_buffer;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
buf->HardUnlock();
|
buf->HardUnlock();
|
||||||
|
continue;
|
||||||
|
sound_clean_buffer:
|
||||||
|
buf->GetCurrentCodec()->ExitMode();
|
||||||
|
delete node;
|
||||||
|
node = m_buffers.First();
|
||||||
|
if (!node)
|
||||||
|
USS_Sleep();
|
||||||
|
if (node)
|
||||||
|
buf = (wxSndBuffer *)node->Data();
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -188,7 +213,7 @@ bool wxUssSound::OnSetupDriver(wxSndBuffer& buf, wxSndMode WXUNUSED(mode))
|
|||||||
wxSoundDataFormat format;
|
wxSoundDataFormat format;
|
||||||
wxSoundCodec *codec;
|
wxSoundCodec *codec;
|
||||||
|
|
||||||
codec = buf.GetFormat().GetCodec();
|
codec = buf.GetCurrentCodec();
|
||||||
format = codec->GetPreferredFormat(WXSOUND_PCM);
|
format = codec->GetPreferredFormat(WXSOUND_PCM);
|
||||||
|
|
||||||
if ((format.GetSampleRate() != m_srate) ||
|
if ((format.GetSampleRate() != m_srate) ||
|
||||||
@@ -200,17 +225,17 @@ bool wxUssSound::OnSetupDriver(wxSndBuffer& buf, wxSndMode WXUNUSED(mode))
|
|||||||
m_buffers.DeleteObject(&buf);
|
m_buffers.DeleteObject(&buf);
|
||||||
buf.Clear(wxSND_BUFLOCKED | wxSND_BUFREADY);
|
buf.Clear(wxSND_BUFLOCKED | wxSND_BUFREADY);
|
||||||
buf.SetError(wxSND_CANTSET);
|
buf.SetError(wxSND_CANTSET);
|
||||||
return false;
|
return FALSE;
|
||||||
}
|
}
|
||||||
m_mode = wxSND_OTHER_IO;
|
m_mode = wxSND_OTHER_IO;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buf.GetMode() != m_mode) {
|
if (buf.GetMode() != m_mode) {
|
||||||
m_mode = buf.GetMode();
|
m_mode = buf.GetMode();
|
||||||
return false;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxUint32 wxUssSound::GetNbFragments()
|
wxUint32 wxUssSound::GetNbFragments()
|
||||||
|
@@ -75,6 +75,7 @@ protected:
|
|||||||
wxCondition m_sleep_cond;
|
wxCondition m_sleep_cond;
|
||||||
|
|
||||||
///
|
///
|
||||||
|
bool InitBuffer(wxSndBuffer *buf);
|
||||||
bool DoInput(wxSndBuffer *buf);
|
bool DoInput(wxSndBuffer *buf);
|
||||||
bool DoOutput(wxSndBuffer *buf);
|
bool DoOutput(wxSndBuffer *buf);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user