diff options
| author | Matthias P. Braendli <matthias.braendli@mpb.li> | 2019-12-04 14:53:54 +0100 | 
|---|---|---|
| committer | Matthias P. Braendli <matthias.braendli@mpb.li> | 2019-12-04 14:53:54 +0100 | 
| commit | c89b5e3c0d9515f07892af464bd6c60fb3427c36 (patch) | |
| tree | 18c7573859606dada82e56d5115cd5d1e71129db /src/Outputs.cpp | |
| parent | 814ec3abaede73ea38c7130333c7bc0a18e05d91 (diff) | |
| download | ODR-SourceCompanion-c89b5e3c0d9515f07892af464bd6c60fb3427c36.tar.gz ODR-SourceCompanion-c89b5e3c0d9515f07892af464bd6c60fb3427c36.tar.bz2 ODR-SourceCompanion-c89b5e3c0d9515f07892af464bd6c60fb3427c36.zip | |
Timestamp arrival of UDP packets
Diffstat (limited to 'src/Outputs.cpp')
| -rw-r--r-- | src/Outputs.cpp | 51 | 
1 files changed, 23 insertions, 28 deletions
| diff --git a/src/Outputs.cpp b/src/Outputs.cpp index d0d3ca4..3b4de65 100644 --- a/src/Outputs.cpp +++ b/src/Outputs.cpp @@ -136,12 +136,13 @@ bool ZMQ::write_frame(const uint8_t *buf, size_t len)  }  EDI::EDI() : +    m_time_last_version_sent(chrono::steady_clock::now()),      m_clock_tai({})  { }  EDI::~EDI() { } -void EDI::add_udp_destination(const std::string& host, unsigned int port) +void EDI::add_udp_destination(const string& host, unsigned int port)  {      auto dest = make_shared<edi::udp_destination_t>();      dest->dest_addr = host; @@ -154,7 +155,7 @@ void EDI::add_udp_destination(const std::string& host, unsigned int port)      // TODO make FEC configurable  } -void EDI::add_tcp_destination(const std::string& host, unsigned int port) +void EDI::add_tcp_destination(const string& host, unsigned int port)  {      auto dest = make_shared<edi::tcp_client_t>();      dest->dest_addr = host; @@ -172,10 +173,22 @@ bool EDI::enabled() const      return not m_edi_conf.destinations.empty();  } -void EDI::set_tist(bool enable, uint32_t delay_ms) +void EDI::set_tist(bool enable, uint32_t delay_ms, const chrono::system_clock::time_point& ts)  {      m_tist = enable;      m_delay_ms = delay_ms; + +    const auto ts_with_delay = ts + chrono::milliseconds(m_delay_ms); + +    const auto ts_s = chrono::time_point_cast<chrono::seconds>(ts_with_delay); +    const auto remainder = ts_with_delay - ts_s; +    if (remainder < chrono::milliseconds(0)) { +        throw logic_error("EDI::set_tist remainder duration negative!"); +    } +    const uint32_t remainder_ms = chrono::duration_cast<chrono::milliseconds>(remainder).count(); + +    m_edi_time = chrono::system_clock::to_time_t(ts_s); +    m_timestamp += remainder_ms << 14; // Shift ms by 14 to Timestamp level 2  }  bool EDI::write_frame(const uint8_t *buf, size_t len) @@ -184,33 +197,11 @@ bool EDI::write_frame(const uint8_t *buf, size_t len)          m_edi_sender = make_shared<edi::Sender>(m_edi_conf);      } -    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); -        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. -         */ -        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 = 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_num_seconds_sent++; -    } -      m_edi_tagDSTI.set_edi_time(m_edi_time, m_clock_tai.get_offset());      m_edi_tagDSTI.tsta = m_timestamp & 0xffffff; @@ -231,8 +222,10 @@ bool EDI::write_frame(const uint8_t *buf, size_t len)  #else      PACKAGE_VERSION;  #endif -    edi::TagODRVersion edi_tagVersion(ss.str(), m_num_seconds_sent); +    // We always send in 24ms interval +    const size_t num_seconds_sent = m_num_frames_sent * 1000 / 24; +    edi::TagODRVersion edi_tagVersion(ss.str(), num_seconds_sent);      // The above Tag Items will be assembled into a TAG Packet      edi::TagPacket edi_tagpacket(m_edi_conf.tagpacket_alignment); @@ -244,13 +237,15 @@ bool EDI::write_frame(const uint8_t *buf, size_t len)      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; +    if (m_time_last_version_sent + chrono::seconds(10) < chrono::steady_clock::now()) { +        m_time_last_version_sent += chrono::seconds(10);          edi_tagpacket.tag_items.push_back(&edi_tagVersion);      }      m_edi_sender->write(edi_tagpacket); +    m_num_frames_sent++; +      // TODO Handle TCP disconnect      return true;  } | 
