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