Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package gqrx for openSUSE:Factory checked in at 2025-06-06 22:44:51 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/gqrx (Old) and /work/SRC/openSUSE:Factory/.gqrx.new.19631 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "gqrx" Fri Jun 6 22:44:51 2025 rev:8 rq:1283662 version:2.17.7 Changes: -------- --- /work/SRC/openSUSE:Factory/gqrx/gqrx.changes 2024-11-30 13:32:06.088340613 +0100 +++ /work/SRC/openSUSE:Factory/.gqrx.new.19631/gqrx.changes 2025-06-06 22:45:37.955208596 +0200 @@ -1,0 +2,8 @@ +Fri May 30 13:27:45 UTC 2025 - Martin Hauke <mar...@gmx.de> + +- Update to version 2.17.7 + * New: Start/stop I/Q recording via remote control. + * Improved: Allow multiple simultaneous remote control + connections. + +------------------------------------------------------------------- Old: ---- gqrx-2.17.6.tar.gz New: ---- gqrx-2.17.7.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ gqrx.spec ++++++ --- /var/tmp/diff_new_pack.Armtj4/_old 2025-06-06 22:45:38.655237606 +0200 +++ /var/tmp/diff_new_pack.Armtj4/_new 2025-06-06 22:45:38.655237606 +0200 @@ -1,7 +1,7 @@ # # spec file for package gqrx # -# Copyright (c) 2024 SUSE LLC +# Copyright (c) 2025 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,7 +17,7 @@ Name: gqrx -Version: 2.17.6 +Version: 2.17.7 Release: 0 Summary: Software defined radio receiver License: GPL-3.0-only ++++++ gqrx-2.17.6.tar.gz -> gqrx-2.17.7.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gqrx-2.17.6/.github/workflows/build.yml new/gqrx-2.17.7/.github/workflows/build.yml --- old/gqrx-2.17.6/.github/workflows/build.yml 2024-11-30 01:45:49.000000000 +0100 +++ new/gqrx-2.17.7/.github/workflows/build.yml 2025-05-28 00:24:03.000000000 +0200 @@ -27,8 +27,8 @@ pkg-config gnuradio-core gnuradio-osmosdr - libboost-headers - mesa-libgl-devel-cos6-x86_64 + libboost-devel + libgl-devel pybind11 pulseaudio qt6-gtk-platformtheme @@ -36,6 +36,7 @@ soapysdr-module-lms7 soapysdr-module-plutosdr soapysdr-module-remote + sysroot_linux-64=2.17.* volk - name: Checkout code uses: actions/checkout@v4 @@ -84,71 +85,28 @@ else echo "available=false" >> $GITHUB_OUTPUT; fi - - name: Install dependencies - run: | - uname -a - # for https://github.com/actions/runner-images/issues/9272 - sudo chown -R runner:admin /usr/local/ - brew update - brew install --HEAD librtlsdr - brew install airspy airspyhf boost dylibbundler gnuradio hackrf libbladerf libserialport portaudio pybind11 six soapyremote uhd qt@6 || true - - cd /tmp - git clone https://github.com/analogdevicesinc/libiio.git - cd libiio - git checkout v0.23 - mkdir build - cd build - cmake -DCMAKE_BUILD_TYPE=Release .. - make -j4 - sudo make install - - cd /tmp - git clone https://github.com/analogdevicesinc/libad9361-iio.git - cd libad9361-iio - mkdir build - cd build - cmake -DCMAKE_BUILD_TYPE=Release .. - make -j4 - sudo make install - - cd /tmp - git clone https://github.com/pothosware/SoapyPlutoSDR.git - cd SoapyPlutoSDR - mkdir build - cd build - cmake -DCMAKE_BUILD_TYPE=Release .. - make -j4 - sudo make install - - cd /tmp - sudo cp /Library/Frameworks/iio.framework/iio /usr/local/lib/libiio.dylib - sudo install_name_tool -id "/usr/local/lib/libiio.dylib" /usr/local/lib/libiio.dylib - sudo cp /Library/Frameworks/ad9361.framework/ad9361 /usr/local/lib/libad9361.dylib - sudo install_name_tool -id "/usr/local/lib/libad9361.dylib" /usr/local/lib/libad9361.dylib - sudo install_name_tool -delete_rpath /Library/Frameworks /usr/local/lib/libad9361.dylib - sudo install_name_tool -change @rpath/iio.framework/Versions/0.23/iio /usr/local/lib/libiio.dylib /usr/local/lib/libad9361.dylib - sudo install_name_tool -change @rpath/iio.framework/Versions/0.23/iio /usr/local/lib/libiio.dylib /usr/local/lib/SoapySDR/modules0.*/libPlutoSDRSupport.so - sudo install_name_tool -change @rpath/ad9361.framework/Versions/0.2/ad9361 /usr/local/lib/libad9361.dylib /usr/local/lib/SoapySDR/modules0.*/libPlutoSDRSupport.so - - cd /tmp - git clone https://gitea.osmocom.org/sdr/gr-iqbal.git - cd gr-iqbal - git submodule update --init --recursive - mkdir build - cd build - cmake -DCMAKE_BUILD_TYPE=Release .. - make -j4 - sudo make install - - cd /tmp - git clone https://gitea.osmocom.org/sdr/gr-osmosdr.git - cd gr-osmosdr - mkdir build - cd build - cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS=-Wno-register .. - LIBRARY_PATH=/usr/local/opt/icu4c/lib make -j4 - sudo make install + - name: Install conda dependencies + id: setup-micromamba + uses: mamba-org/setup-micromamba@v2 + with: + environment-name: gqrx + create-args: >- + c-compiler + cxx-compiler + cmake + make + pkg-config + gnuradio-core + gnuradio-osmosdr + libboost-devel + qt6-main + soapysdr + soapysdr-module-audio + soapysdr-module-lms7 + soapysdr-module-plutosdr + soapysdr-module-remote + soapysdr-module-volk-converters + volk - name: Install Apple certificate if: ${{ steps.secret-check.outputs.available == 'true' }} env: @@ -172,11 +130,14 @@ with: fetch-depth: 0 - name: Configure + shell: bash -el {0} run: mkdir build && cd build && cmake -DCMAKE_BUILD_TYPE=Release .. - name: Compile working-directory: build run: make -j4 - name: Build app bundle + env: + CONDA_PREFIX: ${{ steps.setup-micromamba.outputs.environment-path }} run: ./macos_bundle.sh ${{ steps.secret-check.outputs.available }} - name: Notarize app bundle if: ${{ steps.secret-check.outputs.available == 'true' }} @@ -206,9 +167,11 @@ if: ${{ steps.secret-check.outputs.available == 'true' }} run: xcrun stapler staple --verbose Gqrx.dmg - name: Rename DMG + env: + MATRIX_ARCH: ${{ matrix.arch }} run: | GQRX_VERSION=$(<build/version.txt) - mv Gqrx.dmg Gqrx-$GQRX_VERSION.dmg + mv Gqrx.dmg Gqrx-$GQRX_VERSION-$MATRIX_ARCH.dmg - name: Save artifact uses: actions/upload-artifact@v4 with: @@ -245,7 +208,7 @@ - name: Clone and build GNU Radio working-directory: ${{ runner.temp }} run: | - git clone --branch v3.10.11.0 --depth 1 https://github.com/gnuradio/gnuradio.git + git clone --branch v3.10.12.0 --depth 1 https://github.com/gnuradio/gnuradio.git cd gnuradio cmake -S . -B build \ -DCMAKE_INSTALL_PREFIX=${RUNNER_TEMP}/msys64/mingw64 \ @@ -268,6 +231,7 @@ git clone https://gitea.osmocom.org/sdr/rtl-sdr.git cd rtl-sdr cmake -S . -B build \ + -DCMAKE_C_FLAGS="-std=gnu17" \ -DCMAKE_INSTALL_PREFIX=${RUNNER_TEMP}/msys64/mingw64 \ -DCMAKE_BUILD_TYPE=Release \ -DDETACH_KERNEL_DRIVER=OFF \ @@ -282,6 +246,7 @@ cd airspyone_host cmake -S . -B build \ -G "MinGW Makefiles" \ + -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \ -DCMAKE_INSTALL_PREFIX=${RUNNER_TEMP}/msys64/mingw64 cmake --build build cmake --install build @@ -292,6 +257,7 @@ cd airspyhf cmake -S . -B build \ -G "MSYS Makefiles" \ + -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \ -DCMAKE_INSTALL_PREFIX=${RUNNER_TEMP}/msys64/mingw64 \ -DTHREADS_PTHREADS_INCLUDE_DIR=${RUNNER_TEMP}/msys64/mingw64/include \ -DTHREADS_PTHREADS_WIN32_LIBRARY=${RUNNER_TEMP}/msys64/mingw64/lib/libpthread.a @@ -354,9 +320,9 @@ libgraphite2.dll \ libharfbuzz-0.dll \ libiconv-2.dll \ - libicudt75.dll \ - libicuin75.dll \ - libicuuc75.dll \ + libicudt*.dll \ + libicuin*.dll \ + libicuuc*.dll \ libintl-8.dll \ libmd4c.dll \ libmp3lame-0.dll \ @@ -370,7 +336,7 @@ librtlsdr.dll \ libsndfile-1.dll \ libSoapySDR.dll \ - libspdlog.dll \ + libspdlog-1.15.dll \ libstdc++-6.dll \ libusb-1.0.dll \ libvolk.dll \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gqrx-2.17.6/.github/workflows/ci.yml new/gqrx-2.17.7/.github/workflows/ci.yml --- old/gqrx-2.17.6/.github/workflows/ci.yml 2024-11-30 01:45:49.000000000 +0100 +++ new/gqrx-2.17.7/.github/workflows/ci.yml 2025-05-28 00:24:03.000000000 +0200 @@ -72,24 +72,26 @@ backend: [Portaudio, Gr-audio] runs-on: ${{ matrix.os }} steps: - - name: Install dependencies - run: | - # for https://github.com/actions/runner-images/issues/9272 - sudo chown -R runner:admin /usr/local/ - brew update - brew install airspy boost gnuradio hackrf libbladerf librtlsdr pybind11 six uhd qt@6 || true - - cd /tmp - git clone https://gitea.osmocom.org/sdr/gr-osmosdr.git - cd gr-osmosdr - mkdir build - cd build - cmake -DCMAKE_CXX_FLAGS=-Wno-register .. - LIBRARY_PATH=/usr/local/opt/icu4c/lib make -j4 - sudo make install + - name: Install conda dependencies + id: setup-micromamba + uses: mamba-org/setup-micromamba@v2 + with: + environment-name: gqrx + create-args: >- + c-compiler + cxx-compiler + cmake + make + pkg-config + gnuradio-core + gnuradio-osmosdr + libboost-devel + qt6-main + volk - name: Checkout code uses: actions/checkout@v4 - name: Configure + shell: bash -el {0} run: mkdir build && cd build && cmake -DOSX_AUDIO_BACKEND:STRING=${{ matrix.backend }} .. - name: Compile working-directory: build diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gqrx-2.17.6/CMakeLists.txt new/gqrx-2.17.7/CMakeLists.txt --- old/gqrx-2.17.6/CMakeLists.txt 2024-11-30 01:45:49.000000000 +0100 +++ new/gqrx-2.17.7/CMakeLists.txt 2025-05-28 00:24:03.000000000 +0200 @@ -1,10 +1,10 @@ -cmake_minimum_required(VERSION 3.2) +cmake_minimum_required(VERSION 3.5) # Project name project(gqrx) set(${PROJECT_NAME}_MAJOR "2") set(${PROJECT_NAME}_MINOR "17") -set(${PROJECT_NAME}_PATCH "6") +set(${PROJECT_NAME}_PATCH "7") set(IS_RELEASE TRUE) if(IS_RELEASE) @@ -71,7 +71,7 @@ add_definitions(-DBOOST_ALL_DYN_LINK) #export gr-rds symbols - add_definitions(-Dgnuradio_RDS_EXPORTS) + add_definitions(-Dgnuradio_rds_EXPORTS) if ("${MSVC_VERSION}" VERSION_LESS "1900") add_definitions(-D__func__=__FUNCTION__) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gqrx-2.17.6/README.md new/gqrx-2.17.7/README.md --- old/gqrx-2.17.6/README.md 2024-11-30 01:45:49.000000000 +0100 +++ new/gqrx-2.17.7/README.md 2025-05-28 00:24:03.000000000 +0200 @@ -94,9 +94,8 @@ - gnuradio-pmt - The gr-iqbalance library (optional) - Drivers for the hardware you want to have support for: - - Funcube Dongle Pro driver via gr-fcd - UHD driver via gr-uhd - - Funcube Dongle Pro+ driver from https://github.com/dl1ksv/gr-fcdproplus + - FUNcube Dongle and FUNcube Dongle Pro+ driver from https://github.com/dl1ksv/gr-funcube - RTL-SDR driver from https://gitea.osmocom.org/sdr/rtl-sdr - HackRF driver from https://github.com/mossmann/hackrf - Airspy driver from https://github.com/airspy/airspyone_host @@ -110,7 +109,7 @@ - Network - Widgets - Svg (runtime-only) -- cmake version >= 3.2.0 +- cmake version >= 3.5.0 Gqrx can be compiled from within Qt Creator or in a terminal: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gqrx-2.17.6/dk.gqrx.gqrx.appdata.xml new/gqrx-2.17.7/dk.gqrx.gqrx.appdata.xml --- old/gqrx-2.17.6/dk.gqrx.gqrx.appdata.xml 2024-11-30 01:45:49.000000000 +0100 +++ new/gqrx-2.17.7/dk.gqrx.gqrx.appdata.xml 2025-05-28 00:24:03.000000000 +0200 @@ -6,6 +6,9 @@ <summary xml:lang="nl">Software defined radio ontvanger geïmplementeerd met GNU Radio en de Qt GUI toolkit</summary> <summary xml:lang="ru">Приемник для программно-определенного радио (SDR) использующий GNU Radio и библиотеку Qt</summary> <developer_name>Alexandru Csete</developer_name> + <developer id="dk.gqrx"> + <name>Alexandru Csete</name> + </developer> <description> <p> Gqrx is an open source software defined radio receiver (SDR) powered by the GNU Radio and the Qt graphical toolkit. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gqrx-2.17.6/macos_bundle.sh new/gqrx-2.17.7/macos_bundle.sh --- old/gqrx-2.17.6/macos_bundle.sh 2024-11-30 01:45:49.000000000 +0100 +++ new/gqrx-2.17.7/macos_bundle.sh 2025-05-28 00:24:03.000000000 +0200 @@ -2,8 +2,16 @@ GQRX_VERSION="$(<build/version.txt)" IDENTITY=Y3GC27WZ4S -BREW_PREFIX="$(brew --prefix)" -MACDEPLOYQT6="${BREW_PREFIX}"/opt/qt@6/bin/macdeployqt + +echo "CONDA_PREFIX: " $CONDA_PREFIX + +MACDEPLOYQT6=${CONDA_PREFIX}/bin/macdeployqt6 +echo "macdeployqt6: " ${MACDEPLOYQT6} + +# cleanup and setup +if [ -e Gqrx.app ] ; +then rm -r Gqrx.app +fi mkdir -p Gqrx.app/Contents/MacOS mkdir -p Gqrx.app/Contents/Resources @@ -51,20 +59,15 @@ cp build/src/gqrx Gqrx.app/Contents/MacOS cp resources/icons/gqrx.icns Gqrx.app/Contents/Resources -# NOTE: PlutoSDR is built locally, so it will not in the brew path -cp /usr/local/lib/SoapySDR/modules*/libPlutoSDRSupport.so Gqrx.app/Contents/soapy-modules -cp "${BREW_PREFIX}"/lib/SoapySDR/modules*/libremoteSupport.so Gqrx.app/Contents/soapy-modules -chmod 644 Gqrx.app/Contents/soapy-modules/* +cp "$CONDA_PREFIX"/lib/SoapySDR/modules*/* Gqrx.app/Contents/soapy-modules -dylibbundler -s "${BREW_PREFIX}"/opt/icu4c/lib/ -od -b -x Gqrx.app/Contents/MacOS/gqrx -x Gqrx.app/Contents/soapy-modules/libPlutoSDRSupport.so -x Gqrx.app/Contents/soapy-modules/libremoteSupport.so -d Gqrx.app/Contents/libs/ -"${MACDEPLOYQT6}" Gqrx.app -no-strip -always-overwrite # TODO: Remove macdeployqt workaround if [ "$1" = "true" ]; then - "${MACDEPLOYQT6}" Gqrx.app -no-strip -always-overwrite -sign-for-notarization="${IDENTITY}" + "${MACDEPLOYQT6}" Gqrx.app -verbose=1 -no-strip -always-overwrite -sign-for-notarization="${IDENTITY}" -libpath=Gqrx.app/Contents/Frameworks else - "${MACDEPLOYQT6}" Gqrx.app -no-strip -always-overwrite + "${MACDEPLOYQT6}" Gqrx.app -verbose=1 -no-strip -always-overwrite -libpath=Gqrx.app/Contents/Frameworks fi -for f in Gqrx.app/Contents/libs/*.dylib Gqrx.app/Contents/soapy-modules/*.so Gqrx.app/Contents/Frameworks/*.framework Gqrx.app/Contents/Frameworks/*.dylib Gqrx.app/Contents/MacOS/gqrx +for f in Gqrx.app/Contents/Frameworks/*.dylib Gqrx.app/Contents/soapy-modules/* Gqrx.app/Contents/MacOS/gqrx do if [ "$1" = "true" ]; then codesign --force --verify --verbose --timestamp --options runtime --entitlements /tmp/Entitlements.plist --sign "${IDENTITY}" "$f" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gqrx-2.17.6/resources/gqrx.1 new/gqrx-2.17.7/resources/gqrx.1 --- old/gqrx-2.17.6/resources/gqrx.1 2024-11-30 01:45:49.000000000 +0100 +++ new/gqrx-2.17.7/resources/gqrx.1 2025-05-28 00:24:03.000000000 +0200 @@ -1,4 +1,4 @@ -.TH GQRX "1" "November 29, 2024" "gqrx 2.17.6" "User Commands" +.TH GQRX "1" "May 27, 2025" "gqrx 2.17.7" "User Commands" .SH NAME gqrx \- Software Defined Radio GUI application .SH DESCRIPTION diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gqrx-2.17.6/resources/news.txt new/gqrx-2.17.7/resources/news.txt --- old/gqrx-2.17.6/resources/news.txt 2024-11-30 01:45:49.000000000 +0100 +++ new/gqrx-2.17.7/resources/news.txt 2025-05-28 00:24:03.000000000 +0200 @@ -1,4 +1,12 @@ + 2.17.7: Released May 27, 2025 + + NEW: Start/stop I/Q recording via remote control. + IMPROVED: Allow multiple simultaneous remote control connections. + FIXED: DMG release for ARM-based Macs fails to start. + FIXED: Compilation error affecting MSVC. + + 2.17.6: Released November 29, 2024 NEW: Fetch RDS Program Service & RadioText via remote control. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gqrx-2.17.6/resources/remote-control.txt new/gqrx-2.17.7/resources/remote-control.txt --- old/gqrx-2.17.6/resources/remote-control.txt 2024-11-30 01:45:49.000000000 +0100 +++ new/gqrx-2.17.7/resources/remote-control.txt 2025-05-28 00:24:03.000000000 +0200 @@ -37,6 +37,10 @@ Get status of audio recorder U RECORD <status> Set status of audio recorder to <status> + u IQRECORD + Get status of IQ recorder + U IQRECORD <status> + Set status of IQ recorder to <status> u DSP Get DSP (SDR receiver) status U DSP <status> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gqrx-2.17.6/src/applications/gqrx/main.cpp new/gqrx-2.17.7/src/applications/gqrx/main.cpp --- old/gqrx-2.17.6/src/applications/gqrx/main.cpp 2024-11-30 01:45:49.000000000 +0100 +++ new/gqrx-2.17.7/src/applications/gqrx/main.cpp 2025-05-28 00:24:03.000000000 +0200 @@ -67,6 +67,7 @@ { qputenv("SOAPY_SDR_PLUGIN_PATH", plugin_path.toUtf8()); qputenv("SOAPY_SDR_ROOT", "/invalid"); + qputenv("CONDA_PREFIX", "/invalid"); } // setup controlport via environment variables diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gqrx-2.17.6/src/applications/gqrx/mainwindow.cpp new/gqrx-2.17.7/src/applications/gqrx/mainwindow.cpp --- old/gqrx-2.17.6/src/applications/gqrx/mainwindow.cpp 2024-11-30 01:45:49.000000000 +0100 +++ new/gqrx-2.17.7/src/applications/gqrx/mainwindow.cpp 2025-05-28 00:24:03.000000000 +0200 @@ -319,7 +319,9 @@ // I/Q playback connect(iq_tool, SIGNAL(startRecording(QString, QString)), this, SLOT(startIqRecording(QString, QString))); + connect(iq_tool, SIGNAL(startRecording(QString, QString)), remote, SLOT(startIqRecorder(QString, QString))); connect(iq_tool, SIGNAL(stopRecording()), this, SLOT(stopIqRecording())); + connect(iq_tool, SIGNAL(stopRecording()), remote, SLOT(stopIqRecorder())); connect(iq_tool, SIGNAL(startPlayback(QString,float,qint64)), this, SLOT(startIqPlayback(QString,float,qint64))); connect(iq_tool, SIGNAL(stopPlayback()), this, SLOT(stopIqPlayback())); connect(iq_tool, SIGNAL(seek(qint64)), this,SLOT(seekIqFile(qint64))); @@ -339,6 +341,8 @@ connect(uiDockRxOpt, SIGNAL(sqlLevelChanged(double)), remote, SLOT(setSquelchLevel(double))); connect(remote, SIGNAL(startAudioRecorderEvent()), uiDockAudio, SLOT(startAudioRecorder())); connect(remote, SIGNAL(stopAudioRecorderEvent()), uiDockAudio, SLOT(stopAudioRecorder())); + connect(remote, SIGNAL(startIqRecorderEvent()), iq_tool, SLOT(startIqRecorder())); + connect(remote, SIGNAL(stopIqRecorderEvent()), iq_tool, SLOT(stopIqRecorder())); connect(ui->plotter, SIGNAL(newFilterFreq(int, int)), remote, SLOT(setPassband(int, int))); connect(remote, SIGNAL(newPassband(int)), this, SLOT(setPassband(int))); connect(remote, SIGNAL(gainChanged(QString, double)), uiDockInputCtl, SLOT(setGain(QString,double))); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gqrx-2.17.6/src/applications/gqrx/remote_control.cpp new/gqrx-2.17.7/src/applications/gqrx/remote_control.cpp --- old/gqrx-2.17.6/src/applications/gqrx/remote_control.cpp 2024-11-30 01:45:49.000000000 +0100 +++ new/gqrx-2.17.7/src/applications/gqrx/remote_control.cpp 2025-05-28 00:24:03.000000000 +0200 @@ -50,6 +50,7 @@ squelch_level = -150.0; audio_gain = -6.0; audio_recorder_status = false; + iq_recorder_status = false; receiver_running = false; hamlib_compatible = false; is_audio_muted = false; @@ -57,8 +58,6 @@ rc_port = DEFAULT_RC_PORT; rc_allowed_hosts.append(DEFAULT_RC_ALLOWED_HOSTS); - rc_socket = 0; - connect(&rc_server, SIGNAL(newConnection()), this, SLOT(acceptConnection())); } @@ -77,12 +76,13 @@ /*! \brief Stop the server. */ void RemoteControl::stop_server() { - if (rc_socket != 0) { - rc_socket->close(); - rc_socket->deleteLater(); - rc_socket = 0; - } + for(auto sock : rc_sockets) { + sock->close(); + sock->deleteLater(); + } + rc_sockets.clear(); + if (rc_server.isListening()) rc_server.close(); @@ -163,30 +163,34 @@ */ void RemoteControl::acceptConnection() { - if (rc_socket) - { - rc_socket->close(); - rc_socket->deleteLater(); - } - rc_socket = rc_server.nextPendingConnection(); + auto socket = rc_server.nextPendingConnection(); + rc_sockets.insert(socket); // check if host is allowed - auto address = rc_socket->peerAddress(); + auto address = socket->peerAddress(); for (auto allowed_host : rc_allowed_hosts) { if (address.isEqual(QHostAddress(allowed_host))) { - connect(rc_socket, SIGNAL(readyRead()), this, SLOT(startRead())); + connect(socket, SIGNAL(disconnected()), this, SLOT(socketDisconnect())); + connect(socket, SIGNAL(readyRead()), this, SLOT(startRead())); return; } } std::cout << "*** Remote connection attempt from " << address.toString().toStdString() << " (not in allowed list)" << std::endl; - rc_socket->close(); - rc_socket->deleteLater(); - rc_socket = 0; + socket->close(); + socket->deleteLater(); +} + +void RemoteControl::socketDisconnect() +{ + QTcpSocket *socket = (QTcpSocket*)sender(); + rc_sockets.erase(socket); + socket->close(); + socket->deleteLater(); } /*! \brief Start reading from the socket. @@ -196,6 +200,7 @@ */ void RemoteControl::startRead() { + QTcpSocket *rc_socket = (QTcpSocket*)sender(); while (rc_socket->canReadLine()) { char buffer[1024] = {0}; int bytes_read; @@ -258,9 +263,9 @@ else if (cmd == "q" || cmd == "Q") { // FIXME: for now we assume 'close' command + rc_sockets.erase(rc_socket); rc_socket->close(); rc_socket->deleteLater(); - rc_socket = 0; return; } else @@ -376,6 +381,7 @@ /*! \brief Start audio recorder (from mainwindow). */ void RemoteControl::startAudioRecorder(QString unused) { + /* Check first if a demodulation mode is set. */ if (rc_mode > 0) audio_recorder_status = true; } @@ -386,6 +392,18 @@ audio_recorder_status = false; } +/*! \brief Start IQ recorder (from another window). */ +void RemoteControl::startIqRecorder(QString unused1, QString unused2) +{ + iq_recorder_status = true; +} + +/*! \brief Stop IQ recorder (from another window). */ +void RemoteControl::stopIqRecorder() +{ + iq_recorder_status = false; +} + /*! \brief Set receiver status (from mainwindow). */ void RemoteControl::setReceiverStatus(bool enabled) { @@ -761,9 +779,11 @@ QString func = cmdlist.value(1, ""); if (func == "?") - answer = QString("RECORD DSP RDS MUTE\n"); + answer = QString("RECORD IQRECORD DSP RDS MUTE\n"); else if (func.compare("RECORD", Qt::CaseInsensitive) == 0) answer = QString("%1\n").arg(audio_recorder_status); + else if (func.compare("IQRECORD", Qt::CaseInsensitive) == 0) + answer = QString("%1\n").arg(iq_recorder_status); else if (func.compare("DSP", Qt::CaseInsensitive) == 0) answer = QString("%1\n").arg(receiver_running); else if (func.compare("RDS", Qt::CaseInsensitive) == 0) @@ -786,7 +806,7 @@ if (func == "?") { - answer = QString("RECORD DSP RDS MUTE\n"); + answer = QString("RECORD IQRECORD DSP RDS MUTE\n"); } else if ((func.compare("RECORD", Qt::CaseInsensitive) == 0) && ok) { @@ -804,6 +824,22 @@ emit stopAudioRecorderEvent(); } } + else if ((func.compare("IQRECORD", Qt::CaseInsensitive) == 0) && ok) + { + if (!receiver_running) + { + answer = QString("RPRT 1\n"); + } + else + { + answer = QString("RPRT 0\n"); + iq_recorder_status = status; + if (status) + emit startIqRecorderEvent(); + else + emit stopIqRecorderEvent(); + } + } else if ((func.compare("DSP", Qt::CaseInsensitive) == 0) && ok) { if (status) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gqrx-2.17.6/src/applications/gqrx/remote_control.h new/gqrx-2.17.7/src/applications/gqrx/remote_control.h --- old/gqrx-2.17.6/src/applications/gqrx/remote_control.h 2024-11-30 01:45:49.000000000 +0100 +++ new/gqrx-2.17.7/src/applications/gqrx/remote_control.h 2025-05-28 00:24:03.000000000 +0200 @@ -30,6 +30,7 @@ #include <QTcpServer> #include <QTcpSocket> #include <QtNetwork> +#include <set> /* For gain_t and gain_list_t */ #include "qtgui/dockinputctl.h" @@ -96,6 +97,8 @@ void setAudioMuted(bool muted); void startAudioRecorder(QString unused); void stopAudioRecorder(); + void startIqRecorder(QString unused1, QString unused2); + void stopIqRecorder(); bool setGain(QString name, double gain); void setRDSstatus(bool enabled); void rdsPI(QString program_id); @@ -112,6 +115,8 @@ void newAudioGain(float gain); void startAudioRecorderEvent(); void stopAudioRecorderEvent(); + void startIqRecorderEvent(); + void stopIqRecorderEvent(); void gainChanged(QString name, double value); void dspChanged(bool value); void newRDSmode(bool value); @@ -120,10 +125,11 @@ private slots: void acceptConnection(); void startRead(); + void socketDisconnect(); private: QTcpServer rc_server; /*!< The active server object. */ - QTcpSocket* rc_socket; /*!< The active socket object. */ + std::set<QTcpSocket*> rc_sockets; /*!< The active socket objects. */ QStringList rc_allowed_hosts; /*!< Hosts where we accept connection from. */ int rc_port; /*!< The port we are listening on. */ @@ -143,7 +149,8 @@ QString rc_program_id; /*!< RDS Program identification */ QString rds_station; /*!< RDS program service (station) name */ QString rds_radiotext; /*!< RDS Radiotext */ - bool audio_recorder_status; /*!< Recording enabled */ + bool audio_recorder_status; /*!< Audio recording enabled */ + bool iq_recorder_status; /*!< IQ recording enabled */ bool receiver_running; /*!< Whether the receiver is running or not */ bool hamlib_compatible; gain_list_t gains; /*!< Possible and current gain settings */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gqrx-2.17.6/src/qtgui/iq_tool.cpp new/gqrx-2.17.7/src/qtgui/iq_tool.cpp --- old/gqrx-2.17.6/src/qtgui/iq_tool.cpp 2024-11-30 01:45:49.000000000 +0100 +++ new/gqrx-2.17.7/src/qtgui/iq_tool.cpp 2025-05-28 00:24:03.000000000 +0200 @@ -165,7 +165,6 @@ emit seek(seek_pos); } - /*! \brief Start/stop recording */ void CIqTool::on_recButton_clicked(bool checked) { @@ -186,6 +185,34 @@ } } +/*! Public slot to start IQ recording by external events (e.g. remote control). + * + * If a recording is already in progress we ignore the event. + */ +void CIqTool::startIqRecorder(void) +{ + if (ui->recButton->isChecked()) + { + qDebug() << __func__ << "An IQ recording is already in progress"; + return; + } + + // emulate a button click + ui->recButton->click(); +} + +/*! Public slot to stop IQ recording by external events (e.g. remote control). + * + * The event is ignored if no recording is in progress. + */ +void CIqTool::stopIqRecorder(void) +{ + if (ui->recButton->isChecked()) + ui->recButton->click(); // emulate a button click + else + qDebug() << __func__ << "No IQ recording in progress"; +} + /*! \brief Cancel a recording. * * This slot can be activated to cancel an ongoing recording. Cancelling an diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gqrx-2.17.6/src/qtgui/iq_tool.h new/gqrx-2.17.7/src/qtgui/iq_tool.h --- old/gqrx-2.17.6/src/qtgui/iq_tool.h 2024-11-30 01:45:49.000000000 +0100 +++ new/gqrx-2.17.7/src/qtgui/iq_tool.h 2025-05-28 00:24:03.000000000 +0200 @@ -71,6 +71,8 @@ public slots: void cancelRecording(); void cancelPlayback(); + void startIqRecorder(void); /*!< Used if IQ Recorder is started e.g. from remote control */ + void stopIqRecorder(void); /*!< Used if IQ Recorder is stopped e.g. from remote control */ private slots: void on_recDirEdit_textChanged(const QString &text);