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