From 23572904d24560e1f171c9e0eabca693db197480 Mon Sep 17 00:00:00 2001 From: Kevin Matz Date: Mon, 24 Apr 2023 13:04:49 -0400 Subject: [PATCH] timetag values to/from system time --- protocol/osc/argument.cpp | 50 +++++++++++++++++++++++++++++++++++++++ protocol/osc/argument.h | 4 ++++ 2 files changed, 54 insertions(+) diff --git a/protocol/osc/argument.cpp b/protocol/osc/argument.cpp index a77b6d8..fb72149 100644 --- a/protocol/osc/argument.cpp +++ b/protocol/osc/argument.cpp @@ -94,6 +94,56 @@ void blob::oStream(std::shared_ptr stream) const } +/** + * @brief timetag::time_point + * @return + * + * Convert \cite NTPv4 NTP timestamp to a system referanced time_point, with + * not greater than nanosecond resolution. + * + * \warning \cite Spec11 OSC Spec 1.1 leaves unchanged the reliance on the 64-bit NTP + * timestamp format. The NTP Epoch 0 ends on February 7, 2036, at which time OSC + * timetag values will rollover. + */ +std::chrono::time_point timetag::time() const +{ + std::chrono::time_point time; // POSIX epoch + time -= std::chrono::seconds(2208988800); // NTP epoch offset + time += std::chrono::seconds(seconds); + time += std::chrono::nanoseconds( + (uint32_t)(((double)fractional + *(1.0/(double)std::numeric_limits::max())) + *1e9)); + /// \test validate time conversion from fractional seconds. + return time; +} + + +/** + * @brief timetag::setTime + * @param time + * + * Convert system referanced time_point to \cite NTPv4 NTP timestamps, with + * not greater than nanosecond resolution. + * + * \warning \cite Spec11 OSC Spec 1.1 leaves unchanged the reliance on the 64-bit NTP + * timestamp format. The NTP Epoch 0 ends on February 7, 2036, at which time OSC + * timetag values will rollover. + */ +void timetag::setTime(std::chrono::time_point time) +{ + auto t = time.time_since_epoch(); // POSIX epoch + auto s = std::chrono::duration_cast(t); + auto f = std::chrono::duration_cast(t - s); + s += std::chrono::seconds(2208988800); // NTP epoch offset + seconds = s.count(); + fractional = ((double)f.count() + *1e-9) + *(1.0/(double)std::numeric_limits::max()); + /// \test validate time conversion to fractional seconds. +} + + void character::iStream(std::shared_ptr stream) { value = stream->readType(); diff --git a/protocol/osc/argument.h b/protocol/osc/argument.h index 8777867..8f174ac 100644 --- a/protocol/osc/argument.h +++ b/protocol/osc/argument.h @@ -24,6 +24,7 @@ #pragma once #include +#include #include namespace OSC { @@ -136,6 +137,9 @@ struct timetag { timetag() : Argument('t') {}; + std::chrono::time_point time() const; + void setTime(std::chrono::time_point time = std::chrono::system_clock::now()); + virtual size_t streamSize() const override { return 8; } virtual void iStream(std::shared_ptr stream) override { *stream >> value; } virtual void oStream(std::shared_ptr stream) const override { *stream << value; }