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 <QDockWidget>
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include "boost/format.hpp"
|
||||||
|
#include <sstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <iomanip>
|
||||||
|
|
||||||
#include "dsp/threadedsamplesink.h"
|
#include "dsp/threadedsamplesink.h"
|
||||||
#include "dsp/channelizer.h"
|
#include "dsp/channelizer.h"
|
||||||
#include "dsp/dspengine.h"
|
#include "dsp/dspengine.h"
|
||||||
@ -30,7 +35,6 @@
|
|||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
|
|
||||||
#include "bfmdemodgui.h"
|
#include "bfmdemodgui.h"
|
||||||
|
|
||||||
#include "ui_bfmdemodgui.h"
|
#include "ui_bfmdemodgui.h"
|
||||||
#include "bfmdemod.h"
|
#include "bfmdemod.h"
|
||||||
|
|
||||||
@ -245,6 +249,7 @@ void BFMDemodGUI::on_showPilot_clicked()
|
|||||||
|
|
||||||
void BFMDemodGUI::on_rds_clicked()
|
void BFMDemodGUI::on_rds_clicked()
|
||||||
{
|
{
|
||||||
|
m_rdsParser.clearAllFields();
|
||||||
applySettings();
|
applySettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,6 +273,7 @@ BFMDemodGUI::BFMDemodGUI(PluginAPI* pluginAPI, QWidget* parent) :
|
|||||||
m_pluginAPI(pluginAPI),
|
m_pluginAPI(pluginAPI),
|
||||||
m_channelMarker(this),
|
m_channelMarker(this),
|
||||||
m_basicSettingsShown(false),
|
m_basicSettingsShown(false),
|
||||||
|
m_rdsTimerCount(0),
|
||||||
m_channelPowerDbAvg(20,0),
|
m_channelPowerDbAvg(20,0),
|
||||||
m_rate(625000)
|
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
|
//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);
|
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;
|
ChannelMarker m_channelMarker;
|
||||||
bool m_basicSettingsShown;
|
bool m_basicSettingsShown;
|
||||||
bool m_doApplySettings;
|
bool m_doApplySettings;
|
||||||
|
int m_rdsTimerCount;
|
||||||
|
|
||||||
ThreadedSampleSink* m_threadedChannelizer;
|
ThreadedSampleSink* m_threadedChannelizer;
|
||||||
Channelizer* m_channelizer;
|
Channelizer* m_channelizer;
|
||||||
@ -92,6 +93,7 @@ private:
|
|||||||
|
|
||||||
void blockApplySettings(bool block);
|
void blockApplySettings(bool block);
|
||||||
void applySettings();
|
void applySettings();
|
||||||
|
void rdsUpdate();
|
||||||
|
|
||||||
void leaveEvent(QEvent*);
|
void leaveEvent(QEvent*);
|
||||||
void enterEvent(QEvent*);
|
void enterEvent(QEvent*);
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>335</width>
|
<width>446</width>
|
||||||
<height>333</height>
|
<height>729</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@ -399,7 +399,7 @@
|
|||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>10</x>
|
<x>10</x>
|
||||||
<y>160</y>
|
<y>560</y>
|
||||||
<width>311</width>
|
<width>311</width>
|
||||||
<height>151</height>
|
<height>151</height>
|
||||||
</rect>
|
</rect>
|
||||||
@ -431,6 +431,364 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</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>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
|
@ -212,14 +212,47 @@ const std::string RDSParser::label_descriptions[16] = {
|
|||||||
|
|
||||||
RDSParser::RDSParser()
|
RDSParser::RDSParser()
|
||||||
{
|
{
|
||||||
std::memset(radiotext, ' ', sizeof(radiotext));
|
clearAllFields();
|
||||||
radiotext[sizeof(radiotext) - 1] = '\0';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RDSParser::~RDSParser()
|
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)
|
void RDSParser::parseGroup(unsigned int *group)
|
||||||
{
|
{
|
||||||
unsigned int group_type = (unsigned int)((group[1] >> 12) & 0xf);
|
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')
|
<< " type: " << group_type << (ab ? 'B' :'A')
|
||||||
<< " (" << rds_group_acronyms[group_type].c_str() << ")";
|
<< " (" << rds_group_acronyms[group_type].c_str() << ")";
|
||||||
|
|
||||||
program_identification = group[0]; // "PI"
|
m_pi_count++;
|
||||||
program_type = (group[1] >> 5) & 0x1f; // "PTY"
|
m_pi_updated = true;
|
||||||
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;
|
|
||||||
|
|
||||||
std::string pistring = str(boost::format("%04X") % program_identification);
|
m_pi_program_identification = group[0]; // "PI"
|
||||||
//send_message(0, pistring);
|
m_pi_traffic_program = (group[1] >> 10) & 0x01; // "TP"
|
||||||
//send_message(2, pty_table[program_type]);
|
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:"
|
qDebug() << "RDSParser::parseGroup:"
|
||||||
<< " PI:" << pistring.c_str()
|
<< " PI:" << pistring.c_str()
|
||||||
<< " - " << "PTY:" << pty_table[program_type].c_str()
|
<< " - " << "PTY:" << pty_table[m_pi_program_type].c_str()
|
||||||
<< " (country:" << (pi_country_codes[pi_country_identification - 1][0]).c_str()
|
<< " (country:" << (pi_country_codes[m_pi_country_identification - 1][0]).c_str()
|
||||||
<< "/" << (pi_country_codes[pi_country_identification - 1][1]).c_str()
|
<< "/" << (pi_country_codes[m_pi_country_identification - 1][1]).c_str()
|
||||||
<< "/" << (pi_country_codes[pi_country_identification - 1][2]).c_str()
|
<< "/" << (pi_country_codes[m_pi_country_identification - 1][2]).c_str()
|
||||||
<< "/" << (pi_country_codes[pi_country_identification - 1][3]).c_str()
|
<< "/" << (pi_country_codes[m_pi_country_identification - 1][3]).c_str()
|
||||||
<< "/" << (pi_country_codes[pi_country_identification - 1][4]).c_str()
|
<< "/" << (pi_country_codes[m_pi_country_identification - 1][4]).c_str()
|
||||||
<< ", area:" << coverage_area_codes[pi_area_coverage].c_str()
|
<< ", area:" << coverage_area_codes[m_pi_area_coverage_index].c_str()
|
||||||
<< ", program:" << int(pi_program_reference_number) << ")";
|
<< ", program:" << int(pi_program_reference_number) << ")";*/
|
||||||
|
|
||||||
switch (group_type) {
|
switch (group_type) {
|
||||||
case 0:
|
case 0:
|
||||||
@ -319,40 +355,47 @@ void RDSParser::decode_type0(unsigned int *group, bool B)
|
|||||||
double af_2 = 0;
|
double af_2 = 0;
|
||||||
char flagstring[8] = "0000000";
|
char flagstring[8] = "0000000";
|
||||||
|
|
||||||
traffic_program = (group[1] >> 10) & 0x01; // "TP"
|
m_g0_count++;
|
||||||
traffic_announcement = (group[1] >> 4) & 0x01; // "TA"
|
m_g0_updated = true;
|
||||||
music_speech = (group[1] >> 3) & 0x01; // "MuSp"
|
|
||||||
|
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"
|
bool decoder_control_bit = (group[1] >> 2) & 0x01; // "DI"
|
||||||
unsigned char segment_address = group[1] & 0x03; // "DI segment"
|
unsigned char segment_address = group[1] & 0x03; // "DI segment"
|
||||||
|
|
||||||
program_service_name[segment_address * 2] = (group[3] >> 8) & 0xff;
|
m_g0_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 + 1] = group[3] & 0xff;
|
||||||
|
|
||||||
/* see page 41, table 9 of the standard */
|
/* see page 41, table 9 of the standard */
|
||||||
switch (segment_address) {
|
switch (segment_address)
|
||||||
|
{
|
||||||
case 0:
|
case 0:
|
||||||
mono_stereo=decoder_control_bit;
|
m_g0_mono_stereo = decoder_control_bit;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
artificial_head=decoder_control_bit;
|
m_g0_artificial_head = decoder_control_bit;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
compressed=decoder_control_bit;
|
m_g0_compressed = decoder_control_bit;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
static_pty=decoder_control_bit;
|
m_g0_static_pty = decoder_control_bit;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
flagstring[0] = traffic_program ? '1' : '0';
|
|
||||||
flagstring[1] = traffic_announcement ? '1' : '0';
|
/* unused
|
||||||
flagstring[2] = music_speech ? '1' : '0';
|
flagstring[0] = m_pi_traffic_program ? '1' : '0';
|
||||||
flagstring[3] = mono_stereo ? '1' : '0';
|
flagstring[1] = m_g0_traffic_announcement ? '1' : '0';
|
||||||
flagstring[4] = artificial_head ? '1' : '0';
|
flagstring[2] = m_g0_music_speech ? '1' : '0';
|
||||||
flagstring[5] = compressed ? '1' : '0';
|
flagstring[3] = m_g0_mono_stereo ? '1' : '0';
|
||||||
flagstring[6] = static_pty ? '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;
|
static std::string af_string;
|
||||||
|
|
||||||
if (!B)
|
if (!B)
|
||||||
@ -362,17 +405,25 @@ void RDSParser::decode_type0(unsigned int *group, bool B)
|
|||||||
af_1 = decode_af(af_code_1);
|
af_1 = decode_af(af_code_1);
|
||||||
af_2 = decode_af(af_code_2);
|
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;
|
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;
|
no_af += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
std::string af1_string;
|
std::string af1_string;
|
||||||
std::string af2_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(no_af)
|
||||||
{
|
{
|
||||||
if(af_1 > 80e3) {
|
if(af_1 > 80e3) {
|
||||||
@ -394,20 +445,17 @@ void RDSParser::decode_type0(unsigned int *group, bool B)
|
|||||||
af_string = af2_string;
|
af_string = af2_string;
|
||||||
} else if(no_af == 3) {
|
} else if(no_af == 3) {
|
||||||
af_string = str(boost::format("%s, %s") % af1_string %af2_string);
|
af_string = str(boost::format("%s, %s") % af1_string %af2_string);
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
qDebug() << "RDSParser::decode_type0: "
|
qDebug() << "RDSParser::decode_type0: "
|
||||||
<< "\"" << std::string(program_service_name, 8).c_str()
|
<< "\"" << std::string(m_g0_program_service_name, 8).c_str()
|
||||||
<< "\" -" << (traffic_program ? "TP" : "!TP")
|
<< "\" -" << (m_pi_traffic_program ? "TP" : "!TP")
|
||||||
<< '-' << (traffic_announcement ? "TA" : "!TA")
|
<< '-' << (m_g0_traffic_announcement ? "TA" : "!TA")
|
||||||
<< '-' << (music_speech ? "Music" : "Speech")
|
<< '-' << (m_g0_music_speech ? "Music" : "Speech")
|
||||||
<< '-' << (mono_stereo ? "MONO" : "STEREO")
|
<< '-' << (m_g0_mono_stereo ? "MONO" : "STEREO")
|
||||||
<< " - AF:" << af_string.c_str();
|
<< " - AF:" << af_string.c_str();*/
|
||||||
|
|
||||||
//send_message(1, std::string(program_service_name, 8));
|
|
||||||
//send_message(3, flagstring);
|
|
||||||
//send_message(6, af_string);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
double RDSParser::decode_af(unsigned int af_code)
|
double RDSParser::decode_af(unsigned int af_code)
|
||||||
|
@ -18,6 +18,9 @@
|
|||||||
#ifndef PLUGINS_CHANNEL_BFM_RDSPARSER_H_
|
#ifndef PLUGINS_CHANNEL_BFM_RDSPARSER_H_
|
||||||
#define PLUGINS_CHANNEL_BFM_RDSPARSER_H_
|
#define PLUGINS_CHANNEL_BFM_RDSPARSER_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
class RDSParser
|
class RDSParser
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -29,6 +32,45 @@ public:
|
|||||||
*/
|
*/
|
||||||
void parseGroup(unsigned int *group);
|
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:
|
private:
|
||||||
double decode_af(unsigned int);
|
double decode_af(unsigned int);
|
||||||
void decode_optional_content(int, unsigned long int *);
|
void decode_optional_content(int, unsigned long int *);
|
||||||
@ -49,36 +91,14 @@ private:
|
|||||||
void decode_type14(unsigned int* group, bool B);
|
void decode_type14(unsigned int* group, bool B);
|
||||||
void decode_type15(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_country_identification;
|
||||||
unsigned char pi_area_coverage;
|
|
||||||
unsigned char pi_program_reference_number;
|
unsigned char pi_program_reference_number;
|
||||||
char radiotext[65+1];
|
char radiotext[64+1];
|
||||||
char program_service_name[9];
|
|
||||||
bool radiotext_AB_flag;
|
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 debug;
|
||||||
bool log;
|
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