You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
149 lines
3.1 KiB
149 lines
3.1 KiB
/*
|
|
* 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
|