Skip to content

Commit

Permalink
GTK: add support for alarm announcements
Browse files Browse the repository at this point in the history
Also derive EId from FIG 0/0 instead of 1/0.
  • Loading branch information
basicmaster committed Dec 7, 2022
1 parent 5557f3d commit 9a99ed9
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 9 deletions.
3 changes: 3 additions & 0 deletions README.md
Expand Up @@ -355,6 +355,9 @@ different subchannel leads to cyan highlighting instead e.g. if traffic
news of a different channel shall affect also listeners of a different
service (which does not have its own announcements).

The GTK version indicates an active alarm announcement on ensemble level
by the suffix "Alarm" after the ensemble label, highlighted in red.


### Hotkeys (GTK GUI version)

Expand Down
16 changes: 13 additions & 3 deletions src/dablin_gtk.cpp
Expand Up @@ -1076,20 +1076,30 @@ void DABlinGTK::FICChangeEnsembleEmitted() {
ensemble = fic_change_ensemble.Pop();

std::string charset_name;
std::string label = FICDecoder::ConvertLabelToUTF8(ensemble.label, &charset_name);
std::string label = Glib::Markup::escape_text(FICDecoder::ConvertLabelToUTF8(ensemble.label, &charset_name));

std::string tooltip_text =
"Short label: \"" + FICDecoder::DeriveShortLabelUTF8(label, ensemble.label.short_label_mask) + "\"\n"
"Label charset: " + charset_name + "\n"
"EId: " + StringTools::IntToHex(ensemble.eid, 4);
"EId: " + StringTools::IntToHex(ensemble.eid, 4) + "\n"
"Alarm flag: " + (ensemble.al_flag ? "true" : "false");
if(ensemble.ecc != FIC_ENSEMBLE::ecc_none)
tooltip_text += "\n" "ECC: " + StringTools::IntToHex(ensemble.ecc, 2);
if(ensemble.lto != FIC_ENSEMBLE::lto_none)
tooltip_text += "\n" "LTO: " + FICDecoder::ConvertLTOToString(ensemble.lto);
if(ensemble.inter_table_id != FIC_ENSEMBLE::inter_table_id_none)
tooltip_text += "\n" "International table ID: " + StringTools::IntToHex(ensemble.inter_table_id, 2) + " (" + FICDecoder::ConvertInterTableIDToString(ensemble.inter_table_id) + ")";

label_ensemble.set_label(label);
// indicate active alarm announcement
if(ensemble.al_flag) {
asw_clusters_t::const_iterator cl_it = ensemble.asw_clusters.find(0xFF);
if(cl_it != ensemble.asw_clusters.end() && (cl_it->second.asw_flags & 0x01)) {
label += " <span color='white' bgcolor='red'><b> Alarm </b></span>";
tooltip_text += "\n" "Alarm SubChId: " + std::to_string(cl_it->second.subchid);
}
}

label_ensemble.set_markup(label);
frame_label_ensemble.set_tooltip_text(tooltip_text);
}

Expand Down
33 changes: 28 additions & 5 deletions src/fic_decoder.cpp
@@ -1,6 +1,6 @@
/*
DABlin - capital DAB experience
Copyright (C) 2015-2020 Stefan Pöschel
Copyright (C) 2015-2022 Stefan Pöschel
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -87,6 +87,9 @@ void FICDecoder::ProcessFIG0(const uint8_t *data, size_t len) {

// handle extension
switch(header.extension) {
case 0:
ProcessFIG0_0(data, len);
break;
case 1:
ProcessFIG0_1(data, len);
break;
Expand Down Expand Up @@ -122,6 +125,27 @@ void FICDecoder::ProcessFIG0(const uint8_t *data, size_t len) {
}
}

void FICDecoder::ProcessFIG0_0(const uint8_t *data, size_t len) {
// FIG 0/0 - Ensemble information
// EId and alarm flag only

if(len < 4)
return;

FIC_ENSEMBLE new_ensemble = ensemble;
new_ensemble.eid = data[0] << 8 | data[1];
new_ensemble.al_flag = data[2] & 0x20;

if(ensemble != new_ensemble) {
ensemble = new_ensemble;

fprintf(stderr, "FICDecoder: EId 0x%04X: alarm flag: %s\n",
ensemble.eid, ensemble.al_flag ? "true" : "false");

UpdateEnsemble();
}
}

void FICDecoder::ProcessFIG0_1(const uint8_t *data, size_t len) {
// FIG 0/1 - Basic sub-channel organization

Expand Down Expand Up @@ -620,8 +644,7 @@ void FICDecoder::ProcessFIG1(const uint8_t *data, size_t len) {
}

void FICDecoder::ProcessFIG1_0(uint16_t eid, const FIC_LABEL& label) {
if(ensemble.eid != eid || ensemble.label != label) {
ensemble.eid = eid;
if(ensemble.label != label) {
ensemble.label = label;

std::string label_str = ConvertLabelToUTF8(label, nullptr);
Expand Down Expand Up @@ -777,8 +800,8 @@ int FICDecoder::GetSLSAppType(const ua_data_t& ua_data) {
}

void FICDecoder::UpdateEnsemble() {
// abort update, if label not yet present
if(ensemble.label.IsNone())
// abort update, if EId or label not yet present
if(ensemble.IsNone() || ensemble.label.IsNone())
return;

// forward to observer
Expand Down
6 changes: 5 additions & 1 deletion src/fic_decoder.h
@@ -1,6 +1,6 @@
/*
DABlin - capital DAB experience
Copyright (C) 2015-2020 Stefan Pöschel
Copyright (C) 2015-2022 Stefan Pöschel
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -145,6 +145,7 @@ struct FIC_DAB_DT {

struct FIC_ENSEMBLE {
int eid;
bool al_flag;
FIC_LABEL label;
int ecc;
int lto;
Expand All @@ -160,6 +161,7 @@ struct FIC_ENSEMBLE {

FIC_ENSEMBLE() :
eid(eid_none),
al_flag(false),
ecc(ecc_none),
lto(lto_none),
inter_table_id(inter_table_id_none)
Expand All @@ -168,6 +170,7 @@ struct FIC_ENSEMBLE {
bool operator==(const FIC_ENSEMBLE & ensemble) const {
return
eid == ensemble.eid &&
al_flag == ensemble.al_flag &&
label == ensemble.label &&
ecc == ensemble.ecc &&
lto == ensemble.lto &&
Expand Down Expand Up @@ -287,6 +290,7 @@ class FICDecoder {
void ProcessFIB(const uint8_t *data);

void ProcessFIG0(const uint8_t *data, size_t len);
void ProcessFIG0_0(const uint8_t *data, size_t len);
void ProcessFIG0_1(const uint8_t *data, size_t len);
void ProcessFIG0_2(const uint8_t *data, size_t len);
void ProcessFIG0_5(const uint8_t *data, size_t len);
Expand Down

1 comment on commit 9a99ed9

@andimik
Copy link
Contributor

@andimik andimik commented on 9a99ed9 Dec 7, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow, thanks.

Please sign in to comment.