diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Outputs.cpp | 41 | ||||
-rw-r--r-- | src/Outputs.h | 12 | ||||
-rw-r--r-- | src/odr-audioenc.cpp | 10 |
3 files changed, 57 insertions, 6 deletions
diff --git a/src/Outputs.cpp b/src/Outputs.cpp index 31c7912..f258881 100644 --- a/src/Outputs.cpp +++ b/src/Outputs.cpp @@ -135,7 +135,9 @@ bool ZMQ::write_frame(const uint8_t *buf, size_t len) return true; } -EDI::EDI() { } +EDI::EDI() : + m_clock_tai({}) +{ } EDI::~EDI() { } @@ -170,20 +172,51 @@ bool EDI::enabled() const return not m_edi_conf.destinations.empty(); } +void EDI::set_tist(bool enable, uint32_t delay_ms) +{ + m_tist = enable; + m_delay_ms = delay_ms; +} + bool EDI::write_frame(const uint8_t *buf, size_t len) { if (not m_edi_sender) { m_edi_sender = make_shared<edi::Sender>(m_edi_conf); } - edi::TagStarPTR edi_tagStarPtr; - edi_tagStarPtr.protocol = "DSTI"; + if (m_edi_time == 0) { + using Sec = chrono::seconds; + const auto now = chrono::time_point_cast<Sec>(chrono::system_clock::now()); + m_edi_time = chrono::system_clock::to_time_t(now) + (m_delay_ms / 1000); + + /* TODO we still have to see if 24ms granularity is achievable, given that + * one DAB+ super frame is carried over more than 1 ETI frame. + */ + for (int32_t sub_ms = (m_delay_ms % 1000); sub_ms > 0; sub_ms -= 24) { + m_timestamp += 24 << 14; // Shift 24ms by 14 to Timestamp level 2 + } + + } + + edi::TagStarPTR edi_tagStarPtr("DSTI"); m_edi_tagDSTI.stihf = false; - m_edi_tagDSTI.atstf = false; + m_edi_tagDSTI.atstf = m_tist; + + m_timestamp += 24 << 14; // Shift 24ms by 14 to Timestamp level 2 + if (m_timestamp > 0xf9FFff) { + m_timestamp -= 0xfa0000; // Substract 16384000, corresponding to one second + m_edi_time += 1; + } + + m_edi_tagDSTI.set_edi_time(m_edi_time, m_clock_tai.get_offset()); + m_edi_tagDSTI.tsta = m_timestamp & 0xffffff; + m_edi_tagDSTI.rfadf = false; // DFCT is handled inside the TagDSTI + // TODO invent custom TAG to carry audio levels metadata + edi::TagSSm edi_tagPayload; // TODO make edi_tagPayload.stid configurable edi_tagPayload.istd_data = buf; diff --git a/src/Outputs.h b/src/Outputs.h index b5ee25a..131f35c 100644 --- a/src/Outputs.h +++ b/src/Outputs.h @@ -19,12 +19,14 @@ #pragma once #include <vector> +#include <chrono> #include <deque> #include <cstdint> #include <cstddef> #include <cstdio> #include "common.h" #include "zmq.hpp" +#include "ClockTAI.h" #include "edi/TagItems.h" #include "edi/TagPacket.h" #include "edi/AFPacket.h" @@ -134,18 +136,24 @@ class EDI: public Base { void add_udp_destination(const std::string& host, unsigned int port); void add_tcp_destination(const std::string& host, unsigned int port); + void set_tist(bool enable, uint32_t delay_ms); + bool enabled() const; virtual bool write_frame(const uint8_t *buf, size_t len) override; - // TODO audio levels metadata - private: edi::configuration_t m_edi_conf; std::shared_ptr<edi::Sender> m_edi_sender; + uint32_t m_timestamp = 0; + std::time_t m_edi_time = 0; + edi::TagDSTI m_edi_tagDSTI; + ClockTAI m_clock_tai; + bool m_tist = false; + uint32_t m_delay_ms = 0; }; } diff --git a/src/odr-audioenc.cpp b/src/odr-audioenc.cpp index 6a5f6ea..c3d4cb6 100644 --- a/src/odr-audioenc.cpp +++ b/src/odr-audioenc.cpp @@ -188,6 +188,8 @@ void usage(const char* name) " If more than one ZMQ output is given, the socket\n" " will be connected to all listed endpoints.\n" " -e, --edi=URI EDI output uri, (e.g. 'tcp://localhost:7000')\n" + " -T, --timestamp-delay=DELAY_MS Enabled timestamps in EDI (requires TAI clock bulletin download) and\n" + " add a delay (in milliseconds) to the timestamps carried in EDI\n" " -k, --secret-key=FILE Enable ZMQ encryption with the given secret key.\n" " -p, --pad=BYTES Enable PAD insertion and set PAD size in bytes.\n" " -P, --pad-fifo=FILENAME Set PAD data input fifo name" @@ -432,6 +434,9 @@ public: shared_ptr<Output::ZMQ> zmq_output; Output::EDI edi_output; + bool tist_enabled = false; + uint32_t tist_delay_ms = 0; + vector<string> output_uris; vector<string> edi_output_uris; @@ -1310,6 +1315,7 @@ int main(int argc, char *argv[]) {"dabpsy", required_argument, 0, 5 }, {"device", required_argument, 0, 'd'}, {"edi", required_argument, 0, 'e'}, + {"timestamp-delay", required_argument, 0, 'T'}, {"decode", required_argument, 0, 6 }, {"format", required_argument, 0, 'f'}, {"input", required_argument, 0, 'i'}, @@ -1419,6 +1425,10 @@ int main(int argc, char *argv[]) case 'e': audio_enc.edi_output_uris.push_back(optarg); break; + case 'T': + audio_enc.tist_enabled = true; + audio_enc.tist_delay_ms = std::stoi(optarg); + break; case 'f': if (strcmp(optarg, "raw") == 0) { audio_enc.raw_input = 1; |