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