From dfc67c45c7d48f584a978be24b611494fe3ad930 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 22 Feb 2021 17:40:15 +0100 Subject: [PATCH] output/snapcast: calculate the latency for TIME responses --- src/output/plugins/snapcast/Client.cxx | 8 ++++++-- src/output/plugins/snapcast/Protocol.hxx | 15 +++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/output/plugins/snapcast/Client.cxx b/src/output/plugins/snapcast/Client.cxx index 4e0711071..f1aa21753 100644 --- a/src/output/plugins/snapcast/Client.cxx +++ b/src/output/plugins/snapcast/Client.cxx @@ -22,6 +22,7 @@ #include "Timestamp.hxx" #include "Internal.hxx" #include "tag/RiffFormat.hxx" +#include "event/Loop.hxx" #include "net/SocketError.hxx" #include "net/UniqueSocketDescriptor.hxx" #include "util/StringView.hxx" @@ -146,7 +147,8 @@ SendTime(SocketDescriptor s, const PackedBE16 id, const SnapcastBase &request_header, const SnapcastTime &request_payload) noexcept { - SnapcastTime payload = request_payload; // TODO + SnapcastTime payload = request_payload; + payload.latency = request_header.received - request_header.sent; SnapcastBase base{}; base.type = uint16_t(SnapcastMessageType::TIME); @@ -196,12 +198,14 @@ SnapcastClient::SendWireChunk(ConstBuffer payload, BufferedSocket::InputResult SnapcastClient::OnSocketInput(void *data, size_t length) noexcept { - const auto &base = *(const SnapcastBase *)data; + auto &base = *(SnapcastBase *)data; if (length < sizeof(base) || length < sizeof(base) + base.size) return InputResult::MORE; + base.received = ToSnapcastTimestamp(GetEventLoop().SteadyNow()); + ConsumeInput(sizeof(base) + base.size); const ConstBuffer payload{&base + 1, base.size}; diff --git a/src/output/plugins/snapcast/Protocol.hxx b/src/output/plugins/snapcast/Protocol.hxx index 9a3a6a40c..5e9e10aab 100644 --- a/src/output/plugins/snapcast/Protocol.hxx +++ b/src/output/plugins/snapcast/Protocol.hxx @@ -35,6 +35,21 @@ enum class SnapcastMessageType : uint16_t { struct SnapcastTimestamp { PackedLE32 sec, usec; + + constexpr SnapcastTimestamp operator-(SnapcastTimestamp other) const noexcept { + const uint32_t a_sec = sec, a_usec = usec; + const uint32_t b_sec = other.sec, b_usec = other.usec; + + uint32_t result_sec = a_sec - b_sec; + uint32_t result_usec = a_usec - b_usec; + + if (a_usec < b_usec) { + --result_sec; + result_usec += 1'000'0000; + } + + return {result_sec, result_usec}; + } }; struct SnapcastBase {