00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00038
00039 #if !defined(__RINGBUFFER_HEADER_INCLUDED__)
00040 #define __RINGBUFFER_HEADER_INCLUDED__
00041
00042 #ifdef WIN32
00043 #define INLINE __forceinline
00044 #else
00045 #define INLINE
00046 #endif
00047
00049 static INLINE unsigned int Int2PowTwo (int iValue)
00050 {
00051 unsigned int iOrder = 0;
00052
00053 while (iValue>>iOrder)
00054 iOrder++;
00055
00056 if (!(iValue%(1<<(iOrder-1))))
00057 iOrder--;
00058
00059 return (1<<(iOrder));
00060 }
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 template <class T> class CRingBuffer
00071 {
00072
00073 private:
00074
00075 unsigned int m_uiReadIndex,
00076 m_uiWriteIndex,
00077 m_uiTmpIndex;
00078
00079 unsigned int m_uiSize,
00080 m_uiMask;
00081
00082 T *m_ptBuffer;
00083
00084
00085 public:
00086 static int CreateInstance (CRingBuffer*& pCRingBuffer, unsigned int uiLength)
00087 {
00088 int rErr = 0;
00089 pCRingBuffer = 0;
00090
00091
00092 pCRingBuffer = new CRingBuffer (uiLength);
00093
00094 if (pCRingBuffer == NULL)
00095 rErr = -1;
00096 else if (!pCRingBuffer->m_ptBuffer)
00097 {
00098 rErr = -1;
00099 delete pCRingBuffer;
00100 pCRingBuffer= 0;
00101 }
00102
00103 return rErr;
00104 };
00105
00106 static int DestroyInstance (CRingBuffer*& pCRingBuffer)
00107 {
00108 if (!pCRingBuffer)
00109 return -1;
00110
00111 delete pCRingBuffer;
00112 pCRingBuffer = 0;
00113
00114 return 0;
00115 };
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 CRingBuffer(unsigned int uiNewSize)
00127 {
00128
00129 m_uiSize = Int2PowTwo(uiNewSize);
00130 m_uiMask = m_uiSize-1;
00131 m_uiReadIndex = 0;
00132 m_uiWriteIndex = 0;
00133 m_uiTmpIndex = 0;
00134 m_ptBuffer = 0;
00135 m_ptBuffer = new T[m_uiSize];
00136 for( unsigned int i=0; i<m_uiSize; m_ptBuffer[i++] = 0);
00137 }
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149 ~CRingBuffer()
00150 {
00151 if (m_ptBuffer)
00152 delete [] m_ptBuffer;
00153 }
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 INLINE T GetOff(int iIndex)
00167 {
00168 return m_ptBuffer[(m_uiReadIndex + iIndex + m_uiSize) & m_uiMask];
00169 }
00170
00171 INLINE T GetOffW(int iIndex)
00172 {
00173 return m_ptBuffer[(m_uiWriteIndex + iIndex + m_uiSize) & m_uiMask];
00174 }
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188 INLINE void PutOff(T tItem,int iIndex)
00189 {
00190 m_ptBuffer[(m_uiWriteIndex + iIndex + m_uiSize) & m_uiMask] = tItem;
00191 }
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203 INLINE T GetOffMod(int iIndex)
00204 {
00205 m_uiReadIndex = ((m_uiReadIndex + iIndex + m_uiSize) & m_uiMask);
00206 return m_ptBuffer[ m_uiReadIndex ];
00207 }
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 INLINE void PutOffMod(T tItem,int iIndex)
00222 {
00223 m_uiWriteIndex = (m_uiWriteIndex + iIndex + m_uiSize) & m_uiMask;
00224 m_ptBuffer[m_uiWriteIndex] = tItem;
00225 }
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237 INLINE T Get()
00238 {
00239 return m_ptBuffer[ m_uiReadIndex ];
00240 }
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252 INLINE void Put(T tItem)
00253 {
00254 m_ptBuffer[ m_uiWriteIndex ] = tItem;
00255 }
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268 INLINE T GetPostInc()
00269 {
00270 m_uiTmpIndex = m_uiReadIndex;
00271 m_uiReadIndex = (m_uiReadIndex + 1) & m_uiMask;
00272 return m_ptBuffer[ m_uiTmpIndex ];
00273 }
00274
00275 INLINE void GetPostInc (T* ptBuffer, int iNumOfItems)
00276 {
00277 if (iNumOfItems <= 0)
00278 return;
00279 m_uiTmpIndex = m_uiReadIndex;
00280 m_uiReadIndex = (m_uiReadIndex + iNumOfItems) & m_uiMask;
00281 if (m_uiTmpIndex + iNumOfItems <= m_uiSize)
00282 {
00283 memcpy (ptBuffer, &m_ptBuffer[ m_uiTmpIndex ], sizeof(T) * iNumOfItems);
00284 return;
00285 }
00286 else
00287 {
00288 ZASSERT (m_uiSize - m_uiTmpIndex <= 0);
00289 ZASSERT (iNumOfItems - m_uiSize + m_uiTmpIndex <= 0);
00290 memcpy (ptBuffer, &m_ptBuffer[ m_uiTmpIndex ], sizeof(T) * (m_uiSize - m_uiTmpIndex));
00291 memcpy (&ptBuffer[m_uiSize - m_uiTmpIndex], m_ptBuffer, sizeof(T) * (iNumOfItems - m_uiSize + m_uiTmpIndex));
00292 return;
00293 }
00294 }
00295 INLINE void GetOffPostInc(T* ptBuffer, int iNumOfItems, int iIndex)
00296 {
00297 if (iNumOfItems <= 0)
00298 return;
00299 m_uiTmpIndex = ((m_uiReadIndex + iIndex + m_uiSize) & m_uiMask);
00300 m_uiReadIndex = (m_uiReadIndex + iNumOfItems) & m_uiMask;
00301 if (m_uiTmpIndex + iNumOfItems <= m_uiSize)
00302 {
00303 memcpy (ptBuffer, &m_ptBuffer[ m_uiTmpIndex ], sizeof(T) * iNumOfItems);
00304 return;
00305 }
00306 else
00307 {
00308 ZASSERT (m_uiSize - m_uiTmpIndex <= 0);
00309 ZASSERT (iNumOfItems - m_uiSize + m_uiTmpIndex <= 0);
00310 memcpy (ptBuffer, &m_ptBuffer[ m_uiTmpIndex ], sizeof(T) * (m_uiSize - m_uiTmpIndex));
00311 memcpy (&ptBuffer[m_uiSize - m_uiTmpIndex], m_ptBuffer, sizeof(T) * (iNumOfItems - m_uiSize + m_uiTmpIndex));
00312 return;
00313 }
00314 }
00315 INLINE void GetOff(T* ptBuffer, int iNumOfItems, int iIndex)
00316 {
00317 if (iNumOfItems <= 0)
00318 return;
00319 m_uiTmpIndex = ((m_uiReadIndex + iIndex + m_uiSize) & m_uiMask);
00320 if (m_uiTmpIndex + iNumOfItems <= m_uiSize)
00321 {
00322 memcpy (ptBuffer, &m_ptBuffer[ m_uiTmpIndex ], sizeof(T) * iNumOfItems);
00323 return;
00324 }
00325 else
00326 {
00327 ZASSERT (m_uiSize - m_uiTmpIndex <= 0);
00328 ZASSERT (iNumOfItems - m_uiSize + m_uiTmpIndex <= 0);
00329 memcpy (ptBuffer, &m_ptBuffer[ m_uiTmpIndex ], sizeof(T) * (m_uiSize - m_uiTmpIndex));
00330 memcpy (&ptBuffer[m_uiSize - m_uiTmpIndex], m_ptBuffer, sizeof(T) * (iNumOfItems - m_uiSize + m_uiTmpIndex));
00331 return;
00332 }
00333 }
00334 INLINE void GetOffW(T* ptBuffer, int iNumOfItems, int iIndex)
00335 {
00336 if (iNumOfItems <= 0)
00337 return;
00338 m_uiTmpIndex = ((m_uiWriteIndex + iIndex + m_uiSize) & m_uiMask);
00339 if (m_uiTmpIndex + iNumOfItems <= m_uiSize)
00340 {
00341 memcpy (ptBuffer, &m_ptBuffer[ m_uiTmpIndex ], sizeof(T) * iNumOfItems);
00342 return;
00343 }
00344 else
00345 {
00346 ZASSERT (m_uiSize - m_uiTmpIndex <= 0);
00347 ZASSERT (iNumOfItems - m_uiSize + m_uiTmpIndex <= 0);
00348 memcpy (ptBuffer, &m_ptBuffer[ m_uiTmpIndex ], sizeof(T) * (m_uiSize - m_uiTmpIndex));
00349 memcpy (&ptBuffer[m_uiSize - m_uiTmpIndex], m_ptBuffer, sizeof(T) * (iNumOfItems - m_uiSize + m_uiTmpIndex));
00350 return;
00351 }
00352 }
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364 INLINE void PutPostInc(T tItem)
00365 {
00366 m_uiTmpIndex = m_uiWriteIndex;
00367 m_uiWriteIndex = (m_uiWriteIndex + 1) & m_uiMask;
00368 m_ptBuffer[ m_uiTmpIndex ] = tItem;
00369 }
00370
00371
00372 INLINE void PutPostInc(const T *ptItem, int iNumOfItems)
00373 {
00374 if (iNumOfItems <= 0)
00375 return;
00376 m_uiTmpIndex = m_uiWriteIndex;
00377 m_uiWriteIndex = (m_uiWriteIndex + iNumOfItems) & m_uiMask;
00378 if (m_uiTmpIndex + iNumOfItems <= m_uiSize)
00379 {
00380 memcpy (&m_ptBuffer[ m_uiTmpIndex ], ptItem, sizeof(T) * iNumOfItems);
00381 return;
00382 }
00383 else
00384 {
00385 ZASSERT (m_uiSize - m_uiTmpIndex <= 0);
00386 ZASSERT (iNumOfItems - m_uiSize + m_uiTmpIndex <= 0);
00387 memcpy (&m_ptBuffer[ m_uiTmpIndex ], ptItem, sizeof(T) * (m_uiSize - m_uiTmpIndex));
00388 memcpy (m_ptBuffer, &ptItem[m_uiSize - m_uiTmpIndex], sizeof(T) * (iNumOfItems - m_uiSize + m_uiTmpIndex));
00389 return;
00390 }
00391 }
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404 INLINE T GetPreInc()
00405 {
00406 m_uiReadIndex = (m_uiReadIndex + 1) & m_uiMask;
00407 return m_ptBuffer[ m_uiReadIndex ];
00408 }
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421 INLINE void PutPreInc(T tItem)
00422 {
00423 m_uiWriteIndex = (m_uiWriteIndex + 1) & m_uiMask;
00424 m_ptBuffer[ m_uiWriteIndex ] = tItem;
00425 }
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438 INLINE T GetPostDec()
00439 {
00440 m_uiTmpIndex = m_uiReadIndex;
00441 m_uiReadIndex = (m_uiReadIndex - 1 + m_uiSize) & m_uiMask;
00442 return m_ptBuffer[ m_uiTmpIndex ];
00443 }
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455 INLINE void PutPostDec(T tItem)
00456 {
00457 m_uiTmpIndex = m_uiWriteIndex;
00458 m_uiWriteIndex = (m_uiWriteIndex - 1 + m_uiSize) & m_uiMask;
00459 m_ptBuffer[ m_uiTmpIndex ] = tItem;
00460 }
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473 INLINE T GetPreDec()
00474 {
00475 m_uiReadIndex = (m_uiReadIndex - 1 + m_uiSize) & m_uiMask;
00476 return m_ptBuffer[ m_uiReadIndex ];
00477 }
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491 INLINE void PutPreDec(T tItem)
00492 {
00493 m_uiWriteIndex = (m_uiWriteIndex - 1 + m_uiSize) & m_uiMask;
00494 m_ptBuffer[ m_uiWriteIndex ] = tItem;
00495 }
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507 INLINE int GetReadPos()
00508 {
00509 return m_uiReadIndex;
00510 }
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522 INLINE int GetWritePos()
00523 {
00524 return m_uiWriteIndex;
00525 }
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537 INLINE void SetReadPos(int iIndex)
00538 {
00539 m_uiReadIndex = (iIndex + m_uiSize) & m_uiMask;
00540 }
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552 INLINE void SetWritePos(int iIndex)
00553 {
00554 m_uiWriteIndex = (iIndex + m_uiSize) & m_uiMask;
00555 }
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569 INLINE int GetSamplesInBuffer()
00570 {
00571 int iCount = m_uiWriteIndex - m_uiReadIndex;
00572
00573 return (iCount < 0 ? m_uiSize + iCount : iCount);
00574 }
00575
00576 INLINE void Reset()
00577 {
00578 m_uiReadIndex = 0;
00579 m_uiWriteIndex = 0;
00580 m_uiTmpIndex = 0;
00581 for( unsigned int i=0; i<m_uiSize; m_ptBuffer[i++] = 0);
00582 }
00583
00584 };
00585
00586 #endif // __RINGBUFFER_HEADER_INCLUDED__
00587
00588