roc-streaming / roc-toolkit

Real-time audio streaming over the network.
https://roc-streaming.org
Mozilla Public License 2.0
1.03k stars 205 forks source link

gh-546: Support NTP 2036 year base #550

Closed gavv closed 9 months ago

gavv commented 9 months ago

Fixes #546.

unix_2_ntp() and ntp_2_unix() are updated according to RFC 2030.

ntp_equal_delta() is removed because it was never used and proper implementation is not trivial.

dshil commented 9 months ago

Hi @gavv, this comment isn't directly related to this PR, just some thoughts. it was a little bit tricky for me to find out where was the actual conversation of the fraction part of timestamps. I was playing a little bit with a code, and tried to make it more understandable, at least for me.

namespace {

uint64_t bits_pack(uint32_t hi, uint32_t lo) {
    return ((uint64_t)hi << 32) | (lo & 0x00000000FFFFFFFFULL);
}

void bits_unpack(uint64_t value, uint32_t& hi, uint32_t& lo) {
    hi = (value & 0xFFFFFFFF00000000ULL) >> 32;
    lo = value & 0xFFFFFFFFULL;
}

} // namespace

ntp_timestamp_t nanoseconds_2_ntp(core::nanoseconds_t ns_delta) {
    roc_panic_if_msg(ns_delta < 0, "ntp: can not convert negative delta to ntp");

    const uint32_t seconds = (uint32_t)(ns_delta / core::Second);
    const uint32_t fraction = (uint32_t)ns_delta - seconds * core::Second;
    const uint32_t nans = ((uint64_t)fraction << 32) / core::Second;

    return bits_pack(seconds, nans);
}

core::nanoseconds_t ntp_2_nanoseconds(ntp_timestamp_t ntp_delta) {
    uint32_t hi = 0;
    uint32_t lo = 0;
    bits_unpack(ntp_delta, hi, lo);

    const core::nanoseconds_t seconds = (core::nanoseconds_t)hi;
    const core::nanoseconds_t nans = (core::nanoseconds_t)(lo * core::Second) >> 32;

    return seconds * core::Second + nans;
}

Now, it seems clear how the fractional part should be computed:


Also, I want to mention the following resources that were very helpful with understanding NTP and UNIX timestamps:

gavv commented 9 months ago

Nice, applied suggested refactoring: 73bff5db5cb9322a3efff9dacc0a6360d3f00536 (with some small changes)