00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <cstdio>
00024
00025 #include <Exception.hh>
00026
00027 #include "dsp/DSPOp.hh"
00028
00029
00030 #ifndef RINGBUFFER_HH
00031 #define RINGBUFFER_HH
00032
00033
00037 class clXRingBuffer : public clException
00038 {
00039 public:
00040 clXRingBuffer (const char *cpErrorMsg) :
00041 clException(cpErrorMsg)
00042 { }
00043 };
00044
00045
00049 template <class TRingBuffer_t> class clRingBuffer
00050 {
00051 volatile long lSize;
00052 volatile long lCount;
00053 volatile long lPutIndex;
00054 volatile long lGetIndex;
00055 clDSPAlloc Buffer;
00056 public:
00057 clRingBuffer ()
00058 {
00059 lSize = 0;
00060 lCount = 0;
00061 lPutIndex = 0;
00062 lGetIndex = 0;
00063 }
00064 clRingBuffer (const clRingBuffer<TRingBuffer_t> &CopySrc)
00065 {
00066 lSize = CopySrc.lSize;
00067 lCount = CopySrc.lCount;
00068 lPutIndex = CopySrc.lPutIndex;
00069 lGetIndex = CopySrc.lGetIndex;
00070 Buffer = CopySrc.Buffer;
00071 }
00072 clRingBuffer (long lNewSize)
00073 { SetSize(lNewSize); }
00074 void SetSize (long lNewSize)
00075 {
00076 Buffer.Size(lNewSize * sizeof(TRingBuffer_t));
00077 lSize = lNewSize;
00078 lCount = 0;
00079 lPutIndex = 0;
00080 lGetIndex = 0;
00081 }
00082 void Lock ()
00083 { Buffer.Lock(); }
00084 void UnLock ()
00085 { Buffer.UnLock(); }
00086 long Size () const
00087 {
00088 return lSize;
00089 }
00090 long GetCount () const
00091 {
00092 return lCount;
00093 }
00094 void Put (const TRingBuffer_t *Src, long lSrcCount)
00095 {
00096 register long lLPutIdx = lPutIndex;
00097 register long lLSize = lSize;
00098 if (lSrcCount > lLSize)
00099 throw clXRingBuffer("clRingBuffer::Put(): lSrcCount > lSize");
00100 register long lTailSize = lLSize - lLPutIdx;
00101 register long lHeadSize = lSrcCount - lTailSize;
00102 TRingBuffer_t *LBuf = Buffer;
00103 if (lHeadSize > 0)
00104 {
00105 clDSPOp::Copy(LBuf + lLPutIdx, Src, lTailSize);
00106 clDSPOp::Copy(LBuf, Src + lTailSize, lHeadSize);
00107 }
00108 else
00109 {
00110 clDSPOp::Copy(LBuf + lLPutIdx, Src, lSrcCount);
00111 }
00112 lLPutIdx = (lLPutIdx + lSrcCount) % lLSize;
00113 lPutIndex = lLPutIdx;
00114 register long lLCount = lCount;
00115 lLCount = (lLCount + lSrcCount) % lLSize;
00116 lCount = lLCount;
00117 }
00118 bool Get (TRingBuffer_t *Dst, long lDstCount)
00119 {
00120 register long lLCount = lCount;
00121 if (lLCount < lDstCount)
00122 return false;
00123 lLCount -= lDstCount;
00124 lCount = lLCount;
00125 register long lLGetIdx = lGetIndex;
00126 register long lLSize = lSize;
00127 if (lDstCount > lLSize)
00128 throw clXRingBuffer("clRingBuffer::Get(): lDstCount > lSize");
00129 register long lTailSize = lLSize - lLGetIdx;
00130 register long lHeadSize = lDstCount - lTailSize;
00131 register long lNewIdx = (lLGetIdx + lDstCount) % lLSize;
00132 lGetIndex = lNewIdx;
00133 TRingBuffer_t *LBuf = Buffer;
00134 if (lHeadSize > 0)
00135 {
00136 clDSPOp::Copy(Dst, LBuf + lLGetIdx, lTailSize);
00137 clDSPOp::Copy(Dst + lTailSize, LBuf, lHeadSize);
00138 }
00139 else
00140 {
00141 clDSPOp::Copy(Dst, LBuf + lLGetIdx, lTailSize);
00142 }
00143 return true;
00144 }
00145 };
00146
00147 #endif