Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
The Openvibe Group
extras
Commits
d30346d5
Commit
d30346d5
authored
Mar 24, 2016
by
Jussi Lindgren
Browse files
Modules: Refactored often-used time conversion to a function
- Code cleanup
parent
474be03f
Changes
4
Hide whitespace changes
Inline
Side-by-side
modules/system/src/ovCTime.cpp
View file @
d30346d5
...
...
@@ -11,7 +11,7 @@
#if defined(TARGET_HAS_Boost_Chrono)
#define OV_BOOST_CHRONO_TIME // Use timing routines based on boost::chrono.
#else
#define OV_CLASSIC_TIME // Use the 'classic' openvibe timing routines.
#define OV_CLASSIC_TIME // Use the 'classic' openvibe timing routines.
deprecated, should be removed after a transition period.
#endif
#if defined(OV_BOOST_CHRONO_TIME)
...
...
@@ -36,6 +36,12 @@
#define uint32 System::uint32
#define uint64 System::uint64
// From ITimeArithmetics
static
uint64
subsecondsToTime
(
const
uint64
ui64Seconds
,
const
uint64
ui64Subseconds
,
const
uint64
ui64SubsInSecond
)
{
return
(
ui64Seconds
<<
32
)
+
(
ui64Subseconds
<<
32
)
/
ui64SubsInSecond
;
}
#if defined(OV_CLASSIC_TIME)
boolean
System
::
Time
::
sleep
(
const
uint32
ui32MilliSeconds
)
...
...
@@ -78,7 +84,7 @@ namespace
QueryPerformanceCounter
(
&
l_oPerformanceCounter
);
l_ui64Counter
=
l_oPerformanceCounter
.
QuadPart
-
l_ui64CounterStart
;
l_ui64Result
=
(
(
l_ui64Counter
/
l_ui64Frequency
)
<<
32
)
+
(((
l_ui64Counter
%
l_ui64Frequency
)
<<
32
)
/
l_ui64Frequency
);
l_ui64Result
=
subsecondsToTime
(
l_ui64Counter
/
l_ui64Frequency
,
l_ui64Counter
%
l_ui64Frequency
,
l_ui64Frequency
);
return
l_ui64Result
;
}
...
...
@@ -97,7 +103,7 @@ namespace
uint64
l_ui64Counter
;
l_ui64Counter
=
uint64
(
timeGetTime
());
l_ui64Counter
=
(
(
l_ui64Counter
/
1000
)
<<
32
)
+
(((
l_ui64Counter
%
1000
)
<<
32
)
/
1000
);
l_ui64Counter
=
subsecondsToTime
(
l_ui64Counter
/
1000
,
l_ui64Counter
%
1000
,
1000
);
if
(
!
l_bInitialized
)
{
...
...
@@ -206,7 +212,9 @@ uint64 System::Time::zgetTime(void)
l_i64TimeMicroSecond
+=
l_i64SecDiff
*
1000000
;
l_i64TimeMicroSecond
+=
l_i64USecDiff
;
l_ui64Result
=
((
l_i64TimeMicroSecond
/
1000000
)
<<
32
)
+
(((
l_i64TimeMicroSecond
%
1000000
)
<<
32
)
/
1000000
);
const
uint64
l_ui64MicrosInSecond
=
1000
*
1000
;
l_ui64Result
=
subsecondsToTime
(
l_i64TimeMicroSecond
/
l_ui64MicrosInSecond
,
l_i64TimeMicroSecond
%
l_ui64MicrosInSecond
,
l_ui64MicrosInSecond
);
return
l_ui64Result
;
}
...
...
@@ -278,7 +286,7 @@ uint64 System::Time::zgetTime(void)
const
uint64_t
l_ui64Fraction
=
l_oElapsedMs
.
count
()
%
l_ui64MicrosPerSecond
;
// below in fraction part, scale [0,l_ui64MicrosPerSecond-1] to 32bit integer range
const
uint64_t
l_ui64ReturnValue
=
(
l_ui64Seconds
<<
32
)
+
l_ui64Fraction
*
(
0xFFFFFFFFLL
/
(
l_ui64MicrosPerSecond
-
1
)
);
const
uint64_t
l_ui64ReturnValue
=
subsecondsToTime
(
l_ui64Seconds
,
l_ui64Fraction
,
l_ui64MicrosPerSecond
);
return
l_ui64ReturnValue
;
}
...
...
modules/system/test/test_time.cpp
View file @
d30346d5
...
...
@@ -53,6 +53,12 @@ using namespace std;
namespace
OpenViBE
{
class
ITimeArithmetics
{
public:
// From ITimeArithmetics
static
uint64_t
subsecondsToTime
(
const
uint64_t
ui64Seconds
,
const
uint64_t
ui64Subseconds
,
const
uint64_t
ui64SubsInSecond
)
{
return
(
ui64Seconds
<<
32
)
+
(
ui64Subseconds
<<
32
)
/
ui64SubsInSecond
;
}
static
double
timeToSeconds
(
const
uint64_t
ui64Time
)
{
return
(
ui64Time
>>
m_ui32Shift
)
/
double
(
m_ui32Multiplier
);
...
...
@@ -106,8 +112,8 @@ static uint64_t zgetTime1(void)
LARGE_INTEGER
l_oPerformanceCounter
;
QueryPerformanceCounter
(
&
l_oPerformanceCounter
);
l_ui64Counter
=
l_oPerformanceCounter
.
QuadPart
-
l_ui64CounterStart
;
l_ui64Result
=
(
(
l_ui64Counter
/
l_ui64Frequency
)
<<
32
)
+
(((
l_ui64Counter
%
l_ui64Frequency
)
<<
32
)
/
l_ui64Frequency
);
l_ui64Result
=
OpenViBE
::
ITimeArithmetics
::
subsecondsToTime
(
l_ui64Counter
/
l_ui64Frequency
,
l_ui64Counter
%
l_ui64Frequency
,
l_ui64Frequency
);
return
l_ui64Result
;
}
...
...
@@ -126,7 +132,7 @@ static uint64_t zgetTime2(void)
uint64_t
l_ui64Counter
;
l_ui64Counter
=
uint64_t
(
timeGetTime
());
l_ui64Counter
=
(
(
l_ui64Counter
/
1000
)
<<
32
)
+
(((
l_ui64Counter
%
1000
)
<<
32
)
/
1000
);
l_ui64Counter
=
OpenViBE
::
ITimeArithmetics
::
subsecondsToTime
(
l_ui64Counter
/
1000
,
l_ui64Counter
%
1000
,
1000
);
if
(
!
l_bInitialized
)
{
...
...
@@ -214,10 +220,12 @@ uint64_t zgetTime(void)
uint64_t
l_ui64SecDiff
=
(
uint64_t
)(
l_oTimeValue
.
tv_sec
-
l_oTimeValueStart
.
tv_sec
);
uint64_t
l_ui64USecDiff
=
(
uint64_t
)(
l_oTimeValue
.
tv_usec
-
l_oTimeValueStart
.
tv_usec
);
l_ui64TimeMicroSecond
+=
l_ui64SecDiff
*
1000000
;
const
uint64_t
l_ui64MicrosInSecond
=
1000
*
1000
;
l_ui64TimeMicroSecond
+=
l_ui64SecDiff
*
l_ui64MicrosInSecond
;
l_ui64TimeMicroSecond
+=
l_ui64USecDiff
;
uint64_t
l_ui64Result
=
((
l_ui64TimeMicroSecond
/
1000000
)
<<
32
)
+
(((
l_ui64TimeMicroSecond
%
1000000
)
<<
32
)
/
1000000
);
uint64_t
l_ui64Result
=
OpenViBE
::
ITimeArithmetics
::
subsecondsToTime
(
l_ui64TimeMicroSecond
/
l_ui64MicrosInSecond
,
l_ui64TimeMicroSecond
%
l_ui64MicrosInSecond
,
l_ui64MicrosInSecond
);
return
l_ui64Result
;
#endif
...
...
@@ -237,11 +245,11 @@ uint64_t getSystemTime(void)
static
const
uint64_t
l_ui64IntervalsPerSecond
=
10
*
1000
*
1000
;
// 100ns -> ms -> s
uint64_t
seconds
=
ll_now
/
l_ui64IntervalsPerSecond
;
uint64_t
fraction
=
ll_now
%
l_ui64IntervalsPerSecond
;
const
uint64_t
seconds
=
ll_now
/
l_ui64IntervalsPerSecond
;
const
uint64_t
fraction
=
ll_now
%
l_ui64IntervalsPerSecond
;
// below in fraction part, scale [0,l_uiIntervalsPerSecond-1] to 32bit integer range
return
(
seconds
<<
32
)
+
fraction
*
(
0xFFFFFFFF
/
l_ui64IntervalsPerSecond
);
return
OpenViBE
::
ITimeArithmetics
::
subsecondsToTime
(
seconds
,
fraction
,
l_ui64IntervalsPerSecond
);
}
#endif // TARGET_OS_Windows
...
...
@@ -264,7 +272,7 @@ uint64_t getBoostTime(void)
const
uint64_t
fraction
=
micros
%
l_ui64MicrosPerSecond
;
// below in fraction part, scale [0,l_ui64MicrosPerSecond-1] to 32bit integer range
const
uint64_t
retVal
=
(
seconds
<<
32
)
+
fraction
*
(
0xFFFFFFFF
/
(
l_ui64MicrosPerSecond
-
1
)
);
const
uint64_t
retVal
=
OpenViBE
::
ITimeArithmetics
::
subsecondsToTime
(
seconds
,
fraction
,
l_ui64MicrosPerSecond
);
return
retVal
;
}
...
...
@@ -296,7 +304,7 @@ uint64_t getBoostChronoTime(void)
const
uint64_t
fraction
=
l_oElapsedMs
.
count
()
%
l_ui64MicrosPerSecond
;
// below in fraction part, scale [0,l_ui64MicrosPerSecond-1] to 32bit integer range
const
uint64_t
retVal
=
(
seconds
<<
32
)
+
fraction
*
(
0xFFFFFFFFLL
/
(
l_ui64MicrosPerSecond
-
1
)
);
const
uint64_t
retVal
=
OpenViBE
::
ITimeArithmetics
::
subsecondsToTime
(
seconds
,
fraction
,
l_ui64MicrosPerSecond
);
return
retVal
;
}
...
...
@@ -352,7 +360,7 @@ uint64_t getFTime(void)
const
uint64_t
fraction
=
l_ui64ElapsedMs
%
l_ui64MillisPerSecond
;
// below in fraction part, scale [0,l_ui64MicrosPerSecond-1] to 32bit integer range
const
uint64_t
retVal
=
(
seconds
<<
32
)
+
fraction
*
(
0xFFFFFFFF
/
l_ui64MillisPerSecond
);
const
uint64_t
retVal
=
OpenViBE
::
ITimeArithmetics
::
subsecondsToTime
(
seconds
,
fraction
,
l_ui64MillisPerSecond
);
return
retVal
;
...
...
@@ -506,9 +514,8 @@ int main(int argc, char** argv)
spinTest
(
"ovCTime"
,
ovGetTime
);
#if defined(TARGET_HAS_Boost_Chrono)
spinTest
(
"boost::chrono"
,
getBoostChronoTime
);
#else
spinTest
(
"zgetTime"
,
zgetTime
);
#endif
spinTest
(
"zgetTime"
,
zgetTime
);
#if defined(TARGET_OS_Windows)
spinTest
(
"ftime"
,
getFTime
);
#endif
...
...
@@ -528,7 +535,7 @@ int main(int argc, char** argv)
std
::
vector
<
Clock
>
l_vClocks
;
l_vClocks
.
push_back
(
Clock
(
"ovCTime"
,
System
::
Time
::
zg
etTime
));
// the first clock controls the duration of the test
l_vClocks
.
push_back
(
Clock
(
"ovCTime"
,
ovG
etTime
));
// the first clock controls the duration of the test
#if defined(TARGET_HAS_Boost_Chrono)
l_vClocks
.
push_back
(
Clock
(
"BoostChronoTime"
,
getBoostChronoTime
));
#endif
...
...
@@ -540,8 +547,8 @@ int main(int argc, char** argv)
l_vClocks
.
push_back
(
Clock
(
"zgetTime2"
,
zgetTime2
));
l_vClocks
.
push_back
(
Clock
(
"ftime"
,
getFTime
));
#endif
#define USE_NTP
#if defined(USE_NTP)
//
#define
OV_TEST_
USE_NTP
#if defined(
OV_TEST_
USE_NTP)
l_vClocks
.
push_back
(
Clock
(
"NTP"
,
getNTPTime
));
// NTP clock needs a moment to complete the poll, call once to start
getNTPTime
();
...
...
openvibe/include/openvibe/ovITimeArithmetics.h
View file @
d30346d5
...
...
@@ -65,6 +65,16 @@ namespace OpenViBE
return
((
uint64
)(
f64Time
*
double
(
m_ui32Multiplier
)))
<<
m_ui32Shift
;
}
// \brief Convert seconds and subseconds pair to fixed point
// \param ui64Seconds : Number of seconds
// \param ui64Subseconds : Number of subseconds
// \param ui64SubsInSecond : Maximum subseconds in a second (e.g. 1000*1000 if subseconds are microseconds, 1000 for millis)
// \return Time in fixed point format
static
uint64
subsecondsToTime
(
const
uint64
ui64Seconds
,
const
uint64
ui64Subseconds
,
const
uint64
ui64SubsInSecond
)
{
return
(
ui64Seconds
<<
32
)
+
(
ui64Subseconds
<<
32
)
/
ui64SubsInSecond
;
}
// Increase m_ui32DecimalPrecision to get more precision in decimals for timeToSeconds() and secondsToTime().
// The default value of 10 bits suffices for (1/2^10)s=(1/1024)s precision in time, i.e. a bit under 1ms.
// Using higher sampling rates than 1024hz would require a correspondingly higher decimal precision.
...
...
openvibe/test/test_timearithmetic.cpp
View file @
d30346d5
...
...
@@ -7,6 +7,7 @@
#include <iomanip>
#include <cstdlib> // abs() on Linux
#include <bitset>
#include <vector>
#include <openvibe/ovITimeArithmetics.h>
...
...
@@ -408,7 +409,7 @@ int main(int argc, char *argv[])
//
// 1ms obtained by (1LL<<32)/1000LL is 0x418937 -> about 2x difference to method 1
// 1ms obtained by ov secondstoTime is 0x400000
// 1ms obtained by (2^32/1000 is
4294967.296 = 0x418937 + 0.296
// 1ms obtained by (2^32
)
/1000 is 4294967.296 = 0x418937 + 0.296
// 1ms obtained by (2^32-1)/1000 is 4294967.295 = 0x418937 + 0.295
//
...
...
@@ -456,5 +457,36 @@ int main(int argc, char *argv[])
std::cout << ITimeArithmetics::timeToSeconds(test3) << "->" << ITimeArithmetics::timeToSeconds(test3/10) << "\n";
*/
// Fraction test, converting <secs,ms> pair to 32:32 fixed point
const
uint64
microsInSecond
=
1000
*
1000
;
std
::
vector
<
std
::
pair
<
uint64
,
uint64
>
>
tmp
;
tmp
.
push_back
(
std
::
pair
<
uint64
,
uint64
>
(
0LL
,
0LL
));
// 0s
tmp
.
push_back
(
std
::
pair
<
uint64
,
uint64
>
(
0LL
,
1LL
));
// 1s + 1us
tmp
.
push_back
(
std
::
pair
<
uint64
,
uint64
>
(
0LL
,
2LL
));
tmp
.
push_back
(
std
::
pair
<
uint64
,
uint64
>
(
0LL
,(
microsInSecond
/
2LL
)));
// 500ms
tmp
.
push_back
(
std
::
pair
<
uint64
,
uint64
>
(
0LL
,
microsInSecond
-
2
));
tmp
.
push_back
(
std
::
pair
<
uint64
,
uint64
>
(
0LL
,
microsInSecond
-
1
));
// 1 step below 1s
tmp
.
push_back
(
std
::
pair
<
uint64
,
uint64
>
(
1LL
,
0LL
));
// 1s
tmp
.
push_back
(
std
::
pair
<
uint64
,
uint64
>
(
1LL
,
1LL
));
// 1 step above 1s
tmp
.
push_back
(
std
::
pair
<
uint64
,
uint64
>
(
0LL
,
microsInSecond
+
1
));
// same as (1LL,1LL), but shouldn't happen as micro fraction is meant to be capped under 1s
tmp
.
push_back
(
std
::
pair
<
uint64
,
uint64
>
(
1LL
,
2LL
));
tmp
.
push_back
(
std
::
pair
<
uint64
,
uint64
>
(
1LL
,
1000LL
));
// 1s + 1ms
tmp
.
push_back
(
std
::
pair
<
uint64
,
uint64
>
(
1LL
,
2000LL
));
// 1s + 2ms
for
(
size_t
i
=
0
;
i
<
tmp
.
size
();
i
++
)
{
const
uint64
l_ui64FixedPoint
=
ITimeArithmetics
::
subsecondsToTime
(
tmp
[
i
].
first
,
tmp
[
i
].
second
,
microsInSecond
);
cout
<<
"m9 pair ("
<<
tmp
[
i
].
first
<<
"s, "
<<
tmp
[
i
].
second
<<
"us) as float="
<<
ITimeArithmetics
::
timeToSeconds
(
l_ui64FixedPoint
)
<<
"s, parts secs="
<<
(
l_ui64FixedPoint
>>
32
)
<<
" fract="
<<
(
l_ui64FixedPoint
&
0xFFFFFFFFLL
)
<<
"
\n
"
;
}
// These should be approx equal
cout
<<
"m9 Diff 1 "
<<
ITimeArithmetics
::
subsecondsToTime
(
tmp
[
1
].
first
,
tmp
[
1
].
second
,
microsInSecond
)
-
ITimeArithmetics
::
subsecondsToTime
(
tmp
[
0
].
first
,
tmp
[
0
].
second
,
microsInSecond
)
<<
"
\n
"
;
cout
<<
"m9 Diff 1 "
<<
ITimeArithmetics
::
subsecondsToTime
(
tmp
[
6
].
first
,
tmp
[
6
].
second
,
microsInSecond
)
-
ITimeArithmetics
::
subsecondsToTime
(
tmp
[
5
].
first
,
tmp
[
5
].
second
,
microsInSecond
)
<<
"
\n
"
;
cout
<<
"m9 Diff 1 "
<<
ITimeArithmetics
::
subsecondsToTime
(
tmp
[
7
].
first
,
tmp
[
7
].
second
,
microsInSecond
)
-
ITimeArithmetics
::
subsecondsToTime
(
tmp
[
6
].
first
,
tmp
[
6
].
second
,
microsInSecond
)
<<
"
\n
"
;
return
retVal
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment