Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

ReBufferT.hh

Go to the documentation of this file.
00001 /*
00002 
00003     Template rebuffering class
00004     Copyright (C) 2001-2004 Jussi Laako
00005 
00006     This program is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation; either version 2 of the License, or
00009     (at your option) any later version.
00010 
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014     GNU General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this program; if not, write to the Free Software
00018     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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

Generated on Sun Nov 7 14:32:00 2004 for libDSP by doxygen 1.3.6