summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/fig/FIG0.cpp92
-rw-r--r--src/fig/FIG0.h29
-rw-r--r--src/fig/FIGCarousel.cpp12
-rw-r--r--src/fig/FIGCarousel.h1
4 files changed, 129 insertions, 5 deletions
diff --git a/src/fig/FIG0.cpp b/src/fig/FIG0.cpp
index bc63742..48c2b4b 100644
--- a/src/fig/FIG0.cpp
+++ b/src/fig/FIG0.cpp
@@ -577,6 +577,98 @@ FillStatus FIG0_3::fill(uint8_t *buf, size_t max_size)
return fs;
}
+//=========== FIG 0/5 ===========
+
+FIG0_5::FIG0_5(FIGRuntimeInformation *rti) :
+ m_rti(rti),
+ m_initialised(false)
+{
+}
+
+FillStatus FIG0_5::fill(uint8_t *buf, size_t max_size)
+{
+ FillStatus fs;
+ ssize_t remaining = max_size;
+ auto ensemble = m_rti->ensemble;
+
+ if (not m_initialised) {
+ componentFIG0_5 = m_rti->ensemble->components.end();
+ m_initialised = true;
+ }
+
+ FIGtype0* fig0 = NULL;
+
+ for (; componentFIG0_5 != ensemble->components.end();
+ ++componentFIG0_5) {
+
+ auto service = getService(*componentFIG0_5,
+ ensemble->services);
+ auto subchannel = getSubchannel(ensemble->subchannels,
+ (*componentFIG0_5)->subchId);
+
+ if (subchannel == ensemble->subchannels.end()) {
+ etiLog.log(error,
+ "Subchannel %i does not exist for component "
+ "of service %i\n",
+ (*componentFIG0_5)->subchId,
+ (*componentFIG0_5)->serviceId);
+ throw MuxInitException();
+ }
+
+ if ( (*service)->language == 0) {
+ etiLog.level(debug) << "FIG0_5 no lang";
+ continue;
+ }
+
+ etiLog.level(debug) << "FIG0_5 " << (*componentFIG0_5)->uid;
+
+ const int required_size = 2;
+
+ if (fig0 == NULL) {
+ if (remaining < 2 + required_size) {
+ etiLog.level(debug) << "FIG0_5 no space for header";
+ break;
+ }
+ fig0 = (FIGtype0*)buf;
+ fig0->FIGtypeNumber = 0;
+ fig0->Length = 1;
+ fig0->CN = 0;
+ fig0->OE = 0;
+ fig0->PD = 0;
+ fig0->Extension = 5;
+
+ buf += 2;
+ remaining -= 2;
+ }
+ else if (remaining < required_size) {
+ etiLog.level(debug) << "FIG0_5 no space";
+ break;
+ }
+
+ FIGtype0_5_short *fig0_5 = (FIGtype0_5_short*)buf;
+
+ fig0_5->LS = 0;
+ fig0_5->rfu = 0;
+ fig0_5->SubChId = (*subchannel)->id;
+ fig0_5->language = (*service)->language;
+
+ fig0->Length += 2;
+ buf += 2;
+ remaining -= 2;
+ }
+
+ etiLog.level(debug) << "FIG0_5 out";
+
+ if (componentFIG0_5 == ensemble->components.end()) {
+ componentFIG0_5 = ensemble->components.begin();
+ fs.complete_fig_transmitted = true;
+ etiLog.level(debug) << "FIG0_5 complete";
+ }
+
+ fs.num_bytes_written = max_size - remaining;
+ return fs;
+}
+
//=========== FIG 0/8 ===========
FIG0_8::FIG0_8(FIGRuntimeInformation *rti) :
diff --git a/src/fig/FIG0.h b/src/fig/FIG0.h
index 64d376d..95a8a85 100644
--- a/src/fig/FIG0.h
+++ b/src/fig/FIG0.h
@@ -114,6 +114,28 @@ class FIG0_3 : public IFIG
std::vector<DabComponent*>::iterator componentFIG0_3;
};
+// FIG type 0/5
+// The service component language feature is used to signal a language
+// associated with a service component; the spoken language of an audio
+// component or the language of the content of a data component. This
+// information can be used for user selection or display. The feature is
+// encoded in Extension 5 of FIG type 0 (FIG 0/5).
+class FIG0_5 : public IFIG
+{
+ public:
+ FIG0_5(FIGRuntimeInformation* rti);
+ virtual FillStatus fill(uint8_t *buf, size_t max_size);
+ virtual FIG_rate repetition_rate(void) { return FIG_rate::B; }
+
+ virtual const int figtype(void) const { return 0; }
+ virtual const int figextension(void) const { return 5; }
+
+ private:
+ FIGRuntimeInformation *m_rti;
+ bool m_initialised;
+ std::vector<DabComponent*>::iterator componentFIG0_5;
+};
+
// FIG type 0/8
// The Extension 8 of FIG type 0 (FIG 0/8) provides information to link
// together the service component description that is valid within the ensemble
@@ -371,6 +393,13 @@ struct FIGtype0_3 {
}
} PACKED;
+struct FIGtype0_5_short {
+ uint8_t SubChId:6;
+ uint8_t rfu:1;
+ uint8_t LS:1;
+
+ uint8_t language;
+} PACKED;
struct FIGtype0_8_short {
uint8_t SCIdS:4;
diff --git a/src/fig/FIGCarousel.cpp b/src/fig/FIGCarousel.cpp
index 20b3412..cbea12b 100644
--- a/src/fig/FIGCarousel.cpp
+++ b/src/fig/FIGCarousel.cpp
@@ -63,6 +63,7 @@ FIGCarousel::FIGCarousel(std::shared_ptr<dabEnsemble> ensemble) :
m_fig0_1(&m_rti),
m_fig0_2(&m_rti),
m_fig0_3(&m_rti),
+ m_fig0_5(&m_rti),
m_fig0_17(&m_rti),
m_fig0_8(&m_rti),
m_fig1_0(&m_rti),
@@ -76,7 +77,7 @@ FIGCarousel::FIGCarousel(std::shared_ptr<dabEnsemble> ensemble) :
m_fig0_19(&m_rti)
{
/* Complete MCI except FIG0/8 should be in FIB0.
- * EN 300 401 Clause 6.1
+ * EN 300 401 V1.4.1 Clause 6.1
*
* It seems that this has become a weak requirement
* with time, because current receivers can cope with
@@ -85,18 +86,19 @@ FIGCarousel::FIGCarousel(std::shared_ptr<dabEnsemble> ensemble) :
* and pushed for support for receivers that only could
* decode FIB0.
*
- * In order to alleviate repetition rate issues,
- * this requirement has been dropped.
+ * V2.1.1 of the spec drops this requirement. Only FIG0/0 and
+ * FIG 0/7 have a defined location in the FIC.
*/
load_and_allocate(m_fig0_0, FIBAllocation::FIB0);
load_and_allocate(m_fig0_1, FIBAllocation::FIB_ANY);
load_and_allocate(m_fig0_2, FIBAllocation::FIB_ANY);
load_and_allocate(m_fig0_3, FIBAllocation::FIB_ANY);
+ load_and_allocate(m_fig0_5, FIBAllocation::FIB_ANY);
+ load_and_allocate(m_fig0_8, FIBAllocation::FIB_ANY);
+ load_and_allocate(m_fig0_13, FIBAllocation::FIB_ANY);
load_and_allocate(m_fig0_17, FIBAllocation::FIB_ANY);
- load_and_allocate(m_fig0_8, FIBAllocation::FIB_ANY);
load_and_allocate(m_fig1_0, FIBAllocation::FIB_ANY);
- load_and_allocate(m_fig0_13, FIBAllocation::FIB_ANY);
load_and_allocate(m_fig0_10, FIBAllocation::FIB_ANY);
load_and_allocate(m_fig0_9, FIBAllocation::FIB_ANY);
diff --git a/src/fig/FIGCarousel.h b/src/fig/FIGCarousel.h
index 583ac39..67772a6 100644
--- a/src/fig/FIGCarousel.h
+++ b/src/fig/FIGCarousel.h
@@ -91,6 +91,7 @@ class FIGCarousel {
FIG0_1 m_fig0_1;
FIG0_2 m_fig0_2;
FIG0_3 m_fig0_3;
+ FIG0_5 m_fig0_5;
FIG0_17 m_fig0_17;
FIG0_8 m_fig0_8;
FIG1_0 m_fig1_0;