TokenDelay.hxx
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef _TokenDelay_
00025 #define _TokenDelay_
00026
00027 #include "Processing.hxx"
00028 #include "InControl.hxx"
00029 #include "InPort.hxx"
00030 #include "OutPort.hxx"
00031 #include "Component.hxx"
00032 #include "Enum.hxx"
00033 #include <string>
00034 #include <deque>
00035
00036 #include "Array.hxx"
00037
00038 namespace CLAM
00039 {
00040
00041
00046 class TokenDelayConfig : public ProcessingConfig
00047 {
00048 public:
00049 DYNAMIC_TYPE_USING_INTERFACE (TokenDelayConfig, 2, ProcessingConfig);
00050 DYN_ATTRIBUTE (0, public, unsigned, Delay);
00051 DYN_ATTRIBUTE (1, public, unsigned, MaxDelay );
00052 protected:
00053 void DefaultInit(void)
00054 {
00055 AddDelay();
00056 AddMaxDelay();
00057 UpdateData();
00058 SetDelay(0);
00059 SetMaxDelay(1);
00060 }
00061
00062 };
00063
00076 template <class T> class TokenDelay : public Processing
00077 {
00078
00079 private:
00081 TokenDelayConfig mConfig;
00082
00083 InPort<T> mInput;
00084 OutPort<T> mOutput;
00085 FloatInControl mDelayControl;
00086
00087 public:
00088 TokenDelay(const TokenDelayConfig& cfg = TokenDelayConfig() ) :
00089 mInput ("In", this),
00090 mOutput ("Out", this),
00091 mDelayControl("Delay Control", this),
00092 mCapacity(0)
00093 {
00094 Configure(cfg);
00095 }
00096 virtual ~TokenDelay<T>() {};
00097
00103 bool ConcreteConfigure(const ProcessingConfig& c);
00104
00108 virtual const ProcessingConfig &GetConfig() const { return mConfig;}
00113 virtual bool Do(void);
00114
00124 virtual bool Do(const T & in, T& out);
00125
00126
00127
00130 void Debug() const;
00134 void FulfillsInvariant() const;
00135
00136 const char *GetClassName() const {return "TokenDelay";}
00137
00141 TSize RealDelay() const {
00142 return mTokenQueue.size();
00143 }
00144
00145 unsigned MaxDelay() const {
00146 return mCapacity;
00147 }
00148
00149 unsigned GivenDelay() {
00150
00151 return CastDelayControlValue(mDelayControl.GetLastValue());
00152 }
00153
00154 private:
00160 virtual void Discard(T* toDiscard);
00161
00165 unsigned CastDelayControlValue(TControlData readControlValue);
00170 void UpdateBuffersToDelay();
00171 void WriteNewSample(const T& in);
00172 void ReadCurrentSample(T& out);
00173
00174
00175
00176 std::vector<T> mTokenQueue;
00177 unsigned mReadPointer;
00178 unsigned mWritePointer;
00180 unsigned mCapacity;
00182 unsigned mGivenDelay;
00184 unsigned mLastDelay;
00185
00186 };
00187
00188
00189
00191
00192
00193
00194 #include "Err.hxx"
00195
00196 template <class T>
00197 void TokenDelay<T>::Discard(T* toDiscard) {
00198 CLAM_ASSERT(toDiscard, "TokenDelay: Discarding a null pointer");
00199 delete toDiscard;
00200 }
00201
00202 template <class T>
00203 bool TokenDelay<T>::ConcreteConfigure(const ProcessingConfig& c)
00204 {
00205 CopyAsConcreteConfig(mConfig, c);
00206
00207 mCapacity = mConfig.GetMaxDelay();
00208 mDelayControl.DoControl(TControlData(mConfig.GetDelay()));
00209 mGivenDelay = CastDelayControlValue(mDelayControl.GetLastValue());
00210 mTokenQueue.resize(mCapacity);
00211 mWritePointer = 0;
00212 mReadPointer = -mGivenDelay;
00213 return true;
00214 }
00215
00216
00217 template <class T>
00218 bool TokenDelay<T>::Do(void)
00219 {
00220 Do(mInput.GetData(), mOutput.GetData());
00221 mInput.Consume();
00222 mOutput.Produce();
00223 return false;
00224 }
00225
00226 template <class T>
00227 unsigned TokenDelay<T>::CastDelayControlValue(TControlData readControlValue) {
00228 if (readControlValue > mCapacity) return mCapacity;
00229 if (readControlValue < 0) return 0;
00230 return unsigned(readControlValue);
00231 }
00232
00233 template <class T>
00234 bool TokenDelay<T>::Do(const T& in, T& out)
00235
00236 {
00237
00238 mLastDelay = mGivenDelay;
00239 mGivenDelay = CastDelayControlValue(mDelayControl.GetLastValue());
00240
00241 if (mLastDelay != mGivenDelay)
00242 UpdateBuffersToDelay();
00243 WriteNewSample(in);
00244 ReadCurrentSample(out);
00245 return true;
00246 }
00247
00248 template <class T>
00249 void TokenDelay<T>::WriteNewSample(const T& in)
00250 {
00251 mTokenQueue[mWritePointer++] = in;
00252 if(mWritePointer==mCapacity) mWritePointer=0;
00253
00254 }
00255
00256
00257 template <class T>
00258 void TokenDelay<T>::ReadCurrentSample(T& out)
00259 {
00260 CLAM_DEBUG_ASSERT(mReadPointer>=0, "Trying to read outside buffer");
00261 out = mTokenQueue[mReadPointer++];
00262 if(mReadPointer==mCapacity) mReadPointer=0;
00263 }
00264
00265
00266
00267
00268 template <class T>
00269 void TokenDelay<T>::UpdateBuffersToDelay()
00270 {
00271 mWritePointer = mReadPointer + CastDelayControlValue(mGivenDelay);
00272 if(mWritePointer>=mCapacity) mWritePointer-=mCapacity;
00273 return;
00274 }
00275
00276
00277 template <class T>
00278 void TokenDelay<T>::Debug() const
00279 {
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291 }
00292
00293 template <class T>
00294 void TokenDelay<T>::FulfillsInvariant() const
00295 {
00296
00297
00298
00299
00300
00301
00302
00303
00304 }
00305
00306 };
00307
00308
00309
00310 #endif //_TokenDelay_