* 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:
Guilhem Lavaux
1998-12-25 11:02:39 +00:00
parent 9257d0b705
commit eb4e516dd9
7 changed files with 85 additions and 50 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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