00001 #ifndef _FILTERED_NUMBER_H_ 00002 #define _FILTERED_NUMBER_H_ 00003 00004 #include "AbstractFilteredNumber.h" 00005 00020 template <class T, unsigned int sampleCount, unsigned int maxOrder> 00021 class FilteredNumber : public AbstractFilteredNumber<T, sampleCount, maxOrder> 00022 { 00023 private: 00024 T mSamples[sampleCount]; 00025 T mWeights[sampleCount]; 00026 T mTimeSamples[sampleCount]; 00027 T mInitialValue; 00028 T mCurrentValue; 00029 FilteredNumber<T, sampleCount, maxOrder - 1>mFilteredValue; 00030 CyclicNumber<int> mCurrentIndex; 00031 00032 public: 00041 FilteredNumber(T initialValue, T weights[]); 00042 00046 T getValue(unsigned int order = 1) const; 00047 00058 void setValue(T value, float elapsedTime=TIME_UNIT); 00059 00063 T getSample(int i) const; 00064 00068 T getWeight(int i) const; 00069 }; 00070 00071 template <class T, unsigned int sampleCount, unsigned int maxOrder> 00072 FilteredNumber<T, sampleCount, maxOrder>::FilteredNumber(T initialValue, T weights[]): 00073 mInitialValue(initialValue), 00074 mCurrentValue(initialValue), 00075 mFilteredValue(initialValue, weights), 00076 mCurrentIndex(0, 0, sampleCount, 1) 00077 { 00078 00079 for(int i = 0; i < sampleCount; i++) 00080 { 00081 mSamples[i] = initialValue; 00082 mWeights[i] = weights[i]; 00083 mTimeSamples[i] = TIME_UNIT; 00084 } 00085 } 00086 00087 template <class T, unsigned int sampleCount, unsigned int maxOrder> 00088 void FilteredNumber<T, sampleCount, maxOrder>::setValue(T value, float elapsedTime) 00089 { 00090 mCurrentIndex++; 00091 00092 int index = mCurrentIndex; 00093 T newValue = value * elapsedTime; 00094 00095 mSamples[index] = newValue; 00096 mTimeSamples[index] = elapsedTime; 00097 mCurrentValue = value; 00098 00099 T sum = mInitialValue; 00100 float totalTime = 0; 00101 00102 for(int i = 0; i < sampleCount; i++) 00103 { 00104 sum += mSamples[(sampleCount + index - i) % sampleCount] * mWeights[i]; 00105 totalTime += mTimeSamples[(sampleCount + index - i) % sampleCount] * mWeights[i]; 00106 } 00107 00108 mFilteredValue.setValue(sum / totalTime, elapsedTime); 00109 } 00110 00111 template <class T, unsigned int sampleCount, unsigned int maxOrder> 00112 T FilteredNumber<T, sampleCount, maxOrder>::getValue(unsigned int order) const 00113 { 00114 if(order == 0) 00115 { 00116 return mCurrentValue; 00117 } 00118 else if (order > 0) 00119 { 00120 if(order <= maxOrder) 00121 { 00122 return mFilteredValue.getValue(order - 1); 00123 } 00124 } 00125 00126 return mInitialValue; 00127 00128 } 00129 00130 template <class T, unsigned int sampleCount, unsigned int maxOrder> 00131 T FilteredNumber<T, sampleCount, maxOrder>::getSample(int i) const 00132 { 00133 return mSamples[i]; 00134 } 00135 00136 template <class T, unsigned int sampleCount, unsigned int maxOrder> 00137 T FilteredNumber<T, sampleCount, maxOrder>::getWeight(int i) const 00138 { 00139 return mWeights[i]; 00140 } 00141 00150 template <class T, unsigned int sampleCount> 00151 class FilteredNumber<T, sampleCount, 1> : public AbstractFilteredNumber<T, sampleCount, 1> 00152 { 00153 private: 00154 T mSamples[sampleCount]; 00155 T mWeights[sampleCount]; 00156 T mTimeSamples[sampleCount]; 00157 T mInitialValue; 00158 T mCurrentValue; 00159 T mFilteredValue; 00160 00161 CyclicNumber<int> mCurrentIndex; 00162 00163 public: 00167 FilteredNumber(T initialValue, T weights[]); 00168 00172 T getValue(unsigned int order = 1) const; 00173 00177 void setValue(T value, float elapsedTime=TIME_UNIT); 00178 00182 T getSample(int i) const; 00183 00187 T getWeight(int i) const; 00188 }; 00189 00190 template <class T, unsigned int sampleCount> 00191 FilteredNumber<T, sampleCount, 1>::FilteredNumber(T initialValue, T weights[]): 00192 mInitialValue(initialValue), 00193 mCurrentValue(initialValue), 00194 mFilteredValue(initialValue), 00195 mCurrentIndex(0, 0, sampleCount, 1) 00196 { 00197 for(int i = 0; i < sampleCount; i++) 00198 { 00199 mSamples[i] = initialValue; 00200 mWeights[i] = weights[i]; 00201 mTimeSamples[i] = TIME_UNIT; 00202 } 00203 } 00204 00205 template <class T, unsigned int sampleCount> 00206 void FilteredNumber<T, sampleCount, 1>::setValue(T value, float elapsedTime) 00207 { 00208 mCurrentIndex++; 00209 00210 int index = mCurrentIndex; 00211 T newValue = value * elapsedTime; 00212 00213 mSamples[index] = newValue; 00214 mTimeSamples[index] = elapsedTime; 00215 00216 mCurrentValue = value; 00217 00218 T sum = mInitialValue; 00219 float totalTime = 0; 00220 00221 for(int i = 0; i < sampleCount; i++) 00222 { 00223 sum += mSamples[(sampleCount + index - i) % sampleCount] * mWeights[i]; 00224 totalTime += mTimeSamples[(sampleCount + index - i) % sampleCount] * mWeights[i]; 00225 } 00226 00227 mFilteredValue = sum / totalTime; 00228 } 00229 00230 template <class T, unsigned int sampleCount> 00231 T FilteredNumber<T, sampleCount, 1>::getValue(unsigned int order) const 00232 { 00233 if(order == 0) 00234 { 00235 return mCurrentValue; 00236 } 00237 else if(order == 1) 00238 { 00239 return mFilteredValue; 00240 } 00241 00242 return mInitialValue; 00243 } 00244 00245 template <class T, unsigned int sampleCount> 00246 T FilteredNumber<T, sampleCount, 1>::getSample(int i) const 00247 { 00248 return mSamples[i]; 00249 } 00250 00251 template <class T, unsigned int sampleCount> 00252 T FilteredNumber<T, sampleCount, 1>::getWeight(int i) const 00253 { 00254 return mWeights[i]; 00255 } 00256 00262 template <class T, unsigned int sampleCount> 00263 class FilteredNumber<T, sampleCount, 0>: public AbstractFilteredNumber<T, sampleCount, 0> 00264 { 00265 public: 00269 FilteredNumber(T initialValue, T weights[] = 0); 00270 }; 00271 00272 template <class T, unsigned int sampleCount> 00273 FilteredNumber<T, sampleCount, 0>::FilteredNumber(T initialValue, T weights[]): 00274 AbstractFilteredNumber(initialValue) 00275 { 00276 } 00277 00278 00279 #endif //_FILTERED_NUMBER_H_