X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/4d6306eb4da8cdac4b5dee9784959672c233eec8..f7ac40d158bbc88f497e29b6efcda20be7da4973:/utils/wxMMedia/sndfrag.cpp?ds=sidebyside diff --git a/utils/wxMMedia/sndfrag.cpp b/utils/wxMMedia/sndfrag.cpp index cd4a76bce8..79c7b9a447 100644 --- a/utils/wxMMedia/sndfrag.cpp +++ b/utils/wxMMedia/sndfrag.cpp @@ -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( - wxFragBufPtr *list, wxUint8 max_queue) + wxFragBufPtr *list, wxUint8 max_queue) { if (!list) return NULL; @@ -69,8 +69,7 @@ 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)) return FALSE; @@ -79,18 +78,19 @@ 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; - // Find the end of the buffer - raw_buf = ptr->data + ptr->ptr; - rawbuf_size = ptr->size - ptr->ptr; + // Normally, these three functions could be called only once. + codec->SetOutStream(ptr->sndbuf); + codec->InitIO(m_drvformat); + codec->InitMode(wxSoundCodec::DECODING); // Fill it up - buf->OnNeedOutputData(raw_buf, rawbuf_size); + codec->Decode(); // No data to fill the buffer: dequeue the current wxSndBuffer - if (!rawbuf_size) { + if (codec->Available() == 0) { if (buf->IsNotSet(wxSND_KEEPQUEUED)) { buf->Set(wxSND_UNQUEUEING); m_iodrv->m_buffers.DeleteObject(buf); @@ -101,10 +101,8 @@ bool wxFragmentBuffer::NotifyOutputBuffer(wxSndBuffer *buf) // Data: append it to the list ptr->buffers->Append(buf); - ptr->ptr += rawbuf_size; - // Output buffer full: send it to the driver - if (ptr->ptr == ptr->size) { + if (ptr->sndbuf->GetDataLeft() == 0) { ptr->state = wxBUFFER_FFILLED; OnBufferFilled(ptr, wxSND_OUTPUT); } @@ -114,31 +112,23 @@ bool wxFragmentBuffer::NotifyOutputBuffer(wxSndBuffer *buf) bool wxFragmentBuffer::NotifyInputBuffer(wxSndBuffer *buf) { wxFragBufPtr *ptr; - char *raw_buf; - wxUint32 rawbuf_size; - + size_t inc; + if (!m_iodrv->OnSetupDriver(*buf, wxSND_INPUT)) return FALSE; - + while (1) { ptr = FindFreeBuffer(m_lstiptrs, m_maxiq); - if (!ptr) + if (ptr == NULL) 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); } - // Get data now when there isn't anymore buffer in the queue - if (!LastBuffer() && ptr->ptr) { + if (LastBuffer() == NULL && ptr->sndbuf->GetIntPosition() != 0) { ptr->state = wxBUFFER_FFILLED; if (!OnBufferFilled(ptr, wxSND_INPUT)) return FALSE; @@ -147,15 +137,19 @@ 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); - // Input buffer full => get data - 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 +180,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 +190,15 @@ void wxFragmentBuffer::ClearBuffer(wxFragBufPtr *ptr) if (buf->GetMode() == wxSND_OUTPUT) { buf->OnBufferOutFinished(); } else { - data_read = buf->OnBufferInFinished(data, size); + codec = buf->GetCurrentCodec(); + + // Normally, these three functions could be called only once. + codec->SetInStream(ptr->sndbuf); + codec->InitIO(m_drvformat); + codec->InitMode(wxSoundCodec::ENCODING); - data += data_read; - size -= data_read; + // As there is an "auto-stopper" in the codec, we don't worry ... + codec->Encode(); } if (buf->IsSet(wxSND_UNQUEUEING)) @@ -213,7 +208,7 @@ void wxFragmentBuffer::ClearBuffer(wxFragBufPtr *ptr) node = ptr->buffers->First(); } - ptr->ptr = 0; + ptr->sndbuf->ResetBuffer(); ptr->state = wxBUFFER_FREE; } @@ -257,10 +252,18 @@ void wxFragmentBuffer::OnBufferFinished(wxFragBufPtr *ptr) buf->Clear(wxSND_BUFSTOP); continue; } - if (buf->GetMode() == wxSND_OUTPUT) + switch (buf->GetMode()) { + case wxSND_OUTPUT: ret = NotifyOutputBuffer(buf); - else + break; + case wxSND_INPUT: ret = NotifyInputBuffer(buf); + break; + case wxSND_DUPLEX: + case wxSND_OTHER_IO: + // ret = NotifyDuplexBuffer(buf); + break; + } buf->HardUnlock(); }