summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias P. Braendli <matthias.braendli@mpb.li>2019-09-18 11:49:38 +0200
committerMatthias P. Braendli <matthias.braendli@mpb.li>2019-09-18 11:49:38 +0200
commit4e207da0b1d2faa5fa38888ea824e0430ecd2f33 (patch)
treec998c1924843bd2d9eca30ce3db849a73f4a78fe
parenteab95c0e7a7fad7d8fc5dd9b00b9ddb565d15925 (diff)
downloadODR-AudioEnc-4e207da0b1d2faa5fa38888ea824e0430ecd2f33.tar.gz
ODR-AudioEnc-4e207da0b1d2faa5fa38888ea824e0430ecd2f33.tar.bz2
ODR-AudioEnc-4e207da0b1d2faa5fa38888ea824e0430ecd2f33.zip
EDI: add audio levels and program version TAGs
-rw-r--r--contrib/edi/TagItems.cpp66
-rw-r--r--contrib/edi/TagItems.h24
-rw-r--r--src/Outputs.cpp24
-rw-r--r--src/Outputs.h2
4 files changed, 114 insertions, 2 deletions
diff --git a/contrib/edi/TagItems.cpp b/contrib/edi/TagItems.cpp
index 35a6852..9746469 100644
--- a/contrib/edi/TagItems.cpp
+++ b/contrib/edi/TagItems.cpp
@@ -379,5 +379,71 @@ std::vector<uint8_t> TagStarDMY::Assemble()
return packet;
}
+TagODRVersion::TagODRVersion(const std::string& version, uint32_t uptime_s) :
+ m_version(version),
+ m_uptime(uptime_s)
+{
+}
+
+std::vector<uint8_t> TagODRVersion::Assemble()
+{
+ std::string pack_data("ODRv");
+ std::vector<uint8_t> packet(pack_data.begin(), pack_data.end());
+
+ const size_t length = m_version.size() + sizeof(uint32_t);
+
+ packet.resize(4 + 4 + length);
+
+ const uint32_t length_bits = length * 8;
+
+ size_t i = 4;
+ packet[i++] = (length_bits >> 24) & 0xFF;
+ packet[i++] = (length_bits >> 16) & 0xFF;
+ packet[i++] = (length_bits >> 8) & 0xFF;
+ packet[i++] = length_bits & 0xFF;
+
+ copy(m_version.cbegin(), m_version.cend(), packet.begin() + i);
+ i += m_version.size();
+
+ packet[i++] = (m_uptime >> 24) & 0xFF;
+ packet[i++] = (m_uptime >> 16) & 0xFF;
+ packet[i++] = (m_uptime >> 8) & 0xFF;
+ packet[i++] = m_uptime & 0xFF;
+
+ return packet;
+}
+
+TagODRAudioLevels::TagODRAudioLevels(int16_t audiolevel_left, int16_t audiolevel_right) :
+ m_audio_left(audiolevel_left),
+ m_audio_right(audiolevel_right)
+{
+}
+
+std::vector<uint8_t> TagODRAudioLevels::Assemble()
+{
+ std::string pack_data("ODRa");
+ std::vector<uint8_t> packet(pack_data.begin(), pack_data.end());
+
+ constexpr size_t length = 2*sizeof(int16_t);
+
+ packet.resize(4 + 4 + length);
+
+ const uint32_t length_bits = length * 8;
+
+ size_t i = 4;
+ packet[i++] = (length_bits >> 24) & 0xFF;
+ packet[i++] = (length_bits >> 16) & 0xFF;
+ packet[i++] = (length_bits >> 8) & 0xFF;
+ packet[i++] = length_bits & 0xFF;
+
+ packet[i++] = (m_audio_left >> 8) & 0xFF;
+ packet[i++] = m_audio_left & 0xFF;
+
+ packet[i++] = (m_audio_right >> 8) & 0xFF;
+ packet[i++] = m_audio_right & 0xFF;
+
+ return packet;
+}
+
}
diff --git a/contrib/edi/TagItems.h b/contrib/edi/TagItems.h
index 25daa14..5c81b01 100644
--- a/contrib/edi/TagItems.h
+++ b/contrib/edi/TagItems.h
@@ -225,5 +225,29 @@ class TagStarDMY : public TagItem
uint32_t length_;
};
+// Custom TAG that carries version information of the EDI source
+class TagODRVersion : public TagItem
+{
+ public:
+ TagODRVersion(const std::string& version, uint32_t uptime_s);
+ std::vector<uint8_t> Assemble();
+
+ private:
+ std::string m_version;
+ uint32_t m_uptime;
+};
+
+// Custom TAG that carries audio level metadata
+class TagODRAudioLevels : public TagItem
+{
+ public:
+ TagODRAudioLevels(int16_t audiolevel_left, int16_t audiolevel_right);
+ std::vector<uint8_t> Assemble();
+
+ private:
+ int16_t m_audio_left;
+ int16_t m_audio_right;
+};
+
}
diff --git a/src/Outputs.cpp b/src/Outputs.cpp
index eadbc5e..d0d3ca4 100644
--- a/src/Outputs.cpp
+++ b/src/Outputs.cpp
@@ -188,6 +188,7 @@ bool EDI::write_frame(const uint8_t *buf, size_t len)
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);
+ m_send_version_at_time = m_edi_time;
/* 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.
@@ -206,6 +207,8 @@ bool EDI::write_frame(const uint8_t *buf, size_t len)
if (m_timestamp > 0xf9FFff) {
m_timestamp -= 0xfa0000; // Substract 16384000, corresponding to one second
m_edi_time += 1;
+
+ m_num_seconds_sent++;
}
m_edi_tagDSTI.set_edi_time(m_edi_time, m_clock_tai.get_offset());
@@ -214,13 +217,23 @@ bool EDI::write_frame(const uint8_t *buf, size_t len)
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;
edi_tagPayload.istd_length = len;
+ edi::TagODRAudioLevels edi_tagAudioLevels(m_audio_left, m_audio_right);
+
+ stringstream ss;
+ ss << PACKAGE_NAME << " " <<
+#if defined(GITVERSION)
+ GITVERSION;
+#else
+ PACKAGE_VERSION;
+#endif
+ edi::TagODRVersion edi_tagVersion(ss.str(), m_num_seconds_sent);
+
+
// The above Tag Items will be assembled into a TAG Packet
edi::TagPacket edi_tagpacket(m_edi_conf.tagpacket_alignment);
@@ -228,6 +241,13 @@ bool EDI::write_frame(const uint8_t *buf, size_t len)
edi_tagpacket.tag_items.push_back(&edi_tagStarPtr);
edi_tagpacket.tag_items.push_back(&m_edi_tagDSTI);
edi_tagpacket.tag_items.push_back(&edi_tagPayload);
+ edi_tagpacket.tag_items.push_back(&edi_tagAudioLevels);
+
+ // Send version information only every 10 seconds to save bandwidth
+ if (m_send_version_at_time < m_edi_time) {
+ m_send_version_at_time += 10;
+ edi_tagpacket.tag_items.push_back(&edi_tagVersion);
+ }
m_edi_sender->write(edi_tagpacket);
diff --git a/src/Outputs.h b/src/Outputs.h
index 131f35c..0f1f34f 100644
--- a/src/Outputs.h
+++ b/src/Outputs.h
@@ -147,7 +147,9 @@ class EDI: public Base {
std::shared_ptr<edi::Sender> m_edi_sender;
uint32_t m_timestamp = 0;
+ uint32_t m_num_seconds_sent = 0;
std::time_t m_edi_time = 0;
+ std::time_t m_send_version_at_time = 0;
edi::TagDSTI m_edi_tagDSTI;