diff options
-rw-r--r-- | contrib/edi/TagItems.cpp | 66 | ||||
-rw-r--r-- | contrib/edi/TagItems.h | 24 | ||||
-rw-r--r-- | src/Outputs.cpp | 24 | ||||
-rw-r--r-- | src/Outputs.h | 2 |
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; |