aboutsummaryrefslogtreecommitdiffstats
path: root/src/fig/FIG0_21.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/fig/FIG0_21.cpp')
-rw-r--r--src/fig/FIG0_21.cpp195
1 files changed, 130 insertions, 65 deletions
diff --git a/src/fig/FIG0_21.cpp b/src/fig/FIG0_21.cpp
index a89a8a7..51b4a0d 100644
--- a/src/fig/FIG0_21.cpp
+++ b/src/fig/FIG0_21.cpp
@@ -37,45 +37,21 @@ FIG0_21::FIG0_21(FIGRuntimeInformation *rti) :
FillStatus FIG0_21::fill(uint8_t *buf, size_t max_size)
{
FillStatus fs;
- ssize_t remaining = max_size;
+ size_t remaining = max_size;
auto ensemble = m_rti->ensemble;
if (not m_initialised) {
- freqListEntryFIG0_21 = ensemble->frequency_information.begin();
+ freqInfoFIG0_21 = ensemble->frequency_information.begin();
m_initialised = true;
}
FIGtype0* fig0 = nullptr;
- for (; freqListEntryFIG0_21 != ensemble->frequency_information.end();
- ++freqListEntryFIG0_21) {
+ for (; freqInfoFIG0_21 != ensemble->frequency_information.end();
+ ++freqInfoFIG0_21) {
- size_t num_list_entries_that_fit = 0;
size_t required_size = sizeof(struct FIGtype0_21_header);
- size_t list_entry_size = sizeof(FIGtype0_21_fi_list_header);
- switch ((*freqListEntryFIG0_21)->rm) {
- case RangeModulation::dab_ensemble:
- list_entry_size += (*freqListEntryFIG0_21)->fi_dab.frequencies.size() * 3;
- break;
- case RangeModulation::fm_with_rds:
- list_entry_size += (*freqListEntryFIG0_21)->fi_fm.frequencies.size() * 3;
- break;
- case RangeModulation::amss:
- list_entry_size += 1; // Id field 2
- list_entry_size += (*freqListEntryFIG0_21)->fi_amss.frequencies.size() * 3;
- break;
- case RangeModulation::drm:
- list_entry_size += 1; // Id field 2
- list_entry_size += (*freqListEntryFIG0_21)->fi_drm.frequencies.size() * 3;
- break;
- }
- required_size += list_entry_size;
-
- etiLog.level(debug) << "FIG0/21 " << num_list_entries_that_fit << " entries"
- "will fit";
-
-
if (fig0 == nullptr) {
if (remaining < 2 + required_size) {
break;
@@ -83,8 +59,10 @@ FillStatus FIG0_21::fill(uint8_t *buf, size_t max_size)
fig0 = (FIGtype0*)buf;
fig0->FIGtypeNumber = 0;
fig0->Length = 1;
+
+ // Database start or continuation flag, EN 300 401 Clause 5.2.2.1 part b)
fig0->CN =
- (freqListEntryFIG0_21 == ensemble->frequency_information.begin() ? 0 : 1);
+ (freqInfoFIG0_21 == ensemble->frequency_information.begin() ? 0 : 1);
fig0->OE = 0;
fig0->PD = false;
fig0->Extension = 21;
@@ -92,49 +70,136 @@ FillStatus FIG0_21::fill(uint8_t *buf, size_t max_size)
buf += 2;
remaining -= 2;
}
- else if (remaining < required_size) {
- break;
- }
- auto *fig0_21_header = (FIGtype0_21_header*)buf;
- switch ((*freqListEntryFIG0_21)->rm) {
- case RangeModulation::dab_ensemble:
- fig0_21_header->length_fi = (*freqListEntryFIG0_21)->fi_dab.frequencies.size();
- break;
- case RangeModulation::fm_with_rds:
- fig0_21_header->length_fi = (*freqListEntryFIG0_21)->fi_fm.frequencies.size();
- break;
- case RangeModulation::drm:
- fig0_21_header->length_fi = (*freqListEntryFIG0_21)->fi_drm.frequencies.size();
- break;
- case RangeModulation::amss:
- fig0_21_header->length_fi = (*freqListEntryFIG0_21)->fi_amss.frequencies.size();
- break;
+ if (remaining < required_size) {
+ break;
}
- fig0_21_header->rfa = 0;
-#error "Why do we have lists of FI lists? This is confusing"
-
- switch ((*freqListEntryFIG0_21)->rm) {
- case RangeModulation::dab_ensemble:
- for (const auto& freq : (*freqListEntryFIG0_21)->fi_dab.frequencies) {
+ for (const auto& fle : (*freqInfoFIG0_21)->frequency_information) {
+ size_t list_entry_size = sizeof(FIGtype0_21_fi_list_header);
+ switch (fle.rm) {
+ case RangeModulation::dab_ensemble:
+ list_entry_size += fle.fi_dab.frequencies.size() * 3;
+ break;
+ case RangeModulation::fm_with_rds:
+ list_entry_size += fle.fi_fm.frequencies.size() * 3;
+ break;
+ case RangeModulation::amss:
+ list_entry_size += 1; // Id field 2
+ list_entry_size += fle.fi_amss.frequencies.size() * 3;
+ break;
+ case RangeModulation::drm:
+ list_entry_size += 1; // Id field 2
+ list_entry_size += fle.fi_drm.frequencies.size() * 3;
+ break;
+ }
- }
- break;
- case RangeModulation::fm_with_rds:
- break;
- case RangeModulation::drm:
- break;
- case RangeModulation::amss:
+ if (remaining < list_entry_size) {
break;
- }
+ }
- fig0->Length += sizeof(struct FIGtype0_21_header);
- buf += sizeof(struct FIGtype0_21_header);
- remaining -= sizeof(struct FIGtype0_21_header);
- }
+ auto *fig0_21_header = (FIGtype0_21_header*)buf;
+ fig0_21_header->rfa = 0; // This was RegionId in EN 300 401 V1.4.1
+ switch (fle.rm) {
+ case RangeModulation::dab_ensemble:
+ fig0_21_header->length_fi = fle.fi_dab.frequencies.size();
+ break;
+ case RangeModulation::fm_with_rds:
+ fig0_21_header->length_fi = fle.fi_fm.frequencies.size();
+ break;
+ case RangeModulation::drm:
+ fig0_21_header->length_fi = fle.fi_drm.frequencies.size();
+ break;
+ case RangeModulation::amss:
+ fig0_21_header->length_fi = fle.fi_amss.frequencies.size();
+ break;
+ }
+
+ fig0->Length += sizeof(struct FIGtype0_21_header);
+ buf += sizeof(struct FIGtype0_21_header);
+ remaining -= sizeof(struct FIGtype0_21_header);
+
+ auto *fi_list_header = (FIGtype0_21_fi_list_header*)buf;
+ fig0->Length += sizeof(struct FIGtype0_21_fi_list_header);
+ buf += sizeof(struct FIGtype0_21_fi_list_header);
+ remaining -= sizeof(struct FIGtype0_21_fi_list_header);
+
+ fi_list_header->continuity = fle.continuity;
+
+ switch (fle.rm) {
+ case RangeModulation::dab_ensemble:
+ fi_list_header->id = fle.fi_dab.eid;
+ fi_list_header->range_modulation = static_cast<uint8_t>(fle.rm);
+ assert(fle.fi_dab.frequencies.size() < 8);
+ fi_list_header->length_freq_list = fle.fi_dab.frequencies.size();
+
+ for (const auto& freq : fle.fi_dab.frequencies) {
+ auto *field = (FIGtype0_21_fi_dab_entry*)buf;
+ field->control_field = static_cast<uint8_t>(freq.control_field);
+ field->setFreq(static_cast<uint32_t>(
+ freq.frequency * 1000.0f / 16.0f));
+
+ fig0->Length += 3;
+ buf += 3;
+ remaining -= 3;
+ }
+ break;
+ case RangeModulation::fm_with_rds:
+ fi_list_header->id = fle.fi_fm.pi_code;
+
+ for (const auto& freq : fle.fi_fm.frequencies) {
+ // RealFreq = 87.5 MHz + (F * 100kHz)
+ // => F = (RealFreq - 87.5 MHz) / 100kHz
+ // Do the whole calculation in kHz:
+ *buf = (freq * 1000.0f - 87500.0f) / 100.0f;
+ fig0->Length += 1;
+ buf += 1;
+ remaining -= 1;
+ }
+ break;
+ case RangeModulation::drm:
+ fi_list_header->id = (fle.fi_drm.drm_service_id) & 0xFFFF;
+
+ // Id field 2
+ *buf = (fle.fi_drm.drm_service_id >> 16) & 0xFF;
+ fig0->Length += 1;
+ buf += 1;
+ remaining -= 1;
+
+ for (const auto& freq : fle.fi_drm.frequencies) {
+ uint16_t *freq_field = (uint16_t*)buf;
+
+ *freq_field = static_cast<uint16_t>(freq * 1000.0f);
+
+ fig0->Length += 2;
+ buf += 2;
+ remaining -= 2;
+ }
+ break;
+ case RangeModulation::amss:
+ fi_list_header->id = (fle.fi_amss.amss_service_id) & 0xFFFF;
+
+ // Id field 2
+ *buf = (fle.fi_amss.amss_service_id >> 16) & 0xFF;
+ fig0->Length += 1;
+ buf += 1;
+ remaining -= 1;
+
+ for (const auto& freq : fle.fi_amss.frequencies) {
+ uint16_t *freq_field = (uint16_t*)buf;
+
+ *freq_field = static_cast<uint16_t>(freq * 1000.0f);
+
+ fig0->Length += 2;
+ buf += 2;
+ remaining -= 2;
+ }
+ break;
+ }
+ } // for over fle
+ } // for over FI
- if (freqListEntryFIG0_21 == ensemble->frequency_information.end()) {
+ if (freqInfoFIG0_21 == ensemble->frequency_information.end()) {
fs.complete_fig_transmitted = true;
}