diff --git a/app-files/appimage/AppRun b/app-files/appimage/AppRun index 68c495fc..9807d95f 100644 --- a/app-files/appimage/AppRun +++ b/app-files/appimage/AppRun @@ -4,4 +4,4 @@ HERE="$(dirname "$(readlink -f "${0}")")" # Try to run using sudo, if this does not work ask the user for password #sudo -n -E -- "/tmp/udev-rules-helper" || pkexec "/tmp/udev-rules-helper" #rm "/tmp/udev-rules-helper" -exec "${HERE}/usr/bin/qt-dab-6.9.3" "$@" +exec "${HERE}/usr/bin/qt-dab-6.9.4" "$@" diff --git a/app-files/qt-dab-6.9.desktop b/app-files/qt-dab-6.9.desktop index 6e6f4573..c323630a 100644 --- a/app-files/qt-dab-6.9.desktop +++ b/app-files/qt-dab-6.9.desktop @@ -1,6 +1,6 @@ [Desktop Entry] -Name=Qt6_DAB-6.9.3 -Exec=qt-dab-6.9.3 +Name=Qt6_DAB-6.9.4 +Exec=qt-dab-6.9.4 Icon=qt-dab-6.9 Type=Application Categories=AudioVideo; diff --git a/qt-dab-6.9-build.txt b/qt-dab-6.9-build.txt index 54fa838b..7ac67b7a 100644 --- a/qt-dab-6.9-build.txt +++ b/qt-dab-6.9-build.txt @@ -11,7 +11,7 @@ mkdir -p ./appdir/usr/share/applications mkdir -p ./appdir/usr/share/icons/hicolor/128x128/apps/ mkdir -p ./appdir/usr/share/icons/hicolor/256x256/apps/ -cp linux-bin/qt-dab* appdir/usr/bin/qt-dab-6.9.3 +cp linux-bin/qt-dab* appdir/usr/bin/qt-dab-6.9.4 cp app-files/qt-dab-6.9.desktop appdir/usr/share/applications cp ../res/radio-pcitures/qt-dab-6.9-256x256.png appdir/qt-dab-RC.png cp ../res/radio-pictures/qt-dab-6.9-128x128.png appdir/usr/share/icons/hicolor/128x128/apps/ diff --git a/qt-dab-6.9.pro b/qt-dab-6.9.pro index b17a0a6f..3d4493fc 100644 --- a/qt-dab-6.9.pro +++ b/qt-dab-6.9.pro @@ -392,10 +392,10 @@ SOURCES += ./sources/main/main.cpp \ unix { DESTDIR = ./linux-bin equals (QT_MAJOR_VERSION, 5) { - TARGET = qt-dab-qt5-6.9.3 + TARGET = qt-dab-qt5-6.9.4 } else { - TARGET = qt-dab-qt6-6.9.3 + TARGET = qt-dab-qt6-6.9.4 } exists ("../.git") { GITHASHSTRING = $$system(git rev-parse --short HEAD) @@ -521,17 +521,17 @@ isEmpty(GITHASHSTRING) { # #for win32, comment out the lines above equals (QT_MAJOR_VERSION, 5) { - TARGET = qt-dab32-qt5-6.9V3.3 + TARGET = qt-dab32-qt5-6.9V3.4 } else { - TARGET = qt-dab32-qt6-6.9V3.3 + TARGET = qt-dab32-qt6-6.9V3.4 } CONFIG += dabstick-win-v3 # equals (QT_MAJOR_VERSION, 5) { -# TARGET = qt-dab32-qt5-6.9.3 +# TARGET = qt-dab32-qt5-6.9.4 # } # else { -# TARGET = qt-dab32-qt6-6.9.3 +# TARGET = qt-dab32-qt6-6.9.4 # } # CONFIG += dabstick-win-v4 CONFIG += airspy-2 diff --git a/sources/backend/data/pad-handler.cpp b/sources/backend/data/pad-handler.cpp index c7491fbc..e1898935 100644 --- a/sources/backend/data/pad-handler.cpp +++ b/sources/backend/data/pad-handler.cpp @@ -40,8 +40,8 @@ mr, &RadioInterface::showLabel); connect (this, &padHandler::show_mothandling, mr, &RadioInterface::show_mothandling); - connect (this, &padHandler::show_title, - mr, &RadioInterface::show_title); + connect (this, &padHandler::show_dl2, + mr, &RadioInterface::show_dl2); // // mscGroupElement indicates whether we are handling an // msc datagroup or not. @@ -69,6 +69,12 @@ the_DL2. IR = 10; for (int i = 0; i < 4; i ++) the_DL2. entity [i]. ct = 65; + + DL2_record. theText = ""; + DL2_record. title = ""; + DL2_record. composer = ""; + DL2_record. stationname = ""; + DL2_record. currentProgram = ""; } padHandler::~padHandler() { @@ -624,87 +630,81 @@ uint16_t index; // // Experimental code void padHandler::add_toDL2 (const QString &text) { - if (the_DL2. dlsText != text) { - the_DL2. dlsText = text; -// fprintf (stderr, "dl2 fragment %s\n", text. toLatin1 (). data ()); - the_DL2. valid = true; // non existent key - for (int i = 0; i < 4; i ++) - the_DL2. entity [i]. ct = 65; + if (DL2_record. theText != text) { + DL2_record. theText = text; + DL2_record. valid = true; } } -static uint8_t oldIT = 0; +QString padHandler::extractText (uint16_t start, uint16_t length) { +QString res; + for (int i = start; i <= start + length; i ++) + res = res + QChar (DL2_record. theText. at (i)); + return res; +} void padHandler::add_toDL2 (const uint8_t *data, uint8_t field_2, uint8_t field_3) { -// if (!the_DL2. valid) + if (DL2_record. theText. size () == 0) return; uint8_t CId = (data [0] >> 4) & 0x0f; uint8_t CB = data [0] & 0x0f; -// fprintf (stderr, "IT = %d, IR = %d, NT = %d\n", -// (CB >> 3), (CB >> 2) & 0x01, CB & 0x03); - if ((CB & 04) == 0) + if ((CB & 04) == 0) // IR should be "running" return; - if (oldIT != (CB & 0x08)) { - oldIT = (CB & 0x08); - fprintf (stderr, "switch\n"); - } - + 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; switch (contentType) { case 1 : { // the title - QString ss; - for (int i = startMarker; - i <= startMarker + lengthMarker; i ++) - ss = ss + QChar (the_DL2. dlsText. at (i)); - if (ss. size () > 0) - fprintf (stderr, "Title -> %s\n", - ss. toLatin1 (). data ()); + QString ss = extractText (startMarker, lengthMarker); + if (ss. size () > 0) { + if (ss != DL2_record. title) { + DL2_record. title = ss; + show_dl2 (contentType, IT, ss); + } + } break; } case 4: // the artist - case 8: { // the composer - QString ss; - for (int i = startMarker; - i <= startMarker + lengthMarker; i ++) - ss = ss + QChar (the_DL2. dlsText. at (i)); - if (ss. size () > 0) - fprintf (stderr, "Composer -> %s\n", - ss. toLatin1 (). data ()); + case 8: // the composer + case 9: { // the band + QString ss = extractText (startMarker, lengthMarker); + if (ss. size () > 0) { + if (ss != DL2_record. composer) { + DL2_record. composer = ss; + show_dl2 (contentType, IT, ss); + } + } break; } case 32: // stationname long case 31: { // stationname short - QString ss; - for (int i = startMarker; - i <= startMarker + lengthMarker; i ++) - ss = ss + QChar (the_DL2. dlsText. at (i)); - if (ss. size () > 0) - fprintf (stderr, "stationname -> %s\n", - ss. toLatin1 (). data ()); + QString ss = extractText (startMarker, lengthMarker); + if (ss. size () > 0) { + if (DL2_record. stationname != ss) { + DL2_record. stationname = ss; + show_dl2 (contentType, IT, ss); + } + } break; } case 33: { // program now - QString ss; - for (int i = startMarker; - i <= startMarker + lengthMarker; i ++) - ss = ss + QChar (the_DL2. dlsText. at (i)); - if (ss. size () > 0) - fprintf (stderr, "current program -> %s\n", - ss. toLatin1 (). data ()); + QString ss = extractText (startMarker, lengthMarker); + if (ss. size () > 0) { + if (DL2_record. currentProgram != ss) { + DL2_record. currentProgram = ss; + show_dl2 (contentType, IT, ss); + } + } break; } default: { - QString ss; - for (int i = startMarker; - i <= startMarker + lengthMarker; i ++) - ss = ss + QChar (the_DL2. dlsText. at (i)); - if (ss. size () > 0) - fprintf (stderr, "%d -> %s\n", contentType, - ss. toLatin1 (). data ()); +// QString ss = extractText (startMarker, lengthMarker); +// if (ss. size () > 0) +// fprintf (stderr, "%d -> %s\n", contentType, +// ss. toLatin1 (). data ()); break; } } diff --git a/sources/backend/data/pad-handler.h b/sources/backend/data/pad-handler.h index bd8c4c13..0983ed05 100644 --- a/sources/backend/data/pad-handler.h +++ b/sources/backend/data/pad-handler.h @@ -94,14 +94,23 @@ private: std::vector msc_dataGroupBuffer; // Experimental + struct { + QString theText; + bool valid; + QString title; + QString composer; + QString stationname; + QString currentProgram; + } DL2_record; DL2_base the_DL2; + QString extractText (uint16_t, uint16_t); void add_toDL2 (const QString &); void add_toDL2 (const uint8_t *, uint8_t, uint8_t); signals: void showLabel (const QString &, int); void show_mothandling (bool); - void show_title (uint8_t, uint8_t, + void show_dl2 (uint8_t, uint8_t, const QString &); }; diff --git a/sources/frontend/ofdm-decoder.cpp b/sources/frontend/ofdm-decoder.cpp index 4d09eb34..f05aa688 100644 --- a/sources/frontend/ofdm-decoder.cpp +++ b/sources/frontend/ofdm-decoder.cpp @@ -277,7 +277,7 @@ float sum = 0; else if (this -> decoder == DECODER_2) { // decoder 2 DABFLOAT corrector = - meanLevelVector [index] / sigmaSQ_Vector [index]; + 1.5 * meanLevelVector [index] / sigmaSQ_Vector [index]; corrector /= (1 / snr + 3); Complex R1 = corrector * normalize (fftBin) * (DABFLOAT)(sqrt (jan_abs (fftBin) * diff --git a/sources/main/aboutdialog.cpp b/sources/main/aboutdialog.cpp index 62f73789..4222cdb5 100644 --- a/sources/main/aboutdialog.cpp +++ b/sources/main/aboutdialog.cpp @@ -78,7 +78,7 @@ QString aacComment; ui -> appName -> setText ("Qt-DAB"); ui -> author -> setText(tr("Developed by")+" Jan van Katwijk (J.vanKatwijk@gmail.com)"); ui -> author -> setTextInteractionFlags (Qt::TextBrowserInteraction); - ui -> version -> setText (QString("Version-6.%1").arg ("9.3")); + ui -> version -> setText (QString("Version-6.%1").arg ("9.4")); QString theDate = QString (__DATE__) + " " + QString (__TIME__); ui -> buildInfo -> setText (QString ("Built on ") + theDate + QString (", Commit ") + QString (GITHASH) + " with " + support); ui -> sourceLocation -> setText ("Sources are at github> "); diff --git a/sources/main/config-handler.cpp b/sources/main/config-handler.cpp index 9777d82b..eed4bc90 100644 --- a/sources/main/config-handler.cpp +++ b/sources/main/config-handler.cpp @@ -489,6 +489,13 @@ void configHandler::set_connections () { connect (dcRemoval, &QCheckBox::stateChanged, #endif this, &configHandler::handle_dcRemoval); + +#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0) + connect (saveTitlesSelector, &QCheckBox::checkStateChanged, +#else + connect (saveTitlesSelector, &QCheckBox::stateChanged, +#endif + this, &configHandler::handle_saveTitles); // // botton row connect (decoderSelector, @@ -1066,3 +1073,11 @@ bool configHandler::get_dcRemoval () { return dcRemoval -> isChecked (); } +void configHandler::handle_saveTitles (int h) { + (void)h; +} + +bool configHandler::get_saveTitles () { + return saveTitlesSelector -> isChecked (); +} + diff --git a/sources/main/config-handler.h b/sources/main/config-handler.h index c8a82fe1..0294363a 100644 --- a/sources/main/config-handler.h +++ b/sources/main/config-handler.h @@ -90,6 +90,7 @@ public: bool get_allTIISelector (); bool get_dcRemoval (); + bool get_saveTitles (); private: RadioInterface *myRadioInterface; QSettings *dabSettings; @@ -141,6 +142,7 @@ private slots: void handle_auto_http (int); void handle_dcRemoval (int); + void handle_saveTitles (int); void handle_tiiCollisions (int); void handle_tiiFilter (int); diff --git a/sources/main/forms-v7/config-helper.ui b/sources/main/forms-v7/config-helper.ui index 77f9f5dc..b1ebe64c 100644 --- a/sources/main/forms-v7/config-helper.ui +++ b/sources/main/forms-v7/config-helper.ui @@ -598,9 +598,9 @@ - + - + save titles diff --git a/sources/main/radio.cpp b/sources/main/radio.cpp index 8e627c59..e6ac86ce 100644 --- a/sources/main/radio.cpp +++ b/sources/main/radio.cpp @@ -301,11 +301,11 @@ QString h; this, &RadioInterface::handle_newDisplayFrame_closed); #ifdef HAVE_RTLSDR_V3 - SystemVersion = QString ("9.3") + " with RTLSDR-V3"; + SystemVersion = QString ("9.4") + " with RTLSDR-V3"; #elif HAVE_RTLSDR_V4 - SystemVersion = QString ("9.3") + " with RTLSDR-V4"; + SystemVersion = QString ("9.4") + " with RTLSDR-V4"; #else - SystemVersion = QString ("9.3"); + SystemVersion = QString ("9.4"); #endif #if QT_VERSION > QT_VERSION_CHECK (6, 0, 0) version = "Qt6-DAB-6." + SystemVersion ; @@ -4612,18 +4612,90 @@ void RadioInterface::handle_dcRemoval (bool b) { theNewDisplay. set_dcRemoval (b); } -void RadioInterface::show_title (uint8_t IR, uint8_t ct, +static QString previousComposer; +static uint8_t old_IT = 0; +void RadioInterface::show_dl2 (uint8_t ct, uint8_t IT, const QString &s) { - (void)IR; - return; - if (s == "") - fprintf (stderr, "einde fragment\n"); - else - if (ct == 1) - fprintf (stderr, "Ttitle: %s\n", s. toUtf8 (). data ()); - else - if (ct == 4) - fprintf (stderr, "Artist: %s\n", s. toUtf8 (). data ()); +static QString title = ""; +static QString composer = ""; +static QString stationName = ""; +static QString programNow = ""; + + if (!configHandler_p -> get_saveTitles ()) + return; + + QString fileName = theFilenameFinder. basicPath (); + if (!fileName. endsWith ("/")) + fileName += "/"; + 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; + switch (ct) { + case 1: // the title + title = s; + if (composer != "") { + res = theTime. toString () + ";" + + currentService + ";" + + title + ";" + composer + ";"; + title = ""; + composer = ""; + } + break; + case 4: // the artist + case 8: // the composer + case 9: // the band + if (previousComposer == "") + previousComposer = s; + else + if (previousComposer. startsWith (s) || + s. startsWith (previousComposer) || + s == previousComposer) + break; + previousComposer = s; + composer = s; + if (title != "") { + res = theTime. toString () + ";" + + currentService + ";" + + title + ";" + composer + ";"; + title = ""; + composer = ""; + } + break; + case 31: // stationname short + case 32: // stationname long + stationName = s; + if (programNow != "") { + res = theTime. toString () + ";" + + currentService + ";" + stationName + ";" + + programNow + ";"; + stationName = ""; + programNow = ""; + } + break; + case 33: // program now + programNow = s; + if (stationName != "") { + res = theTime. toString () + ";" + + currentService + ";" + stationName + ";" + + programNow + ";"; + stationName = ""; + programNow = ""; + } + break; + default: + break; + } + if (res != "") { + FILE *dlTextFile = fopen (fileName. toUtf8 (). data (), "a+"); + if (dlTextFile != nullptr) { + fprintf (dlTextFile, "%s\n", res. toLatin1 (). data ()); + fclose (dlTextFile); + } + } } void RadioInterface::nrActiveServices (int n) { diff --git a/sources/main/radio.h b/sources/main/radio.h index 54939ea5..9689bd1c 100644 --- a/sources/main/radio.h +++ b/sources/main/radio.h @@ -548,6 +548,10 @@ public slots: void handleFramedumpButton (); void handleAudiodumpButton (); + void startJournaline (int); + void stopJournaline (int); + void journalineData (QByteArray, + int); // Somehow, these must be connected to the GUI private slots: void handle_aboutLabel (); @@ -616,15 +620,10 @@ public slots: void handle_tiiFilter (bool); void deviceListChanged (); - void show_title (uint8_t, + void show_dl2 (uint8_t, uint8_t, const QString &); void nrActiveServices (int); void handle_activeServices (); - - void startJournaline (int); - void stopJournaline (int); - void journalineData (QByteArray, - int); };