Another Ring buffer ————from pudn
5478 ワード
#ifndef RINGBUFFER_H
#define RINGBUFFER_H
#include "EEGData.h"
template<class T>
class RingBuffer
{
public:
RingBuffer();
virtual ~RingBuffer();
// Initialize the ring buffer
// blockSize: the sampling number of a block.
// chanNum: the channel numbers of EEG
// blockNum: the number of block in the ring buffer
void Initialize(int blockSize,int chanNum,int blockNum);//initialize
// Input a single(int)
// void InputData(T& a );// add one data to the buffer
// Input a block data to the ring buffer.
// buffer is the pointer of data would be input to the ring buffer
// bufferSize is the block size. Ususally the bufferSize must be equal to the blockSize.
void InputBlockData(T *buffer,int bufferSize);//add a block data to the buffer.
// Get data fromt data
// length: the nu length sampling before to current position.
// signal: outpumber of sampling would be put into *signal
// return TRUE if the operation is successes; otherwise return FALSE;
//numOfSampling
bool GetData(T *signal,int numOfSampling);
bool GetData(EEGData<T> &dataA,int numOfSamplingA);
void GetEventData(EEGData<T> &dataA,int erpLeft,int erpRight);
void GetEventData(T *erp,int erpLeft,int erpRight);
bool IsOnTimer(int timeInterval);
bool IsEvent(int epoch);
// ,
int GetLength(){return m_blockSize*m_blockNum;}
int GetChanNum(){return m_chanNum;}
// ,
T& GetPointData(int channelA,int lengthA);
//
void Show();
private:
T *m_data;
int m_curPosition;
int m_blockNum;
int m_chanNum;
int m_blockSize;
int m_eventPos;
int m_size;
};
//----------------------------------------------------------------------------------------------------
#include <memory.h>
template<class T>
RingBuffer<T>::RingBuffer()
{
m_blockNum=m_blockSize=m_chanNum=m_curPosition=0;
m_size=0;
m_data=NULL;
}
template<class T>
RingBuffer<T>::~RingBuffer()
{
if (m_data)
delete []m_data;
m_data=NULL;
}
template<class T>
void RingBuffer<T>::Initialize(int blockSize,int chanNum,int blockNum)
{
m_chanNum=chanNum;
m_blockNum=blockNum;
m_blockSize=blockSize;
m_data=new T[blockSize*chanNum*blockNum];
memset(m_data,0,blockSize*chanNum*blockNum*sizeof(T));
m_curPosition=0;
m_size=blockSize*chanNum*blockNum;
m_eventPos=0;
}
template<class T>
void RingBuffer<T>::InputBlockData(T *buffer,int bufferSize)
{
for (int i=0;i<bufferSize;i++)
{
m_data[(m_curPosition+i)%m_size]=buffer[i];
}
m_curPosition=m_curPosition+bufferSize;
m_curPosition%=m_size;
}
template<class T>
bool RingBuffer<T>::GetData(T *signal,int numOfSampling)
{
if (numOfSampling*m_chanNum>m_size)
{
return false;
}
for (int i=0;i<numOfSampling*m_chanNum;i++)
{
signal[i]=m_data[(2*m_size+m_curPosition-numOfSampling*m_chanNum+i)%m_size];
}
return true;
}
template<class T>
bool RingBuffer<T>::GetData(EEGData<T> &dataA,int numOfSamplingA)
{
if (numOfSamplingA*m_chanNum>m_size)
{
return false;
}
T *signal=new T[numOfSamplingA*m_chanNum];
for (int i=0;i<numOfSamplingA*m_chanNum;i++)
{
signal[i]=m_data[(2*m_size+m_curPosition-numOfSamplingA*m_chanNum+i)%m_size];
}
dataA.Initialize( numOfSamplingA, m_chanNum,signal);
delete[]signal;
return true;
}
template<class T>
T& RingBuffer<T>::GetPointData(int channelA,int lengthA)
{
if (lengthA>m_blockSize*m_blockNum||channelA>m_chanNum
||lengthA<0||channelA<0)
{
return -1;
}
int pos=(GetChanLength()+(m_curPosition-lengthA))%GetChanLength()+channelA;
return m_data[pos];
}
template<class T>
bool RingBuffer<T>::IsEvent(int epoch)
{
int startPos=(2*m_size+m_curPosition-(epoch-epoch%m_blockSize)*m_chanNum-m_chanNum*m_blockSize)%m_size;
int endPos=startPos+m_chanNum*m_blockSize;
for (int i=startPos+m_chanNum-1;i<endPos;i=i+m_chanNum)
{
// Event
if ((int)m_data[i%m_size]-(int)m_data[(m_size+i-m_chanNum)%m_size]>0)
{
m_eventPos=i;
return true;
}
}
return false;
}
template<class T>
void RingBuffer<T>::GetEventData(T *erp,int erpLeft,int erpRight)
{
for (int i=erpLeft*m_chanNum;i<erpRight*m_chanNum;i++)
{
erp[i]=m_data[(2*m_size+m_eventPos-m_chanNum+1+i)%m_size];
}
}
template<class T>
void RingBuffer<T>::GetEventData(EEGData<T> &dataA,int erpLeft,int erpRight)
{
int epoch=erpRight-erpLeft+1;
T *erp=new T[epoch*m_chanNum];
int j=0;
for (int i=erpLeft*m_chanNum;i<erpRight*m_chanNum+m_chanNum;i++)
{
erp[j]=m_data[(2*m_size+m_eventPos-m_chanNum+1+i)%m_size];
j++;
}
dataA.Initialize( epoch, m_chanNum,erp);
delete[]erp;
}
template<class T>
bool RingBuffer<T>::IsOnTimer(int timeInterval)
{
if (timeInterval*m_chanNum>m_size)
{
AfxMessageBox("Buffer is too small");
return false;
}
if (m_curPosition%(m_blockSize*(timeInterval/m_blockSize)*m_chanNum)==0)
{
return true;
}
else
return false;
}
template<class T>
void RingBuffer<T>::Show()
{
for(int i=0;i<m_size;i++)
{
cout<<m_data[(m_curPosition+i)%m_size]<<" "<<endl;
}
}
#endif