]> git.saurik.com Git - wxWidgets.git/blobdiff - utils/wxMMedia/sndfrag.cpp
wxPython 2.1b1:
[wxWidgets.git] / utils / wxMMedia / sndfrag.cpp
index cd4a76bce8c318d00fba86b4f1e22eacade97575..79c7b9a4470e12bd26da153da8d190d76009ad89 100644 (file)
@@ -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();
   }