AJA NTV2 SDK  17.5.0.1242
NTV2 SDK 17.5.0.1242
ajamovingavg.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: MIT */
8 #ifndef AJA_MOVINGAVG_H
9 #define AJA_MOVINGAVG_H
10 
11 //#include "ajabase/common/public.h"
12 #include "ajabase/system/lock.h"
13 #include <climits>
14 #include <cfloat>
15 #include <deque>
16 #include <ostream>
17 #include <typeinfo>
18 #if defined(AJA_WINDOWS)
19  #pragma warning(disable:4056)
20 #endif
21 
22 
28 template <typename T> class AJAMovingAvg
29 {
30  public:
31  static const size_t kDefaultMaxNumSamples = 10;
32 
33  public:
39  inline explicit AJAMovingAvg (const size_t inMaxNumSamples = kDefaultMaxNumSamples)
40  {
41  reset(inMaxNumSamples);
42  }
43 
49  inline void addSample (const T inValue)
50  { AJAAutoLock tmp(&mLock);
51  mValues.push_front(inValue);
52  if (mValues.size() > mSampleCapacity)
53  mValues.pop_back();
54  mTotNumSamples++;
55  if (inValue < mMinValue)
56  mMinValue = inValue;
57  if (inValue > mMaxValue)
58  mMaxValue = inValue;
59  }
60 
66  inline void reset (const size_t inMaxNumSamples = kDefaultMaxNumSamples)
67  { AJAAutoLock tmp(&mLock);
68  mValues.clear();
69  mSampleCapacity = inMaxNumSamples;
70  mTotNumSamples = 0;
71  mMinValue = largestPossibleValue();
72  mMaxValue = smallestPossibleValue();
73  }
74 
78  inline size_t numStoredSamples (void) const {AJAAutoLock tmp(&mLock); return mValues.size();}
79 
83  inline size_t sampleCapacity (void) const {AJAAutoLock tmp(&mLock); return mSampleCapacity;}
84 
88  inline size_t totalSamples (void) const {AJAAutoLock tmp(&mLock); return mTotNumSamples;}
89 
93  inline bool isValid (void) const {AJAAutoLock tmp(&mLock); return totalSamples() > 0;}
94 
98  inline bool isEmpty (void) const {AJAAutoLock tmp(&mLock); return mValues.empty();}
99 
103  inline bool isFilled (void) const {AJAAutoLock tmp(&mLock); return totalSamples() >= sampleCapacity();}
104 
108  inline T average (void) const
109  { AJAAutoLock tmp(&mLock);
110  if (isEmpty())
111  return 0;
112  return sum() / T(numStoredSamples());
113  }
114 
118  inline double averageF (void) const
119  { AJAAutoLock tmp(&mLock);
120  if (isEmpty())
121  return 0.0;
122  return double(sum()) / double(numStoredSamples());
123  }
124 
128  inline T minimum (void) const {AJAAutoLock tmp(&mLock); return mMinValue;}
129 
133  inline T recentMinimum (void) const
134  {
135  T result(largestPossibleValue());
136  AJAAutoLock tmp(&mLock);
137  for (auto it(mValues.begin()); it != mValues.end(); ++it)
138  if (*it < result)
139  result = *it;
140  return result;
141  }
142 
146  inline T maximum (void) const {AJAAutoLock tmp(&mLock); return mMaxValue;}
147 
151  inline T recentMaximum (void) const
152  {
153  T result(smallestPossibleValue());
154  AJAAutoLock tmp(&mLock);
155  for (auto it(mValues.begin()); it != mValues.end(); ++it)
156  if (*it > result)
157  result = *it;
158  return result;
159  }
160 
169  inline std::ostream & Print (std::ostream & oss, const bool inDetailed = false) const
170  {
171  AJAAutoLock tmp(&mLock);
172  if (isValid())
173  {
174  if (inDetailed)
175  oss << averageF() << " (avg) for last " << numStoredSamples() << " of " << totalSamples() << " samples" << std::endl
176  << recentMinimum() << " (min), " << recentMaximum() << " (max)";
177  else oss << averageF();
178  }
179  else oss << "n/a";
180  return oss;
181  }
182 
183  protected:
184  inline T sum (void) const
185  {
186  AJAAutoLock tmp(&mLock);
187  if (isEmpty())
188  return T(0);
189  T result = T(0);
190  for (auto it(mValues.begin()); it != mValues.end(); ++it)
191  result += *it;
192  return result;
193  }
194 
195  static inline T smallestPossibleValue (void)
196  {
197  if (typeid(T) == typeid(char))
198  return SCHAR_MIN;
199  else if (typeid(T) == typeid(int8_t))
200  return SCHAR_MIN;
201  else if (typeid(T) == typeid(uint8_t))
202  return 0;
203  else if (typeid(T) == typeid(int16_t))
204  return T(SHRT_MIN);
205  else if (typeid(T) == typeid(uint16_t))
206  return 0;
207  else if (typeid(T) == typeid(int))
208  return T(INT_MIN);
209  else if (typeid(T) == typeid(int32_t))
210  return T(LONG_MIN);
211  else if (typeid(T) == typeid(uint32_t))
212  return 0;
213  else if (typeid(T) == typeid(int64_t))
214  return T(LLONG_MIN);
215  else if (typeid(T) == typeid(uint64_t))
216  return 0;
217  else if (typeid(T) == typeid(float))
218  return T(-FLT_MAX);
219  else if (typeid(T) == typeid(double))
220  return T(-DBL_MAX);
221  else if (typeid(T) == typeid(long double))
222  return T(-LDBL_MAX);
223  return 0;
224  }
225 
226  static inline T largestPossibleValue (void)
227  {
228  if (typeid(T) == typeid(char))
229  return SCHAR_MAX;
230  else if (typeid(T) == typeid(int8_t))
231  return SCHAR_MAX;
232  else if (typeid(T) == typeid(uint8_t))
233  return T(UCHAR_MAX);
234  else if (typeid(T) == typeid(int16_t))
235  return T(SHRT_MAX);
236  else if (typeid(T) == typeid(uint16_t))
237  return T(0xFFFF);
238  else if (typeid(T) == typeid(int))
239  return T(INT_MAX);
240  else if (typeid(T) == typeid(int32_t))
241  return T(LONG_MAX);
242  else if (typeid(T) == typeid(uint32_t))
243  return T(0xFFFFFFFF);
244  else if (typeid(T) == typeid(int64_t))
245  return T(LLONG_MAX);
246  else if (typeid(T) == typeid(uint64_t))
247  return T(0xFFFFFFFFFFFFFFFF);
248  else if (typeid(T) == typeid(float))
249  return T(FLT_MAX);
250  else if (typeid(T) == typeid(double))
251  return T(DBL_MAX);
252  else if (typeid(T) == typeid(long double))
253  return T(LDBL_MAX);
254  return 0;
255  }
256 
257  private:
258  mutable AJALock mLock;
259  std::deque<T> mValues;
260  size_t mSampleCapacity;
261  size_t mTotNumSamples;
262  T mMinValue;
263  T mMaxValue;
264 
265 }; // AJAMovingAvg
266 
267 
274 template <typename T> inline std::ostream & operator << (std::ostream & oss, const AJAMovingAvg<T> & inAvg)
275 {
276  inAvg.Print(oss,true);
277  return oss;
278 }
279 
280 #endif // AJA_MOVINGAVG_H
AJAMovingAvg::recentMaximum
T recentMaximum(void) const
Definition: ajamovingavg.h:151
AJAMovingAvg::smallestPossibleValue
static T smallestPossibleValue(void)
Definition: ajamovingavg.h:195
AJAMovingAvg::recentMinimum
T recentMinimum(void) const
Definition: ajamovingavg.h:133
AJAMovingAvg::Print
std::ostream & Print(std::ostream &oss, const bool inDetailed=false) const
Definition: ajamovingavg.h:169
AJAMovingAvg::kDefaultMaxNumSamples
static const size_t kDefaultMaxNumSamples
Definition: ajamovingavg.h:31
AJAMovingAvg::numStoredSamples
size_t numStoredSamples(void) const
Definition: ajamovingavg.h:78
AJAMovingAvg::average
T average(void) const
Definition: ajamovingavg.h:108
AJAMovingAvg::AJAMovingAvg
AJAMovingAvg(const size_t inMaxNumSamples=kDefaultMaxNumSamples)
Definition: ajamovingavg.h:39
AJAMovingAvg::isEmpty
bool isEmpty(void) const
Definition: ajamovingavg.h:98
AJAMovingAvg::sum
T sum(void) const
Definition: ajamovingavg.h:184
lock.h
Declares the AJALock class.
AJAMovingAvg::isFilled
bool isFilled(void) const
Definition: ajamovingavg.h:103
AJAMovingAvg
Definition: ajamovingavg.h:28
AJAMovingAvg::totalSamples
size_t totalSamples(void) const
Definition: ajamovingavg.h:88
AJALock
Definition: lock.h:30
AJAMovingAvg::maximum
T maximum(void) const
Definition: ajamovingavg.h:146
AJAAutoLock
Definition: lock.h:91
AJAMovingAvg::sampleCapacity
size_t sampleCapacity(void) const
Definition: ajamovingavg.h:83
AJAMovingAvg::reset
void reset(const size_t inMaxNumSamples=kDefaultMaxNumSamples)
Definition: ajamovingavg.h:66
AJAMovingAvg::isValid
bool isValid(void) const
Definition: ajamovingavg.h:93
AJAMovingAvg::addSample
void addSample(const T inValue)
Definition: ajamovingavg.h:49
operator<<
std::ostream & operator<<(std::ostream &oss, const AJAMovingAvg< T > &inAvg)
Definition: ajamovingavg.h:274
AJAMovingAvg::minimum
T minimum(void) const
Definition: ajamovingavg.h:128
AJAMovingAvg::largestPossibleValue
static T largestPossibleValue(void)
Definition: ajamovingavg.h:226
AJAMovingAvg::averageF
double averageF(void) const
Definition: ajamovingavg.h:118