CPI_CircleBuffer.c
上传用户:tuheem
上传日期:2007-05-01
资源大小:21889k
文件大小:7k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. #include "stdafx.h"
  2. #include "globals.h"
  3. #include "CPI_CircleBuffer.h"
  4. #define CIC_WAITTIMEOUT 3000
  5. void CircleBufferUninitialise(CPs_CircleBuffer* pCBuffer);
  6. void CircleBufferWrite(CPs_CircleBuffer* pCBuffer, const void* pSourceBuffer, const unsigned int iNumBytes);
  7. BOOL CircleBufferRead(CPs_CircleBuffer* pCBuffer, void* pDestBuffer, const unsigned int iBytesToRead, unsigned int* pbBytesRead);
  8. void CircleFlush(CPs_CircleBuffer* pCBuffer);
  9. unsigned int CircleGetFreeSpace(CPs_CircleBuffer* pCBuffer);
  10. unsigned int CircleGetUsedSpace(CPs_CircleBuffer* pCBuffer);
  11. void CircleSetComplete(CPs_CircleBuffer* pCBuffer);
  12. BOOL CircleIsComplete(CPs_CircleBuffer* pCBuffer);
  13. ////////////////////////////////////////////////////////////////////////////////
  14. CPs_CircleBuffer* CP_CreateCircleBuffer(const unsigned int iBufferSize)
  15. {
  16.     CPs_CircleBuffer* pNewBuffer = (CPs_CircleBuffer*)malloc(sizeof(CPs_CircleBuffer));
  17.     pNewBuffer->Uninitialise = CircleBufferUninitialise;
  18.     pNewBuffer->Write = CircleBufferWrite;
  19.     pNewBuffer->Read = CircleBufferRead;
  20.     pNewBuffer->Flush = CircleFlush;
  21.     pNewBuffer->GetUsedSize = CircleGetUsedSpace;
  22.     pNewBuffer->GetFreeSize = CircleGetFreeSpace;
  23.     pNewBuffer->SetComplete = CircleSetComplete;
  24.     pNewBuffer->IsComplete = CircleIsComplete;
  25.     pNewBuffer->m_iBufferSize = iBufferSize;
  26.     pNewBuffer->m_pBuffer = (BYTE*)malloc(iBufferSize);
  27.     pNewBuffer->m_iReadCursor = 0;
  28.     pNewBuffer->m_iWriteCursor = 0;
  29.     pNewBuffer->m_bComplete = FALSE;
  30.     pNewBuffer->m_evtDataAvailable = CreateEvent(NULL, FALSE, FALSE, NULL);
  31.     InitializeCriticalSection(&pNewBuffer->m_csCircleBuffer);
  32.     return pNewBuffer;
  33. }
  34. //
  35. //
  36. //
  37. void CircleBufferUninitialise(CPs_CircleBuffer* pCBuffer)
  38. {
  39.     CP_CHECKOBJECT(pCBuffer);
  40.     DeleteCriticalSection(&pCBuffer->m_csCircleBuffer);
  41.     CloseHandle(pCBuffer->m_evtDataAvailable);
  42.     free(pCBuffer->m_pBuffer);
  43.     free(pCBuffer);
  44. }
  45. //
  46. //
  47. //
  48. void CircleBufferWrite(CPs_CircleBuffer* pCBuffer, const void* _pSourceBuffer, const unsigned int _iNumBytes)
  49. {
  50.     unsigned int iBytesToWrite = _iNumBytes;
  51.     BYTE* pReadCursor = (BYTE*)_pSourceBuffer;
  52.     CP_ASSERT(iBytesToWrite <= pCBuffer->GetFreeSize(pCBuffer));
  53.     CP_ASSERT(pCBuffer->m_bComplete == FALSE);
  54.     EnterCriticalSection(&pCBuffer->m_csCircleBuffer);
  55.     if(pCBuffer->m_iWriteCursor >= pCBuffer->m_iReadCursor)
  56.     {
  57.         unsigned int iChunkSize = pCBuffer->m_iBufferSize - pCBuffer->m_iWriteCursor;
  58.         if(iChunkSize > iBytesToWrite)
  59.             iChunkSize = iBytesToWrite;
  60.         memcpy(pCBuffer->m_pBuffer + pCBuffer->m_iWriteCursor,
  61.                pReadCursor, iChunkSize);
  62.         pReadCursor += iChunkSize;
  63.         iBytesToWrite -= iChunkSize;
  64.         pCBuffer->m_iWriteCursor += iChunkSize;
  65.         if(pCBuffer->m_iWriteCursor >= pCBuffer->m_iBufferSize)
  66.             pCBuffer->m_iWriteCursor -= pCBuffer->m_iBufferSize;
  67.     }
  68.     if(iBytesToWrite)
  69.     {
  70.         memcpy(pCBuffer->m_pBuffer + pCBuffer->m_iWriteCursor,
  71.                pReadCursor, iBytesToWrite);
  72.         pCBuffer->m_iWriteCursor += iBytesToWrite;
  73.         CP_ASSERT(pCBuffer->m_iWriteCursor < pCBuffer->m_iBufferSize);
  74.     }
  75.     SetEvent(pCBuffer->m_evtDataAvailable);
  76.     LeaveCriticalSection(&pCBuffer->m_csCircleBuffer);
  77. }
  78. //
  79. BOOL CircleBufferRead(CPs_CircleBuffer* pCBuffer, void* pDestBuffer, const unsigned int _iBytesToRead, unsigned int* pbBytesRead)
  80. {
  81.     unsigned int iBytesToRead = _iBytesToRead;
  82.     unsigned int iBytesRead = 0;
  83.     DWORD dwWaitResult;
  84.     BOOL bComplete = FALSE;
  85.     CP_CHECKOBJECT(pCBuffer);
  86.     while(iBytesToRead > 0 && bComplete == FALSE)
  87.     {
  88.         dwWaitResult = WaitForSingleObject(pCBuffer->m_evtDataAvailable, CIC_WAITTIMEOUT);
  89.         if(dwWaitResult == WAIT_TIMEOUT)
  90.         {
  91.             CP_TRACE0("Circle buffer - did not fill in time!");
  92.             *pbBytesRead = iBytesRead;
  93.             return FALSE;
  94.         }
  95.         EnterCriticalSection(&pCBuffer->m_csCircleBuffer);
  96.         if(pCBuffer->m_iReadCursor > pCBuffer->m_iWriteCursor)
  97.         {
  98.             unsigned int iChunkSize = pCBuffer->m_iBufferSize - pCBuffer->m_iReadCursor;
  99.             if(iChunkSize > iBytesToRead)
  100.                 iChunkSize = iBytesToRead;
  101.             memcpy((BYTE*)pDestBuffer + iBytesRead,
  102.                    pCBuffer->m_pBuffer + pCBuffer->m_iReadCursor,
  103.                    iChunkSize);
  104.             iBytesRead += iChunkSize;
  105.             iBytesToRead -= iChunkSize;
  106.             pCBuffer->m_iReadCursor += iChunkSize;
  107.             if(pCBuffer->m_iReadCursor >= pCBuffer->m_iBufferSize)
  108.                 pCBuffer->m_iReadCursor -= pCBuffer->m_iBufferSize;
  109.         }
  110.         if(iBytesToRead && pCBuffer->m_iReadCursor < pCBuffer->m_iWriteCursor)
  111.         {
  112.             unsigned int iChunkSize = pCBuffer->m_iWriteCursor - pCBuffer->m_iReadCursor;
  113.             if(iChunkSize > iBytesToRead)
  114.                 iChunkSize = iBytesToRead;
  115.             memcpy((BYTE*)pDestBuffer + iBytesRead,
  116.                    pCBuffer->m_pBuffer + pCBuffer->m_iReadCursor,
  117.                    iChunkSize);
  118.             iBytesRead += iChunkSize;
  119.             iBytesToRead -= iChunkSize;
  120.             pCBuffer->m_iReadCursor += iChunkSize;
  121.         }
  122.         if(pCBuffer->m_iReadCursor == pCBuffer->m_iWriteCursor)
  123.         {
  124.             if(pCBuffer->m_bComplete)
  125.                 bComplete = TRUE;
  126.         }
  127.         else
  128.             SetEvent(pCBuffer->m_evtDataAvailable);
  129.         LeaveCriticalSection(&pCBuffer->m_csCircleBuffer);
  130.     }
  131.     *pbBytesRead = iBytesRead;
  132.     return bComplete ? FALSE : TRUE;
  133. }
  134. //
  135. //
  136. //
  137. void CircleFlush(CPs_CircleBuffer* pCBuffer)
  138. {
  139.     CP_CHECKOBJECT(pCBuffer);
  140.     EnterCriticalSection(&pCBuffer->m_csCircleBuffer);
  141.     pCBuffer->m_iReadCursor = 0;
  142.     pCBuffer->m_iWriteCursor = 0;
  143.     LeaveCriticalSection(&pCBuffer->m_csCircleBuffer);
  144. }
  145. //
  146. //
  147. //
  148. unsigned int CircleGetFreeSpace(CPs_CircleBuffer* pCBuffer)
  149. {
  150.     unsigned int iNumBytesFree;
  151.     CP_CHECKOBJECT(pCBuffer);
  152.     EnterCriticalSection(&pCBuffer->m_csCircleBuffer);
  153.     if(pCBuffer->m_iWriteCursor < pCBuffer->m_iReadCursor)
  154.         iNumBytesFree = (pCBuffer->m_iReadCursor-1) - pCBuffer->m_iWriteCursor;
  155.     else if(pCBuffer->m_iWriteCursor == pCBuffer->m_iReadCursor)
  156.         iNumBytesFree = pCBuffer->m_iBufferSize;
  157.     else
  158.         iNumBytesFree = (pCBuffer->m_iReadCursor-1) + (pCBuffer->m_iBufferSize - pCBuffer->m_iWriteCursor);
  159.     LeaveCriticalSection(&pCBuffer->m_csCircleBuffer);
  160.     return iNumBytesFree;
  161. }
  162. //
  163. //
  164. //
  165. unsigned int CircleGetUsedSpace(CPs_CircleBuffer* pCBuffer)
  166. {
  167.     return pCBuffer->m_iBufferSize - CircleGetFreeSpace(pCBuffer);
  168. }
  169. //
  170. //
  171. //
  172. void CircleSetComplete(CPs_CircleBuffer* pCBuffer)
  173. {
  174.     CP_CHECKOBJECT(pCBuffer);
  175.     EnterCriticalSection(&pCBuffer->m_csCircleBuffer);
  176.     pCBuffer->m_bComplete = TRUE;
  177.     SetEvent(pCBuffer->m_evtDataAvailable);
  178.     LeaveCriticalSection(&pCBuffer->m_csCircleBuffer);
  179. }
  180. //
  181. //
  182. //
  183. BOOL CircleIsComplete(CPs_CircleBuffer* pCBuffer)
  184. {
  185.     return pCBuffer->m_bComplete;
  186. }
  187. //
  188. //
  189. //