summaryrefslogtreecommitdiffstats
path: root/flow/bufferqueue.h
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-01-05 00:01:18 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-01-05 00:01:18 +0000
commit42995d7bf396933ee60c5f89c354ea89cf13df0d (patch)
treecfdcea0ac57420e7baf570bfe435e107bb842541 /flow/bufferqueue.h
downloadarts-42995d7bf396933ee60c5f89c354ea89cf13df0d.tar.gz
arts-42995d7bf396933ee60c5f89c354ea89cf13df0d.zip
Copy of aRts for Trinity modifications
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/dependencies/arts@1070145 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'flow/bufferqueue.h')
-rw-r--r--flow/bufferqueue.h148
1 files changed, 148 insertions, 0 deletions
diff --git a/flow/bufferqueue.h b/flow/bufferqueue.h
new file mode 100644
index 0000000..5344c4a
--- /dev/null
+++ b/flow/bufferqueue.h
@@ -0,0 +1,148 @@
+/*
+ * BC - Status (2002-03-08): ByteBuffer, BufferQueue
+ *
+ * None of these classes is considered part of the public API. Do NOT use it
+ * in your apps. These are part of the implementation of libartsflow's
+ * AudioSubSystem, and subject to change/disappearing due to optimization
+ * work.
+ */
+
+#ifndef _BUFFERQUEUE_H
+#define _BUFFERQUEUE_H
+
+#include "thread.h"
+
+#define _DEFAULT_CHUNK_SIZE 4096
+#define _MAX_CHUNKS 3
+
+namespace Arts
+{
+
+class ByteBuffer
+{
+ unsigned char* content;
+ int _size;
+ int _maxSize;
+ int rp;
+
+public:
+ ByteBuffer() {
+ _size = rp = 0;
+ _maxSize = _DEFAULT_CHUNK_SIZE;
+ content = new unsigned char[_DEFAULT_CHUNK_SIZE];
+ }
+ ByteBuffer(const void* s, int len) {
+ _maxSize = _DEFAULT_CHUNK_SIZE;
+ content = new unsigned char[_DEFAULT_CHUNK_SIZE];
+ put(s, len);
+ }
+
+ ~ByteBuffer() { delete [] content; }
+
+ void put(const void* s, int len) {
+ if ((_size = len) != 0)
+ memcpy(content, s, len);
+ rp = 0;
+ }
+
+ void* get() { return content+rp; }
+ void* reset() { _size = 0; rp = 0; return content; }
+ int push(int len) { _size -= len; rp += len; return _size; }
+ void set(int len) { _size = len; rp = 0; }
+ int size() const { return _size; }
+ int maxSize() const { return _maxSize; }
+
+ void setMaxSize(int size) {
+ delete [] content;
+ content = new unsigned char[size];
+ _maxSize = size;
+ }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+class BufferQueue
+{
+private:
+ ByteBuffer bufs[_MAX_CHUNKS];
+ int rp;
+ int wp;
+ Arts::Semaphore* sema_produced;
+ Arts::Semaphore* sema_consumed;
+
+ void semaReinit() {
+ delete sema_consumed;
+ delete sema_produced;
+ sema_consumed = new Arts::Semaphore(0, _MAX_CHUNKS);
+ sema_produced = new Arts::Semaphore(0, 0);
+ }
+
+
+public:
+ BufferQueue() {
+ rp = wp = 0;
+ sema_consumed = new Arts::Semaphore(0, _MAX_CHUNKS);
+ sema_produced = new Arts::Semaphore(0, 0);
+ }
+
+ ~BufferQueue() {
+ delete sema_consumed;
+ delete sema_produced;
+ }
+
+ void write(void* data, int len);
+ ByteBuffer* waitConsumed();
+ void produced();
+
+ ByteBuffer* waitProduced();
+ void consumed();
+
+ bool isEmpty() const { return sema_produced->getValue() == 0; }
+ int bufferedChunks() const { return sema_produced->getValue(); }
+ int freeChunks() const { return sema_consumed->getValue(); }
+ int maxChunks() const { return _MAX_CHUNKS; }
+ int chunkSize() const { return bufs[0].maxSize(); }
+ void clear() { rp = wp = 0; semaReinit(); }
+ void setChunkSize(int size){
+ for (int i=0; i < maxChunks(); i++)
+ bufs[i].setMaxSize(size);
+ }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+inline void BufferQueue::write(void* data, int len)
+{
+ sema_consumed->wait();
+ bufs[wp].put(data, len);
+ ++wp %= _MAX_CHUNKS;
+ sema_produced->post();
+}
+
+inline ByteBuffer* BufferQueue::waitConsumed()
+{
+ sema_consumed->wait();
+ return &bufs[wp];
+}
+
+inline void BufferQueue::produced()
+{
+ ++wp %= _MAX_CHUNKS;
+ sema_produced->post();
+}
+
+inline ByteBuffer* BufferQueue::waitProduced()
+{
+ sema_produced->wait();
+ return &bufs[rp];
+}
+
+inline void BufferQueue::consumed()
+{
+ ++rp %=_MAX_CHUNKS;
+ sema_consumed->post();
+}
+
+}
+
+#endif