1
0
mirror of https://github.com/JvanKatwijk/qt-dab.git synced 2025-10-06 00:02:40 +02:00

update hackrf handler and dl2 handling

This commit is contained in:
Jan
2025-09-10 18:05:28 +02:00
parent d68e45f59a
commit 2a8ea5af00
7 changed files with 103 additions and 50 deletions

View File

@@ -366,8 +366,7 @@ int16_t dataLength = 0;
#endif
}
//
// etsi TS 102 980 specifies the DL plus objects, I just let it go
// for the time being
// etsi TS 102 980 specifies the DL plus objects,
if (Cflag) { // special dynamic label command
uint16_t Command = (prefix >> 8) & 0x0f;
uint8_t field_2 = (prefix >> 4) & 0x0f;
@@ -628,7 +627,9 @@ uint16_t index;
}
//
// Experimental code
//
// Experimental code to extract titles and composers from
// the DL2 data
void padHandler::add_toDL2 (const QString &text) {
if (DL2_record. theText != text) {
DL2_record. theText = text;
@@ -638,6 +639,8 @@ void padHandler::add_toDL2 (const QString &text) {
QString padHandler::extractText (uint16_t start, uint16_t length) {
QString res;
if (start + length >= DL2_record. theText. size ())
return "";
for (int i = start; i <= start + length; i ++)
res = res + QChar (DL2_record. theText. at (i));
return res;
@@ -651,11 +654,12 @@ void padHandler::add_toDL2 (const uint8_t *data,
uint8_t CB = data [0] & 0x0f;
if ((CB & 04) == 0) // IR should be "running"
return;
uint8_t NT = data [0] & 0x03;
uint8_t IT = CB & 0x08;
for (int i = 0; i < field_3; i += 3) {
uint8_t contentType = data [1 + i + 0] & 0x3F;
uint8_t startMarker = data [1 + i + 1] & 0x7F;
uint8_t lengthMarker = data [1 + i + 2] & 0x7F;
for (int i = 0; i <= NT; i ++) {
uint8_t contentType = data [1 + 3 * i + 0] & 0x3F;
uint8_t startMarker = data [1 + 3 * i + 1] & 0x7F;
uint8_t lengthMarker = data [1 + 3 * i + 2] & 0x7F;
switch (contentType) {
case 1 : { // the title
QString ss = extractText (startMarker, lengthMarker);
@@ -679,7 +683,7 @@ void padHandler::add_toDL2 (const uint8_t *data,
}
break;
}
case 32: // stationname long
case 32: // stationname long
case 31: { // stationname short
QString ss = extractText (startMarker, lengthMarker);
if (ss. size () > 0) {
@@ -701,6 +705,9 @@ void padHandler::add_toDL2 (const uint8_t *data,
break;
}
default: {
// fprintf (stderr,
// "i = %d, NT = %d, field_3 = %d start %d len %d\n",
// i, NT, field_3, startMarker, lengthMarker);
// QString ss = extractText (startMarker, lengthMarker);
// if (ss. size () > 0)
// fprintf (stderr, "%d -> %s\n", contentType,

View File

@@ -101,6 +101,7 @@ hackrf_error errorCode;
ppm_correction -> setValue (
value_i (hackrfSettings, HACKRF_SETTINGS,
"hack_ppmCorrection", 0));
ppmValue = ppm_correction -> value ();
save_gainSettings =
value_i (hackrfSettings, HACKRF_SETTINGS,
"save_gainSettings", 1);
@@ -125,7 +126,7 @@ hackrf_error errorCode;
}
errorCode = (hackrf_error)
(hackrf_set_baseband_filter_bandwidth (theDevice, 1750000));
(hackrf_baseband_filter (theDevice, 1750000));
if (errorCode != HACKRF_SUCCESS) {
delete library_p;
throw (device_exception (hackrf_error_name (errorCode)));
@@ -177,6 +178,8 @@ hackrf_error errorCode;
connect (ppm_correction, qOverload<int>(&QSpinBox::valueChanged),
this, &hackrfHandler::handle_ppmCorrection);
connect (samplerate_correction, qOverload<int>(&QSpinBox::valueChanged),
this, &hackrfHandler::handle_samplerateCorrection);
connect (dumpButton, &QPushButton::clicked,
this, &hackrfHandler::handle_xmlDump);
@@ -295,26 +298,53 @@ bool b;
}
// correction is in Hz
// This function has to be modified to implement ppm correction
// writing in the si5351 register does not seem to work yet
// To be completed
// This function has to be modified to implement ppm correction
// writing in the si5351 register does not seem to work yet
// Asking on the various fora made clear that writing in that
// particular register has no effect at all.
// So, it should be addressed differently
// An Option is to maintain a ppm value and correct the
// frequency each time it is set (works more or less but
// a little clumsy)
void hackrfHandler::handle_ppmCorrection (int32_t ppm) {
uint16_t value;
hackrf_error errorCode;
errorCode = (hackrf_error) this -> hackrf_si5351c_write (theDevice,
162,
static_cast<uint16_t>(ppm));
if (errorCode != HACKRF_SUCCESS)
theErrorLogger -> add ("Hackrf", hackrf_error_name (errorCode));
errorCode = (hackrf_error)this -> hackrf_si5351c_read (theDevice,
162, &value);
if (errorCode != HACKRF_SUCCESS)
theErrorLogger -> add ("Hackrf", hackrf_error_name (errorCode));
qDebug() << "Read si5351c register 162 : " << value <<"\n";
ppmValue = ppm;
if (!running. load ()) // while initing ....
return;
int adjustedFreq = lastFrequency * (1 + ppm / 1000000.0);
errorCode = (hackrf_error)(hackrf_set_freq (theDevice, adjustedFreq));
if (errorCode != HACKRF_SUCCESS) {
statusLabel -> setText (hackrf_error_name (errorCode));
theErrorLogger -> add ("Hackrf restart",
hackrf_error_name (errorCode));
}
}
void hackrfHandler::handle_samplerateCorrection (int32_t correction) {
hackrf_error errorCode;
float correctedRate = SAMPLERATE + correction;
errorCode = (hackrf_error)hackrf_set_sample_rate (theDevice,
correctedRate);
if (errorCode != HACKRF_SUCCESS) {
statusLabel -> setText (hackrf_error_name (errorCode));
theErrorLogger -> add ("Hackrf samplerate correction",
hackrf_error_name (errorCode));
}
// the filter must be set after the sample rate to be not overwritten
hackrf_baseband_filter (theDevice, 1750000);
if (errorCode != HACKRF_SUCCESS) {
statusLabel -> setText (hackrf_error_name (errorCode));
theErrorLogger -> add ("Hackrf set bandwidth",
hackrf_error_name (errorCode));
}
if (!running. load ())
return;
stopReader();
restartReader(getVFOFrequency());
}
//
// we use a static large buffer, rather than trying to allocate
// a buffer on the stack
@@ -347,6 +377,7 @@ hackrf_error errorCode;
lastFrequency = freq;
this -> toSkip = skipped;
int adjustedFreq = freq + ppmValue * (freq / 1000000);
if (save_gainSettings)
update_gainSettings (freq / MHz (1));
errorCode = (hackrf_error) (hackrf_set_lna_gain (theDevice,
@@ -377,7 +408,7 @@ hackrf_error errorCode;
theErrorLogger -> add ("Hackrf", hackrf_error_name (errorCode));
}
errorCode = (hackrf_error)(hackrf_set_freq (theDevice, freq));
errorCode = (hackrf_error)(hackrf_set_freq (theDevice, adjustedFreq));
if (errorCode != HACKRF_SUCCESS) {
showStatus (this -> hackrf_error_name (errorCode));
return false;
@@ -506,10 +537,10 @@ bool hackrfHandler::load_hackrfFunctions () {
return false;
}
this -> hackrf_set_baseband_filter_bandwidth =
this -> hackrf_baseband_filter =
(pfn_hackrf_set_baseband_filter_bandwidth)
library_p -> resolve ("hackrf_set_baseband_filter_bandwidth");
if (this -> hackrf_set_baseband_filter_bandwidth == nullptr) {
if (this -> hackrf_baseband_filter == nullptr) {
fprintf (stderr, "Could not find hackrf_set_baseband_filter_bandwidth\n");
return false;
}

View File

@@ -116,7 +116,7 @@ private:
pfn_hackrf_stop_rx hackrf_stop_rx;
pfn_hackrf_device_list hackrf_device_list;
pfn_hackrf_set_baseband_filter_bandwidth
hackrf_set_baseband_filter_bandwidth;
hackrf_baseband_filter;
pfn_hackrf_set_lna_gain hackrf_set_lna_gain;
pfn_hackrf_set_vga_gain hackrf_set_vga_gain;
pfn_hackrf_set_freq hackrf_set_freq;
@@ -135,6 +135,7 @@ private:
pfn_hackrf_si5351c_write hackrf_si5351c_write;
pfn_hackrf_board_rev_read hackrf_board_rev_read;
int ppmValue;
// Fine aggiunta
QSettings *hackrfSettings;
@@ -165,6 +166,7 @@ private slots:
void handle_biasT (int);
void handle_Ampli (int);
void handle_ppmCorrection (int);
void handle_samplerateCorrection (int);
// Fine aggiunta
void handle_xmlDump ();
};

View File

@@ -45,7 +45,7 @@
<item>
<widget class="QSpinBox" name="ppm_correction">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Unfortunately, the hackrf API does not support ppm handling&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Unfortunately, the hackrf API does not support ppm handling so ppm handling is done by - in software - adapting the channel frequencies&lt;/p&gt;&lt;p&gt;Since it takes time for the software to react on a change, make changes one step at the time and wait a while&lt;/p&gt;&lt;p&gt;(Note 1 ppm on 227360 KHz is 227 Hz)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="minimum">
<number>-100</number>
@@ -55,6 +55,13 @@
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="samplerate_correction">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Experimental. My hackrf device shows a pretty large samplerate offset (clock offset on the spectrum display), app -36 for channel 12C, i.e. 227360 Khz. With this spinbox the samplerate can be altered. &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="usb_board_id_display">
<property name="text">

View File

@@ -103,7 +103,7 @@ QString aacComment;
"<li> Andreas Mikula, for continuous support </li>" +
"<li> Jarod Middelman, for continuous feedback</li>" +
"<li> Stefan Poeschel, for providing code for saving AAC </li>" +
"<li> Rolf Zerr, for an improved TII decoder </li>" +
"<li> Rolf Zerr, for an improved TII decoder and some other improvements </li>" +
"</ul>");
// ui -> configuration -> setTextInteractionFlags (Qt::TextBrowserInteraction);
ui -> configuration -> setOpenExternalLinks(true);
@@ -127,14 +127,17 @@ QString aacComment;
#ifdef HAVE_PLUTO
"<li>Adalm Pluto device<a href=\"https://www.analog.com/\">Adalm Pluto One</a></li>"
#endif
#ifdef HAVE_RTL_TCP
"<li>Client for RTL_TCP</li>"
#endif
#ifdef HAVE_SOAPY
"<li>Soapy interface<a href=\"https://github.com/pothosware/SoapySDR/wiki\">SoapySDR</a></li>"
#endif
#ifdef HAVE_SPYSERVER_16
"<li>SpyServer interface<a href=\"https://airspy.com/download/\">spyserver</a></li>"
#endif
"<li> and has support for reading (and writing) files in different formats.</li>");
"<li> and has support for reading (and writing) files in different formats, including files (in xml and in RIFF/Raw64 format) with sizes larger than 4 Gb.</li>"
"</ul>");
ui->disclaimer->setText("<p>Copyright © 2016-2024 Jan van Katwijk</p>"
"<p>Permission is hereby granted, free of charge, to any person obtaining a copy of this software "
"and associated documentation files (the “Software”), to deal in the Software without restriction, "

View File

@@ -4611,7 +4611,8 @@ void RadioInterface::handle_dcRemoval (bool b) {
theOFDMHandler -> set_dcRemoval (b);
theNewDisplay. set_dcRemoval (b);
}
//
// Experimental code for handling DL2 data
static QString previousComposer;
static uint8_t old_IT = 0;
void RadioInterface::show_dl2 (uint8_t ct, uint8_t IT,
@@ -4621,6 +4622,14 @@ static QString composer = "";
static QString stationName = "";
static QString programNow = "";
if (IT != old_IT) {
title = "";
composer = "";
stationName = "";
programNow = "";
}
old_IT = IT;
if (!configHandler_p -> get_saveTitles ())
return;
@@ -4630,17 +4639,17 @@ static QString programNow = "";
fileName += "DL2_titles.csv";
QDateTime theTime = QDateTime::currentDateTime ();
QString currentService = channel. currentService. serviceName;
QString res = "";
if (IT != old_IT)
fprintf (stderr, "Switch\n");
old_IT = IT;
QString ensemble = channel. ensembleName;
QString channelName = channel. channelName;
QString front = theTime. toString () + ";" +
channelName + ";" +
ensemble + ";" + currentService + ";";;
QString res;
switch (ct) {
case 1: // the title
title = s;
if (composer != "") {
res = theTime. toString () + ";" +
currentService + ";" +
title + ";" + composer + ";";
res = front + title + ";" + composer + ";";
title = "";
composer = "";
}
@@ -4658,9 +4667,7 @@ static QString programNow = "";
previousComposer = s;
composer = s;
if (title != "") {
res = theTime. toString () + ";" +
currentService + ";" +
title + ";" + composer + ";";
res = front + title + ";" + composer + ";";
title = "";
composer = "";
}
@@ -4669,9 +4676,7 @@ static QString programNow = "";
case 32: // stationname long
stationName = s;
if (programNow != "") {
res = theTime. toString () + ";" +
currentService + ";" + stationName + ";" +
programNow + ";";
res = front + stationName + ";" + programNow + ";";
stationName = "";
programNow = "";
}
@@ -4679,9 +4684,7 @@ static QString programNow = "";
case 33: // program now
programNow = s;
if (stationName != "") {
res = theTime. toString () + ";" +
currentService + ";" + stationName + ";" +
programNow + ";";
res = front + stationName + ";" + programNow + ";";
stationName = "";
programNow = "";
}

View File

@@ -30,7 +30,7 @@ void superFrame::closeEvent (QCloseEvent * event) {
void superFrame::mousePressEvent (QMouseEvent *event) {
if (event -> button () == Qt::LeftButton) {
emit makePicture ();
// emit makePicture ();
}
}