Allolib  1.0
C++ Components For Interactive Multimedia
al_Time.hpp
1 #ifndef INCLUDE_AL_TIME_HPP
2 #define INCLUDE_AL_TIME_HPP
3 
4 /* Allocore --
5  Multimedia / virtual environment application class library
6 
7  Copyright (C) 2009. AlloSphere Research Group, Media Arts & Technology, UCSB.
8  Copyright (C) 2012. The Regents of the University of California.
9  All rights reserved.
10 
11  Redistribution and use in source and binary forms, with or without
12  modification, are permitted provided that the following conditions are met:
13 
14  Redistributions of source code must retain the above copyright notice,
15  this list of conditions and the following disclaimer.
16 
17  Redistributions in binary form must reproduce the above copyright
18  notice, this list of conditions and the following disclaimer in the
19  documentation and/or other materials provided with the distribution.
20 
21  Neither the name of the University of California nor the names of its
22  contributors may be used to endorse or promote products derived from
23  this software without specific prior written permission.
24 
25  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
29  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35  POSSIBILITY OF SUCH DAMAGE.
36 
37 
38  File description:
39  C++ helper wrappers for al_time
40 
41  File author(s):
42  Graham Wakefield, 2010, grrrwaaa@gmail.com
43  Lance Putnam, 2010, putnam.lance@gmail.com
44 
45  Keehong Youn, 2016, younkeehong@gmail.com
46 */
47 
48 #include <climits>
49 #include <string>
50 
51 #include <cmath>
52 
53 typedef long long int
54  al_nsec;
55 typedef double al_sec;
58 #define al_time_ns2s 1.0e-9
59 #define al_time_s2ns 1.0e9
60 
61 namespace al {
62 
64 al_sec al_system_time();
65 al_nsec al_system_time_nsec();
66 
67 void al_start_steady_clock();
68 void al_reset_steady_clock();
69 al_sec al_steady_time();
70 al_nsec al_steady_time_nsec();
71 
73 void al_sleep(al_sec dt);
74 void al_sleep_nsec(al_nsec dt);
75 void al_sleep_until(al_sec target);
76 
77 // backward compatibility
78 inline void wait(al_sec dt) { al_sleep(dt); }
79 inline al_sec walltime() { return al_system_time(); }
80 inline al_sec timeNow() { return al_system_time(); }
81 
83 std::string toTimecode(al_nsec t, const std::string& format = "D:H:M:S:m:u");
84 
88 class Timer {
89  public:
90  Timer(bool setStartTime = true) {
91  if (setStartTime) start();
92  }
93 
95  al_nsec elapsed() const { return mStop - mStart; }
96 
98  al_sec elapsedSec() const { return al_time_ns2s * elapsed(); }
99 
101  void start() { mStart = getTime(); }
102 
104  void stop() { mStop = getTime(); }
105 
107  void print() const;
108 
109  private:
110  al_nsec mStart = 0, mStop = 0; // start and stop times
111  static al_nsec getTime() { return al_steady_time_nsec(); }
112 };
113 
115 
124  public:
125  DelayLockedLoop(al_sec step_period, double bandwidth = 0.5) {
126  tperiod = step_period;
127  setBandwidth(bandwidth);
128  mReset = true;
129  }
130 
132  void setBandwidth(double bandwidth);
133 
135  void reset() { mReset = true; }
136 
138 
141  void step(al_sec realtime);
142  void operator()(al_sec realtime) { step(realtime); }
143 
145  al_sec period_smoothed() const { return t2; }
146 
148  al_sec rate_smoothed() const { return 1. / t2; }
149 
151  al_sec period_ideal() const { return tperiod; }
152 
154  al_sec rate_ideal() const { return 1. / tperiod; }
155 
157 
161  al_sec realtime_interp(double alpha) const { return t0 + alpha * (t1 - t0); }
162 
163  protected:
164  al_sec tperiod; // event period in seconds
165  al_sec t0; // 0th-order component: timestamp of the current event
166  al_sec t1; // 1st-order component: ideally the timestamp of the next event
167  al_sec t2; // 2nd-order component (akin to acceleration, or smoothed event
168  // period)
169  double mB, mC; // 1st & 2nd order weights
170  bool mReset;
171 };
172 
176 class Clock {
177  public:
179  Clock(bool useRT = true)
180  : mNow(0),
181  mReferenceTime(al_system_time()),
182  mDT(0.33),
183  mFPS(1. / mDT),
184  mFrame(0),
185  bUseRT(useRT) {}
186 
188  Clock(al_sec dt)
189  : mNow(0),
190  mReferenceTime(al_system_time()),
191  mDT(dt),
192  mFPS(1. / mDT),
193  mFrame(0),
194  bUseRT(false) {}
195 
197  al_sec now() const { return mNow; }
198  al_sec operator()() const { return mNow; }
199 
201  al_sec dt() const { return mDT; }
202 
204  double fps() const { return mFPS; }
205 
207  unsigned frame() const { return mFrame; }
208 
210  bool rt() const { return bUseRT; }
211 
213  al_sec update() {
214  if (bUseRT) {
215  al_sec t2 = al_system_time() - mReferenceTime;
216  mDT = t2 - mNow;
217  mNow = t2;
218  mFrame++;
219  mFPS = mFPS + 0.1 * ((1. / mDT) - mFPS);
220  } else {
221  mNow += mDT;
222  mFrame++;
223  mFPS = 1. / mDT;
224  }
225  return now();
226  }
227  al_sec update(al_sec dt) {
228  mDT = dt;
229  return update();
230  }
231 
233  void useRT() {
234  if (!bUseRT) {
235  // need to reset reference time:
236  mReferenceTime = al_system_time() - mNow;
237  }
238  bUseRT = true;
239  }
241  void useNRT(al_sec dt) {
242  mDT = dt;
243  bUseRT = false;
244  }
245 
246  protected:
247  al_sec mNow, mReferenceTime, mDT;
248  double mFPS;
249  unsigned mFrame;
250  bool bUseRT;
251 };
252 
253 } // namespace al
254 
255 #endif /* INCLUDE_AL_TIME_CPP_H */
bool rt() const
get current mode:
Definition: al_Time.hpp:210
al_sec update()
update the internal clock.
Definition: al_Time.hpp:213
void useRT()
set RT mode:
Definition: al_Time.hpp:233
al_sec now() const
get current clock time
Definition: al_Time.hpp:197
unsigned frame() const
get current frame:
Definition: al_Time.hpp:207
al_sec dt() const
get current delta time
Definition: al_Time.hpp:201
double fps() const
get current FPS:
Definition: al_Time.hpp:204
void useNRT(al_sec dt)
set NRT mode with specific frame rate:
Definition: al_Time.hpp:241
Clock(bool useRT=true)
Constructor that defaults to realtime mode.
Definition: al_Time.hpp:179
Clock(al_sec dt)
Constructor that defaults to a fixed 'frame rate'.
Definition: al_Time.hpp:188
Self-correcting timer.
Definition: al_Time.hpp:123
al_sec rate_smoothed() const
Get the current rate estimation (smoothed)
Definition: al_Time.hpp:148
void step(al_sec realtime)
Trigger this from the periodic event.
al_sec rate_ideal() const
Get the ideal rate.
Definition: al_Time.hpp:154
void setBandwidth(double bandwidth)
Set degree of smoothing.
al_sec period_smoothed() const
Get the current period estimation (smoothed)
Definition: al_Time.hpp:145
al_sec realtime_interp(double alpha) const
Returns time estimate between current and next event.
Definition: al_Time.hpp:161
al_sec period_ideal() const
Get the ideal period.
Definition: al_Time.hpp:151
void reset()
Call this after an xrun: will reset the timing adjustments.
Definition: al_Time.hpp:135
al_sec elapsedSec() const
Returns seconds between start() and stop() calls.
Definition: al_Time.hpp:98
void print() const
Print current elapsed time.
void start()
Set start time to current time.
Definition: al_Time.hpp:101
al_nsec elapsed() const
Returns nsec between start() and stop() calls.
Definition: al_Time.hpp:95
void stop()
Set stop time to current time.
Definition: al_Time.hpp:104
Definition: al_App.hpp:23
al_sec al_system_time()
Get current wall time in seconds.
std::string toTimecode(al_nsec t, const std::string &format="D:H:M:S:m:u")
Convert nanoseconds to timecode string.
void al_sleep(al_sec dt)
Sleep for an interval of seconds.