diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-05 00:01:18 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-05 00:01:18 +0000 |
commit | 42995d7bf396933ee60c5f89c354ea89cf13df0d (patch) | |
tree | cfdcea0ac57420e7baf570bfe435e107bb842541 /flow/bufferqueue.h | |
download | arts-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.h | 148 |
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 |