From c4d841b4901563e38f705f62860d6214da53a689 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Mon, 8 Apr 2024 15:26:06 +0200 Subject: Clean up FIG carousel a bit --- src/fig/FIGCarousel.cpp | 82 +++++++++++++++++++++++++++---------------------- 1 file changed, 46 insertions(+), 36 deletions(-) (limited to 'src/fig/FIGCarousel.cpp') diff --git a/src/fig/FIGCarousel.cpp b/src/fig/FIGCarousel.cpp index 4c5c04c..9748dbf 100644 --- a/src/fig/FIGCarousel.cpp +++ b/src/fig/FIGCarousel.cpp @@ -3,7 +3,7 @@ 2011, 2012 Her Majesty the Queen in Right of Canada (Communications Research Center Canada) - Copyright (C) 2020 + Copyright (C) 2024 Matthias P. Braendli, matthias.braendli@mpb.li Implementation of the FIG carousel to schedule the FIGs into the @@ -148,11 +148,14 @@ void FIGCarousel::load_and_allocate(IFIG& fig, FIBAllocation fib) m_fibs[fib].push_back(el); } -void FIGCarousel::update(unsigned long currentFrame) +size_t FIGCarousel::write_fibs( + uint8_t *buf, + uint64_t current_frame, + bool fib3_present) { - m_rti.currentFrame = currentFrame; + m_rti.currentFrame = current_frame; - if ((currentFrame % 250) == 0 and m_missed_deadlines.size() > 0) { + if ((current_frame % 250) == 0 and m_missed_deadlines.size() > 0) { std::stringstream ss; for (const auto& fig_missed_count : m_missed_deadlines) { ss << " " << fig_missed_count; @@ -161,21 +164,7 @@ void FIGCarousel::update(unsigned long currentFrame) etiLog.level(info) << "Could not respect repetition rates for FIGs:" << ss.str(); } -} - -void dumpfib(const uint8_t *buf, size_t bufsize) { - std::cerr << "FIB "; - for (size_t i = 0; i < bufsize; i++) { - std::cerr << boost::format("%02x ") % (unsigned int)buf[i]; - } - std::cerr << std::endl; -} -size_t FIGCarousel::write_fibs( - uint8_t *buf, - int framephase, - bool fib3_present) -{ /* Decrement all deadlines of all figs */ for (auto& fib_fig : m_fibs) { auto& fig = fib_fig.second; @@ -183,6 +172,9 @@ size_t FIGCarousel::write_fibs( fig_el.reduce_deadline(); if (fig_el.deadline < 0) { +#if CAROUSELDEBUG + etiLog.level(warn) << " FIG" << fig_el.fig->name() << " LATE"; +#endif m_missed_deadlines.insert(fig_el.fig->name()); } } @@ -192,7 +184,7 @@ size_t FIGCarousel::write_fibs( for (int fib = 0; fib < fibCount; fib++) { memset(buf, 0x00, 30); - size_t figSize = carousel(fib, buf, 30, framephase); + size_t figSize = carousel(fib, buf, 30, current_frame); if (figSize < 30) { buf[figSize] = 0xff; // end marker @@ -219,8 +211,10 @@ size_t FIGCarousel::carousel( int fib, uint8_t *buf, const size_t bufsize, - int framephase) + uint64_t current_frame) { + const int framephase = current_frame % 4; + uint8_t *pbuf = buf; FIBAllocation fibix; @@ -253,9 +247,10 @@ size_t FIGCarousel::carousel( for (auto& fig : sorted_figs) { if (fig->check_deadline()) { #if CAROUSELDEBUG - std::cerr << " FIG" << fig->fig->figtype() << "/" << - fig->fig->figextension() << " deadline changed" << - std::endl; + etiLog.level(debug) << + "FRAME " << current_frame << + " FIG" << fig->fig->figtype() << "/" << + fig->fig->figextension() << " deadline changed"; #endif } } @@ -267,12 +262,18 @@ size_t FIGCarousel::carousel( return left->deadline < right->deadline; }); -#if CAROUSELDEBUG - std::cerr << " ************** FIGs" << std::endl; - for (auto& f : sorted_figs) { - std::cerr << " FIG" << f->fig->figtype() << "/" << - f->fig->figextension() << " deadline " << - f->deadline << std::endl; +#if 0 + { + std::stringstream ss; + ss << "FRAME " << current_frame + << " sorted FIGs "; + + for (auto& f : sorted_figs) { + ss << f->fig->figtype() << "/" << + f->fig->figextension() << "(" << + f->deadline << ") "; + } + etiLog.level(debug) << ss.str(); } #endif @@ -301,8 +302,9 @@ size_t FIGCarousel::carousel( pbuf += written; #if CAROUSELDEBUG - std::cerr << " ****** FIG0/0(special) wrote\t" << written << " bytes" - << std::endl; + etiLog.level(debug) << + "FRAME " << current_frame << + " *** FIG0/0(special) wrote\t" << written << " bytes"; #endif } else { @@ -325,8 +327,9 @@ size_t FIGCarousel::carousel( pbuf += written; #if CAROUSELDEBUG - std::cerr << " ****** FIG0/7(special) wrote\t" << written << " bytes" - << std::endl; + etiLog.level(debug) << + "FRAME " << current_frame << + " ****** FIG0/7(special) wrote\t" << written << " bytes"; #endif } @@ -376,13 +379,14 @@ size_t FIGCarousel::carousel( } #if CAROUSELDEBUG if (written) { - std::cerr << + etiLog.level(debug) << + " FRAME " << current_frame << " ** FIB" << fib << " FIG" << fig_el->fig->figtype() << "/" << fig_el->fig->figextension() << " wrote\t" << written << " bytes" << (status.complete_fig_transmitted ? ", complete" : ", incomplete") << - std::endl; + ", margin " << fig_el->deadline; } #endif @@ -393,7 +397,13 @@ size_t FIGCarousel::carousel( sorted_figs.pop_front(); } - //dumpfib(buf, bufsize); +#if 0 + std::cerr << "FIB "; + for (size_t i = 0; i < bufsize; i++) { + std::cerr << boost::format("%02x ") % (unsigned int)buf[i]; + } + std::cerr << std::endl; +#endif return bufsize - available_size; } -- cgit v1.2.3 From 103841bc578888a828d176eddfdd9fa345549f03 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Wed, 23 Apr 2025 11:18:08 +0200 Subject: Rework FIG0/10 DAB time indication to match EDI time --- src/DabMultiplexer.cpp | 24 ++++++++++++++++-------- src/DabMultiplexer.h | 6 ++---- src/fig/FIG.h | 10 +++++++++- src/fig/FIG0_10.cpp | 11 +++++------ src/fig/FIGCarousel.cpp | 7 +++++-- src/fig/FIGCarousel.h | 4 +++- src/utils.cpp | 24 +----------------------- src/utils.h | 6 +----- 8 files changed, 42 insertions(+), 50 deletions(-) (limited to 'src/fig/FIGCarousel.cpp') diff --git a/src/DabMultiplexer.cpp b/src/DabMultiplexer.cpp index 58e0f9b..e6e6782 100644 --- a/src/DabMultiplexer.cpp +++ b/src/DabMultiplexer.cpp @@ -100,9 +100,11 @@ uint64_t MuxTime::init(uint32_t tist_at_fct0_us) return currentFrame; } +constexpr int TIMESTAMP_LEVEL_2_SHIFT = 14; + void MuxTime::increment_timestamp() { - m_timestamp += 24 << 14; // Shift 24ms by 14 to Timestamp level 2 + m_timestamp += 24 << TIMESTAMP_LEVEL_2_SHIFT; // Shift 24ms by 14 to Timestamp level 2 if (m_timestamp > 0xf9FFff) { m_timestamp -= 0xfa0000; // Subtract 16384000, corresponding to one second m_edi_time += 1; @@ -112,10 +114,10 @@ void MuxTime::increment_timestamp() } } -std::pair MuxTime::get_time() +std::pair MuxTime::get_tist_seconds() { // The user-visible configuration tist_offset is the effective - // offset, but since we implicityle add the tist_at_fct0 to it, + // offset, but since we implicitly add the tist_at_fct0 to it, // we must compensate. double corrected_tist_offset = tist_offset - (m_tist_at_fct0_us / 1e6); @@ -124,7 +126,7 @@ std::pair MuxTime::get_time() double fractional_part = corrected_tist_offset - std::floor(corrected_tist_offset); const size_t steps = std::lround(std::floor(fractional_part / 24e-3)); - uint32_t timestamp = m_timestamp + (24 << 14) * steps; + uint32_t timestamp = m_timestamp + (24 << TIMESTAMP_LEVEL_2_SHIFT) * steps; std::time_t edi_time = m_edi_time + std::lround(std::floor(corrected_tist_offset)); @@ -135,13 +137,20 @@ std::pair MuxTime::get_time() return {timestamp % 0xfa0000, edi_time}; } +std::pair MuxTime::get_milliseconds_seconds() +{ + auto tist_seconds = get_tist_seconds(); + return {tist_seconds.first >> TIMESTAMP_LEVEL_2_SHIFT, tist_seconds.second}; +} + DabMultiplexer::DabMultiplexer(boost::property_tree::ptree pt) : RemoteControllable("mux"), m_pt(pt), + m_time(), ensemble(std::make_shared()), m_clock_tai(split_pipe_separated_string(pt.get("general.tai_clock_bulletins", ""))), - fig_carousel(ensemble) + fig_carousel(ensemble, [&]() { return m_time.get_milliseconds_seconds(); }) { RC_ADD_PARAMETER(frames, "Show number of frames generated [read-only]"); RC_ADD_PARAMETER(tist_offset, "Timestamp offset in fractional number of seconds"); @@ -197,7 +206,7 @@ void DabMultiplexer::prepare(bool require_tai_clock) bool tist_enabled = m_pt.get("general.tist", false); m_time.tist_offset = m_pt.get("general.tist_offset", 0.0); - auto tist_edi_time = m_time.get_time(); + auto tist_edi_time = m_time.get_tist_seconds(); const auto timestamp = tist_edi_time.first; const auto edi_time = tist_edi_time.second; m_time.mnsc_time = edi_time; @@ -474,9 +483,8 @@ void DabMultiplexer::mux_frame(std::vector >& outputs etiLog.level(error) << "Could not get UTC-TAI offset for EDI timestamp"; } } - update_dab_time(); - auto tist_edi_time = m_time.get_time(); + auto tist_edi_time = m_time.get_tist_seconds(); const auto timestamp = tist_edi_time.first; const auto edi_time = tist_edi_time.second; diff --git a/src/DabMultiplexer.h b/src/DabMultiplexer.h index bbb4bde..5a0d906 100644 --- a/src/DabMultiplexer.h +++ b/src/DabMultiplexer.h @@ -50,7 +50,8 @@ class MuxTime { uint32_t m_tist_at_fct0_us = 0; public: - std::pair get_time(); + std::pair get_tist_seconds(); + std::pair get_milliseconds_seconds(); double tist_offset = 0; @@ -81,8 +82,6 @@ class DabMultiplexer : public RemoteControllable { void prepare(bool require_tai_clock); - uint64_t getCurrentFrame() const { return currentFrame; } - void mux_frame(std::vector >& outputs); void print_info(void); @@ -116,6 +115,5 @@ class DabMultiplexer : public RemoteControllable { bool m_tai_clock_required = false; ClockTAI m_clock_tai; - /* New FIG Carousel */ FIC::FIGCarousel fig_carousel; }; diff --git a/src/fig/FIG.h b/src/fig/FIG.h index 9752245..eda4671 100644 --- a/src/fig/FIG.h +++ b/src/fig/FIG.h @@ -35,11 +35,19 @@ namespace FIC { class FIGRuntimeInformation { public: - FIGRuntimeInformation(std::shared_ptr& e) : + + using dab_time_t = std::pair; + using get_time_func_t = std::function; + + FIGRuntimeInformation( + std::shared_ptr& e, + get_time_func_t getTimeFunc) : + getTimeFunc(getTimeFunc), currentFrame(0), ensemble(e), factumAnalyzer(false) {} + get_time_func_t getTimeFunc; unsigned long currentFrame; std::shared_ptr ensemble; bool factumAnalyzer; diff --git a/src/fig/FIG0_10.cpp b/src/fig/FIG0_10.cpp index 56ce9fb..240aa19 100644 --- a/src/fig/FIG0_10.cpp +++ b/src/fig/FIG0_10.cpp @@ -3,7 +3,7 @@ 2011, 2012 Her Majesty the Queen in Right of Canada (Communications Research Center Canada) - Copyright (C) 2016 + Copyright (C) 2025 Matthias P. Braendli, matthias.braendli@mpb.li */ /* @@ -23,7 +23,6 @@ along with ODR-DabMux. If not, see . */ -#include "fig/FIG0structs.h" #include "fig/FIG0_10.h" #include "utils.h" @@ -89,7 +88,7 @@ FillStatus FIG0_10::fill(uint8_t *buf, size_t max_size) return fs; } - //Time and country identifier + // Time and country identifier auto fig0_10 = (FIGtype0_10_LongForm*)buf; fig0_10->FIGtypeNumber = 0; @@ -102,9 +101,9 @@ FillStatus FIG0_10::fill(uint8_t *buf, size_t max_size) remaining -= 2; struct tm timeData; - time_t dab_time_seconds = 0; - uint32_t dab_time_millis = 0; - get_dab_time(&dab_time_seconds, &dab_time_millis); + const auto dab_time = m_rti->getTimeFunc(); + time_t dab_time_seconds = dab_time.second; + uint32_t dab_time_millis = dab_time.first; gmtime_r(&dab_time_seconds, &timeData); fig0_10->RFU = 0; diff --git a/src/fig/FIGCarousel.cpp b/src/fig/FIGCarousel.cpp index 9748dbf..ceda275 100644 --- a/src/fig/FIGCarousel.cpp +++ b/src/fig/FIGCarousel.cpp @@ -68,8 +68,11 @@ bool FIGCarouselElement::check_deadline() /**************** FIGCarousel *****************/ -FIGCarousel::FIGCarousel(std::shared_ptr ensemble) : - m_rti(ensemble), +FIGCarousel::FIGCarousel( + std::shared_ptr ensemble, + FIGRuntimeInformation::get_time_func_t getTimeFunc + ) : + m_rti(ensemble, getTimeFunc), m_fig0_0(&m_rti), m_fig0_1(&m_rti), m_fig0_2(&m_rti), diff --git a/src/fig/FIGCarousel.h b/src/fig/FIGCarousel.h index 1e33577..a2a8022 100644 --- a/src/fig/FIGCarousel.h +++ b/src/fig/FIGCarousel.h @@ -67,7 +67,9 @@ enum class FIBAllocation { class FIGCarousel { public: - FIGCarousel(std::shared_ptr ensemble); + FIGCarousel( + std::shared_ptr ensemble, + FIGRuntimeInformation::get_time_func_t getTimeFunc); /* Write all FIBs to the buffer, including correct padding and crc. * Returns number of bytes written. diff --git a/src/utils.cpp b/src/utils.cpp index 1a13caf..7ea6293 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -3,7 +3,7 @@ 2011, 2012 Her Majesty the Queen in Right of Canada (Communications Research Center Canada) - Copyright (C) 2021 + Copyright (C) 2025 Matthias P. Braendli, matthias.braendli@mpb.li http://www.opendigitalradio.org @@ -34,30 +34,8 @@ using namespace std; -static time_t dab_time_seconds = 0; -static int dab_time_millis = 0; - static void printServices(const vector >& services); -void update_dab_time() -{ - if (dab_time_seconds == 0) { - dab_time_seconds = time(nullptr); - } else { - dab_time_millis+= 24; - if (dab_time_millis >= 1000) { - dab_time_millis -= 1000; - ++dab_time_seconds; - } - } -} - -void get_dab_time(time_t *time, uint32_t *millis) -{ - *time = dab_time_seconds; - *millis = dab_time_millis; -} - uint32_t gregorian2mjd(int year, int month, int day) { diff --git a/src/utils.h b/src/utils.h index 331a0b2..d037bb3 100644 --- a/src/utils.h +++ b/src/utils.h @@ -3,7 +3,7 @@ 2011, 2012 Her Majesty the Queen in Right of Canada (Communications Research Center Canada) - Copyright (C) 2020 + Copyright (C) 2025 Matthias P. Braendli, matthias.braendli@mpb.li This file contains a set of utility functions that are used to show @@ -34,10 +34,6 @@ #include #include "MuxElements.h" -/* Must be called once per ETI frame to update the time */ -void update_dab_time(void); -void get_dab_time(time_t *time, uint32_t *millis); - /* Convert a date and time into the modified Julian date * used in FIG 0/10 * -- cgit v1.2.3