From 5e0c4449f84c94c748ceb2dead344ada4e8d6c32 Mon Sep 17 00:00:00 2001 From: AlexandreRouma Date: Fri, 9 Feb 2024 22:13:25 +0100 Subject: [PATCH 01/14] switched back ATV demod to black and white --- decoder_modules/atv_decoder/src/main.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/decoder_modules/atv_decoder/src/main.cpp b/decoder_modules/atv_decoder/src/main.cpp index 9ae9856dc..5d9ffce23 100644 --- a/decoder_modules/atv_decoder/src/main.cpp +++ b/decoder_modules/atv_decoder/src/main.cpp @@ -139,18 +139,19 @@ class ATVDecoderModule : public ModuleManager::Instance { _this->pll.process(720, _this->fir.out.writeBuf, _this->pll.out.writeBuf, ((_this->ypos%2)==1) ^ _this->evenFrame); // Render line to the image without color - //int lypos = _this->ypos - 1; - //if (lypos < 0) { lypos = 624; } - //uint32_t* lastLine = &((uint32_t *)_this->img.buffer)[(lypos < 313) ? (lypos*720*2) : ((((lypos - 313)*2)+1)*720) ]; - //uint32_t* currentLine = &((uint32_t *)_this->img.buffer)[(_this->ypos < 313) ? (_this->ypos*720*2) : ((((_this->ypos - 313)*2)+1)*720) ]; + int lypos = _this->ypos - 1; + if (lypos < 0) { lypos = 624; } + uint32_t* lastLine = &((uint32_t *)_this->img.buffer)[(lypos < 313) ? (lypos*720*2) : ((((lypos - 313)*2)+1)*720) ]; + uint32_t* currentLine = &((uint32_t *)_this->img.buffer)[(_this->ypos < 313) ? (_this->ypos*720*2) : ((((_this->ypos - 313)*2)+1)*720) ]; - uint32_t* currentLine = &((uint32_t *)_this->img.buffer)[_this->ypos*720]; + //uint32_t* currentLine = &((uint32_t *)_this->img.buffer)[_this->ypos*720]; for (int i = 0; i < count; i++) { - //float imval = std::clamp((data[i] - _this->minLvl) * 255.0 / _this->spanLvl, 0, 255); - uint32_t re = std::clamp((_this->pll.out.writeBuf[i].re - _this->minLvl) * 255.0 / _this->spanLvl, 0, 255); - uint32_t im = std::clamp((_this->pll.out.writeBuf[i].im - _this->minLvl) * 255.0 / _this->spanLvl, 0, 255); - currentLine[i] = 0xFF000000 | (im << 8) | re; + int imval = std::clamp((data[i] - _this->minLvl) * 255.0 / _this->spanLvl, 0, 255); + // uint32_t re = std::clamp((_this->pll.out.writeBuf[i].re - _this->minLvl) * 255.0 / _this->spanLvl, 0, 255); + // uint32_t im = std::clamp((_this->pll.out.writeBuf[i].im - _this->minLvl) * 255.0 / _this->spanLvl, 0, 255); + // currentLine[i] = 0xFF000000 | (im << 8) | re; + currentLine[i] = 0xFF000000 | (imval << 16) | (imval << 8) | imval; } // Vertical scan logic From 5f23c1f3124c0c35291b90e68f9ba498ab8846c9 Mon Sep 17 00:00:00 2001 From: AlexandreRouma Date: Sat, 10 Feb 2024 20:59:37 +0100 Subject: [PATCH 02/14] added new patrons and hardware donors --- core/src/credits.cpp | 3 +++ readme.md | 2 ++ 2 files changed, 5 insertions(+) diff --git a/core/src/credits.cpp b/core/src/credits.cpp index 58685fbdc..f2ea9a6fa 100644 --- a/core/src/credits.cpp +++ b/core/src/credits.cpp @@ -41,6 +41,7 @@ namespace sdrpp_credits { "CaribouLabs", "Ettus Research", "Howard Su", + "MicroPhase", "MyriadRF", "Nuand", "RFspace", @@ -54,6 +55,7 @@ namespace sdrpp_credits { "Croccydile", "Dale L Puckett (K0HYD)", "Daniele D'Agnelli", + "David Taylor (GM8ARV)", "D. Jones", "Dexruus", "EB3FRN", @@ -81,6 +83,7 @@ namespace sdrpp_credits { "Syne Ardwin (WI9SYN)", "W4IPA", "William Arcand (W1WRA)", + "William Pitchford", "Yves Rougy", "Zipper" }; diff --git a/readme.md b/readme.md index 785c14207..8a02ca87d 100644 --- a/readme.md +++ b/readme.md @@ -433,6 +433,7 @@ I will soon publish a contributing.md listing the code style to use. * Croccydile * Dale L Puckett (K0HYD) * [Daniele D'Agnelli](https://linkedin.com/in/dagnelli) +* [David Taylor (GM8ARV)](https://twitter.com/gm8arv) * D. Jones * Dexruus * [EB3FRN](https://www.eb3frn.net/) @@ -460,6 +461,7 @@ I will soon publish a contributing.md listing the code style to use. * Syne Ardwin (WI9SYN) * [W4IPA](https://twitter.com/W4IPAstroke5) * William Arcand (W1WRA) +* William Pitchford * [Yves Rougy](https://www.twitch.tv/yorzian) * [Zipper](https://github.com/reppiZ) From c616892eda3756915a8c5bdbf432335b73c28d16 Mon Sep 17 00:00:00 2001 From: AlexandreRouma Date: Sun, 11 Feb 2024 19:36:26 +0100 Subject: [PATCH 03/14] attempt to add MacOS M1 CI --- .github/workflows/build_all.yml | 61 +++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build_all.yml b/.github/workflows/build_all.yml index 03a97fa5f..6cdf8151b 100644 --- a/.github/workflows/build_all.yml +++ b/.github/workflows/build_all.yml @@ -84,8 +84,8 @@ jobs: name: sdrpp_windows_x64 path: ${{runner.workspace}}/sdrpp_windows_x64.zip - build_macos: - runs-on: macos-latest + build_macos_intel: + runs-on: macos-12 steps: - uses: actions/checkout@v4 @@ -138,6 +138,60 @@ jobs: name: sdrpp_macos_intel path: ${{runner.workspace}}/sdrpp_macos_intel.zip + build_macos_arm: + runs-on: macos-14 + + steps: + - uses: actions/checkout@v4 + + - name: Create Build Environment + run: cmake -E make_directory ${{runner.workspace}}/build + + - name: Update brew repositories + run: brew update + + - name: Install dependencies + run: brew install pkg-config libusb fftw glfw airspy airspyhf portaudio hackrf libbladerf codec2 zstd autoconf automake libtool && pip3 install mako + + - name: Install volk + run: git clone --recursive https://github.com/gnuradio/volk && cd volk && mkdir build && cd build && cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 -DCMAKE_BUILD_TYPE=Release .. && make -j3 && sudo make install && cd ../../ + + - name: Install SDRplay API + run: wget https://www.sdrplay.com/software/SDRplayAPI-macos-installer-universal-3.12.1.pkg && sudo installer -pkg SDRplayAPI-macos-installer-universal-3.12.1.pkg -target / + + - name: Install libiio + run: wget https://github.com/analogdevicesinc/libiio/archive/refs/tags/v0.25.zip && 7z x v0.25.zip && cd libiio-0.25 && mkdir build && cd build && cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 -DCMAKE_BUILD_TYPE=Release .. && make -j3 && sudo make install && cd ../../ + + - name: Install libad9361 + run: git clone https://github.com/analogdevicesinc/libad9361-iio && cd libad9361-iio && mkdir build && cd build && cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 -DCMAKE_BUILD_TYPE=Release .. && make -j3 && sudo make install && cd ../../ + + - name: Install LimeSuite + run: git clone https://github.com/myriadrf/LimeSuite && cd LimeSuite && mkdir builddir && cd builddir && cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 -DCMAKE_BUILD_TYPE=Release .. && make -j3 && sudo make install && cd ../../ + + - name: Install libperseus + run: git clone https://github.com/Microtelecom/libperseus-sdr && cd libperseus-sdr && autoreconf -i && ./configure --prefix=/usr/local && make && make install && cd .. + + - name: Install more recent librtlsdr + run: git clone https://github.com/osmocom/rtl-sdr && cd rtl-sdr && mkdir build && cd build && cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 -DCMAKE_BUILD_TYPE=Release .. && make -j3 LIBRARY_PATH=$(pkg-config --libs-only-L libusb-1.0 | sed 's/\-L//') && sudo make install && cd ../../ + + - name: Prepare CMake + working-directory: ${{runner.workspace}}/build + run: cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 $GITHUB_WORKSPACE -DOPT_BUILD_PLUTOSDR_SOURCE=ON -DOPT_BUILD_SOAPY_SOURCE=OFF -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_AUDIO_SINK=OFF -DOPT_BUILD_PORTAUDIO_SINK=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=ON -DOPT_BUILD_PERSEUS_SOURCE=ON -DOPT_BUILD_AUDIO_SOURCE=OFF -DUSE_BUNDLE_DEFAULTS=ON -DCMAKE_BUILD_TYPE=Release + + - name: Build + working-directory: ${{runner.workspace}}/build + run: make VERBOSE=1 -j3 + + - name: Create Archive + working-directory: ${{runner.workspace}} + run: cd $GITHUB_WORKSPACE && sh make_macos_bundle.sh ${{runner.workspace}}/build ./SDR++.app && zip -r ${{runner.workspace}}/sdrpp_macos_arm.zip SDR++.app + + - name: Save Archive + uses: actions/upload-artifact@v4 + with: + name: sdrpp_macos_arm + path: ${{runner.workspace}}/sdrpp_macos_arm.zip + build_debian_buster: runs-on: ubuntu-latest @@ -347,7 +401,7 @@ jobs: path: ${{runner.workspace}}/sdrpp.apk create_full_archive: - needs: ['build_windows', 'build_macos', 'build_debian_buster', 'build_debian_bullseye', 'build_debian_bookworm', 'build_debian_sid', 'build_ubuntu_focal', 'build_ubuntu_jammy', 'build_ubuntu_mantic', 'build_raspios_bullseye_armhf', 'build_android'] + needs: ['build_windows', 'build_macos_intel', 'build_macos_arm', 'build_debian_buster', 'build_debian_bullseye', 'build_debian_bookworm', 'build_debian_sid', 'build_ubuntu_focal', 'build_ubuntu_jammy', 'build_ubuntu_mantic', 'build_raspios_bullseye_armhf', 'build_android'] runs-on: ubuntu-latest steps: @@ -359,6 +413,7 @@ jobs: mkdir sdrpp_all && mv sdrpp_windows_x64/sdrpp_windows_x64.zip sdrpp_all/ && mv sdrpp_macos_intel/sdrpp_macos_intel.zip sdrpp_all/ && + mv sdrpp_macos_arm/sdrpp_macos_arm.zip sdrpp_all/ && mv sdrpp_debian_buster_amd64/sdrpp_debian_amd64.deb sdrpp_all/sdrpp_debian_buster_amd64.deb && mv sdrpp_debian_bullseye_amd64/sdrpp_debian_amd64.deb sdrpp_all/sdrpp_debian_bullseye_amd64.deb && mv sdrpp_debian_bookworm_amd64/sdrpp_debian_amd64.deb sdrpp_all/sdrpp_debian_bookworm_amd64.deb && From 5204cfec56fede44d03357fb99d3d16471b95dbd Mon Sep 17 00:00:00 2001 From: AlexandreRouma Date: Sun, 11 Feb 2024 19:41:49 +0100 Subject: [PATCH 04/14] disable perseus source on macos M1 --- .github/workflows/build_all.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build_all.yml b/.github/workflows/build_all.yml index 6cdf8151b..862d41586 100644 --- a/.github/workflows/build_all.yml +++ b/.github/workflows/build_all.yml @@ -168,15 +168,15 @@ jobs: - name: Install LimeSuite run: git clone https://github.com/myriadrf/LimeSuite && cd LimeSuite && mkdir builddir && cd builddir && cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 -DCMAKE_BUILD_TYPE=Release .. && make -j3 && sudo make install && cd ../../ - - name: Install libperseus - run: git clone https://github.com/Microtelecom/libperseus-sdr && cd libperseus-sdr && autoreconf -i && ./configure --prefix=/usr/local && make && make install && cd .. + # - name: Install libperseus + # run: git clone https://github.com/Microtelecom/libperseus-sdr && cd libperseus-sdr && autoreconf -i && ./configure --prefix=/usr/local && make && make install && cd .. - name: Install more recent librtlsdr run: git clone https://github.com/osmocom/rtl-sdr && cd rtl-sdr && mkdir build && cd build && cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 -DCMAKE_BUILD_TYPE=Release .. && make -j3 LIBRARY_PATH=$(pkg-config --libs-only-L libusb-1.0 | sed 's/\-L//') && sudo make install && cd ../../ - name: Prepare CMake working-directory: ${{runner.workspace}}/build - run: cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 $GITHUB_WORKSPACE -DOPT_BUILD_PLUTOSDR_SOURCE=ON -DOPT_BUILD_SOAPY_SOURCE=OFF -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_AUDIO_SINK=OFF -DOPT_BUILD_PORTAUDIO_SINK=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=ON -DOPT_BUILD_PERSEUS_SOURCE=ON -DOPT_BUILD_AUDIO_SOURCE=OFF -DUSE_BUNDLE_DEFAULTS=ON -DCMAKE_BUILD_TYPE=Release + run: cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 $GITHUB_WORKSPACE -DOPT_BUILD_PLUTOSDR_SOURCE=ON -DOPT_BUILD_SOAPY_SOURCE=OFF -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_AUDIO_SINK=OFF -DOPT_BUILD_PORTAUDIO_SINK=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=ON -DOPT_BUILD_PERSEUS_SOURCE=OFF -DOPT_BUILD_AUDIO_SOURCE=OFF -DUSE_BUNDLE_DEFAULTS=ON -DCMAKE_BUILD_TYPE=Release - name: Build working-directory: ${{runner.workspace}}/build From 2b752bb26761bb144dd855f0c2596bcccabaa327 Mon Sep 17 00:00:00 2001 From: AlexandreRouma Date: Sun, 11 Feb 2024 19:57:13 +0100 Subject: [PATCH 05/14] disable M17 decoder on M1 CI --- .github/workflows/build_all.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_all.yml b/.github/workflows/build_all.yml index 862d41586..ae2e3020c 100644 --- a/.github/workflows/build_all.yml +++ b/.github/workflows/build_all.yml @@ -176,7 +176,7 @@ jobs: - name: Prepare CMake working-directory: ${{runner.workspace}}/build - run: cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 $GITHUB_WORKSPACE -DOPT_BUILD_PLUTOSDR_SOURCE=ON -DOPT_BUILD_SOAPY_SOURCE=OFF -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_AUDIO_SINK=OFF -DOPT_BUILD_PORTAUDIO_SINK=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=ON -DOPT_BUILD_PERSEUS_SOURCE=OFF -DOPT_BUILD_AUDIO_SOURCE=OFF -DUSE_BUNDLE_DEFAULTS=ON -DCMAKE_BUILD_TYPE=Release + run: cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 $GITHUB_WORKSPACE -DOPT_BUILD_PLUTOSDR_SOURCE=ON -DOPT_BUILD_SOAPY_SOURCE=OFF -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_AUDIO_SINK=OFF -DOPT_BUILD_PORTAUDIO_SINK=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=OFF -DOPT_BUILD_PERSEUS_SOURCE=OFF -DOPT_BUILD_AUDIO_SOURCE=OFF -DUSE_BUNDLE_DEFAULTS=ON -DCMAKE_BUILD_TYPE=Release - name: Build working-directory: ${{runner.workspace}}/build From 01ab1831e8cff851028453f1dde7868f7f0dc6ff Mon Sep 17 00:00:00 2001 From: AlexandreRouma Date: Mon, 12 Feb 2024 22:07:17 +0100 Subject: [PATCH 06/14] more progress on the network source --- source_modules/network_source/src/main.cpp | 41 ++++++++++------------ 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/source_modules/network_source/src/main.cpp b/source_modules/network_source/src/main.cpp index fac955947..90f6d8ae5 100644 --- a/source_modules/network_source/src/main.cpp +++ b/source_modules/network_source/src/main.cpp @@ -35,6 +35,13 @@ enum SampleType { SAMPLE_TYPE_FLOAT32 }; +const size_t SAMPLE_TYPE_SIZE[] { + sizeof(int8_t)*2, + sizeof(int16_t)*2, + sizeof(int32_t)*2, + sizeof(float)*2, +}; + class NetworkSourceModule : public ModuleManager::Instance { public: NetworkSourceModule(std::string name) { @@ -237,40 +244,28 @@ class NetworkSourceModule : public ModuleManager::Instance { } void worker() { - int frameSize = samplerate / 200; - switch (sampType) { - case SAMPLE_TYPE_INT8: - frameSize *= 2*sizeof(int8_t);; - break; - case SAMPLE_TYPE_INT16: - frameSize *= 2*sizeof(int16_t); - break; - case SAMPLE_TYPE_INT32: - frameSize *= 2*sizeof(int32_t); - break; - case SAMPLE_TYPE_FLOAT32: - frameSize *= sizeof(dsp::complex_t); - break; - default: - return; - } - uint8_t* buffer = dsp::buffer::alloc(STREAM_BUFFER_SIZE*sizeof(uint32_t)); + int blockSize = samplerate / 200; + int frameSize = blockSize*SAMPLE_TYPE_SIZE[sampType]; + uint8_t* buffer = dsp::buffer::alloc(frameSize); while (true) { // Read samples from socket - int bytes = sock->recv(buffer, frameSize, true); + { + std::lock_guard lck(sockMtx); + int bytes = sock->recv(buffer, frameSize, true); + } // Convert to CF32 int count; switch (sampType) { case SAMPLE_TYPE_INT8: - frameSize *= 2*sizeof(int8_t);; + break; case SAMPLE_TYPE_INT16: - frameSize *= 2*sizeof(int16_t); + break; case SAMPLE_TYPE_INT32: - frameSize *= 2*sizeof(int32_t); + break; case SAMPLE_TYPE_FLOAT32: //memcpy(stream.writeBuf, buffer, ) @@ -280,7 +275,7 @@ class NetworkSourceModule : public ModuleManager::Instance { } // Send out converted samples - //if (!stream.swap(bufferSize)) + if (!stream.swap(count)) { break; } } dsp::buffer::free(buffer); From 61c14bab482ec377c3c9f9f25fa99c9643159664 Mon Sep 17 00:00:00 2001 From: AlexandreRouma Date: Mon, 12 Feb 2024 22:43:16 +0100 Subject: [PATCH 07/14] fix iq_exporter module crashing when removed in the case it's disabled and in baseband mode --- misc_modules/iq_exporter/src/main.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/misc_modules/iq_exporter/src/main.cpp b/misc_modules/iq_exporter/src/main.cpp index 4f8ec61d1..645e30578 100644 --- a/misc_modules/iq_exporter/src/main.cpp +++ b/misc_modules/iq_exporter/src/main.cpp @@ -408,9 +408,9 @@ class IQExporterModule : public ModuleManager::Instance { if (!_this->enabled) { ImGui::EndDisabled(); } } - void setMode(Mode newMode, bool fromDisabled = false) { + void setMode(Mode newMode, bool forceSet = false) { // If there is no mode to change, do nothing - if (!fromDisabled && mode == newMode) { return; } + if (!forceSet && mode == newMode) { return; } // Stop the DSP reshape.stop(); @@ -421,14 +421,13 @@ class IQExporterModule : public ModuleManager::Instance { sigpath::vfoManager.deleteVFO(vfo); vfo = NULL; } - if (mode == MODE_BASEBAND && !fromDisabled) { + if (streamBound) { sigpath::iqFrontEnd.unbindIQStream(&iqStream); + streamBound = false; } // If the mode was none, we're done - if (newMode == MODE_NONE) { - return; - } + if (newMode == MODE_NONE) { return; } // Create VFO or bind IQ stream if (newMode == MODE_VFO) { @@ -441,6 +440,7 @@ class IQExporterModule : public ModuleManager::Instance { else { // Bind IQ stream sigpath::iqFrontEnd.bindIQStream(&iqStream); + streamBound = true; // Set its output as the input to the DSP reshape.setInput(&iqStream); @@ -555,6 +555,7 @@ class IQExporterModule : public ModuleManager::Instance { OptionList packetSizes; VFOManager::VFO* vfo = NULL; + bool streamBound = false; dsp::stream iqStream; dsp::buffer::Reshaper reshape; dsp::sink::Handler handler; From 726e1069bf105567b93a6dea8bbfc45ea99012b3 Mon Sep 17 00:00:00 2001 From: AlexandreRouma Date: Mon, 12 Feb 2024 22:46:03 +0100 Subject: [PATCH 08/14] fix wrong mode name in rigctl server as described in #1327 --- misc_modules/rigctl_server/src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc_modules/rigctl_server/src/main.cpp b/misc_modules/rigctl_server/src/main.cpp index 3673d4dd8..926ce6ea7 100644 --- a/misc_modules/rigctl_server/src/main.cpp +++ b/misc_modules/rigctl_server/src/main.cpp @@ -334,7 +334,7 @@ class SigctlServerModule : public ModuleManager::Instance { } std::map radioModeToString = { - { RADIO_IFACE_MODE_NFM, "NFM" }, + { RADIO_IFACE_MODE_NFM, "FM" }, { RADIO_IFACE_MODE_WFM, "WFM" }, { RADIO_IFACE_MODE_AM, "AM" }, { RADIO_IFACE_MODE_DSB, "DSB" }, From 34171d4edc69fd8534aeb39e01ea6e66192c75a9 Mon Sep 17 00:00:00 2001 From: AlexandreRouma Date: Mon, 12 Feb 2024 23:24:00 +0100 Subject: [PATCH 09/14] fix windows CI --- .github/workflows/build_all.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_all.yml b/.github/workflows/build_all.yml index ae2e3020c..5792dd967 100644 --- a/.github/workflows/build_all.yml +++ b/.github/workflows/build_all.yml @@ -37,10 +37,10 @@ jobs: run: 7z x libusb.7z -olibusb_old ; rm "C:/Program Files/PothosSDR/bin/libusb-1.0.dll" ; cp "libusb_old/MS64/dll/libusb-1.0.dll" "C:/Program Files/PothosSDR/bin/" ; rm "C:/Program Files/PothosSDR/lib/libusb-1.0.lib" ; cp "libusb_old/MS64/dll/libusb-1.0.lib" "C:/Program Files/PothosSDR/lib/" - name: Download SDRPlay API - run: Invoke-WebRequest -Uri "https://drive.google.com/uc?id=12UHPMwkfa67A11QZDmpCT4iwHnyJHWuu&confirm=t" -OutFile ${{runner.workspace}}/SDRPlay.zip + run: Invoke-WebRequest -Uri "https://www.sdrpp.org/SDRplay.zip" -OutFile ${{runner.workspace}}/SDRplay.zip - name: Install SDRPlay API - run: 7z x ${{runner.workspace}}/SDRPlay.zip -o"C:/Program Files/" + run: 7z x ${{runner.workspace}}/SDRplay.zip -o"C:/Program Files/" - name: Download codec2 run: git clone https://github.com/AlexandreRouma/codec2 From 95052c34ff83a1d713bfb20279befd85f5beb601 Mon Sep 17 00:00:00 2001 From: AlexandreRouma Date: Tue, 13 Feb 2024 03:11:37 +0100 Subject: [PATCH 10/14] more work on network source and syntax cleanup in iq exporter --- misc_modules/iq_exporter/src/main.cpp | 2 +- source_modules/network_source/src/main.cpp | 23 ++++++++++++++-------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/misc_modules/iq_exporter/src/main.cpp b/misc_modules/iq_exporter/src/main.cpp index 645e30578..9c9c50113 100644 --- a/misc_modules/iq_exporter/src/main.cpp +++ b/misc_modules/iq_exporter/src/main.cpp @@ -509,7 +509,7 @@ class IQExporterModule : public ModuleManager::Instance { size = sizeof(int16_t)*2; break; case SAMPLE_TYPE_INT32: - volk_32f_s32f_convert_32i((int32_t*)_this->buffer, (float*)data, (float)2147483647.0f, count*2); + volk_32f_s32f_convert_32i((int32_t*)_this->buffer, (float*)data, 2147483647.0f, count*2); size = sizeof(int32_t)*2; break; case SAMPLE_TYPE_FLOAT32: diff --git a/source_modules/network_source/src/main.cpp b/source_modules/network_source/src/main.cpp index 90f6d8ae5..08cd7c7da 100644 --- a/source_modules/network_source/src/main.cpp +++ b/source_modules/network_source/src/main.cpp @@ -244,31 +244,37 @@ class NetworkSourceModule : public ModuleManager::Instance { } void worker() { + // Compute sizes int blockSize = samplerate / 200; - int frameSize = blockSize*SAMPLE_TYPE_SIZE[sampType]; + int sampleSize = SAMPLE_TYPE_SIZE[sampType]; + int frameSize = blockSize*sampleSize; + + // Allocate receive buffer uint8_t* buffer = dsp::buffer::alloc(frameSize); while (true) { // Read samples from socket + int bytes; { std::lock_guard lck(sockMtx); - int bytes = sock->recv(buffer, frameSize, true); + bytes = sock->recv(buffer, frameSize, true); + if (bytes <= 0) { break; } } - // Convert to CF32 - int count; + // Convert to CF32 (note: problem if partial sample) + int count = bytes / sampleSize; switch (sampType) { case SAMPLE_TYPE_INT8: - + volk_8i_s32f_convert_32f((float*)stream.writeBuf, (int8_t*)buffer, 128.0f, count*2); break; case SAMPLE_TYPE_INT16: - + volk_16i_s32f_convert_32f((float*)stream.writeBuf, (int16_t*)buffer, 32768.0f, count*2); break; case SAMPLE_TYPE_INT32: - + volk_32i_s32f_convert_32f((float*)stream.writeBuf, (int32_t*)buffer, 2147483647.0f, count*2); break; case SAMPLE_TYPE_FLOAT32: - //memcpy(stream.writeBuf, buffer, ) + memcpy(stream.writeBuf, buffer, bytes); break; default: break; @@ -278,6 +284,7 @@ class NetworkSourceModule : public ModuleManager::Instance { if (!stream.swap(count)) { break; } } + // Free receive buffer dsp::buffer::free(buffer); } From edc08ddc0823c3a350c4bb32487d86314efca938 Mon Sep 17 00:00:00 2001 From: AlexandreRouma Date: Tue, 13 Feb 2024 16:17:17 +0100 Subject: [PATCH 11/14] more progress on the network source --- CMakeLists.txt | 2 +- source_modules/network_source/src/main.cpp | 48 ++++++++++++++++++---- 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0c82dbb9a..0f3fe4044 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ option(OPT_BUILD_FILE_SOURCE "Wav file source" ON) option(OPT_BUILD_HACKRF_SOURCE "Build HackRF Source Module (Dependencies: libhackrf)" ON) option(OPT_BUILD_HERMES_SOURCE "Build Hermes Source Module (no dependencies required)" ON) option(OPT_BUILD_LIMESDR_SOURCE "Build LimeSDR Source Module (Dependencies: liblimesuite)" OFF) -option(OPT_BUILD_NETWORK_SOURCE "Build Network Source Module (no dependencies required)" on) +option(OPT_BUILD_NETWORK_SOURCE "Build Network Source Module (no dependencies required)" ON) option(OPT_BUILD_PERSEUS_SOURCE "Build Perseus Source Module (Dependencies: libperseus-sdr)" OFF) option(OPT_BUILD_PLUTOSDR_SOURCE "Build PlutoSDR Source Module (Dependencies: libiio, libad9361)" ON) option(OPT_BUILD_RFSPACE_SOURCE "Build RFspace Source Module (no dependencies required)" ON) diff --git a/source_modules/network_source/src/main.cpp b/source_modules/network_source/src/main.cpp index 08cd7c7da..29db4032d 100644 --- a/source_modules/network_source/src/main.cpp +++ b/source_modules/network_source/src/main.cpp @@ -73,7 +73,7 @@ class NetworkSourceModule : public ModuleManager::Instance { } // Define protocols - protocols.define("TCP (Server)", PROTOCOL_TCP_SERVER); + // protocols.define("TCP (Server)", PROTOCOL_TCP_SERVER); protocols.define("TCP (Client)", PROTOCOL_TCP_CLIENT); protocols.define("UDP", PROTOCOL_UDP); @@ -164,7 +164,31 @@ class NetworkSourceModule : public ModuleManager::Instance { NetworkSourceModule* _this = (NetworkSourceModule*)ctx; if (_this->running) { return; } - // TODO + // Depends on protocol + try { + if (_this->proto == PROTOCOL_TCP_SERVER) { + // Create TCP listener + // TODO + + // Start listen worker + // TODO + } + else if (_this->proto == PROTOCOL_TCP_CLIENT) { + // Connect to TCP server + _this->sock = net::connect(_this->hostname, _this->port); + } + else if (_this->proto == PROTOCOL_UDP) { + // Open UDP socket + _this->sock = net::openudp("0.0.0.0", _this->port, _this->hostname, _this->port, true); + } + } + catch (const std::exception& e) { + flog::error("Could not start Network Source: {}", e.what()); + return; + } + + // Start receive worker + _this->workerThread = std::thread(&NetworkSourceModule::worker, _this); _this->running = true; flog::info("NetworkSourceModule '{0}': Start!", _this->name); @@ -174,8 +198,17 @@ class NetworkSourceModule : public ModuleManager::Instance { NetworkSourceModule* _this = (NetworkSourceModule*)ctx; if (!_this->running) { return; } + // Stop listen worker // TODO + // Close connection + if (_this->sock) { _this->sock->close(); } + + // Stop worker thread + _this->stream.stopWriter(); + if (_this->workerThread.joinable()) { _this->workerThread.join(); } + _this->stream.clearWriteStop(); + _this->running = false; flog::info("NetworkSourceModule '{0}': Stop!", _this->name); } @@ -254,12 +287,8 @@ class NetworkSourceModule : public ModuleManager::Instance { while (true) { // Read samples from socket - int bytes; - { - std::lock_guard lck(sockMtx); - bytes = sock->recv(buffer, frameSize, true); - if (bytes <= 0) { break; } - } + int bytes = sock->recv(buffer, frameSize, true); + if (bytes <= 0) { break; } // Convert to CF32 (note: problem if partial sample) int count = bytes / sampleSize; @@ -297,7 +326,7 @@ class NetworkSourceModule : public ModuleManager::Instance { int samplerate = 1000000; int srId; - Protocol proto = PROTOCOL_TCP_SERVER; + Protocol proto = PROTOCOL_UDP; int protoId; SampleType sampType = SAMPLE_TYPE_INT16; int sampTypeId; @@ -308,6 +337,7 @@ class NetworkSourceModule : public ModuleManager::Instance { OptionList protocols; OptionList sampleTypes; + std::thread workerThread; std::thread listenWorkerThread; std::mutex sockMtx; From 9ab3c97c44ae90934adebaab133533356596721e Mon Sep 17 00:00:00 2001 From: AlexandreRouma Date: Tue, 13 Feb 2024 16:18:25 +0100 Subject: [PATCH 12/14] don't include rc file on platforms other than windows --- CMakeLists.txt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0f3fe4044..470b17cb1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -287,7 +287,12 @@ if (OPT_BUILD_SCHEDULER) add_subdirectory("misc_modules/scheduler") endif (OPT_BUILD_SCHEDULER) -add_executable(sdrpp "src/main.cpp" "win32/resources.rc") +if (MSVC) + add_executable(sdrpp "src/main.cpp" "win32/resources.rc") +else () + add_executable(sdrpp "src/main.cpp") +endif () + target_link_libraries(sdrpp PRIVATE sdrpp_core) # Compiler arguments From 61ffb3e6bf63df866cb568cd75c4b52464623265 Mon Sep 17 00:00:00 2001 From: AlexandreRouma Date: Tue, 13 Feb 2024 16:27:54 +0100 Subject: [PATCH 13/14] revert pager decoder to traditional clock recovery --- .../pager_decoder/src/pocsag/decoder.h | 4 +- .../pager_decoder/src/pocsag/dsp.h | 104 +-------- .../src/pocsag/packet_clock_sync.h | 221 ------------------ 3 files changed, 6 insertions(+), 323 deletions(-) delete mode 100644 decoder_modules/pager_decoder/src/pocsag/packet_clock_sync.h diff --git a/decoder_modules/pager_decoder/src/pocsag/decoder.h b/decoder_modules/pager_decoder/src/pocsag/decoder.h index 672bed3db..9807e6d39 100644 --- a/decoder_modules/pager_decoder/src/pocsag/decoder.h +++ b/decoder_modules/pager_decoder/src/pocsag/decoder.h @@ -13,7 +13,7 @@ class POCSAGDecoder : public Decoder { public: - POCSAGDecoder(const std::string& name, VFOManager::VFO* vfo) : diag(0.6, 544) { + POCSAGDecoder(const std::string& name, VFOManager::VFO* vfo) : diag(0.6, BAUDRATE) { this->name = name; this->vfo = vfo; @@ -26,7 +26,7 @@ class POCSAGDecoder : public Decoder { vfo->setBandwidthLimits(12500, 12500, true); vfo->setSampleRate(SAMPLERATE, 12500); dsp.init(vfo->output, SAMPLERATE, BAUDRATE); - reshape.init(&dsp.soft, 544, 0); + reshape.init(&dsp.soft, BAUDRATE, (BAUDRATE / 30.0) - BAUDRATE); dataHandler.init(&dsp.out, _dataHandler, this); diagHandler.init(&reshape.out, _diagHandler, this); diff --git a/decoder_modules/pager_decoder/src/pocsag/dsp.h b/decoder_modules/pager_decoder/src/pocsag/dsp.h index f5d10a6fe..20a1b8f89 100644 --- a/decoder_modules/pager_decoder/src/pocsag/dsp.h +++ b/decoder_modules/pager_decoder/src/pocsag/dsp.h @@ -11,89 +11,6 @@ #include #include -#include "packet_clock_sync.h" - -inline float PATTERN_DSDSDZED[] = { - -1.00000000e+00, -8.00000000e-01, -6.00000000e-01, -4.00000000e-01, - -2.00000000e-01, -2.77555756e-17, 2.00000000e-01, 4.00000000e-01, - 6.00000000e-01, 8.00000000e-01, 1.00000000e+00, 1.00000000e+00, - 1.00000000e+00, 1.00000000e+00, 1.00000000e+00, 1.00000000e+00, - 1.00000000e+00, 1.00000000e+00, 1.00000000e+00, 1.00000000e+00, - 1.00000000e+00, 1.00000000e+00, 1.00000000e+00, 1.00000000e+00, - 1.00000000e+00, 1.00000000e+00, 1.00000000e+00, 1.00000000e+00, - 1.00000000e+00, 1.00000000e+00, 1.00000000e+00, 1.00000000e+00, - 1.00000000e+00, 1.00000000e+00, 1.00000000e+00, 1.00000000e+00, - 1.00000000e+00, 1.00000000e+00, 1.00000000e+00, 1.00000000e+00, - 1.00000000e+00, 1.00000000e+00, 1.00000000e+00, 1.00000000e+00, - 1.00000000e+00, 1.00000000e+00, 1.00000000e+00, 1.00000000e+00, - 1.00000000e+00, 1.00000000e+00, 1.00000000e+00, 8.00000000e-01, - 6.00000000e-01, 4.00000000e-01, 2.00000000e-01, 2.77555756e-17, - -2.00000000e-01, -4.00000000e-01, -6.00000000e-01, -8.00000000e-01, - -1.00000000e+00, -1.00000000e+00, -1.00000000e+00, -1.00000000e+00, - -1.00000000e+00, -1.00000000e+00, -1.00000000e+00, -1.00000000e+00, - -1.00000000e+00, -1.00000000e+00, -1.00000000e+00, -8.00000000e-01, - -6.00000000e-01, -4.00000000e-01, -2.00000000e-01, -2.77555756e-17, - 2.00000000e-01, 4.00000000e-01, 6.00000000e-01, 8.00000000e-01, - 1.00000000e+00, 1.00000000e+00, 1.00000000e+00, 1.00000000e+00, - 1.00000000e+00, 1.00000000e+00, 1.00000000e+00, 1.00000000e+00, - 1.00000000e+00, 1.00000000e+00, 1.00000000e+00, 8.00000000e-01, - 6.00000000e-01, 4.00000000e-01, 2.00000000e-01, 2.77555756e-17, - -2.00000000e-01, -4.00000000e-01, -6.00000000e-01, -8.00000000e-01, - -1.00000000e+00, -8.00000000e-01, -6.00000000e-01, -4.00000000e-01, - -2.00000000e-01, -2.77555756e-17, 2.00000000e-01, 4.00000000e-01, - 6.00000000e-01, 8.00000000e-01, 1.00000000e+00, 8.00000000e-01, - 6.00000000e-01, 4.00000000e-01, 2.00000000e-01, 2.77555756e-17, - -2.00000000e-01, -4.00000000e-01, -6.00000000e-01, -8.00000000e-01, - -1.00000000e+00, -1.00000000e+00, -1.00000000e+00, -1.00000000e+00, - -1.00000000e+00, -1.00000000e+00, -1.00000000e+00, -1.00000000e+00, - -1.00000000e+00, -1.00000000e+00, -1.00000000e+00, -8.00000000e-01, - -6.00000000e-01, -4.00000000e-01, -2.00000000e-01, -2.77555756e-17, - 2.00000000e-01, 4.00000000e-01, 6.00000000e-01, 8.00000000e-01, - 1.00000000e+00, 8.00000000e-01, 6.00000000e-01, 4.00000000e-01, - 2.00000000e-01, 2.77555756e-17, -2.00000000e-01, -4.00000000e-01, - -6.00000000e-01, -8.00000000e-01, -1.00000000e+00, -1.00000000e+00, - -1.00000000e+00, -1.00000000e+00, -1.00000000e+00, -1.00000000e+00, - -1.00000000e+00, -1.00000000e+00, -1.00000000e+00, -1.00000000e+00, - -1.00000000e+00, -1.00000000e+00, -1.00000000e+00, -1.00000000e+00, - -1.00000000e+00, -1.00000000e+00, -1.00000000e+00, -1.00000000e+00, - -1.00000000e+00, -1.00000000e+00, -1.00000000e+00, -1.00000000e+00, - -1.00000000e+00, -1.00000000e+00, -1.00000000e+00, -1.00000000e+00, - -1.00000000e+00, -1.00000000e+00, -1.00000000e+00, -1.00000000e+00, - -1.00000000e+00, -8.00000000e-01, -6.00000000e-01, -4.00000000e-01, - -2.00000000e-01, -2.77555756e-17, 2.00000000e-01, 4.00000000e-01, - 6.00000000e-01, 8.00000000e-01, 1.00000000e+00, 8.00000000e-01, - 6.00000000e-01, 4.00000000e-01, 2.00000000e-01, 2.77555756e-17, - -2.00000000e-01, -4.00000000e-01, -6.00000000e-01, -8.00000000e-01, - -1.00000000e+00, -8.00000000e-01, -6.00000000e-01, -4.00000000e-01, - -2.00000000e-01, -2.77555756e-17, 2.00000000e-01, 4.00000000e-01, - 6.00000000e-01, 8.00000000e-01, 1.00000000e+00, 8.00000000e-01, - 6.00000000e-01, 4.00000000e-01, 2.00000000e-01, 2.77555756e-17, - -2.00000000e-01, -4.00000000e-01, -6.00000000e-01, -8.00000000e-01, - -1.00000000e+00, -8.00000000e-01, -6.00000000e-01, -4.00000000e-01, - -2.00000000e-01, -2.77555756e-17, 2.00000000e-01, 4.00000000e-01, - 6.00000000e-01, 8.00000000e-01, 1.00000000e+00, 1.00000000e+00, - 1.00000000e+00, 1.00000000e+00, 1.00000000e+00, 1.00000000e+00, - 1.00000000e+00, 1.00000000e+00, 1.00000000e+00, 1.00000000e+00, - 1.00000000e+00, 1.00000000e+00, 1.00000000e+00, 1.00000000e+00, - 1.00000000e+00, 1.00000000e+00, 1.00000000e+00, 1.00000000e+00, - 1.00000000e+00, 1.00000000e+00, 1.00000000e+00, 8.00000000e-01, - 6.00000000e-01, 4.00000000e-01, 2.00000000e-01, 2.77555756e-17, - -2.00000000e-01, -4.00000000e-01, -6.00000000e-01, -8.00000000e-01, - -1.00000000e+00, -8.00000000e-01, -6.00000000e-01, -4.00000000e-01, - -2.00000000e-01, -2.77555756e-17, 2.00000000e-01, 4.00000000e-01, - 6.00000000e-01, 8.00000000e-01, 1.00000000e+00, 1.00000000e+00, - 1.00000000e+00, 1.00000000e+00, 1.00000000e+00, 1.00000000e+00, - 1.00000000e+00, 1.00000000e+00, 1.00000000e+00, 1.00000000e+00, - 1.00000000e+00, 8.00000000e-01, 6.00000000e-01, 4.00000000e-01, - 2.00000000e-01, 2.77555756e-17, -2.00000000e-01, -4.00000000e-01, - -6.00000000e-01, -8.00000000e-01, -1.00000000e+00, -1.00000000e+00, - -1.00000000e+00, -1.00000000e+00, -1.00000000e+00, -1.00000000e+00, - -1.00000000e+00, -1.00000000e+00, -1.00000000e+00, -1.00000000e+00, - -1.00000000e+00, -1.00000000e+00, -1.00000000e+00, -1.00000000e+00, - -1.00000000e+00, -1.00000000e+00, -1.00000000e+00, -1.00000000e+00, - -1.00000000e+00, -1.00000000e+00, -1.00000000e+00 -}; - class POCSAGDSP : public dsp::Processor { using base_type = dsp::Processor; public: @@ -106,16 +23,12 @@ class POCSAGDSP : public dsp::Processor { // Configure blocks demod.init(NULL, -4500.0, samplerate); - //dcBlock.init(NULL, 0.001); // NOTE: DC blocking causes issues because no scrambling, think more about it float taps[] = { 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f }; shape = dsp::taps::fromArray(10, taps); fir.init(NULL, shape); - //recov.init(NULL, samplerate/baudrate, 1e-4, 1.0, 0.05); - - cs.init(NULL, PATTERN_DSDSDZED, sizeof(PATTERN_DSDSDZED)/sizeof(float), 544, 10); + recov.init(NULL, samplerate/baudrate, 1e-4, 1.0, 0.05); // Free useless buffers - // dcBlock.out.free(); fir.out.free(); recov.out.free(); @@ -125,13 +38,9 @@ class POCSAGDSP : public dsp::Processor { int process(int count, dsp::complex_t* in, float* softOut, uint8_t* out) { count = demod.process(count, in, demod.out.readBuf); - //count = dcBlock.process(count, demod.out.readBuf, demod.out.readBuf); count = fir.process(count, demod.out.readBuf, demod.out.readBuf); - //count = recov.process(count, demod.out.readBuf, softOut); - - count = cs.process(count, demod.out.readBuf, softOut); - - //dsp::digital::BinarySlicer::process(count, softOut, out); + count = recov.process(count, demod.out.readBuf, softOut); + dsp::digital::BinarySlicer::process(count, softOut, out); return count; } @@ -146,10 +55,8 @@ class POCSAGDSP : public dsp::Processor { count = process(count, base_type::_in->readBuf, soft.writeBuf, base_type::out.writeBuf); base_type::_in->flush(); - //if (!base_type::out.swap(count)) { return -1; } - + if (!base_type::out.swap(count)) { return -1; } if (count) { if (!soft.swap(count)) { return -1; } } - return count; } @@ -157,11 +64,8 @@ class POCSAGDSP : public dsp::Processor { private: dsp::demod::Quadrature demod; - //dsp::correction::DCBlocker dcBlock; dsp::tap shape; dsp::filter::FIR fir; dsp::clock_recovery::MM recov; - dsp::PacketClockSync cs; - }; \ No newline at end of file diff --git a/decoder_modules/pager_decoder/src/pocsag/packet_clock_sync.h b/decoder_modules/pager_decoder/src/pocsag/packet_clock_sync.h deleted file mode 100644 index e5367f579..000000000 --- a/decoder_modules/pager_decoder/src/pocsag/packet_clock_sync.h +++ /dev/null @@ -1,221 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace dsp { - class PacketClockSync : public dsp::Processor { - using base_type = dsp::Processor; - public: - PacketClockSync() {} - PacketClockSync(dsp::stream* in, float* pattern, int patternLen, int frameLen, float sampsPerSym, float threshold = 0.4f) { init(in, pattern, patternLen, frameLen, sampsPerSym, threshold); } - - // TODO: Free in destroyer - - void init(dsp::stream* in, float* pattern, int patternLen, int frameLen, float sampsPerSym, float threshold = 0.4f) { - // Compute the required FFT size and associated delay length - fftSize = 512;// TODO: Find smallest power of 2 that fits patternLen - delayLen = fftSize - 1; - - // Allocate buffers - buffer = dsp::buffer::alloc(STREAM_BUFFER_SIZE+delayLen); - bufferStart = &buffer[delayLen]; - this->pattern = dsp::buffer::alloc(patternLen); - patternFFT = dsp::buffer::alloc(fftSize); - patternFFTAmps = dsp::buffer::alloc(fftSize); - fftIn = fftwf_alloc_real(fftSize); - fftOut = (complex_t*)fftwf_alloc_complex(fftSize); - - // Copy parameters - memcpy(this->pattern, pattern, patternLen*sizeof(float)); - this->sampsPerSym = sampsPerSym; - this->threshold = threshold; - this->patternLen = patternLen; - this->frameLen = frameLen; - - // Plan FFT - plan = fftwf_plan_dft_r2c_1d(fftSize, fftIn, (fftwf_complex*)fftOut, FFTW_ESTIMATE); - - // Pre-compute pattern conjugated FFT - // TODO: Offset the pattern to avoid it being cut off (EXTREMELY IMPORTANT) - memcpy(fftIn, pattern, patternLen*sizeof(float)); - memset(&fftIn[patternLen], 0, (fftSize-patternLen)*sizeof(float)); - fftwf_execute(plan); - volk_32fc_conjugate_32fc((lv_32fc_t*)patternFFT, (lv_32fc_t*)fftOut, fftSize); - - // Compute amplitudes of the pattern FFT - volk_32fc_magnitude_32f(patternFFTAmps, (lv_32fc_t*)patternFFT, fftSize); - - // Normalize the amplitudes - float maxAmp = 0.0f; - for (int i = 0; i < fftSize/2; i++) { - if (patternFFTAmps[i] > maxAmp) { maxAmp = patternFFTAmps[i]; } - } - volk_32f_s32f_multiply_32f(patternFFTAmps, patternFFTAmps, 1.0f/maxAmp, fftSize); - - // Initialize the phase control loop - float omegaRelLimit = 0.05; - pcl.init(1, 10e-4, 0.0, 0.0, 1.0, sampsPerSym, sampsPerSym * (1.0 - omegaRelLimit), sampsPerSym * (1.0 + omegaRelLimit)); - generateInterpTaps(); - - // Init base - base_type::init(in); - } - - int process(int count, float* in, float* out) { - // Copy to buffer - memcpy(bufferStart, in, count * sizeof(float)); - - int outCount = 0; - - for (int i = 0; i < count;) { - // Run clock recovery if needed - while (toRead) { - // Interpolate symbol - float symbol; - int phase = std::clamp(floorf(pcl.phase * (float)interpPhaseCount), 0, interpPhaseCount - 1); - volk_32f_x2_dot_prod_32f(&symbol, &buffer[offsetInt], interpBank.phases[phase], interpTapCount); - out[outCount++] = symbol; - - // Compute symbol phase error - float error = (math::step(lastSymbol) * symbol) - (lastSymbol * math::step(symbol)); - lastSymbol = symbol; - - // Clamp symbol phase error - if (error > 1.0f) { error = 1.0f; } - if (error < -1.0f) { error = -1.0f; } - - // Advance symbol offset and phase - pcl.advance(error); - float delta = floorf(pcl.phase); - offsetInt += delta; - i = offsetInt; - pcl.phase -= delta; - - // Decrement read counter - toRead--; - - if (offsetInt >= count) { - offsetInt -= count; - break; - } - } - - - // Measure correlation to the sync pattern - float corr; - volk_32f_x2_dot_prod_32f(&corr, &buffer[i], pattern, patternLen); - - // If not correlated enough, go to next sample. Otherwise continue with fine detection - if (corr/(float)patternLen < threshold) { - i++; - continue; - } - - // Copy samples into FFT input (only the part where we think the pattern is located) - // TODO: Instead, check the interval onto which correlation occurs to determine where the pattern is located (IMPORTANT) - memcpy(fftIn, &buffer[i], patternLen*sizeof(float)); - - // Compute FFT - fftwf_execute(plan); - - // Multiply with the conjugated pattern FFT to get the phase offset at each frequency - volk_32fc_x2_multiply_32fc((lv_32fc_t*)fftOut, (lv_32fc_t*)fftOut, (lv_32fc_t*)patternFFT, fftSize); - - // Compute the average phase delay rate - float last = 0; - float rateIntegral = 0; - for (int j = 1; j < fftSize/2; j++) { - // Compute instantanous rate - float currentPhase = fftOut[j].phase(); - float instantRate = dsp::math::normalizePhase(currentPhase - last); - last = currentPhase; - - // Compute current rate guess - float rateGuess = rateIntegral / (float)j; - - // Update the rate integral as a weighted average of the current guess and measured rate depending on pattern amplitude - rateIntegral += patternFFTAmps[j]*instantRate + (1.0f-patternFFTAmps[j])*rateGuess; - } - float avgRate = 1.14f*rateIntegral/(float)(fftSize/2); - - // Compute the total offset - float offset = (float)i - avgRate*(float)fftSize/(2.0f*FL_M_PI); - flog::debug("Detected: {} -> {}", i, offset); - - // Initialize clock recovery - offsetInt = floorf(offset) - 3; // TODO: Will be negative sometimes, has to be taken into account - pcl.phase = offset - (float)floorf(offset); - pcl.freq = sampsPerSym; - - // Start reading symbols - toRead = frameLen; - } - - // Move unused data - memmove(buffer, &buffer[count], delayLen * sizeof(float)); - - return outCount; - } - - int run() { - int count = base_type::_in->read(); - if (count < 0) { return -1; } - - count = process(count, base_type::_in->readBuf, base_type::out.writeBuf); - - base_type::_in->flush(); - if (count) { - if (!base_type::out.swap(count)) { return -1; } - } - return count; - } - - private: - void generateInterpTaps() { - double bw = 0.5 / (double)interpPhaseCount; - dsp::tap lp = dsp::taps::windowedSinc(interpPhaseCount * interpTapCount, dsp::math::hzToRads(bw, 1.0), dsp::window::nuttall, interpPhaseCount); - interpBank = dsp::multirate::buildPolyphaseBank(interpPhaseCount, lp); - taps::free(lp); - } - - int delayLen; - float* buffer = NULL; - float* bufferStart = NULL; - float* pattern = NULL; - int patternLen; - bool locked; - int fftSize; - int frameLen; - float threshold; - - float* fftIn = NULL; - complex_t* fftOut = NULL; - fftwf_plan plan; - - complex_t* patternFFT; - float* patternFFTAmps; - - float sampsPerSym; - int toRead = 0; - - loop::PhaseControlLoop pcl; - dsp::multirate::PolyphaseBank interpBank; - int interpTapCount = 8; - int interpPhaseCount = 128; - float lastSymbol = 0.0f; - int offsetInt; - }; -} \ No newline at end of file From 650a61930ca45ef28ac2f2729da65a4b926371da Mon Sep 17 00:00:00 2001 From: AlexandreRouma Date: Tue, 13 Feb 2024 18:39:11 +0100 Subject: [PATCH 14/14] fix SDR++ server crash at high samplerates #1326 --- core/src/dsp/compression/sample_stream_compressor.h | 4 ++++ core/src/server.cpp | 2 +- .../sdrpp_server_source/src/sdrpp_server_client.cpp | 4 ++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/core/src/dsp/compression/sample_stream_compressor.h b/core/src/dsp/compression/sample_stream_compressor.h index 69b5cbbfa..8e79b8bf8 100644 --- a/core/src/dsp/compression/sample_stream_compressor.h +++ b/core/src/dsp/compression/sample_stream_compressor.h @@ -12,6 +12,10 @@ namespace dsp::compression { void init(stream* in, PCMType pcmType) { _pcmType = pcmType; + + // Set the output buffer size to the max size of a complex buffer + 8 bytes for the header + out.setBufferSize(STREAM_BUFFER_SIZE*sizeof(complex_t) + 8); + base_type::init(in); } diff --git a/core/src/server.cpp b/core/src/server.cpp index a780a3845..501198c33 100644 --- a/core/src/server.cpp +++ b/core/src/server.cpp @@ -230,7 +230,7 @@ namespace server { // Compress data if needed and fill out header fields if (compression) { bb_pkt_hdr->type = PACKET_TYPE_BASEBAND_COMPRESSED; - bb_pkt_hdr->size = sizeof(PacketHeader) + (uint32_t)ZSTD_compressCCtx(cctx, &bbuf[sizeof(PacketHeader)], SERVER_MAX_PACKET_SIZE, data, count, 1); + bb_pkt_hdr->size = sizeof(PacketHeader) + (uint32_t)ZSTD_compressCCtx(cctx, &bbuf[sizeof(PacketHeader)], SERVER_MAX_PACKET_SIZE-sizeof(PacketHeader), data, count, 1); } else { bb_pkt_hdr->type = PACKET_TYPE_BASEBAND; diff --git a/source_modules/sdrpp_server_source/src/sdrpp_server_client.cpp b/source_modules/sdrpp_server_source/src/sdrpp_server_client.cpp index 0e25efe75..9b1e63d56 100644 --- a/source_modules/sdrpp_server_source/src/sdrpp_server_client.cpp +++ b/source_modules/sdrpp_server_source/src/sdrpp_server_client.cpp @@ -30,7 +30,7 @@ namespace server { dctx = ZSTD_createDCtx(); // Initialize DSP - decompIn.setBufferSize((sizeof(dsp::complex_t) * STREAM_BUFFER_SIZE) + 8); + decompIn.setBufferSize(STREAM_BUFFER_SIZE*sizeof(dsp::complex_t) + 8); decompIn.clearWriteStop(); decomp.init(&decompIn); link.init(&decomp.out, output); @@ -209,7 +209,7 @@ namespace server { if (!decompIn.swap(r_pkt_hdr->size - sizeof(PacketHeader))) { break; } } else if (r_pkt_hdr->type == PACKET_TYPE_BASEBAND_COMPRESSED) { - size_t outCount = ZSTD_decompressDCtx(dctx, decompIn.writeBuf, STREAM_BUFFER_SIZE, r_pkt_data, r_pkt_hdr->size - sizeof(PacketHeader)); + size_t outCount = ZSTD_decompressDCtx(dctx, decompIn.writeBuf, STREAM_BUFFER_SIZE*sizeof(dsp::complex_t)+8, r_pkt_data, r_pkt_hdr->size - sizeof(PacketHeader)); if (outCount) { if (!decompIn.swap(outCount)) { break; } };