summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Outputs.cpp41
-rw-r--r--src/Outputs.h12
-rw-r--r--src/odr-audioenc.cpp10
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;