* Stream: update in doc, fix in code.
* wxMMedia: various fixes, WAV and AIFF should work on Linux, preparing it for Windows. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1692 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
20239453d5
commit
9fc0fe377b
@ -284,7 +284,12 @@ Returns the current position (counted in bytes) in the stream buffer.
|
||||
|
||||
\func{void}{SetIntPosition}{\void}
|
||||
|
||||
Sets the current position in the stream buffer.
|
||||
Sets the current position (in bytes) in the stream buffer.
|
||||
|
||||
\wxheading{Warning}
|
||||
|
||||
Since it is a very low-level function, there is no check on the position:
|
||||
specify an invalid position can induce unexpected results.
|
||||
|
||||
\membersection{wxStreamBuffer::GetLastAccess}
|
||||
|
||||
|
@ -251,8 +251,8 @@ void wxStreamBuffer::PutChar(char c)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!GetDataLeft() && !FlushBuffer()) {
|
||||
CHECK_ERROR(wxStream_READ_ERR);
|
||||
if (GetDataLeft() == 0 && !FlushBuffer()) {
|
||||
CHECK_ERROR(wxStream_WRITE_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxSndAiffCodec, wxSndFileCodec)
|
||||
IMPLEMENT_ABSTRACT_CLASS(wxVideoBaseDriver, wxMMediaFile)
|
||||
IMPLEMENT_DYNAMIC_CLASS(wxVideoOutput, wxWindow)
|
||||
#if defined(__X__) || defined(__WXGTK__)
|
||||
IMPLEMENT_DYNAMIC_CLASS(wxVideoXANIM, wxVideoBaseDriver)
|
||||
// IMPLEMENT_DYNAMIC_CLASS(wxVideoXANIM, wxVideoBaseDriver)
|
||||
#endif
|
||||
#ifdef __WINDOWS__
|
||||
IMPLEMENT_DYNAMIC_CLASS(wxVideoWindows, wxVideoBaseDriver)
|
||||
@ -88,7 +88,7 @@ MMD_REGISTER_FILE("audio/x-wav", "Wav Player", wxSndWavCodec, "wav")
|
||||
MMD_REGISTER_FILE("audio/x-aiff", "Aiff Player", wxSndAiffCodec, "aif")
|
||||
MMD_REGISTER_FILE("audio/x-au", "Sun Audio File Player", wxSndAuCodec, "au")
|
||||
#if defined(__X__) || defined(__WXGTK__)
|
||||
MMD_REGISTER_FILE("video/*", "Video Player", wxVideoXANIM, "mov")
|
||||
// MMD_REGISTER_FILE("video/*", "Video Player", wxVideoXANIM, "mov")
|
||||
#else
|
||||
MMD_REGISTER_FILE("video/avi", "AVI Player", wxVideoWindows, "avi")
|
||||
#endif
|
||||
|
@ -85,7 +85,7 @@ void wxMMediaFile::SetFile(wxInputStream& str, bool preload, bool seekable)
|
||||
m_o_temp = new wxOutputStream(streamb);
|
||||
m_i_temp = new wxInputStream(streamb);
|
||||
|
||||
m_o_temp->Write(is);
|
||||
m_o_temp->Write(str);
|
||||
streamb->ResetBuffer();
|
||||
}
|
||||
}
|
||||
@ -116,7 +116,7 @@ void wxMMediaFile::CleanUpPrevious()
|
||||
if (m_ostream)
|
||||
m_ostream->Write(*m_i_temp);
|
||||
|
||||
delete m_i_temp->StreamBuffer();
|
||||
delete (m_i_temp->InputStreamBuffer());
|
||||
delete m_i_temp;
|
||||
delete m_o_temp;
|
||||
|
||||
|
@ -103,7 +103,7 @@ wxUint32 wxSndAiffCodec::PrepareToPlay()
|
||||
m_spos = 0;
|
||||
m_slen = 0;
|
||||
m_sndformat.SetSampleRate(0);
|
||||
while (1) {
|
||||
while (!m_spos || !m_sndformat.GetSampleRate()) {
|
||||
READ_STRING(chunk_name, 4);
|
||||
READ32(m_chunksize);
|
||||
|
||||
@ -113,9 +113,6 @@ wxUint32 wxSndAiffCodec::PrepareToPlay()
|
||||
ParseCOMM();
|
||||
else
|
||||
m_istream->SeekI(m_chunksize, wxFromCurrent);
|
||||
|
||||
if (m_spos && m_sndformat.GetSampleRate())
|
||||
break;
|
||||
}
|
||||
|
||||
m_sndmode = wxSND_OUTPUT;
|
||||
@ -183,13 +180,51 @@ bool wxSndAiffCodec::OnWriteData(char *buf, wxUint32 size)
|
||||
return ( !(m_ostream->Write(buf, size).LastError()) );
|
||||
}
|
||||
|
||||
bool wxSndAiffCodec::PrepareToRecord(wxUint32 m_fsize)
|
||||
void wxSndAiffCodec::WriteCOMM()
|
||||
{
|
||||
/*
|
||||
wxDataOutputStream data_s(*m_ostream);
|
||||
char tmp_buf[10];
|
||||
wxUint16 channels;
|
||||
wxUint32 srate, num_samples;
|
||||
wxUint16 bps;
|
||||
|
||||
m_chunksize = 18;
|
||||
WRITE32(m_chunksize);
|
||||
channels = m_sndformat.GetChannels();
|
||||
srate = m_sndformat.GetSampleRate();
|
||||
bps = m_sndformat.GetBps();
|
||||
|
||||
WRITE16(channels);
|
||||
WRITE32(num_samples);
|
||||
WRITE16(bps);
|
||||
|
||||
data_s.WriteDouble((double)srate);
|
||||
|
||||
m_sndformat.SetByteOrder(wxSND_SAMPLE_BE);
|
||||
m_sndformat.SetSign(wxSND_SAMPLE_UNSIGNED);
|
||||
ChangeCodec(WXSOUND_PCM);
|
||||
*/
|
||||
}
|
||||
|
||||
void wxSndAiffCodec::WriteSSND(wxUint32 fsize)
|
||||
{
|
||||
/*
|
||||
wxUint32 total_size;
|
||||
char tmp_buf[10];
|
||||
|
||||
m_ostream->SeekO(0, wxBeginPosition);
|
||||
WRITE32(m_spos);
|
||||
// WRITE32(dummy ??);
|
||||
|
||||
m_slen = m_chunksize - m_spos;
|
||||
m_spos += m_istream->TellI();
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
bool wxSndAiffCodec::PrepareToRecord(wxUint32 m_fsize)
|
||||
{
|
||||
wxUint32 total_size = m_fsize + 0;
|
||||
char tmp_buf[10];
|
||||
|
||||
m_ostream->Write("FORM", 4);
|
||||
WRITE32(total_size);
|
||||
@ -199,7 +234,6 @@ bool wxSndAiffCodec::PrepareToRecord(wxUint32 m_fsize)
|
||||
WriteCOMM();
|
||||
WriteSSND(m_fsize);
|
||||
|
||||
*/
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -51,8 +51,6 @@ wxUint32 wxSndAuCodec::PrepareToPlay()
|
||||
int offset, srate, codec, ch_count;
|
||||
size_t len;
|
||||
|
||||
m_istream->SeekI(0);
|
||||
|
||||
m_istream->Read(temp_buf, 4);
|
||||
temp_buf[4] = 0;
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
wxFragmentBuffer::wxFragmentBuffer(wxSound& io_drv)
|
||||
: m_iodrv(&io_drv), m_maxoq(0), m_maxiq(0),
|
||||
m_optrs(NULL), m_iptrs(NULL), m_lstoptrs(NULL), m_lstiptrs(NULL),
|
||||
m_lstoptrs(NULL), m_lstiptrs(NULL),
|
||||
m_buf2free(FALSE), m_dontq(FALSE), m_freeing(FALSE)
|
||||
{
|
||||
}
|
||||
@ -53,7 +53,7 @@ void wxFragmentBuffer::AbortBuffer(wxSndBuffer *buf)
|
||||
}
|
||||
|
||||
wxFragmentBuffer::wxFragBufPtr *wxFragmentBuffer::FindFreeBuffer(
|
||||
xFragBufPtr *list, wxUint8 max_queue)
|
||||
wxFragBufPtr *list, wxUint8 max_queue)
|
||||
{
|
||||
if (!list)
|
||||
return NULL;
|
||||
@ -69,8 +69,6 @@ wxFragmentBuffer::wxFragBufPtr *wxFragmentBuffer::FindFreeBuffer(
|
||||
bool wxFragmentBuffer::NotifyOutputBuffer(wxSndBuffer *buf)
|
||||
{
|
||||
wxFragBufPtr *ptr;
|
||||
char *raw_buf;
|
||||
wxUint32 rawbuf_size;
|
||||
wxSoundCodec *codec = buf->GetCurrentCodec();
|
||||
|
||||
if (!m_iodrv->OnSetupDriver(*buf, wxSND_OUTPUT))
|
||||
@ -80,7 +78,7 @@ bool wxFragmentBuffer::NotifyOutputBuffer(wxSndBuffer *buf)
|
||||
// Find the first free (at least partly free) output buffer
|
||||
ptr = FindFreeBuffer(m_lstoptrs, m_maxoq);
|
||||
// No free : go out !
|
||||
if (!ptr)
|
||||
if (ptr == NULL)
|
||||
return FALSE;
|
||||
|
||||
codec->SetOutStream(ptr->sndbuf);
|
||||
@ -90,7 +88,7 @@ bool wxFragmentBuffer::NotifyOutputBuffer(wxSndBuffer *buf)
|
||||
codec->Decode();
|
||||
|
||||
// No data to fill the buffer: dequeue the current wxSndBuffer
|
||||
if (!codec->Available()) {
|
||||
if (codec->Available() == 0) {
|
||||
if (buf->IsNotSet(wxSND_KEEPQUEUED)) {
|
||||
buf->Set(wxSND_UNQUEUEING);
|
||||
m_iodrv->m_buffers.DeleteObject(buf);
|
||||
@ -102,7 +100,7 @@ bool wxFragmentBuffer::NotifyOutputBuffer(wxSndBuffer *buf)
|
||||
ptr->buffers->Append(buf);
|
||||
|
||||
// Output buffer full: send it to the driver
|
||||
if (ptr->sndbuf->GetDataLeft()) {
|
||||
if (ptr->sndbuf->GetDataLeft() == 0) {
|
||||
ptr->state = wxBUFFER_FFILLED;
|
||||
OnBufferFilled(ptr, wxSND_OUTPUT);
|
||||
}
|
||||
@ -111,32 +109,24 @@ bool wxFragmentBuffer::NotifyOutputBuffer(wxSndBuffer *buf)
|
||||
|
||||
bool wxFragmentBuffer::NotifyInputBuffer(wxSndBuffer *buf)
|
||||
{
|
||||
/*
|
||||
wxFragBufPtr *ptr;
|
||||
char *raw_buf;
|
||||
wxUint32 rawbuf_size;
|
||||
wxFragBufPtr *ptr;
|
||||
size_t inc;
|
||||
|
||||
if (!m_iodrv->OnSetupDriver(*buf, wxSND_INPUT))
|
||||
if (!m_iodrv->OnSetupDriver(*buf, wxSND_INPUT))
|
||||
return FALSE;
|
||||
|
||||
while (1) {
|
||||
ptr = FindFreeBuffer(m_lstiptrs, m_maxiq);
|
||||
if (ptr == NULL)
|
||||
return FALSE;
|
||||
|
||||
while (1) {
|
||||
ptr = FindFreeBuffer(m_lstiptrs, m_maxiq);
|
||||
if (!ptr)
|
||||
return FALSE;
|
||||
|
||||
raw_buf = ptr->data + ptr->ptr;
|
||||
rawbuf_size = ptr->size - ptr->ptr;
|
||||
|
||||
rawbuf_size = (buf->Available() < rawbuf_size) ? buf->Available() : rawbuf_size;
|
||||
|
||||
if (!rawbuf_size) {
|
||||
|
||||
if (buf->Available() == 0) {
|
||||
if (buf->IsNotSet(wxSND_KEEPQUEUED)) {
|
||||
buf->Set(wxSND_UNQUEUEING);
|
||||
m_iodrv->m_buffers.DeleteObject(buf);
|
||||
}
|
||||
|
||||
if (!LastBuffer() && ptr->ptr) {
|
||||
if (LastBuffer() == NULL && ptr->sndbuf->GetIntPosition() != 0) {
|
||||
ptr->state = wxBUFFER_FFILLED;
|
||||
if (!OnBufferFilled(ptr, wxSND_INPUT))
|
||||
return FALSE;
|
||||
@ -145,16 +135,18 @@ bool wxFragmentBuffer::NotifyInputBuffer(wxSndBuffer *buf)
|
||||
}
|
||||
ptr->buffers->Append(buf);
|
||||
|
||||
ptr->ptr += rawbuf_size;
|
||||
// TODO: Add an "incrementer" in wxStreamBuffer.
|
||||
inc = (buf->Available() < ptr->sndbuf->GetDataLeft()) ?
|
||||
buf->Available() : ptr->sndbuf->GetDataLeft();
|
||||
|
||||
ptr->sndbuf->SetIntPosition(ptr->sndbuf->GetIntPosition() + inc);
|
||||
|
||||
if (ptr->ptr == ptr->size) {
|
||||
if (ptr->sndbuf->GetDataLeft() == 0) {
|
||||
ptr->state = wxBUFFER_FFILLED;
|
||||
if (!OnBufferFilled(ptr, wxSND_INPUT))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -186,11 +178,7 @@ void wxFragmentBuffer::ClearBuffer(wxFragBufPtr *ptr)
|
||||
{
|
||||
wxNode *node;
|
||||
wxSndBuffer *buf;
|
||||
char *data;
|
||||
wxUint32 size, data_read;
|
||||
|
||||
data = ptr->data;
|
||||
size = ptr->size;
|
||||
wxSoundCodec *codec;
|
||||
|
||||
node = ptr->buffers->First();
|
||||
|
||||
@ -200,10 +188,13 @@ void wxFragmentBuffer::ClearBuffer(wxFragBufPtr *ptr)
|
||||
if (buf->GetMode() == wxSND_OUTPUT) {
|
||||
buf->OnBufferOutFinished();
|
||||
} else {
|
||||
data_read = buf->OnBufferInFinished(data, size);
|
||||
codec = buf->GetCurrentCodec();
|
||||
|
||||
data += data_read;
|
||||
size -= data_read;
|
||||
codec->SetInStream(ptr->sndbuf);
|
||||
codec->InitIO(m_drvformat);
|
||||
|
||||
// As there is an "auto-stopper" in the codec, we don't worry ...
|
||||
codec->Encode();
|
||||
}
|
||||
|
||||
if (buf->IsSet(wxSND_UNQUEUEING))
|
||||
|
@ -32,65 +32,60 @@ protected:
|
||||
typedef enum {
|
||||
wxBUFFER_FREE,
|
||||
wxBUFFER_FFILLED,
|
||||
wxBUFFER_TOFREE
|
||||
wxBUFFER_TOFREE,
|
||||
wxBUFFER_PLAYING
|
||||
} BufState;
|
||||
public:
|
||||
///
|
||||
typedef struct {
|
||||
char *data;
|
||||
///
|
||||
// Local stream buffer for this fragment.
|
||||
wxStreamBuffer *sndbuf;
|
||||
// Data the driver would like to pass to the callback.
|
||||
char *user_data;
|
||||
///
|
||||
wxUint32 size, ptr;
|
||||
///
|
||||
// Buffers included in this fragment.
|
||||
wxList *buffers;
|
||||
///
|
||||
// State of the fragment.
|
||||
BufState state;
|
||||
} wxFragBufPtr;
|
||||
protected:
|
||||
///
|
||||
//
|
||||
wxFragBufPtr *m_optrs, *m_iptrs;
|
||||
///
|
||||
//
|
||||
wxFragBufPtr *m_lstoptrs, *m_lstiptrs;
|
||||
///
|
||||
//
|
||||
bool m_buf2free, m_dontq, m_freeing;
|
||||
///
|
||||
//
|
||||
wxSoundDataFormat m_drvformat;
|
||||
public:
|
||||
///
|
||||
wxFragmentBuffer(wxSound& io_drv);
|
||||
///
|
||||
virtual ~wxFragmentBuffer();
|
||||
|
||||
///
|
||||
// These functions initializes the fragments. They must initialize
|
||||
// m_lstoptrs, m_lstiptrs, m_maxoq, m_maxiq.
|
||||
virtual void AllocIOBuffer() = 0;
|
||||
///
|
||||
virtual void FreeIOBuffer() = 0;
|
||||
|
||||
///
|
||||
void AbortBuffer(wxSndBuffer *buf);
|
||||
|
||||
///
|
||||
// Find a free (or partly free) fragment.
|
||||
wxFragBufPtr *FindFreeBuffer(wxFragBufPtr *list, wxUint8 max_queue);
|
||||
///
|
||||
// Add this sound buffer to an "OUTPUT" fragment.
|
||||
bool NotifyOutputBuffer(wxSndBuffer *buf);
|
||||
///
|
||||
// Add this sound buffer to an "INPUT" fragment.
|
||||
bool NotifyInputBuffer(wxSndBuffer *buf);
|
||||
|
||||
///
|
||||
// Called when a fragment is finished.
|
||||
void OnBufferFinished(wxFragBufPtr *ptr);
|
||||
|
||||
///
|
||||
// Called when a fragment is full and it should be flushed in the sound card.
|
||||
virtual bool OnBufferFilled(wxFragBufPtr *ptr, wxSndMode mode) = 0;
|
||||
|
||||
///
|
||||
inline wxSndBuffer *LastBuffer() {
|
||||
wxNode *node = m_iodrv->m_buffers.Last();
|
||||
|
||||
if (!node) return NULL;
|
||||
return (wxSndBuffer *)node->Data();
|
||||
}
|
||||
///
|
||||
inline wxSndBuffer *FirstBuffer() {
|
||||
wxNode *node = m_iodrv->m_buffers.First();
|
||||
|
||||
|
@ -49,7 +49,8 @@ wxUssSound::~wxUssSound()
|
||||
m_sleep_cond.Signal();
|
||||
m_sleep_mtx.Unlock();
|
||||
}
|
||||
Join();
|
||||
while (IsAlive())
|
||||
Yield();
|
||||
}
|
||||
|
||||
if (m_fd != -1)
|
||||
|
@ -42,12 +42,10 @@ void wxSndWinFragment::AllocIOBuffer(void)
|
||||
m_maxoq = 5;
|
||||
m_maxiq = 5;
|
||||
|
||||
m_lstoptrs = m_optrs = new wxFragBufPtr[m_maxoq];
|
||||
m_lstiptrs = m_iptrs = new wxFragBufPtr[m_maxiq];
|
||||
m_lstoptrs = new wxFragBufPtr[m_maxoq];
|
||||
m_lstiptrs = new wxFragBufPtr[m_maxiq];
|
||||
|
||||
for (i=0;i<m_maxoq;i++) {
|
||||
m_lstoptrs[i].size = MMD_WIN_IO_BSIZE;
|
||||
m_lstoptrs[i].ptr = 0;
|
||||
m_lstoptrs[i].buffers = new wxList();
|
||||
m_lstoptrs[i].state = wxBUFFER_FREE;
|
||||
|
||||
@ -198,7 +196,7 @@ void wxWinSound::PrepareHeader(wxFragmentBuffer::wxFragBufPtr& frag,
|
||||
|
||||
info = new wxSndWinInfo;
|
||||
|
||||
info->h_data = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, frag.size);
|
||||
info->h_data = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, MMD_WIN_IO_BSIZE);
|
||||
info->h_hdr = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, sizeof(WAVEHDR));
|
||||
|
||||
info->data = (char *)GlobalLock(info->h_data);
|
||||
@ -214,19 +212,18 @@ void wxWinSound::PrepareHeader(wxFragmentBuffer::wxFragBufPtr& frag,
|
||||
MMRESULT result = waveInPrepareHeader(internal->devin_id, hdr,
|
||||
sizeof(WAVEHDR));
|
||||
|
||||
printf("prepareIn = %d\n", result);
|
||||
if (result != MMSYSERR_NOERROR)
|
||||
wxExit();
|
||||
} else {
|
||||
MMRESULT result = waveOutPrepareHeader(internal->devout_id, hdr,
|
||||
sizeof(WAVEHDR));
|
||||
printf("prepareOut = %d\n", result);
|
||||
if (result != MMSYSERR_NOERROR)
|
||||
wxExit();
|
||||
}
|
||||
|
||||
frag.sndbuf = new wxStreamBuffer();
|
||||
frag.sndbuf->SetBufferIO(info->data, info->data + MMD_WIN_IO_BSIZE);
|
||||
frag.user_data = (char *)info;
|
||||
frag.data = info->data;
|
||||
}
|
||||
|
||||
void wxWinSound::UnprepareHeader(wxFragmentBuffer::wxFragBufPtr& frag,
|
||||
@ -246,6 +243,8 @@ void wxWinSound::UnprepareHeader(wxFragmentBuffer::wxFragBufPtr& frag,
|
||||
result = waveOutUnprepareHeader(internal->devout_id, info->hdr, sizeof(*info->hdr));
|
||||
}
|
||||
|
||||
delete frag.sndbuf;
|
||||
|
||||
printf("unprepare = %d\n", result);
|
||||
|
||||
GlobalUnlock(info->h_hdr);
|
||||
@ -282,6 +281,7 @@ LRESULT APIENTRY _EXPORT wxSoundHandlerWndProc(HWND hWnd, UINT message,
|
||||
printf("wave Close ack\n");
|
||||
break;
|
||||
default:
|
||||
// TODO: Useful ?
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
}
|
||||
return (LRESULT)0;
|
||||
|
Loading…
Reference in New Issue
Block a user