C++ 为浮点值实现一个简单的环形缓冲区
我试图实现一个非常简单的环形缓冲区,用于以浮点值的形式保存音频样本流 我希望能够在任何时候拍摄音频输入的快照。我不需要弹出或删除任何值,只需保留最后n个样本的移动缓冲区 我想问一下,出于我的目的,这个实现是否存在任何潜在的问题C++ 为浮点值实现一个简单的环形缓冲区,c++,C++,我试图实现一个非常简单的环形缓冲区,用于以浮点值的形式保存音频样本流 我希望能够在任何时候拍摄音频输入的快照。我不需要弹出或删除任何值,只需保留最后n个样本的移动缓冲区 我想问一下,出于我的目的,这个实现是否存在任何潜在的问题 class RingBuffer { public: RingBuffer (int bufferSize) : bufferSize (bufferSize), count (0), head (0) { buffer = sta
class RingBuffer
{
public:
RingBuffer (int bufferSize) : bufferSize (bufferSize), count (0), head (0)
{
buffer = static_cast<float *> (malloc(bufferSize * sizeof(float)));
readBuffer = static_cast<float *> (malloc(bufferSize * sizeof(float)));
}
~RingBuffer ()
{
if (buffer != nullptr) free(buffer);
buffer = nullptr;
if (readBuffer != nullptr) free(readBuffer);
readBuffer = nullptr;
}
void push (float value)
{
if (count < bufferSize && head == 0)
{
buffer[count++] = value;
}
else if (count == bufferSize)
{
// reset head to beginning if reached the end
if (head >= bufferSize)
{
head = 0;
buffer[head] = value;
}
else
{
buffer[head++] = value;
}
}
}
/**
* Return a snapshot of the buffer as a continous array
*/
const float* getSnapshot ()
{
// Set up read buffer as continuous stream
int writeIndex = 0;
for (int i = head; i < count; ++i)
{
readBuffer[writeIndex++] = buffer[i];
}
for (int i = 0; i < head; ++i)
{
readBuffer[writeIndex++] = buffer[i];
}
return readBuffer;
}
private:
int bufferSize, head, count;
float* buffer;
float* readBuffer;
};
class-RingBuffer
{
公众:
RingBuffer(int bufferSize):bufferSize(bufferSize)、count(0)、head(0)
{
buffer=static_cast(malloc(bufferSize*sizeof(float));
readBuffer=static_cast(malloc(bufferSize*sizeof(float));
}
~RingBuffer()
{
如果(buffer!=nullptr)空闲(buffer);
缓冲区=空PTR;
如果(readBuffer!=nullptr)空闲(readBuffer);
readBuffer=nullptr;
}
无效推送(浮动值)
{
如果(计数<缓冲区大小和头==0)
{
缓冲区[计数++]=值;
}
else if(计数==缓冲区大小)
{
//如果到达终点,则将头部重置为起点
如果(磁头>=缓冲区大小)
{
水头=0;
缓冲区[头]=值;
}
其他的
{
缓冲区[head++]=值;
}
}
}
/**
*以连续数组的形式返回缓冲区的快照
*/
常量浮点*getSnapshot()
{
//将读取缓冲区设置为连续流
int writeIndex=0;
用于(int i=头;i<计数;++i)
{
readBuffer[writeIndex++]=缓冲区[i];
}
对于(int i=0;i
嗯,我确实看到了几个问题。对坏消息感到抱歉:-/
虫子
- 这里有一个bug:
buffer[head]=value代码>。您不增加
,因此当下一个样本进入时,此位置的样本将丢失(覆盖)头
- 在构造函数中,您应该将
和buffer
初始化为readBuffer
:如果其中一个malloc失败,析构函数将尝试释放nullptr
中的第一个循环出现故障:终点应该是getSnapshot
而不是min(缓冲区大小、头部+计数)
count
- 正如mathematician1975所指出的,您应该为数组分配
,它比mallocs更简单、更可读新的float[bufferSize]
- 您应该使用
保存每个缓冲区,这样您就不再需要任何析构函数(并且您的代码会更安全)std::unique_ptr
- 在处理循环缓冲区时,应使用模运算,例如
。这样您的代码会简单得多,尤其是在getSnapshot中(一个循环而不是两个循环)writeIndex=(writeIndex+1)%bufferSize