mirror of
				https://github.com/f4exb/sdrangel.git
				synced 2025-10-27 11:00:31 -04: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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user