CLAM-Development
1.1
|
00001 /* 00002 * Copyright (c) 2001-2004 MUSIC TECHNOLOGY GROUP (MTG) 00003 * UNIVERSITAT POMPEU FABRA 00004 * 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 // TokenDelay.hxx 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: 00058 void DefaultInit(void) 00059 { 00060 AddDelay(); 00061 AddMaxDelay(); 00062 UpdateData(); 00063 SetDelay(0); 00064 SetMaxDelay(1); 00065 } 00066 00067 }; 00068 00081 template <class T> class TokenDelay : public Processing 00082 { 00083 00084 private: 00086 TokenDelayConfig mConfig; 00087 // Ports and control 00088 InPort<T> mInput; 00089 OutPort<T> mOutput; 00090 InControl mDelayControl; 00091 00092 public: 00093 TokenDelay(const TokenDelayConfig& cfg = TokenDelayConfig() ) : 00094 mInput ("In", this), 00095 mOutput ("Out", this), 00096 mDelayControl("Delay Control", this), 00097 mCapacity(0) 00098 { 00099 Configure(cfg); 00100 } 00101 virtual ~TokenDelay<T>() {}; 00102 00108 bool ConcreteConfigure(const ProcessingConfig& c); 00109 00113 virtual const ProcessingConfig &GetConfig() const { return mConfig;} 00118 virtual bool Do(void); 00119 00129 virtual bool Do(const T & in, T& out); 00130 00131 00132 00135 void Debug() const; 00139 void FulfillsInvariant() const; 00140 00141 const char *GetClassName() const {return "TokenDelay";} 00142 00146 TSize RealDelay() const { 00147 return mTokenQueue.size(); 00148 } 00149 00150 unsigned MaxDelay() const { 00151 return mCapacity; 00152 } 00153 00154 unsigned GivenDelay() { 00155 00156 return CastDelayControlValue(mDelayControl.GetLastValue()); 00157 } 00158 00159 private: 00165 virtual void Discard(T* toDiscard); 00166 00170 unsigned CastDelayControlValue(TControlData readControlValue); 00175 void UpdateBuffersToDelay(); 00176 void WriteNewSample(const T& in); 00177 void ReadCurrentSample(T& out); 00178 00179 // Implementation Details: 00180 00181 std::vector<T> mTokenQueue; 00182 unsigned mReadPointer; 00183 unsigned mWritePointer; 00185 unsigned mCapacity; 00187 unsigned mGivenDelay; 00189 unsigned mLastDelay; 00190 00191 }; 00192 00193 00194 00196 // Class implementation 00197 00198 00199 #include "Err.hxx" 00200 00201 template <class T> 00202 void TokenDelay<T>::Discard(T* toDiscard) { 00203 CLAM_ASSERT(toDiscard, "TokenDelay: Discarding a null pointer"); 00204 delete toDiscard; 00205 } 00206 00207 template <class T> 00208 bool TokenDelay<T>::ConcreteConfigure(const ProcessingConfig& c) 00209 { 00210 CopyAsConcreteConfig(mConfig, c); 00211 mCapacity = mConfig.GetMaxDelay(); 00212 mDelayControl.DoControl(TControlData(mConfig.GetDelay())); 00213 mGivenDelay = CastDelayControlValue(mDelayControl.GetLastValue()); 00214 mTokenQueue.resize(mCapacity); 00215 mWritePointer = 0; 00216 mReadPointer = -mGivenDelay; 00217 return true; 00218 } 00219 00220 00221 template <class T> 00222 bool TokenDelay<T>::Do(void) 00223 { 00224 Do(mInput.GetData(), mOutput.GetData()); 00225 mInput.Consume(); 00226 mOutput.Produce(); 00227 return false; 00228 } 00229 00230 template <class T> 00231 unsigned TokenDelay<T>::CastDelayControlValue(TControlData readControlValue) { 00232 if (readControlValue > mCapacity) return mCapacity; 00233 if (readControlValue < 0) return 0; 00234 return unsigned(readControlValue); 00235 } 00236 00237 template <class T> 00238 bool TokenDelay<T>::Do(const T& in, T& out) 00239 // implementation using the supervised-mode Do 00240 { 00241 // @todo debug 00242 mLastDelay = mGivenDelay; 00243 mGivenDelay = CastDelayControlValue(mDelayControl.GetLastValue()); 00244 // If the value is different make the difference efective 00245 if (mLastDelay != mGivenDelay) 00246 UpdateBuffersToDelay(); 00247 WriteNewSample(in); 00248 ReadCurrentSample(out); 00249 return true; 00250 } 00251 00252 template <class T> 00253 void TokenDelay<T>::WriteNewSample(const T& in) 00254 { 00255 mTokenQueue[mWritePointer] = in; 00256 mWritePointer++; 00257 if(mWritePointer==mCapacity) mWritePointer=0; 00258 00259 } 00260 00261 00262 template <class T> 00263 void TokenDelay<T>::ReadCurrentSample(T& out) 00264 { 00265 CLAM_DEBUG_ASSERT(mReadPointer>0, "Trying to read outside buffer"); 00266 int oldReadPointer = mReadPointer; 00267 mReadPointer++; 00268 if(mReadPointer==mCapacity) mReadPointer=0; 00269 out = mTokenQueue[oldReadPointer]; 00270 } 00271 00272 00273 00274 // Delay change 00275 template <class T> 00276 void TokenDelay<T>::UpdateBuffersToDelay() 00277 { 00278 mWritePointer = mReadPointer + CastDelayControlValue(mGivenDelay); 00279 if(mWritePointer>=mCapacity) mWritePointer-=mCapacity; 00280 return; 00281 } 00282 00283 00284 template <class T> 00285 void TokenDelay<T>::Debug() const 00286 { 00287 /* 00288 unsigned real = RealDelay(); 00289 unsigned size = mVector.size(); 00290 unsigned cap = mVector.capacity(); 00291 00292 std::cout << "\n-- " << mConfig.GetClassName() << "\n-- (first,last)=(" << mFirst <<","<< mLast <<")\n-- "\ 00293 << "(given,real delay)=("<< mGivenDelay <<"," << real << ")\n-- (vector size,capacity;mCapacity)=("\ 00294 << size <<","<< cap <<";"<< mCapacity <<")\n-- (mInstantToken,mVector[mFirst])=("<< mInstantToken\ 00295 <<","<< mVector[mFirst] <<")\n"; 00296 */ 00297 00298 } 00299 00300 template <class T> 00301 void TokenDelay<T>::FulfillsInvariant() const 00302 {/* 00303 unsigned real = RealDelay(); 00304 00305 if (mVector.capacity() < mCapacity) throw Err("TokenDelay : invariant not fullfilled!: vector capacity < req. capacity"); 00306 if (real && mFirst==mLast) throw Err("TokenDelay : invariant not fullfilled!: there is a 'real' delay and mFirst==mLast"); 00307 if (real > mCapacity) throw Err("TokenDelay : invariant not fullfilled!: real delay > mCapacity"); 00308 if (mGivenDelay > mCapacity) throw Err("TokenDelay : invariant not fullfilled!: given (by control) delay > mCapacity"); 00309 if (mFirst <0 || mLast<0 || mCapacity <= 0) throw Err("TokenDelay : invariant not fullfilled!: some very bad thing..."); 00310 */ 00311 } 00312 00313 // Control Enumeration 00314 00315 class ETokenDelayControls 00316 : public Enum 00317 { 00318 00319 public: 00320 ETokenDelayControls() : Enum( ValueTable(), delay ) { } 00321 ETokenDelayControls( tValue v ) : Enum( ValueTable(), v ) { } 00322 ETokenDelayControls( std::string s ) : Enum( ValueTable(), s ) { } 00323 ~ETokenDelayControls() { } 00324 Component* Species() const 00325 { 00326 return new ETokenDelayControls; 00327 } 00328 00329 typedef enum 00330 { 00331 delay = 0 00332 } tEnum; 00333 static tEnumValue * ValueTable() 00334 { 00335 static tEnumValue sEnumValues[] = 00336 { 00337 { delay, "delay" }, 00338 { 0, NULL } 00339 }; 00340 return sEnumValues; 00341 } 00342 00343 }; 00344 00345 }; //namespace CLAM 00346 00347 00348 00349 #endif //_TokenDelay_