[#1882] Finilize multiple reading pointer in RingBuffer

This commit is contained in:
Alexandre Savard
2009-07-31 14:40:39 -04:00
parent 7b3e4e226b
commit d213ea72aa
4 changed files with 177 additions and 29 deletions

View File

@ -59,12 +59,29 @@ RingBuffer::flush (void)
}
int
RingBuffer::Len()
RingBuffer::putLen()
{
mStart = getReadPointer();
if(_readpointer.size() > 1)
{
mStart = getSmallestReadPointer();
}
else
{
mStart = getReadPointer();
}
return (mEnd + mBufferSize - mStart) % mBufferSize;
}
int
RingBuffer::getLen(CallID call_id)
{
mStart = getReadPointer(call_id);
return (mEnd + mBufferSize - mStart) % mBufferSize;
}
void
RingBuffer::debug()
{
@ -83,6 +100,21 @@ RingBuffer::getReadPointer(CallID call_id)
}
int
RingBuffer::getSmallestReadPointer()
{
int smallest = mBufferSize;
ReadPointer::iterator iter;
for( iter = _readpointer.begin(); iter != _readpointer.end(); iter++)
{
if((iter->first != "default_id") && (iter->second < smallest))
smallest = iter->second;
}
return smallest;
}
void
RingBuffer::storeReadPointer(int pointer_value, CallID call_id)
{
@ -118,7 +150,7 @@ int
RingBuffer::AvailForPut()
{
// Always keep 4 bytes safe (?)
return (mBufferSize-4) - Len();
return (mBufferSize-4) - putLen();
}
// This one puts some data inside the ring buffer.
@ -130,7 +162,7 @@ RingBuffer::Put (void* buffer, int toCopy, unsigned short volume)
int block;
int copied;
int pos;
int len = Len();
int len = putLen();
if (toCopy > (mBufferSize-4) - len)
toCopy = (mBufferSize-4) - len;
@ -186,20 +218,20 @@ RingBuffer::Put (void* buffer, int toCopy, unsigned short volume)
//
int
RingBuffer::AvailForGet()
RingBuffer::AvailForGet(CallID call_id)
{
// Used space
return Len();
return getLen(call_id);
}
// Get will move 'toCopy' bytes from the internal FIFO to 'buffer'
int
RingBuffer::Get (void *buffer, int toCopy, unsigned short volume)
RingBuffer::Get (void *buffer, int toCopy, unsigned short volume, CallID call_id)
{
samplePtr dest;
int block;
int copied;
int len = Len();
int len = getLen(call_id);
if (toCopy > len)
toCopy = len;
@ -208,7 +240,7 @@ RingBuffer::Get (void *buffer, int toCopy, unsigned short volume)
copied = 0;
mStart = getReadPointer();
mStart = getReadPointer(call_id);
//fprintf(stderr, "G");
while (toCopy) {
@ -239,25 +271,25 @@ RingBuffer::Get (void *buffer, int toCopy, unsigned short volume)
copied += block;
}
storeReadPointer(mStart);
storeReadPointer(mStart, call_id);
return copied;
}
// Used to discard some bytes.
int
RingBuffer::Discard (int toDiscard)
RingBuffer::Discard (int toDiscard, CallID call_id)
{
int len = Len();
int len = getLen(call_id);
mStart = getReadPointer();
mStart = getReadPointer(call_id);
if (toDiscard > len)
toDiscard = len;
mStart = (mStart + toDiscard) % mBufferSize;
storeReadPointer(mStart);
storeReadPointer(mStart, call_id);
return toDiscard;
}

View File

@ -53,6 +53,8 @@ class RingBuffer {
int getReadPointer(CallID call_id = "default_id");
int getSmallestReadPointer();
void storeReadPointer(int pointer_value, CallID call_id = "default_id");
void createReadPointer(CallID call_id = "default_id");
@ -78,7 +80,7 @@ class RingBuffer {
* To get how much space is available in the buffer to read in
* @return int The available size
*/
int AvailForGet (void);
int AvailForGet (CallID call_id = "default_id");
/**
* Get data in the ring buffer
@ -87,20 +89,22 @@ class RingBuffer {
* @param volume The volume
* @return int Number of bytes copied
*/
int Get (void* buffer, int toCopy, unsigned short volume = 100);
int Get (void* buffer, int toCopy, unsigned short volume = 100, CallID call_id = "default_id");
/**
* Discard data from the buffer
* @param toDiscard Number of bytes to discard
* @return int Number of bytes discarded
*/
int Discard(int toDiscard);
int Discard(int toDiscard, CallID call_id = "default_id");
/**
* Total length of the ring buffer
* @return int
*/
int Len();
int putLen();
int getLen(CallID call_id = "default_id");
/**
* Debug function print mEnd, mStart, mBufferSize

View File

@ -99,24 +99,24 @@ void MainBufferTest::testRingBufferInt()
int testint2 = 13;
CPPUNIT_ASSERT(test_ring_buffer->Put(&testint1, sizeof(int)) == sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->Len() == sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->putLen() == sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->Put(&testint2, sizeof(int)) == sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->Len() == 2*sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->putLen() == 2*sizeof(int));
int testget;
CPPUNIT_ASSERT(test_ring_buffer->Get(&testget, sizeof(int)) == sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->Len() == sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->getLen() == sizeof(int));
CPPUNIT_ASSERT(testget == testint1);
CPPUNIT_ASSERT(test_ring_buffer->Get(&testget, sizeof(int)) == sizeof(int));
CPPUNIT_ASSERT(testget == testint2);
CPPUNIT_ASSERT(test_ring_buffer->Len() == 0);
CPPUNIT_ASSERT(test_ring_buffer->getLen() == 0);
CPPUNIT_ASSERT(test_ring_buffer->Put(&testint1, sizeof(int)) == sizeof(int));
test_ring_buffer->flush();
CPPUNIT_ASSERT(test_ring_buffer->Len() == 0);
CPPUNIT_ASSERT(test_ring_buffer->putLen() == 0);
_mainbuffer.removeRingBuffer(test_id);
}
@ -134,24 +134,24 @@ void MainBufferTest::testRingBufferFloat()
float testfloat2 = 13.4;
CPPUNIT_ASSERT(test_ring_buffer->Put(&testfloat1, sizeof(float)) == sizeof(float));
CPPUNIT_ASSERT(test_ring_buffer->Len() == sizeof(float));
CPPUNIT_ASSERT(test_ring_buffer->putLen() == sizeof(float));
CPPUNIT_ASSERT(test_ring_buffer->Put(&testfloat2, sizeof(float)) == sizeof(float));
CPPUNIT_ASSERT(test_ring_buffer->Len() == 2*sizeof(float));
CPPUNIT_ASSERT(test_ring_buffer->putLen() == 2*sizeof(float));
float testget;
CPPUNIT_ASSERT(test_ring_buffer->Get(&testget, sizeof(float)) == sizeof(float));
CPPUNIT_ASSERT(test_ring_buffer->Len() == sizeof(float));
CPPUNIT_ASSERT(test_ring_buffer->getLen() == sizeof(float));
CPPUNIT_ASSERT(testget == testfloat1);
CPPUNIT_ASSERT(test_ring_buffer->Get(&testget, sizeof(float)) == sizeof(float));
CPPUNIT_ASSERT(testget == testfloat2);
CPPUNIT_ASSERT(test_ring_buffer->Len() == 0);
CPPUNIT_ASSERT(test_ring_buffer->getLen() == 0);
CPPUNIT_ASSERT(test_ring_buffer->Put(&testfloat1, sizeof(float)) == sizeof(float));
test_ring_buffer->flush();
CPPUNIT_ASSERT(test_ring_buffer->Len() == 0);
CPPUNIT_ASSERT(test_ring_buffer->putLen() == 0);
_mainbuffer.removeRingBuffer(test_id);
}
@ -316,8 +316,117 @@ void MainBufferTest::testReadPointerInit()
test_ring_buffer->storeReadPointer(10, test_id);
CPPUNIT_ASSERT(test_ring_buffer->getReadPointer(test_id) == 10);
test_ring_buffer->removeReadPointer(test_id);
CPPUNIT_ASSERT(test_ring_buffer->getReadPointer(test_id) == NULL);
CPPUNIT_ASSERT(test_ring_buffer->getReadPointer(test_id) == (int)NULL);
test_ring_buffer->removeReadPointer("false id");
_mainbuffer.removeRingBuffer(test_id);
}
void MainBufferTest::testRingBufferSeveralPointers()
{
_debug("MainBufferTest::testRingBufferSeveralPointers\n");
CallID test_id = "test multiple read pointer";
RingBuffer* test_ring_buffer = _mainbuffer.createRingBuffer(test_id);
CallID test_pointer1 = "test pointer 1";
CallID test_pointer2 = "test pointer 2";
test_ring_buffer->createReadPointer(test_pointer1);
test_ring_buffer->createReadPointer(test_pointer2);
int testint1 = 12;
int testint2 = 13;
int testint3 = 14;
int testint4 = 15;
int testoutput;
int initPutLen = test_ring_buffer->AvailForPut();
CPPUNIT_ASSERT(test_ring_buffer->Put(&testint1, sizeof(int)) == sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->putLen() == sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->AvailForPut() == initPutLen - sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->getLen(test_pointer1) == sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->getLen(test_pointer2) == sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->AvailForGet(test_pointer1) == sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->AvailForGet(test_pointer2) == sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->Put(&testint2, sizeof(int)) == sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->putLen() == 2*sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->AvailForPut() == initPutLen - 2*sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->getLen(test_pointer1) == 2*sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->getLen(test_pointer2) == 2*sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->AvailForGet(test_pointer1) == 2*sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->AvailForGet(test_pointer2) == 2*sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->Put(&testint3, sizeof(int)) == sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->putLen() == 3*sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->AvailForPut() == initPutLen - 3*sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->getLen(test_pointer1) == 3*sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->getLen(test_pointer2) == 3*sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->AvailForGet(test_pointer1) == 3*sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->AvailForGet(test_pointer2) == 3*sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->Put(&testint4, sizeof(int)) == sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->putLen() == 4*sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->AvailForPut() == initPutLen - 4*sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->getLen(test_pointer1) == 4*sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->getLen(test_pointer2) == 4*sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->AvailForGet(test_pointer1) == 4*sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->AvailForGet(test_pointer2) == 4*sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->Get(&testoutput, sizeof(int), 100, test_pointer1) == sizeof(int));
CPPUNIT_ASSERT(testoutput == testint1);
CPPUNIT_ASSERT(test_ring_buffer->AvailForPut() == initPutLen - 4*sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->AvailForGet(test_pointer1) == 3*sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->AvailForGet(test_pointer2) == 4*sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->Get(&testoutput, sizeof(int), 100, test_pointer2) == sizeof(int));
CPPUNIT_ASSERT(testoutput == testint1);
CPPUNIT_ASSERT(test_ring_buffer->AvailForPut() == initPutLen - 3*sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->AvailForGet(test_pointer1) == 3*sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->AvailForGet(test_pointer2) == 3*sizeof(int));
// AvailForPut() is ok but AvailForGet(default_id) is not ok
// However, we should no be alowed to read in our own ring buffer
// if we are either an AudioLayer or and RTP session
CPPUNIT_ASSERT(test_ring_buffer->AvailForGet() == 4*sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->Get(&testoutput, sizeof(int), 100, test_pointer1) == sizeof(int));
CPPUNIT_ASSERT(testoutput == testint2);
CPPUNIT_ASSERT(test_ring_buffer->AvailForPut() == initPutLen - 3*sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->AvailForGet(test_pointer1) == 2*sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->AvailForGet(test_pointer2) == 3*sizeof(int));
// AvailForPut() is ok but AvailForGet(default_id) is not ok
// However, we should no be alowed to read in our own ring buffer
// if we are either an AudioLayer or and RTP session
CPPUNIT_ASSERT(test_ring_buffer->AvailForGet() == 4*sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->Get(&testoutput, sizeof(int), 100, test_pointer2) == sizeof(int));
CPPUNIT_ASSERT(testoutput == testint2);
CPPUNIT_ASSERT(test_ring_buffer->AvailForPut() == initPutLen - 2*sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->AvailForGet(test_pointer1) == 2*sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->AvailForGet(test_pointer2) == 2*sizeof(int));
// AvailForPut() is ok but AvailForGet(default_id) is not ok
// However, we should no be alowed to read in our own ring buffer
// if we are either an AudioLayer or and RTP session
CPPUNIT_ASSERT(test_ring_buffer->AvailForGet() == 4*sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->Discard(sizeof(int), test_pointer1) == sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->AvailForPut() == initPutLen - 2*sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->AvailForGet(test_pointer1) == sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->AvailForGet(test_pointer2) == 2*sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->Discard(sizeof(int), test_pointer2) == sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->AvailForPut() == initPutLen - sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->AvailForGet(test_pointer1) == sizeof(int));
CPPUNIT_ASSERT(test_ring_buffer->AvailForGet(test_pointer2) == sizeof(int));
_mainbuffer.removeRingBuffer(test_id);
}

View File

@ -73,6 +73,7 @@ class MainBufferTest : public CppUnit::TestCase {
CPPUNIT_TEST( testAvailForGetPut );
CPPUNIT_TEST( testDiscardFlush );
CPPUNIT_TEST( testReadPointerInit );
CPPUNIT_TEST( testRingBufferSeveralPointers );
CPPUNIT_TEST_SUITE_END();
public:
@ -111,6 +112,8 @@ class MainBufferTest : public CppUnit::TestCase {
void testReadPointerInit();
void testRingBufferSeveralPointers();
private:
MainBuffer _mainbuffer;