00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <cmath>
00024 #include <cfloat>
00025 #include <cstring>
00026 #include <typeinfo>
00027
00028 #include <Exception.hh>
00029
00030 #include "dsp/DSPOp.hh"
00031
00032
00033 #ifndef REBUFFERT_HH
00034 #define REBUFFERT_HH
00035
00036
00040 class clXReBufferT : public clException
00041 {
00042 public:
00043 clXReBufferT (const char *cpErrorMsg) :
00044 clException(cpErrorMsg)
00045 { }
00046 };
00047
00048
00054 template <class TReBuffer_t> class clReBufferT
00055 {
00056 long lSize;
00057 long lPutIndex;
00058 long lGetIndex;
00059 long lCount;
00060 clDSPAlloc Buffer;
00061
00062 inline void CheckSize (long lDataCount)
00063 {
00064 long lTotalSize = (lCount + lDataCount) *
00065 sizeof(TReBuffer_t);
00066 if (lTotalSize > Buffer.GetSize())
00067 {
00068 #ifndef _ISOC9X_SOURCE
00069 long lTwosExp = (long) std::ceil(
00070 std::log((double) lTotalSize) /
00071 std::log((double) 2));
00072 long lNewBufferSize = (long)
00073 std::pow(2.0, (double) lTwosExp);
00074 #else
00075 long lTwosExp = (long) ceil(log2(lTotalSize));
00076 long lNewBufferSize = (long) exp2(lTwosExp);
00077 #endif
00078 Buffer.Resize(lNewBufferSize);
00079
00080 long lTailSize = lSize - lGetIndex;
00081 if (lCount > lTailSize)
00082 {
00083 long lHeadSize = lCount - lTailSize;
00084 long lNewSize =
00085 lNewBufferSize / sizeof(TReBuffer_t);
00086 unsigned char *cpBuffer = Buffer;
00087 unsigned char *cpDest =
00088 cpBuffer + lSize * sizeof(TReBuffer_t);
00089 memcpy(cpDest, cpBuffer,
00090 lHeadSize * sizeof(TReBuffer_t));
00091 lPutIndex = lSize + lHeadSize;
00092 if (lPutIndex >= lNewSize)
00093 lPutIndex -= lNewSize;
00094 }
00095
00096 lSize = lNewBufferSize / sizeof(TReBuffer_t);
00097 }
00098 }
00099 protected:
00100 TReBuffer_t * GetPtr ()
00101 {
00102 if (lGetIndex == 0 || lCount == 0)
00103 return ((TReBuffer_t *) Buffer);
00104 long lTempCount = lCount;
00105 clDSPAlloc Temp(lTempCount * sizeof(TReBuffer_t));
00106 Get((TReBuffer_t *) Temp, lTempCount);
00107 Clear();
00108 Put((TReBuffer_t *) Temp, lTempCount);
00109 return ((TReBuffer_t *) Buffer);
00110 }
00111 void CopyGet (TReBuffer_t *fpDestData, long lDestCount) const
00112 {
00113 long lTailSize = lSize - lGetIndex;
00114 const TReBuffer_t *fpBuffer =
00115 (const TReBuffer_t *) Buffer.GetPtr();
00116 if (lDestCount > lTailSize)
00117 {
00118 long lHeadSize = lDestCount - lTailSize;
00119 memcpy(fpDestData, &fpBuffer[lGetIndex],
00120 lTailSize * sizeof(TReBuffer_t));
00121 memcpy(&fpDestData[lTailSize], fpBuffer,
00122 lHeadSize * sizeof(TReBuffer_t));
00123 }
00124 else
00125 {
00126 memcpy(fpDestData, &fpBuffer[lGetIndex],
00127 lDestCount * sizeof(TReBuffer_t));
00128 }
00129 }
00130 public:
00131 clReBufferT ()
00132 {
00133 lSize = 0;
00134 lPutIndex = 0;
00135 lGetIndex = 0;
00136 lCount = 0;
00137 }
00138 clReBufferT (const clReBufferT &CopySrc)
00139 {
00140 lSize = 0;
00141 lPutIndex = 0;
00142 lGetIndex = 0;
00143 lCount = 0;
00144 *this = CopySrc;
00145 }
00146 clReBufferT (long lNewSize)
00147 {
00148 lSize = 0;
00149 lPutIndex = 0;
00150 lGetIndex = 0;
00151 lCount = 0;
00152 SetSize(lNewSize);
00153 }
00154 clReBufferT (const TReBuffer_t *fpSrcData, long lSrcCount)
00155 {
00156 lSize = 0;
00157 lPutIndex = 0;
00158 lGetIndex = 0;
00159 lCount = 0;
00160 Put(fpSrcData, lSrcCount);
00161 }
00162 ~clReBufferT ()
00163 { }
00170 void Put (const TReBuffer_t *fpSrcData, long lSrcCount)
00171 {
00172 CheckSize(lSrcCount);
00173 if (lPutIndex >= lSize) lPutIndex = 0;
00174 long lTailSpace = lSize - lPutIndex;
00175 TReBuffer_t *fpBuffer = Buffer;
00176 if (lSrcCount > lTailSpace)
00177 {
00178 long lHeadSize = lSrcCount - lTailSpace;
00179 memcpy(&fpBuffer[lPutIndex], fpSrcData,
00180 lTailSpace * sizeof(TReBuffer_t));
00181 memcpy(fpBuffer, &fpSrcData[lTailSpace],
00182 lHeadSize * sizeof(TReBuffer_t));
00183 lPutIndex = lHeadSize;
00184 }
00185 else
00186 {
00187 memcpy(&fpBuffer[lPutIndex], fpSrcData,
00188 lSrcCount * sizeof(TReBuffer_t));
00189 lPutIndex += lSrcCount;
00190 }
00191 lCount += lSrcCount;
00192 }
00198 void Put (clReBufferT &Src)
00199 {
00200 Put(Src.GetPtr(), Src.Size());
00201 }
00211 bool Get (TReBuffer_t *fpDestData, long lDestCount)
00212 {
00213 if (lCount < lDestCount)
00214 return false;
00215 long lTailSize = lSize - lGetIndex;
00216 TReBuffer_t *fpBuffer = Buffer;
00217 if (lDestCount > lTailSize)
00218 {
00219 long lHeadSize = lDestCount - lTailSize;
00220 memcpy(fpDestData, &fpBuffer[lGetIndex],
00221 lTailSize * sizeof(TReBuffer_t));
00222 memcpy(&fpDestData[lTailSize], fpBuffer,
00223 lHeadSize * sizeof(TReBuffer_t));
00224 lGetIndex = lHeadSize;
00225 }
00226 else
00227 {
00228 memcpy(fpDestData, &fpBuffer[lGetIndex],
00229 lDestCount * sizeof(TReBuffer_t));
00230 lGetIndex += lDestCount;
00231 }
00232 lCount -= lDestCount;
00233 return true;
00234 }
00240 long GetCount () const
00241 {
00242 return lCount;
00243 }
00244 long Size () const
00245 {
00246 return lCount;
00247 }
00253 void SetSize (long lNewCount)
00254 {
00255 Clear();
00256 CheckSize(lNewCount);
00257 lCount = lNewCount;
00258 lPutIndex = lCount;
00259 }
00265 void Resize (long lNewCount)
00266 {
00267 if (lNewCount > lSize)
00268 CheckSize(lNewCount - lCount);
00269 lCount = lNewCount;
00270 lPutIndex = lCount;
00271 }
00275 void Clear ()
00276 {
00277 lSize = 0;
00278 lPutIndex = 0;
00279 lGetIndex = 0;
00280 lCount = 0;
00281 Buffer.Free();
00282 }
00283 clReBufferT & operator= (const clReBufferT &Src)
00284 {
00285 SetSize(Src.Size());
00286 Src.CopyGet((TReBuffer_t *) Buffer, Src.Size());
00287 lPutIndex = Src.Size();
00288 lCount = Src.Size();
00289 return (*this);
00290 }
00291 TReBuffer_t & operator[] (long lIndex)
00292 {
00293 if (lIndex >= lCount)
00294 {
00295 throw clXReBufferT(
00296 "clReBufferT<>::operator[]: Index >= Size()");
00297 }
00298 long lBufIdx = lGetIndex + lIndex;
00299 if (lBufIdx >= lSize) lBufIdx -= lSize;
00300 TReBuffer_t *fpBuffer = Buffer;
00301 return fpBuffer[lIndex];
00302 }
00303 };
00304
00305
00306 #endif