SDRAngel  4.11.5
Developer docs for <a href="https://github.com/f4exb/sdrangel">SDRangel<\a>, an Open Source Qt5 / OpenGL 3.0+ SDR and signal analyzer frontend to various hardware.
rtptimeutilities.h
Go to the documentation of this file.
1 /*
2 
3  This file is a part of JRTPLIB
4  Copyright (c) 1999-2017 Jori Liesenborgs
5 
6  Contact: jori.liesenborgs@gmail.com
7 
8  This library was developed at the Expertise Centre for Digital Media
9  (http://www.edm.uhasselt.be), a research center of the Hasselt University
10  (http://www.uhasselt.be). The library is based upon work done for
11  my thesis at the School for Knowledge Technology (Belgium/The Netherlands).
12 
13  Permission is hereby granted, free of charge, to any person obtaining a
14  copy of this software and associated documentation files (the "Software"),
15  to deal in the Software without restriction, including without limitation
16  the rights to use, copy, modify, merge, publish, distribute, sublicense,
17  and/or sell copies of the Software, and to permit persons to whom the
18  Software is furnished to do so, subject to the following conditions:
19 
20  The above copyright notice and this permission notice shall be included
21  in all copies or substantial portions of the Software.
22 
23  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
29  IN THE SOFTWARE.
30 
31  */
32 
37 #ifndef RTPTIMEUTILITIES_H
38 
39 #define RTPTIMEUTILITIES_H
40 
41 #include "rtpconfig.h"
42 #include "rtptypes.h"
43 #ifndef RTP_HAVE_QUERYPERFORMANCECOUNTER
44 #include <sys/time.h>
45 #include <time.h>
46 #include <errno.h>
47 #else
48 #include "Windows.h"
49 #endif // RTP_HAVE_QUERYPERFORMANCECOUNTER
50 
51 #include "export.h"
52 
53 #define RTP_NTPTIMEOFFSET 2208988800UL
54 
55 #ifdef RTP_HAVE_VSUINT64SUFFIX
56 #define C1000000 1000000ui64
57 #define CEPOCH 11644473600000000ui64
58 #else
59 #define C1000000 1000000ULL
60 #define CEPOCH 11644473600000000ULL
61 #endif // RTP_HAVE_VSUINT64SUFFIX
62 
63 #ifdef __APPLE__
64 #include "../custom/apple/apple_compat.h"
65 #endif
66 
67 namespace qrtplib
68 {
69 
75 {
76 public:
79  {
80  msw = m;
81  lsw = l;
82  }
83 
85  uint32_t GetMSW() const
86  {
87  return msw;
88  }
89 
91  uint32_t GetLSW() const
92  {
93  return lsw;
94  }
95 private:
96  uint32_t msw, lsw;
97 };
98 
104 {
105 public:
110  static RTPTime CurrentTime();
111 
113  static void Wait(const RTPTime &delay);
114 
116  RTPTime(double t);
117 
123  RTPTime(RTPNTPTime ntptime);
124 
126  RTPTime(int64_t seconds, uint32_t microseconds);
127 
129  int64_t GetSeconds() const;
130 
132  uint32_t GetMicroSeconds() const;
133 
135  double GetDouble() const
136  {
137  return m_t;
138  }
139 
141  RTPNTPTime GetNTPTime() const;
142 
143  RTPTime &operator-=(const RTPTime &t);
144  RTPTime &operator+=(const RTPTime &t);
145  bool operator<(const RTPTime &t) const;
146  bool operator>(const RTPTime &t) const;
147  bool operator<=(const RTPTime &t) const;
148  bool operator>=(const RTPTime &t) const;
149 
150  bool IsZero() const
151  {
152  return m_t == 0.0;
153  }
154 private:
155 #ifdef RTP_HAVE_QUERYPERFORMANCECOUNTER
156  static inline uint64_t CalculateMicroseconds(uint64_t performancecount,uint64_t performancefrequency);
157 #endif // RTP_HAVE_QUERYPERFORMANCECOUNTER
158 
159  double m_t;
160 };
161 
162 inline RTPTime::RTPTime(double t)
163 {
164  m_t = t;
165 }
166 
167 inline RTPTime::RTPTime(int64_t seconds, uint32_t microseconds)
168 {
169  if (seconds >= 0)
170  {
171  m_t = (double) seconds + 1e-6 * (double) microseconds;
172  }
173  else
174  {
175  int64_t possec = -seconds;
176 
177  m_t = (double) possec + 1e-6 * (double) microseconds;
178  m_t = -m_t;
179  }
180 }
181 
183 {
184  if (ntptime.GetMSW() < RTP_NTPTIMEOFFSET)
185  {
186  m_t = 0;
187  }
188  else
189  {
190  uint32_t sec = ntptime.GetMSW() - RTP_NTPTIMEOFFSET;
191 
192  double x = (double) ntptime.GetLSW();
193  x /= (65536.0 * 65536.0);
194  x *= 1000000.0;
195  uint32_t microsec = (uint32_t) x;
196 
197  m_t = (double) sec + 1e-6 * (double) microsec;
198  }
199 }
200 
202 {
203  return (int64_t) m_t;
204 }
205 
207 {
208  uint32_t microsec;
209 
210  if (m_t >= 0)
211  {
212  int64_t sec = (int64_t) m_t;
213  microsec = (uint32_t) (1e6 * (m_t - (double) sec) + 0.5);
214  }
215  else // m_t < 0
216  {
217  int64_t sec = (int64_t) (-m_t);
218  microsec = (uint32_t) (1e6 * ((-m_t) - (double) sec) + 0.5);
219  }
220 
221  if (microsec >= 1000000)
222  return 999999;
223  // Unsigned, it can never be less than 0
224  // if (microsec < 0)
225  // return 0;
226  return microsec;
227 }
228 
229 #ifdef RTP_HAVE_QUERYPERFORMANCECOUNTER
230 
231 inline uint64_t RTPTime::CalculateMicroseconds(uint64_t performancecount,uint64_t performancefrequency)
232 {
233  uint64_t f = performancefrequency;
234  uint64_t a = performancecount;
235  uint64_t b = a/f;
236  uint64_t c = a%f; // a = b*f+c => (a*1000000)/f = b*1000000+(c*1000000)/f
237 
238  return b*C1000000+(c*C1000000)/f;
239 }
240 
242 {
243  static int inited = 0;
244  static uint64_t microseconds, initmicroseconds;
245  static LARGE_INTEGER performancefrequency;
246 
247  uint64_t emulate_microseconds, microdiff;
248  SYSTEMTIME systemtime;
249  FILETIME filetime;
250 
251  LARGE_INTEGER performancecount;
252 
253  QueryPerformanceCounter(&performancecount);
254 
255  if(!inited)
256  {
257  inited = 1;
258  QueryPerformanceFrequency(&performancefrequency);
259  GetSystemTime(&systemtime);
260  SystemTimeToFileTime(&systemtime,&filetime);
261  microseconds = ( ((uint64_t)(filetime.dwHighDateTime) << 32) + (uint64_t)(filetime.dwLowDateTime) ) / (uint64_t)10;
262  microseconds-= CEPOCH; // EPOCH
263  initmicroseconds = CalculateMicroseconds(performancecount.QuadPart, performancefrequency.QuadPart);
264  }
265 
266  emulate_microseconds = CalculateMicroseconds(performancecount.QuadPart, performancefrequency.QuadPart);
267 
268  microdiff = emulate_microseconds - initmicroseconds;
269 
270  double t = 1e-6*(double)(microseconds + microdiff);
271  return RTPTime(t);
272 }
273 
274 inline void RTPTime::Wait(const RTPTime &delay)
275 {
276  if (delay.m_t <= 0)
277  return;
278 
279  uint64_t sec = (uint64_t)delay.m_t;
280  uint32_t microsec = (uint32_t)(1e6*(delay.m_t-(double)sec));
281  DWORD t = ((DWORD)sec)*1000+(((DWORD)microsec)/1000);
282  Sleep(t);
283 }
284 
285 #else // unix style
286 
287 #ifdef RTP_HAVE_CLOCK_GETTIME
288 inline double RTPTime_timespecToDouble(struct timespec &ts)
289 {
290  return (double) ts.tv_sec + 1e-9 * (double) ts.tv_nsec;
291 }
292 
294 {
295  static bool s_initialized = false;
296  static double s_startOffet = 0;
297 
298  if (!s_initialized)
299  {
300  s_initialized = true;
301 
302  // Get the corresponding times in system time and monotonic time
303  struct timespec tpSys, tpMono;
304 
305  clock_gettime(CLOCK_REALTIME, &tpSys);
306  clock_gettime(CLOCK_MONOTONIC, &tpMono);
307 
308  double tSys = RTPTime_timespecToDouble(tpSys);
309  double tMono = RTPTime_timespecToDouble(tpMono);
310 
311  s_startOffet = tSys - tMono;
312  return tSys;
313  }
314 
315  struct timespec tpMono;
316  clock_gettime(CLOCK_MONOTONIC, &tpMono);
317 
318  double tMono0 = RTPTime_timespecToDouble(tpMono);
319  return tMono0 + s_startOffet;
320 }
321 
322 #else // gettimeofday fallback
323 
325 {
326  struct timeval tv;
327 
328  gettimeofday(&tv,0);
329  return RTPTime((uint64_t)tv.tv_sec,(uint32_t)tv.tv_usec);
330 }
331 #endif // RTP_HAVE_CLOCK_GETTIME
332 
333 inline void RTPTime::Wait(const RTPTime &delay)
334 {
335  if (delay.m_t <= 0)
336  return;
337 
338  uint64_t sec = (uint64_t) delay.m_t;
339  uint64_t nanosec = (uint32_t) (1e9 * (delay.m_t - (double) sec));
340 
341  struct timespec req, rem;
342  int ret;
343 
344  req.tv_sec = (time_t) sec;
345  req.tv_nsec = ((long) nanosec);
346  do
347  {
348  ret = nanosleep(&req, &rem);
349  req = rem;
350  } while (ret == -1 && errno == EINTR);
351 }
352 
353 #endif // RTP_HAVE_QUERYPERFORMANCECOUNTER
354 
356 {
357  m_t -= t.m_t;
358  return *this;
359 }
360 
362 {
363  m_t += t.m_t;
364  return *this;
365 }
366 
368 {
369  uint32_t sec = (uint32_t) m_t;
370  uint32_t microsec = (uint32_t) ((m_t - (double) sec) * 1e6);
371 
372  uint32_t msw = sec + RTP_NTPTIMEOFFSET;
373  uint32_t lsw;
374  double x;
375 
376  x = microsec / 1000000.0;
377  x *= (65536.0 * 65536.0);
378  lsw = (uint32_t) x;
379 
380  return RTPNTPTime(msw, lsw);
381 }
382 
383 inline bool RTPTime::operator<(const RTPTime &t) const
384 {
385  return m_t < t.m_t;
386 }
387 
388 inline bool RTPTime::operator>(const RTPTime &t) const
389 {
390  return m_t > t.m_t;
391 }
392 
393 inline bool RTPTime::operator<=(const RTPTime &t) const
394 {
395  return m_t <= t.m_t;
396 }
397 
398 inline bool RTPTime::operator>=(const RTPTime &t) const
399 {
400  return m_t >= t.m_t;
401 }
402 
404 {
405 public:
407  void Dummy()
408  {
409  dummy++;
410  }
411 private:
412  int dummy;
413 };
414 
416 
417 } // end namespace
418 
419 #endif // RTPTIMEUTILITIES_H
420 
bool operator<=(const RTPTime &t) const
RTPNTPTime(uint32_t m, uint32_t l)
double GetDouble() const
RTPTimeInitializerObject timeinit
uint32_t GetMicroSeconds() const
RTPTime & operator+=(const RTPTime &t)
bool operator<=(double a, Fixed< IntType, IntBits > const &b)
Definition: fixed.h:2025
bool operator>(const RTPTime &t) const
#define QRTPLIB_API
Definition: export.h:112
__int64 int64_t
Definition: rtptypes_win.h:47
uint32_t GetMSW() const
bool operator>=(double a, Fixed< IntType, IntBits > const &b)
Definition: fixed.h:2145
unsigned int uint32_t
Definition: rtptypes_win.h:46
double RTPTime_timespecToDouble(struct timespec &ts)
#define C1000000
#define RTP_NTPTIMEOFFSET
bool IsZero() const
RTPTime & operator-=(const RTPTime &t)
bool operator>=(const RTPTime &t) const
#define CEPOCH
uint32_t GetLSW() const
bool operator<(double a, Fixed< IntType, IntBits > const &b)
Definition: fixed.h:1785
static void Wait(const RTPTime &delay)
RTPNTPTime GetNTPTime() const
static RTPTime CurrentTime()
bool operator>(double a, Fixed< IntType, IntBits > const &b)
Definition: fixed.h:1905
bool operator<(const RTPTime &t) const
int64_t GetSeconds() const
unsigned __int64 uint64_t
Definition: rtptypes_win.h:48