MNE-CPP  beta 1.0
circularmatrixbuffer.h
Go to the documentation of this file.
1 //=============================================================================================================
36 #ifndef CIRCULARMATRIXBUFFER_H
37 #define CIRCULARMATRIXBUFFER_H
38 
39 
40 //*************************************************************************************************************
41 //=============================================================================================================
42 // INCLUDES
43 //=============================================================================================================
44 
45 #include "generics_global.h"
46 #include "buffer.h"
47 
48 #include <typeinfo>
49 
50 
51 //*************************************************************************************************************
52 //=============================================================================================================
53 // Eigen INCLUDES
54 //=============================================================================================================
55 
56 #include <Eigen/Core>
57 
58 
59 //*************************************************************************************************************
60 //=============================================================================================================
61 // QT INCLUDES
62 //=============================================================================================================
63 
64 #include <QPair>
65 #include <QSemaphore>
66 #include <QSharedPointer>
67 
68 
69 //*************************************************************************************************************
70 //=============================================================================================================
71 // DEFINE NAMESPACE IOBuffer
72 //=============================================================================================================
73 
74 namespace IOBuffer
75 {
76 
77 
78 //*************************************************************************************************************
79 //=============================================================================================================
80 // USED NAMESPACES
81 //=============================================================================================================
82 
83 using namespace Eigen;
84 
85 
86 //=============================================================================================================
92 template<typename _Tp>
94 {
95 public:
96  typedef QSharedPointer<CircularMatrixBuffer> SPtr;
97  typedef QSharedPointer<const CircularMatrixBuffer> ConstSPtr;
99  //=========================================================================================================
108  explicit CircularMatrixBuffer(unsigned int uiMaxNumMatrices, unsigned int uiRows, unsigned int uiCols);
109 
110  //=========================================================================================================
115 
116  //=========================================================================================================
122  inline void push(const Matrix<_Tp, Dynamic, Dynamic>* pMatrix);
123 
124  //=========================================================================================================
130  inline Matrix<_Tp, Dynamic, Dynamic> pop();
131 
132  //=========================================================================================================
136  void clear();
137 
138  //=========================================================================================================
142  inline quint32 size() const;
143 
144  //=========================================================================================================
148  inline quint32 rows() const;
149 
150  //=========================================================================================================
154  inline quint32 cols() const;
155 
156  //=========================================================================================================
160  inline void pause(bool);
161 
162  //=========================================================================================================
167  inline bool releaseFromPop();
168 
169  //=========================================================================================================
174  inline bool releaseFromPush();
175 
176 private:
177  //=========================================================================================================
184  inline unsigned int mapIndex(int& index);
185 
186  unsigned int m_uiMaxNumMatrices;
187  unsigned int m_uiRows;
188  unsigned int m_uiCols;
189  unsigned int m_uiMaxNumElements;
190  _Tp* m_pBuffer;
191  int m_iCurrentReadIndex;
192  int m_iCurrentWriteIndex;
193  QSemaphore* m_pFreeElements;
194  QSemaphore* m_pUsedElements;
195  bool m_bPause;
196 };
197 
198 
199 //*************************************************************************************************************
200 //=============================================================================================================
201 // DEFINE MEMBER METHODS
202 //=============================================================================================================
203 
204 template<typename _Tp>
205 CircularMatrixBuffer<_Tp>::CircularMatrixBuffer(unsigned int uiMaxNumMatrices, unsigned int uiRows, unsigned int uiCols)
206 : Buffer(typeid(_Tp).name())
207 , m_uiMaxNumMatrices(uiMaxNumMatrices)
208 , m_uiRows(uiRows)
209 , m_uiCols(uiCols)
210 , m_uiMaxNumElements(m_uiMaxNumMatrices*m_uiRows*m_uiCols)
211 , m_pBuffer(new _Tp[m_uiMaxNumElements])
212 , m_iCurrentReadIndex(-1)
213 , m_iCurrentWriteIndex(-1)
214 , m_pFreeElements(new QSemaphore(m_uiMaxNumElements))
215 , m_pUsedElements(new QSemaphore(0))
216 , m_bPause(false)
217 {
218 
219 }
220 
221 
222 //*************************************************************************************************************
223 
224 template<typename _Tp>
226 {
227  delete m_pFreeElements;
228  delete m_pUsedElements;
229  delete [] m_pBuffer;
230 }
231 
232 
233 //*************************************************************************************************************
234 
235 template<typename _Tp>
236 inline void CircularMatrixBuffer<_Tp>::push(const Matrix<_Tp, Dynamic, Dynamic>* pMatrix)
237 {
238  if(!m_bPause)
239  {
240  unsigned int t_size = pMatrix->size();
241  if(t_size == m_uiRows*m_uiCols)
242  {
243  m_pFreeElements->acquire(t_size);
244  for(unsigned int i = 0; i < t_size; ++i)
245  m_pBuffer[mapIndex(m_iCurrentWriteIndex)] = pMatrix->data()[i];
246  m_pUsedElements->release(t_size);
247  }
248  // else
249  // printf("Error: Matrix not appended to CircularMatrixBuffer - wrong dimensions\n");
250  }
251 }
252 
253 
254 //*************************************************************************************************************
255 
256 template<typename _Tp>
257 inline Matrix<_Tp, Dynamic, Dynamic> CircularMatrixBuffer<_Tp>::pop()
258 {
259  Matrix<_Tp, Dynamic, Dynamic> matrix(m_uiRows, m_uiCols);
260 
261  if(!m_bPause)
262  {
263  m_pUsedElements->acquire(m_uiRows*m_uiCols);
264  for(quint32 i = 0; i < m_uiRows*m_uiCols; ++i)
265  matrix.data()[i] = m_pBuffer[mapIndex(m_iCurrentReadIndex)];
266  m_pFreeElements->release(m_uiRows*m_uiCols);
267  }
268  else
269  matrix.setZero();
270 
271  return matrix;
272 }
273 
274 
275 //*************************************************************************************************************
276 
277 template<typename _Tp>
278 inline unsigned int CircularMatrixBuffer<_Tp>::mapIndex(int& index)
279 {
280  int AuxIndex;
281  AuxIndex = ++index;
282  return index = AuxIndex % m_uiMaxNumElements;
283 
284 }
285 
286 
287 //*************************************************************************************************************
288 
289 template<typename _Tp>
291 {
292  delete m_pFreeElements;
293  m_pFreeElements = new QSemaphore(m_uiMaxNumElements);
294  delete m_pUsedElements;
295  m_pUsedElements = new QSemaphore(0);
296 
297  m_iCurrentReadIndex = -1;
298  m_iCurrentWriteIndex = -1;
299 }
300 
301 
302 //*************************************************************************************************************
303 
304 template<typename _Tp>
305 inline quint32 CircularMatrixBuffer<_Tp>::size() const
306 {
307  return m_uiMaxNumMatrices;
308 }
309 
310 
311 //*************************************************************************************************************
312 
313 template<typename _Tp>
314 inline quint32 CircularMatrixBuffer<_Tp>::rows() const
315 {
316  return m_uiRows;
317 }
318 
319 
320 //*************************************************************************************************************
321 
322 template<typename _Tp>
323 inline quint32 CircularMatrixBuffer<_Tp>::cols() const
324 {
325  return m_uiCols;
326 }
327 
328 
329 //*************************************************************************************************************
330 
331 template<typename _Tp>
332 inline void CircularMatrixBuffer<_Tp>::pause(bool bPause)
333 {
334  m_bPause = bPause;
335 }
336 
337 
338 //*************************************************************************************************************
339 
340 template<typename _Tp>
342 {
343  if((uint)m_pUsedElements->available() < m_uiRows*m_uiCols)
344  {
345  //The last matrix which is to be popped from the buffer is supposed to be a zero matrix
346  unsigned int t_size = m_uiRows*m_uiCols;
347  for(unsigned int i = 0; i < t_size; ++i)
348  m_pBuffer[mapIndex(m_iCurrentWriteIndex)] = 0;
349 
350  //Release (create) values from m_pUsedElements so that the pop function can leave the acquire statement in the pop function
351  m_pUsedElements->release(m_uiRows*m_uiCols);
352 
353  return true;
354  }
355 
356  return false;
357 }
358 
359 
360 //*************************************************************************************************************
361 
362 template<typename _Tp>
364 {
365  if((uint)m_pFreeElements->available() < m_uiRows*m_uiCols)
366  {
367  //The last matrix which is to be pushed to the buffer is supposed to be a zero matrix
368  unsigned int t_size = m_uiRows*m_uiCols;
369  for(unsigned int i = 0; i < t_size; ++i)
370  m_pBuffer[mapIndex(m_iCurrentWriteIndex)] = 0;
371 
372  //Release (create) values from m_pFreeElements so that the push function can leave the acquire statement in the push function
373  m_pFreeElements->release(m_uiRows*m_uiCols);
374 
375  return true;
376  }
377 
378  return false;
379 }
380 
381 
382 //*************************************************************************************************************
383 //=============================================================================================================
384 // TYPEDEF
385 //=============================================================================================================
386 
387 //ToDo Typedef -> warning visibility ignored -> dllexport/dllimport problem
388 
389 typedef GENERICSSHARED_EXPORT CircularMatrixBuffer<int> _int_CircularMatrixBuffer;
390 typedef GENERICSSHARED_EXPORT CircularMatrixBuffer<float> _float_CircularMatrixBuffer;
391 typedef GENERICSSHARED_EXPORT CircularMatrixBuffer<char> _char_CircularMatrixBuffer;
392 typedef GENERICSSHARED_EXPORT CircularMatrixBuffer<double> _double_CircularMatrixBuffer;
394 typedef GENERICSSHARED_EXPORT _float_CircularMatrixBuffer RawMatrixBuffer;
396 } // NAMESPACE
397 
398 #endif // CIRCULARMATRIXBUFFER_H
CircularMatrixBuffer(unsigned int uiMaxNumMatrices, unsigned int uiRows, unsigned int uiCols)
#define GENERICSSHARED_EXPORT
QSharedPointer< CircularMatrixBuffer > SPtr
The circular matrix buffer.
generics library export/import macros.
void push(const Matrix< _Tp, Dynamic, Dynamic > *pMatrix)
Matrix< _Tp, Dynamic, Dynamic > pop()
Contains the declaration of the Buffer base class.
The Buffer class provides a base class for buffers.
Definition: buffer.h:63
QSharedPointer< const CircularMatrixBuffer > ConstSPtr