实现一个循环buffer, 新数据会覆盖旧数据
RingBuffer.h
#pragma once
#include <stdio.h>
#include <string.h>
class RingBuffer
{
public:
RingBuffer()
{
size = 0;
}
~RingBuffer()
{
if (buffer)
{
delete buffer;
buffer = 0;
}
}
void setSize(int t_size)
{
if (t_size != size)
{
if (buffer)
{
delete buffer;
buffer = 0;
}
size = t_size;
mSize = t_size + 1;
buffer = new short[mSize];
pEnd = mSize - 1; //
pRead = 0;
pWrite = 0;
offset = 0;
}
}
bool push(short * pData, int nSample)
{
if (nSample > size)
{
printf("len is too large ... \n");
return false;
}
int freeSize = size - GetSampleSize();
int dis = pWrite - pRead;
if (freeSize >= nSample) // 够用
{
if (dis >= 0) /// pWrite 在右侧
{
if (pEnd - pWrite + 1 >= nSample) // 不需要折返拷贝
{
memcpy(&buffer[pWrite], pData, nSample * sizeof(short));
//pWrite += nSample;
pWrite = add(pWrite, nSample);
}
else // 需要折返拷贝
{
//右边空间多少
int rightFreeSize = pEnd - pWrite + 1;
// 左边需要拷贝的大小
int leftSize = nSample - rightFreeSize;
memcpy(&buffer[pWrite], pData, rightFreeSize * sizeof(short));
memcpy(&buffer[0], pData + rightFreeSize, leftSize * sizeof(short));
//pWrite = leftSize;
pWrite = add(pWrite, nSample);
}
}
else/// pWrite 在左侧
{
//
memcpy(&buffer[pWrite], pData, nSample * sizeof(short));
//pWrite += nSample;
pWrite = add(pWrite, nSample);
}
}
else // 不够用,覆盖, 需要更新pRead
{
printf("差几个 %d ... \n", nSample - freeSize);
if (dis > 0) /// pWrite 在右侧,
{
//右边空间多少
int rightFreeSize = pEnd - pWrite + 1;
// 左边需要拷贝的大小
int leftSize = nSample - rightFreeSize;
memcpy(&buffer[pWrite], pData, rightFreeSize * sizeof(short));
memcpy(&buffer[0], pData + rightFreeSize, leftSize * sizeof(short));
//pWrite = leftSize;
//pRead = pWrite + 1;
pWrite = add(pWrite, nSample);
pRead = add(pWrite, 1);
pRead = add(pRead, offset);
}
else if (dis < 0) /// pWrite 在左侧
{
if (pEnd - pWrite + 1 >= nSample) // 不需要折返拷贝
{
memcpy(&buffer[pWrite], pData, nSample * sizeof(short));
//pWrite += nSample;
//pRead = pWrite + 1;
pWrite = add(pWrite, nSample);
pRead = add(pWrite, 1);
pRead = add(pRead, offset);
}
else // 需要折返拷贝
{
//右边空间多少
int rightFreeSize = pEnd - pWrite + 1;
// 左边需要拷贝的大小
int leftSize = nSample - rightFreeSize;
memcpy(&buffer[pWrite], pData, rightFreeSize * sizeof(short));
memcpy(&buffer[0], pData + rightFreeSize, leftSize * sizeof(short));
//pWrite = leftSize;
//pRead = pWrite + 1;
pWrite = add(pWrite, nSample);
pRead = add(pWrite, 1);
pRead = add(pRead, offset);
}
}
else // 不存在这种情况
{
}
}
return true;
}
// 外部开空间
bool pop(short * pData, int nSamples)
{
int curSampleSize = GetSampleSize();
if (curSampleSize < nSamples)
{
return false;
}
int dis = pWrite - pRead;
if (dis > 0) /// pWrite 在右侧
{
memcpy(pData, &buffer[pRead], nSamples * sizeof(short));
//pRead += nSamples;
pRead = add(pRead, nSamples);
}
else // dis < 0
{
if (pEnd - pRead + 1 >= nSamples) // 不需要折返拷贝
{
memcpy(pData, &buffer[pRead], nSamples * sizeof(short));
//pRead += nSamples;
pRead = add(pRead, nSamples);
}
else // 需要折返拷贝
{
//右边空间多少
int rightFreeSize = pEnd - pRead + 1;
// 左边需要拷贝的大小
int leftSize = nSamples - rightFreeSize;
memcpy(pData, &buffer[pRead], rightFreeSize * sizeof(short));
memcpy(pData + rightFreeSize, &buffer[0], leftSize * sizeof(short));
//pRead = leftSize;
pRead = add(pRead, nSamples);
}
}
return true;
}
int GetSampleSize()
{
return (pWrite - pRead + mSize) % mSize;
}
int add(int pos, int t)
{
return (pos + t) % mSize;
}
private:
int mSize; // 申请空间比容量大1
int size; // 循环buffer 的容量
short * buffer;
int offset;
int pEnd;
int pRead;
int pWrite;
};
main.cpp
#include <stdio.h>
#include "RingBuffer.h"
int main()
{
RingBuffer mRingBuffer;
int mMaxSize = 5;
mRingBuffer.setSize(mMaxSize * 2);
int mGetSize = 3;
short * pShort = new short[mMaxSize];
for (int i = 0; i < mMaxSize; i++)
{
pShort[i] = i;
}
short * pGet = new short[mGetSize];
for (int i = 0; i < 10; i++)
{
printf("################ %d ....\n", i);
mRingBuffer.push(pShort, mMaxSize);
bool isOk = mRingBuffer.pop(pGet, mGetSize);
if (isOk)
{
for (int j = 0; j < mGetSize; j++)
{
printf("%d .. \n", pGet[j]);
}
}
}
printf("## ");
return 0;
}
代码经过初步测试,后续会用模板的方式更新测试