aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSamuel Hunt <sam@maxxwave.co.uk>2026-01-08 16:13:19 +0000
committerSamuel Hunt <sam@maxxwave.co.uk>2026-01-08 16:13:19 +0000
commitb084bd07570cd031cbba4cc0617418883d82a9c7 (patch)
tree4d27d6b4cf64aa03bf8b822280cb1208325f0ba3 /src
parent18398455642cf265995aa2988f1f3f610c6baf03 (diff)
downloaddabmux-b084bd07570cd031cbba4cc0617418883d82a9c7.tar.gz
dabmux-b084bd07570cd031cbba4cc0617418883d82a9c7.tar.bz2
dabmux-b084bd07570cd031cbba4cc0617418883d82a9c7.zip
Priority based FIC scheduler capable of >40 services
Diffstat (limited to 'src')
-rw-r--r--src/ConfigParser.cpp5
-rw-r--r--src/DabMultiplexer.cpp32
-rw-r--r--src/DabMultiplexer.h15
-rw-r--r--src/MuxElements.h2
-rw-r--r--src/utils.cpp3
5 files changed, 52 insertions, 5 deletions
diff --git a/src/ConfigParser.cpp b/src/ConfigParser.cpp
index 8f4052c..4e20dea 100644
--- a/src/ConfigParser.cpp
+++ b/src/ConfigParser.cpp
@@ -55,6 +55,7 @@
#include <memory>
#include <string>
#include <vector>
+#include "fig/FIGSchedulerType.h"
using namespace std;
using boost::property_tree::ptree;
@@ -532,6 +533,10 @@ static void parse_general(ptree& pt,
ensemble->reconfig_counter = pt_ensemble.get("reconfig-counter", ensemble->reconfig_counter);
}
+ // FIG scheduler type selection
+ std::string fic_scheduler_str = pt_general.get("fic-scheduler", "classic");
+ ensemble->fic_scheduler = FIC::parse_scheduler_type(fic_scheduler_str);
+
string lto_auto = pt_ensemble.get("local-time-offset", "");
if (lto_auto == "auto") {
ensemble->lto_auto = true;
diff --git a/src/DabMultiplexer.cpp b/src/DabMultiplexer.cpp
index 7a8ac97..32ed2b3 100644
--- a/src/DabMultiplexer.cpp
+++ b/src/DabMultiplexer.cpp
@@ -158,8 +158,7 @@ DabMultiplexer::DabMultiplexer(DabMultiplexerConfig& config) :
m_config(config),
m_time(),
ensemble(std::make_shared<dabEnsemble>()),
- m_clock_tai(split_pipe_separated_string(m_config.pt.get("general.tai_clock_bulletins", ""))),
- fig_carousel(ensemble, [&]() { return m_time.get_milliseconds_seconds(); })
+ m_clock_tai(split_pipe_separated_string(m_config.pt.get("general.tai_clock_bulletins", "")))
{
RC_ADD_PARAMETER(frames, "Show number of frames generated [read-only]");
RC_ADD_PARAMETER(tist_offset, "Configured tist-offset");
@@ -185,6 +184,20 @@ void DabMultiplexer::prepare(bool require_tai_clock)
{
parse_ptree(m_config.pt, ensemble);
+ /* Create the appropriate FIG carousel based on config.
+ * This must happen after parse_ptree() which sets ensemble->fic_scheduler
+ */
+ m_scheduler_type = ensemble->fic_scheduler;
+ auto time_func = [&]() { return m_time.get_milliseconds_seconds(); };
+
+ if (m_scheduler_type == FIC::FIGSchedulerType::Priority) {
+ etiLog.level(info) << "Using priority-based FIG scheduler";
+ m_fig_carousel_priority.reset(new FIC::FIGCarouselPriority(ensemble, time_func));
+ } else {
+ etiLog.level(info) << "Using classic FIG scheduler";
+ m_fig_carousel_classic.reset(new FIC::FIGCarousel(ensemble, time_func));
+ }
+
rcs.enrol(this);
rcs.enrol(ensemble.get());
@@ -489,6 +502,17 @@ void DabMultiplexer::reload_linkagesets()
}
}
+/* Helper method for FIG carousel write_fibs - abstracts the scheduler type */
+size_t DabMultiplexer::fig_carousel_write_fibs(uint8_t* buf, uint64_t current_frame, bool fib3_present)
+{
+ if (m_fig_carousel_priority) {
+ return m_fig_carousel_priority->write_fibs(buf, current_frame, fib3_present);
+ } else if (m_fig_carousel_classic) {
+ return m_fig_carousel_classic->write_fibs(buf, current_frame, fib3_present);
+ }
+ return 0;
+}
+
/* Each call creates one ETI frame */
void DabMultiplexer::mux_frame(std::vector<std::shared_ptr<DabOutput> >& outputs)
{
@@ -709,9 +733,9 @@ void DabMultiplexer::mux_frame(std::vector<std::shared_ptr<DabOutput> >& outputs
edi_tagDETI.fic_data = &etiFrame[index];
edi_tagDETI.fic_length = FICL * 4;
- // Insert all FIBs
+ // Insert all FIBs using the selected scheduler
const bool fib3_present = (ensemble->transmission_mode == TransmissionMode_e::TM_III);
- index += fig_carousel.write_fibs(&etiFrame[index], currentFrame, fib3_present);
+ index += fig_carousel_write_fibs(&etiFrame[index], currentFrame, fib3_present);
/**********************************************************************
****** Input Data Reading *******************************************
diff --git a/src/DabMultiplexer.h b/src/DabMultiplexer.h
index 620e65d..afb308f 100644
--- a/src/DabMultiplexer.h
+++ b/src/DabMultiplexer.h
@@ -32,6 +32,8 @@
#include "dabOutput/dabOutput.h"
#include "edioutput/Transport.h"
#include "fig/FIGCarousel.h"
+#include "fig/FIGCarouselPriority.h"
+#include "fig/FIGSchedulerType.h"
#include "MuxElements.h"
#include "RemoteControl.h"
#include "ClockTAI.h"
@@ -130,5 +132,16 @@ class DabMultiplexer : public RemoteControllable {
bool m_tai_clock_required = false;
ClockTAI m_clock_tai;
- FIC::FIGCarousel fig_carousel;
+ /* FIG Carousel - supports classic and priority schedulers
+ *
+ * Only one of these will be instantiated based on config.
+ * The scheduler type is determined by ensemble->fic_scheduler
+ * which is set during config parsing in prepare().
+ */
+ FIC::FIGSchedulerType m_scheduler_type = FIC::FIGSchedulerType::Classic;
+ std::unique_ptr<FIC::FIGCarousel> m_fig_carousel_classic;
+ std::unique_ptr<FIC::FIGCarouselPriority> m_fig_carousel_priority;
+
+ /* Helper method for FIG carousel write_fibs */
+ size_t fig_carousel_write_fibs(uint8_t* buf, uint64_t current_frame, bool fib3_present);
};
diff --git a/src/MuxElements.h b/src/MuxElements.h
index 8ba103f..ab05ce3 100644
--- a/src/MuxElements.h
+++ b/src/MuxElements.h
@@ -40,6 +40,7 @@
#include "dabOutput/dabOutput.h"
#include "input/inputs.h"
#include "RemoteControl.h"
+#include "fig/FIGSchedulerType.h" // For FIGSchedulerType enum
// Protection levels and bitrates for UEP.
const unsigned char ProtectionLevelTable[64] = {
@@ -410,6 +411,7 @@ class dabEnsemble : public RemoteControllable {
std::vector<std::shared_ptr<LinkageSet> > linkagesets;
std::vector<FrequencyInformation> frequency_information;
std::vector<ServiceOtherEnsembleInfo> service_other_ensemble;
+ FIC::FIGSchedulerType fic_scheduler = FIC::FIGSchedulerType::Classic;
vec_sp_sci sci_entries;
};
diff --git a/src/utils.cpp b/src/utils.cpp
index 7ea6293..127ba78 100644
--- a/src/utils.cpp
+++ b/src/utils.cpp
@@ -31,6 +31,7 @@
#include <boost/algorithm/string/join.hpp>
#include "utils.h"
#include "fig/FIG0structs.h"
+#include "fig/FIGSchedulerType.h"
using namespace std;
@@ -496,6 +497,8 @@ void printEnsemble(const shared_ptr<dabEnsemble>& ensemble)
break;
}
+ etiLog.level(info) << " FIC sched: " << FIC::scheduler_type_to_string(ensemble->fic_scheduler);
+
if (ensemble->lto_auto) {
time_t now = time(nullptr);
struct tm ltime;