mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-26 17:58:43 -05:00
BFM demod: RDS GUI part #1: counters, PI and Group 0
This commit is contained in:
parent
48855bfb63
commit
4d156044e4
@ -18,6 +18,11 @@
|
||||
#include <QDockWidget>
|
||||
#include <QMainWindow>
|
||||
#include <QDebug>
|
||||
#include "boost/format.hpp"
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
#include "dsp/threadedsamplesink.h"
|
||||
#include "dsp/channelizer.h"
|
||||
#include "dsp/dspengine.h"
|
||||
@ -30,7 +35,6 @@
|
||||
#include "mainwindow.h"
|
||||
|
||||
#include "bfmdemodgui.h"
|
||||
|
||||
#include "ui_bfmdemodgui.h"
|
||||
#include "bfmdemod.h"
|
||||
|
||||
@ -245,6 +249,7 @@ void BFMDemodGUI::on_showPilot_clicked()
|
||||
|
||||
void BFMDemodGUI::on_rds_clicked()
|
||||
{
|
||||
m_rdsParser.clearAllFields();
|
||||
applySettings();
|
||||
}
|
||||
|
||||
@ -268,6 +273,7 @@ BFMDemodGUI::BFMDemodGUI(PluginAPI* pluginAPI, QWidget* parent) :
|
||||
m_pluginAPI(pluginAPI),
|
||||
m_channelMarker(this),
|
||||
m_basicSettingsShown(false),
|
||||
m_rdsTimerCount(0),
|
||||
m_channelPowerDbAvg(20,0),
|
||||
m_rate(625000)
|
||||
{
|
||||
@ -388,6 +394,13 @@ void BFMDemodGUI::tick()
|
||||
}
|
||||
}
|
||||
|
||||
if (ui->rds->isChecked() && (m_rdsTimerCount == 0))
|
||||
{
|
||||
rdsUpdate();
|
||||
}
|
||||
|
||||
m_rdsTimerCount = (m_rdsTimerCount + 1) % 25;
|
||||
|
||||
//qDebug() << "Pilot lock: " << m_bfmDemod->getPilotLock() << ":" << m_bfmDemod->getPilotLevel(); TODO: update a GUI item with status
|
||||
}
|
||||
|
||||
@ -398,3 +411,75 @@ void BFMDemodGUI::channelSampleRateChanged()
|
||||
ui->glSpectrum->setSampleRate(m_rate / 2);
|
||||
}
|
||||
|
||||
void BFMDemodGUI::rdsUpdate()
|
||||
{
|
||||
// PI group
|
||||
if (m_rdsParser.m_pi_updated)
|
||||
{
|
||||
ui->piLabel->setStyleSheet("QLabel { background-color : green; }");
|
||||
ui->piCountText->setNum((int) m_rdsParser.m_pi_count);
|
||||
QString pistring(str(boost::format("%04X") % m_rdsParser.m_pi_program_identification).c_str());
|
||||
ui->piText->setText(pistring);
|
||||
|
||||
if (m_rdsParser.m_pi_traffic_program) {
|
||||
ui->piTPIndicator->setStyleSheet("QLabel { background-color : green; }");
|
||||
} else {
|
||||
ui->piTPIndicator->setStyleSheet("QLabel { background:rgb(79,79,79); }");
|
||||
}
|
||||
|
||||
ui->piType->setText(QString(m_rdsParser.pty_table[m_rdsParser.m_pi_program_type].c_str()));
|
||||
ui->piCoverage->setText(QString(m_rdsParser.coverage_area_codes[m_rdsParser.m_pi_area_coverage_index].c_str()));
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->piLabel->setStyleSheet("QLabel { background:rgb(79,79,79); }");
|
||||
}
|
||||
|
||||
// G0 group
|
||||
if (m_rdsParser.m_g0_updated)
|
||||
{
|
||||
ui->g00Label->setStyleSheet("QLabel { background-color : green; }");
|
||||
ui->g00CountText->setNum((int) m_rdsParser.m_g0_count);
|
||||
ui->g00ProgServiceName->setText(QString(m_rdsParser.m_g0_program_service_name));
|
||||
|
||||
if (m_rdsParser.m_g0_traffic_announcement) {
|
||||
ui->g00TrafficAnnouncement->setStyleSheet("QLabel { background-color : green; }");
|
||||
} else {
|
||||
ui->g00TrafficAnnouncement->setStyleSheet("QLabel { background:rgb(79,79,79); }");
|
||||
}
|
||||
|
||||
ui->g00MusicSpeech->setText(QString((m_rdsParser.m_g0_music_speech ? "Music" : "Speech")));
|
||||
ui->g00MonoStereo->setText(QString((m_rdsParser.m_g0_mono_stereo ? "Mono" : "Stereo")));
|
||||
|
||||
if (m_rdsParser.m_g0_af_updated)
|
||||
{
|
||||
bool isFirst = true;
|
||||
std::ostringstream os;
|
||||
os << std::fixed << std::showpoint << std::setprecision(2);
|
||||
|
||||
for (std::set<double>::iterator it = m_rdsParser.m_g0_alt_freq.begin(); it != m_rdsParser.m_g0_alt_freq.end(); ++it)
|
||||
{
|
||||
if (*it > 76.0)
|
||||
{
|
||||
if (!isFirst)
|
||||
{
|
||||
os << ", ";
|
||||
}
|
||||
|
||||
os << *it;
|
||||
isFirst = false;
|
||||
}
|
||||
}
|
||||
|
||||
ui->g00AltFrequencies->setText(QString(os.str().c_str()));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->g00Label->setStyleSheet("QLabel { background:rgb(79,79,79); }");
|
||||
}
|
||||
|
||||
// G1 group
|
||||
|
||||
m_rdsParser.clearUpdateFlags();
|
||||
}
|
||||
|
@ -75,6 +75,7 @@ private:
|
||||
ChannelMarker m_channelMarker;
|
||||
bool m_basicSettingsShown;
|
||||
bool m_doApplySettings;
|
||||
int m_rdsTimerCount;
|
||||
|
||||
ThreadedSampleSink* m_threadedChannelizer;
|
||||
Channelizer* m_channelizer;
|
||||
@ -92,6 +93,7 @@ private:
|
||||
|
||||
void blockApplySettings(bool block);
|
||||
void applySettings();
|
||||
void rdsUpdate();
|
||||
|
||||
void leaveEvent(QEvent*);
|
||||
void enterEvent(QEvent*);
|
||||
|
@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>335</width>
|
||||
<height>333</height>
|
||||
<width>446</width>
|
||||
<height>729</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@ -399,7 +399,7 @@
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>160</y>
|
||||
<y>560</y>
|
||||
<width>311</width>
|
||||
<height>151</height>
|
||||
</rect>
|
||||
@ -431,6 +431,364 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="rdsContainer" native="true">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>150</y>
|
||||
<width>421</width>
|
||||
<height>91</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>RDS data</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="rdsLayout">
|
||||
<property name="spacing">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="countersLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="piCountLabel">
|
||||
<property name="text">
|
||||
<string>PI</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="piCountText">
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="g00CountLabel">
|
||||
<property name="text">
|
||||
<string>G00</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="g00CountText">
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="4">
|
||||
<widget class="QLabel" name="g03CountLabel">
|
||||
<property name="text">
|
||||
<string>G03</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="g01CountLabel">
|
||||
<property name="text">
|
||||
<string>G01</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLabel" name="g01CountText">
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QLabel" name="g02CountLabel">
|
||||
<property name="text">
|
||||
<string>G02</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QLabel" name="g02CountText">
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="9">
|
||||
<widget class="QLabel" name="g08CountLabel">
|
||||
<property name="text">
|
||||
<string>G08</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="8">
|
||||
<widget class="QLabel" name="g07CountLabel">
|
||||
<property name="text">
|
||||
<string>G07</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="4">
|
||||
<widget class="QLabel" name="g03CountText">
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="5">
|
||||
<widget class="QLabel" name="g04CountLabel">
|
||||
<property name="text">
|
||||
<string>G04</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="5">
|
||||
<widget class="QLabel" name="g04CountText">
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="6">
|
||||
<widget class="QLabel" name="g05CountLabel">
|
||||
<property name="text">
|
||||
<string>G05</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="6">
|
||||
<widget class="QLabel" name="g05CountText">
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="7">
|
||||
<widget class="QLabel" name="g06CountLabel">
|
||||
<property name="text">
|
||||
<string>G06</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="7">
|
||||
<widget class="QLabel" name="g06CountText">
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="8">
|
||||
<widget class="QLabel" name="g07CountText">
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="9">
|
||||
<widget class="QLabel" name="g08CountText">
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="10">
|
||||
<widget class="QLabel" name="g09CountLabel">
|
||||
<property name="text">
|
||||
<string>G09</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="10">
|
||||
<widget class="QLabel" name="g09CountText">
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="11">
|
||||
<widget class="QLabel" name="g14CountLabel">
|
||||
<property name="text">
|
||||
<string>G14</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="11">
|
||||
<widget class="QLabel" name="g14CountText">
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="countSeparator">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="piDataLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="piLabel">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>30</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>PI</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="piSeparator1">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="piText">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>0000</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="piSeparator2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="piTPIndicator">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TP</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="piType">
|
||||
<property name="text">
|
||||
<string>None</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="piCoverage">
|
||||
<property name="text">
|
||||
<string>Local</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="g00DataLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="g00Label">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>30</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>G00</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="g00Separator1">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="g00ProgServiceName">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>........</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="g00Separator2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="g00TrafficAnnouncement">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TA</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="g00MusicSpeech">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Music</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="g00MonoStereo">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Mono</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="g00AltFrequencies">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
|
@ -212,14 +212,47 @@ const std::string RDSParser::label_descriptions[16] = {
|
||||
|
||||
RDSParser::RDSParser()
|
||||
{
|
||||
std::memset(radiotext, ' ', sizeof(radiotext));
|
||||
radiotext[sizeof(radiotext) - 1] = '\0';
|
||||
clearAllFields();
|
||||
}
|
||||
|
||||
RDSParser::~RDSParser()
|
||||
{
|
||||
}
|
||||
|
||||
void RDSParser::clearUpdateFlags()
|
||||
{
|
||||
m_pi_updated = false;
|
||||
m_g0_updated = false;
|
||||
m_g0_af_updated = false;
|
||||
}
|
||||
|
||||
void RDSParser::clearAllFields()
|
||||
{
|
||||
// PI data
|
||||
m_pi_count = 0;
|
||||
m_pi_program_identification = 0;
|
||||
m_pi_program_type = 0;
|
||||
m_pi_traffic_program = false;
|
||||
|
||||
// Group 00 data
|
||||
m_g0_count = 0;
|
||||
std::memset(m_g0_program_service_name, ' ', sizeof(m_g0_program_service_name));
|
||||
radiotext[sizeof(m_g0_program_service_name) - 1] = '\0';
|
||||
m_g0_traffic_announcement = false;
|
||||
m_g0_music_speech = false;
|
||||
m_g0_mono_stereo = false;
|
||||
m_g0_artificial_head = false;
|
||||
m_g0_compressed = false;
|
||||
m_g0_static_pty = false;
|
||||
m_g0_alt_freq.clear();
|
||||
|
||||
// Group 02 data
|
||||
std::memset(radiotext, ' ', sizeof(radiotext));
|
||||
radiotext[sizeof(radiotext) - 1] = '\0';
|
||||
|
||||
clearUpdateFlags();
|
||||
}
|
||||
|
||||
void RDSParser::parseGroup(unsigned int *group)
|
||||
{
|
||||
unsigned int group_type = (unsigned int)((group[1] >> 12) & 0xf);
|
||||
@ -229,26 +262,29 @@ void RDSParser::parseGroup(unsigned int *group)
|
||||
<< " type: " << group_type << (ab ? 'B' :'A')
|
||||
<< " (" << rds_group_acronyms[group_type].c_str() << ")";
|
||||
|
||||
program_identification = group[0]; // "PI"
|
||||
program_type = (group[1] >> 5) & 0x1f; // "PTY"
|
||||
int pi_country_identification = (program_identification >> 12) & 0xf;
|
||||
int pi_area_coverage = (program_identification >> 8) & 0xf;
|
||||
unsigned char pi_program_reference_number = program_identification & 0xff;
|
||||
m_pi_count++;
|
||||
m_pi_updated = true;
|
||||
|
||||
std::string pistring = str(boost::format("%04X") % program_identification);
|
||||
//send_message(0, pistring);
|
||||
//send_message(2, pty_table[program_type]);
|
||||
m_pi_program_identification = group[0]; // "PI"
|
||||
m_pi_traffic_program = (group[1] >> 10) & 0x01; // "TP"
|
||||
m_pi_program_type = (group[1] >> 5) & 0x1f; // "PTY"
|
||||
m_pi_country_identification = (m_pi_program_identification >> 12) & 0xf;
|
||||
m_pi_area_coverage_index = (m_pi_program_identification >> 8) & 0xf;
|
||||
unsigned char pi_program_reference_number = m_pi_program_identification & 0xff;
|
||||
|
||||
/*
|
||||
std::string pistring = str(boost::format("%04X") % m_pi_program_identification);
|
||||
|
||||
qDebug() << "RDSParser::parseGroup:"
|
||||
<< " PI:" << pistring.c_str()
|
||||
<< " - " << "PTY:" << pty_table[program_type].c_str()
|
||||
<< " (country:" << (pi_country_codes[pi_country_identification - 1][0]).c_str()
|
||||
<< "/" << (pi_country_codes[pi_country_identification - 1][1]).c_str()
|
||||
<< "/" << (pi_country_codes[pi_country_identification - 1][2]).c_str()
|
||||
<< "/" << (pi_country_codes[pi_country_identification - 1][3]).c_str()
|
||||
<< "/" << (pi_country_codes[pi_country_identification - 1][4]).c_str()
|
||||
<< ", area:" << coverage_area_codes[pi_area_coverage].c_str()
|
||||
<< ", program:" << int(pi_program_reference_number) << ")";
|
||||
<< " - " << "PTY:" << pty_table[m_pi_program_type].c_str()
|
||||
<< " (country:" << (pi_country_codes[m_pi_country_identification - 1][0]).c_str()
|
||||
<< "/" << (pi_country_codes[m_pi_country_identification - 1][1]).c_str()
|
||||
<< "/" << (pi_country_codes[m_pi_country_identification - 1][2]).c_str()
|
||||
<< "/" << (pi_country_codes[m_pi_country_identification - 1][3]).c_str()
|
||||
<< "/" << (pi_country_codes[m_pi_country_identification - 1][4]).c_str()
|
||||
<< ", area:" << coverage_area_codes[m_pi_area_coverage_index].c_str()
|
||||
<< ", program:" << int(pi_program_reference_number) << ")";*/
|
||||
|
||||
switch (group_type) {
|
||||
case 0:
|
||||
@ -319,40 +355,47 @@ void RDSParser::decode_type0(unsigned int *group, bool B)
|
||||
double af_2 = 0;
|
||||
char flagstring[8] = "0000000";
|
||||
|
||||
traffic_program = (group[1] >> 10) & 0x01; // "TP"
|
||||
traffic_announcement = (group[1] >> 4) & 0x01; // "TA"
|
||||
music_speech = (group[1] >> 3) & 0x01; // "MuSp"
|
||||
m_g0_count++;
|
||||
m_g0_updated = true;
|
||||
|
||||
m_pi_traffic_program = (group[1] >> 10) & 0x01; // "TP"
|
||||
m_g0_traffic_announcement = (group[1] >> 4) & 0x01; // "TA"
|
||||
m_g0_music_speech = (group[1] >> 3) & 0x01; // "MuSp"
|
||||
|
||||
bool decoder_control_bit = (group[1] >> 2) & 0x01; // "DI"
|
||||
unsigned char segment_address = group[1] & 0x03; // "DI segment"
|
||||
|
||||
program_service_name[segment_address * 2] = (group[3] >> 8) & 0xff;
|
||||
program_service_name[segment_address * 2 + 1] = group[3] & 0xff;
|
||||
m_g0_program_service_name[segment_address * 2] = (group[3] >> 8) & 0xff;
|
||||
m_g0_program_service_name[segment_address * 2 + 1] = group[3] & 0xff;
|
||||
|
||||
/* see page 41, table 9 of the standard */
|
||||
switch (segment_address) {
|
||||
switch (segment_address)
|
||||
{
|
||||
case 0:
|
||||
mono_stereo=decoder_control_bit;
|
||||
m_g0_mono_stereo = decoder_control_bit;
|
||||
break;
|
||||
case 1:
|
||||
artificial_head=decoder_control_bit;
|
||||
m_g0_artificial_head = decoder_control_bit;
|
||||
break;
|
||||
case 2:
|
||||
compressed=decoder_control_bit;
|
||||
m_g0_compressed = decoder_control_bit;
|
||||
break;
|
||||
case 3:
|
||||
static_pty=decoder_control_bit;
|
||||
m_g0_static_pty = decoder_control_bit;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
flagstring[0] = traffic_program ? '1' : '0';
|
||||
flagstring[1] = traffic_announcement ? '1' : '0';
|
||||
flagstring[2] = music_speech ? '1' : '0';
|
||||
flagstring[3] = mono_stereo ? '1' : '0';
|
||||
flagstring[4] = artificial_head ? '1' : '0';
|
||||
flagstring[5] = compressed ? '1' : '0';
|
||||
flagstring[6] = static_pty ? '1' : '0';
|
||||
|
||||
/* unused
|
||||
flagstring[0] = m_pi_traffic_program ? '1' : '0';
|
||||
flagstring[1] = m_g0_traffic_announcement ? '1' : '0';
|
||||
flagstring[2] = m_g0_music_speech ? '1' : '0';
|
||||
flagstring[3] = m_g0_mono_stereo ? '1' : '0';
|
||||
flagstring[4] = m_g0_artificial_head ? '1' : '0';
|
||||
flagstring[5] = m_g0_compressed ? '1' : '0';
|
||||
flagstring[6] = m_g0_static_pty ? '1' : '0';*/
|
||||
|
||||
static std::string af_string;
|
||||
|
||||
if (!B)
|
||||
@ -362,17 +405,25 @@ void RDSParser::decode_type0(unsigned int *group, bool B)
|
||||
af_1 = decode_af(af_code_1);
|
||||
af_2 = decode_af(af_code_2);
|
||||
|
||||
if(af_1) {
|
||||
if (af_1)
|
||||
{
|
||||
std::pair<std::_Rb_tree_const_iterator<double>, bool> res = m_g0_alt_freq.insert(af_1/1e3);
|
||||
m_g0_af_updated = m_g0_af_updated || res.second;
|
||||
no_af += 1;
|
||||
}
|
||||
if(af_2) {
|
||||
|
||||
if (af_2)
|
||||
{
|
||||
std::pair<std::_Rb_tree_const_iterator<double>, bool> res = m_g0_alt_freq.insert(af_2/1e3);
|
||||
m_g0_af_updated = m_g0_af_updated || res.second;
|
||||
no_af += 2;
|
||||
}
|
||||
|
||||
/*
|
||||
std::string af1_string;
|
||||
std::string af2_string;
|
||||
|
||||
/* only AF1 => no_af==1, only AF2 => no_af==2, both AF1 and AF2 => no_af==3 */
|
||||
// only AF1 => no_af==1, only AF2 => no_af==2, both AF1 and AF2 => no_af==3
|
||||
if(no_af)
|
||||
{
|
||||
if(af_1 > 80e3) {
|
||||
@ -394,20 +445,17 @@ void RDSParser::decode_type0(unsigned int *group, bool B)
|
||||
af_string = af2_string;
|
||||
} else if(no_af == 3) {
|
||||
af_string = str(boost::format("%s, %s") % af1_string %af2_string);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
/*
|
||||
qDebug() << "RDSParser::decode_type0: "
|
||||
<< "\"" << std::string(program_service_name, 8).c_str()
|
||||
<< "\" -" << (traffic_program ? "TP" : "!TP")
|
||||
<< '-' << (traffic_announcement ? "TA" : "!TA")
|
||||
<< '-' << (music_speech ? "Music" : "Speech")
|
||||
<< '-' << (mono_stereo ? "MONO" : "STEREO")
|
||||
<< " - AF:" << af_string.c_str();
|
||||
|
||||
//send_message(1, std::string(program_service_name, 8));
|
||||
//send_message(3, flagstring);
|
||||
//send_message(6, af_string);
|
||||
<< "\"" << std::string(m_g0_program_service_name, 8).c_str()
|
||||
<< "\" -" << (m_pi_traffic_program ? "TP" : "!TP")
|
||||
<< '-' << (m_g0_traffic_announcement ? "TA" : "!TA")
|
||||
<< '-' << (m_g0_music_speech ? "Music" : "Speech")
|
||||
<< '-' << (m_g0_mono_stereo ? "MONO" : "STEREO")
|
||||
<< " - AF:" << af_string.c_str();*/
|
||||
}
|
||||
|
||||
double RDSParser::decode_af(unsigned int af_code)
|
||||
|
@ -18,6 +18,9 @@
|
||||
#ifndef PLUGINS_CHANNEL_BFM_RDSPARSER_H_
|
||||
#define PLUGINS_CHANNEL_BFM_RDSPARSER_H_
|
||||
|
||||
#include <string>
|
||||
#include <set>
|
||||
|
||||
class RDSParser
|
||||
{
|
||||
public:
|
||||
@ -29,6 +32,45 @@ public:
|
||||
*/
|
||||
void parseGroup(unsigned int *group);
|
||||
|
||||
void clearAllFields();
|
||||
void clearUpdateFlags();
|
||||
|
||||
// PI data
|
||||
bool m_pi_updated;
|
||||
unsigned int m_pi_count;
|
||||
unsigned int m_pi_program_identification;
|
||||
unsigned char m_pi_program_type;
|
||||
bool m_pi_traffic_program;
|
||||
int m_pi_country_identification;
|
||||
int m_pi_area_coverage_index;
|
||||
|
||||
// G0 data
|
||||
bool m_g0_updated;
|
||||
bool m_g0_af_updated;
|
||||
unsigned int m_g0_count;
|
||||
char m_g0_program_service_name[9];
|
||||
bool m_g0_traffic_announcement;
|
||||
bool m_g0_music_speech;
|
||||
bool m_g0_mono_stereo;
|
||||
bool m_g0_artificial_head;
|
||||
bool m_g0_compressed;
|
||||
bool m_g0_static_pty;
|
||||
std::set<double> m_g0_alt_freq;
|
||||
|
||||
// Static tables
|
||||
static const unsigned int offset_pos[5];
|
||||
static const unsigned int offset_word[5];
|
||||
static const unsigned int syndrome[5];
|
||||
static const char * const offset_name[];
|
||||
static const std::string pty_table[32];
|
||||
static const std::string pi_country_codes[15][5];
|
||||
static const std::string coverage_area_codes[16];
|
||||
static const std::string rds_group_acronyms[16];
|
||||
static const std::string language_codes[44];
|
||||
static const std::string tmc_duration[8][2];
|
||||
static const int optional_content_lengths[16];
|
||||
static const std::string label_descriptions[16];
|
||||
|
||||
private:
|
||||
double decode_af(unsigned int);
|
||||
void decode_optional_content(int, unsigned long int *);
|
||||
@ -49,36 +91,14 @@ private:
|
||||
void decode_type14(unsigned int* group, bool B);
|
||||
void decode_type15(unsigned int* group, bool B);
|
||||
|
||||
unsigned int program_identification;
|
||||
unsigned char program_type;
|
||||
unsigned char pi_country_identification;
|
||||
unsigned char pi_area_coverage;
|
||||
unsigned char pi_program_reference_number;
|
||||
char radiotext[65+1];
|
||||
char program_service_name[9];
|
||||
char radiotext[64+1];
|
||||
|
||||
bool radiotext_AB_flag;
|
||||
bool traffic_program;
|
||||
bool traffic_announcement;
|
||||
bool music_speech;
|
||||
bool mono_stereo;
|
||||
bool artificial_head;
|
||||
bool compressed;
|
||||
bool static_pty;
|
||||
bool debug;
|
||||
bool log;
|
||||
|
||||
static const unsigned int offset_pos[5];
|
||||
static const unsigned int offset_word[5];
|
||||
static const unsigned int syndrome[5];
|
||||
static const char * const offset_name[];
|
||||
static const std::string pty_table[32];
|
||||
static const std::string pi_country_codes[15][5];
|
||||
static const std::string coverage_area_codes[16];
|
||||
static const std::string rds_group_acronyms[16];
|
||||
static const std::string language_codes[44];
|
||||
static const std::string tmc_duration[8][2];
|
||||
static const int optional_content_lengths[16];
|
||||
static const std::string label_descriptions[16];
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user