怎么编写循环缓冲区

如何编写循环缓冲区
需要一个循环缓冲区,从网络接收音频数据,解码后写入这个缓冲区,另外一个线程在周期性的读取这个缓冲区的数据到声卡缓冲区来实现声音播放(用的DIrectSound)

在现有程序中,是一个固定的缓冲区,设置了一个int play_signal变量通过其值 = 0 或1 的切换 作为“信号量”来保证不冲突地读写该缓冲区。
这种形式可能导致,要将数据读出供播放,必须要等解码后数据写入该缓冲区后才能实现,要等待。。因此其可能导致声音播放的不连续性。

因此考虑开辟一个循环缓冲区,设置读指针和写指针,读指针在写指针之后,可以同时对该缓冲区进行读写操作。以保障音频播放的连续性。

编程新手,不知道用C/C++如何编写循环缓冲区。

------解决方案--------------------
试试~:
if( recv 到数据 并 添加到 CPtrList 成功)
{
if (声卡缓冲区 还有空间) 
{
while(CPtrList.GetCount() >0) 
{
从List中取出1条数据添加到声卡缓冲区;
删除1条数据;
}
}
}

struct bufInfo{
buf; //数据
bufsize; //数据大小
}

------解决方案--------------------
应该是个循环队列,我这儿有个现成的。
CPP文件如下。你可以直接用。我已经测试过。读与写不能同时操作,要加锁的。

// QueueBuffer.cpp: implementation of the QueueBuffer class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "QueueBuffer.h"
#include <afxmt.h>

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

QueueBuffer::QueueBuffer()
{
m_pData = new BYTE[LEN];
m_pHead = m_pData;
m_pTail = m_pData;
}

QueueBuffer::~QueueBuffer()
{
delete[] m_pData;
m_pData = NULL;
m_pHead = NULL;
m_pTail = NULL;
}
boolean QueueBuffer::Add(BYTE* pByte,int iLen){
if(GetRemain() < iLen){ 
//TRACE("too Full can not contain pByte!\n");
return false;
}

if (m_pTail < m_pHead) { //如果指针尾小于指针头
memcpy(m_pTail,pByte,iLen);
} else { //指针尾大于指针头
if ((LEN - (m_pTail - m_pData)) >= iLen) {//
memcpy(m_pTail,pByte,iLen);
} else {
int iTailOff = m_pTail - m_pData;
memcpy(m_pTail,pByte,LEN - iTailOff);
memcpy(m_pData,pByte+LEN - iTailOff,iLen - (LEN - iTailOff));

}
}
m_pTail = (iLen + m_pTail - m_pData) % LEN + m_pData;
return true;
}
boolean QueueBuffer::Pop(BYTE* pByte,int iCount){
if( GetSize() < iCount){
return false;
}
if (m_pTail >= m_pHead) {
memcpy(pByte,m_pHead,iCount);
} else {
int iHeadOff = m_pHead - m_pData;
if ((LEN - iHeadOff) >= iCount) {
memcpy(pByte,m_pHead,iCount);
} else {
memcpy(pByte,m_pHead,LEN - iHeadOff);
memcpy(pByte + LEN - iHeadOff ,m_pData,iCount - (LEN - iHeadOff));
}
}
m_pHead = (m_pHead - m_pData + iCount) % LEN + m_pData;
return true;
}


boolean QueueBuffer::IsFull(){
int iTailOff = m_pTail - m_pData;
int iHeadOff = m_pHead - m_pData;
if ((iTailOff + 1) % LEN == iHeadOff)
return true;// 采取牺牲一个单元的方法来判断是否为满
return false;
}
boolean QueueBuffer::IsEmpty() {
if (m_pTail == m_pHead)
return true;
return false;
}
//剩余的存储容量
int QueueBuffer::GetRemain() {
if (IsEmpty())
return (LEN - 1);
int iTailOff = m_pTail - m_pData;
int iHeadOff = m_pHead - m_pData;

return (LEN - iTailOff + iHeadOff) % LEN - 1;
}

//当前存储的字节数
int QueueBuffer::GetSize() {
return (m_pTail - m_pHead + LEN) % LEN;
}